1. 词法分析器与语法分析器
1.1 javac词法、语法分析器概览及Intellij IDEA调试跟踪流程
javac词法分析器Intellij IDEA调试跟踪流程
词法分析器实例的生成流程
词法器与语法器实例生成
1.2 词法分析器——核心流程是readToken()
词法分析器的接口类是com.sun.tools.javac.parser.Lexer;
实现类是com.sun.tools.javac.parser.Scanner。
字符流存放在JavaTokenizer类的成员protected UnicodeReader reader;里面,在该类的方法public Token readToken()里面将字符流组装成Token,在这里会将收集到的新名字加入到Names字符表里面。
Scanner类token的获取
readToken()返回Token类别
switch (tk.tag) {
case DEFAULT: return new Token(tk, pos, endPos, comments);
case NAMED: return new NamedToken(tk, pos, endPos, name, comments);
case STRING: return new StringToken(tk, pos, endPos, reader.chars(), comments);
case NUMERIC: return new NumericToken(tk, pos, endPos, reader.chars(), radix, comments);
default: throw new AssertionError();
}
Tokens类具体内容
问题.Javac如何划分Token,如何知道哪些字符组合成一个Token?(词法器)
Java代码有package、import、类定义、field定义、method定义、变量定义、表达式定义等语法规则。
这些规则除了一些Java语法规定的关键词,就是用户自定义的变量名称。
自定义的名称包括包名、类名、变量名、方法名。
关键词和自定义名称之间用空格隔开,每个语法表达式用分号结束。
如何判断哪些字符组合是一个Token的规则是在Scanner的nextToken方法中定义的,每次都会构造一个Token。
PaserFactory构建Names Tokens等
枚举类的关键方法
1)静态values方法返回一个包含全部枚举值的数组
2)ordinal方法返回enum声明中枚举常量的位置,位置从0开始计数
构建Names Tokens的流程
关于Tokens
为了显示方便,下图中对TokenKind枚举类的枚举值个数定义进行了删减
1)Tokens.tokenName存储的是“关键字在TokenKind里面的位置(token.ordinal())”与“关键字Name”的关系,该数组映射这两对关系。
2)Tokens.key存储的是“关键字Name在Names存储的位置index”与“关键字TokenKind本身”的关系,该数组映射这两对关系。
3)Tokens.maxKey在初始化更新完所有关键字后就固定下来,所以非关键字的index都大于maxKey
关于Name Table Names
分析后可知:Names是每个区域的名字表。
1)该表是利用哈希表+链表