java 编写java编译器_从零开始写个编译器吧 - Token.java 文件的编写

现在,让我们来动手写编译器的第一个个java文件吧。本章要写的类,是Token类。如其名字所示,这个类实例化的对象用于表示词法分析器 Tokenizer 的产物。同时,也作为下一阶段的语法分析器 Parser 的原料。

让我们开始吧!先新建一个Token.java 于 src/com/taozeyu/taolan/analysis之中。

package com.taozeyu.taolan.analysis;

public class Token {

public static enum Type {

Keyword, Number, Identifier, Sign, Annotation,

String, RegEx, Space, NewLine, EndSymbol;

}

final Type type;

final String value;

Token(Type type, String value) {

//TODO

}

}

如之前章节讨论的一样,Token对象应该包含类型和语素两个属性。注意这个 Type 枚举类型,其内容就是我在上一章所说的 tao 语言应该具备的10种单词类型。

我希望词法分析器从源代码中提取出语素,并根据上下文推测出单词类型,从而构造出Token对象。但实际上,请注意Type这个枚举类的三个类型:

Keyword, Number, Identifier

这三个类型不同之处?实际上这三个类型的形式极其类似(甚至 Keyword 和 Identifier 的形式是完全相同的),并且可以仅通过语素准确判定其类型。因此,我希望对词法分析器 Tokenizer 隐藏着三种类型的区别,将这三种类型统称 Identifier,以简化编码。

Token(Type type, String value) {

if(type == Type.Identifier) {

char firstChar = value.charAt(0);

if(firstChar >= '0' & firstChar < '9') {

type = Type.Number;

} else if(keywordsSet.contains(value)){

type = Type.Keyword;

}

}

this.type = type;

this.value = value;

}

于是,Token 对 Tokenizer 隐藏了 Number、Keyword 类型。Tokenizer 只需要构造出 Identifier 类型即可,进一步细分将在 Token 的构造函数中进行。

特别的,构造函数中引用了一个 keywordsSet 变量。实际上这个变量应该包含所有 tao 语言的关键字。此处稍稍定义一下。

private static final HashSet keywordsSet = new HashSet<>();

static {

keywordsSet.add("if");

keywordsSet.add("when");

keywordsSet.add("elsif");

keywordsSet.add("else");

keywordsSet.add("while");

keywordsSet.add("begin");

keywordsSet.add("until");

keywordsSet.add("for");

keywordsSet.add("do");

keywordsSet.add("try");

keywordsSet.add("catch");

keywordsSet.add("finally");

keywordsSet.add("end");

keywordsSet.add("def");

keywordsSet.add("var");

keywordsSet.add("this");

keywordsSet.add("null");

keywordsSet.add("throw");

keywordsSet.add("break");

keywordsSet.add("continue");

keywordsSet.add("return");

keywordsSet.add("operator");

}

好吧,tao 语言我能想出的可能有的关键字都在这里了。如果有遗漏或者多余,其实以后再回过头来改也没问题。

特别的,对于 Annotation、String、RegEx ,它们在源代码中存在的形式和具体的语素并不完全等同。

#我是注释(回车)

"我是一个字符串"

^\s+\d+$

对于 Tokenizer 而言,它倾向于读出如上一整行信息。但是仅仅只加下划线的文字是Token的语素。因此,我还需要再构造函数中对构造参数value进行进一步提取,以得到正确的语素。

另外,EndSymbol 的语素必须为空,不管 Tokenizer 传入什么参数都必须如此。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值