2.2.5 调用parseCompilationUnit()方法执行词法解析词法解析的核心就是校验当前 Token 是否匹配 com.sun.tools.javac.parser.JavacParser类在 parseCompilationUnit()方法中定义的匹配规则。本书在 2.2.4 节中提及过 Token 的读取顺序是在 Scanner 类的 nextToken()方法中进行控制的,那么当成功读取到 Token 后, parseCompilationUnit()方法便会按照 Java 语法规范校验 Token 的匹配顺序。也就是说, Token的读取顺序与 Token 的匹配顺序必然需要保持一致, Token 的读取规则决定规定了什么情况下应该出现什么 Token,这样一来,词法解析器便会按照指定的 Token 读取顺序返回与匹配顺序一致的 Token。为了使大家阅读更方便,本书示例了 parseCompilationUnit()方法的完整代码,如下所示:代码 2-8 parseCompilationUnit()方法的完整代码 public JCTree.JCCompilationUnit parseCompilationUnit() { int pos = S.pos(); JCExpression pid = null; String dc = S.docComment();27B2.2 词法解析步骤 JCModifiers mods = null; ListJCAnnotation packageAnnotations = List.nil(); /* 解析访问修饰符 */ if (S.token() == MONKEYS_AT) mods = modifiersOpt(); /* 解析 package 关键字 */ if (S.token() == PACKAGE) { if (mods != null) { checkNoMods(mods.flags); packageAnnotations = mods.annotations; mods = null; } S.nextToken(); pid = qualident(); accept(SEMI); } ListBufferJCTree defs = new ListBufferJCTree(); boolean checkForImports = true; while (S.token() != EOF) { if (S.pos() = errorEndPos) { // error recovery skip(checkForImports, false, false, false); if (S.token() == EOF) break; } /* 解析 import 关键字 */ if (checkForImports mods == null S.token() == IMPORT) { defs.append(importDeclaration()); } else { /* 解析类主体信息并转换为语法树 */ JCTree def = typeDeclaration(mods); if (keepDocComments dc != null docComments.get(def) == dc) { // If the first type declaration has consumed