Javac 语法分析1

Javac 语法分析1

语法分析: 根据一个个 Token 构造出抽象语法树

语法树节点类

基类 JCTree
其他类均在 JCTree 里 定义的静态内部类,比如

JCStatement in JCTree (com.sun.tools.javac.tree) 表示语句
    JCMethodDecl in JCTree (com.sun.tools.javac.tree) 表示一个方法定义,包括抽象 和 非抽象方法
    JCModifiers in JCTree (com.sun.tools.javac.tree) 修饰符,如 如public等
    JCTypeParameter in JCTree (com.sun.tools.javac.tree) 类型参数,比如类,接口
    JCImport in JCTree (com.sun.tools.javac.tree) 导入声明
    JCExpression in JCTree (com.sun.tools.javac.tree) 表达式
    JCCompilationUnit in JCTree (com.sun.tools.javac.tree) 一个Java源文件对应一个 JCCompilationUnit
    JCCatch in JCTree (com.sun.tools.javac.tree)
    TypeBoundKind in JCTree (com.sun.tools.javac.tree)

文法

[x] 表示 x 可以出现 0 次或者一次;

{x} 表示 x 可以出现 0 次或者多次;

(x|y) 表示可以出现 x 或者 y

建立语法树

入口 com.sun.tools.javac.parser.JavacParser#parseCompilationUnit()
解析 包声明、ImportDeclaration 与 TypeDeclaration,然后创建一个编译单元.

public JCTree.JCCompilationUnit parseCompilationUnit() {
    Token firstToken = token;
    JCExpression pid = null;
    JCModifiers mods = null;
    boolean consumedToplevelDoc = false;
    boolean seenImport = false; // 看到了 import 的 token
    boolean seenPackage = false; // 看到了 package 的 token
    List<JCAnnotation> packageAnnotations = List.nil();
    if (token.kind == MONKEYS_AT) // 解析包上注解
        mods = modifiersOpt();

    if (token.kind == PACKAGE) { // 解析包
        seenPackage = true;
        if (mods != null) {
            checkNoMods(mods.flags);
            packageAnnotations = mods.annotations;
            mods = null;
        }
        nextToken(); // 读取下一个token
        pid = qualident(false); // 解析包名
        accept(SEMI); // 处理包名最后的 分号(;)
    }
    ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
    boolean checkForImports = true;
    boolean firstTypeDecl = true;
    while (token.kind != EOF) {
        if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
            // error recovery
            skip(checkForImports, false, false, false);
            if (token.kind == EOF)
                break;
        }
        if (checkForImports && mods == null && token.kind == IMPORT) { // 解析 import
            seenImport = true;
            defs.append(importDeclaration()); // 处理 import 声明
        } else { // 解析 类型声明
            Comment docComment = token.comment(CommentStyle.JAVADOC);
            if (firstTypeDecl && !seenImport && !seenPackage) {
                docComment = firstToken.comment(CommentStyle.JAVADOC);
                consumedToplevelDoc = true;
            }
            JCTree def = typeDeclaration(mods, docComment); // 类型声明
            if (def instanceof JCExpressionStatement)
                def = ((JCExpressionStatement)def).expr;
            defs.append(def);
            if (def instanceof JCClassDecl)
                checkForImports = false;
            mods = null;
            firstTypeDecl = false;
        }
    }
    JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList());
    if (!consumedToplevelDoc)
        attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
    if (defs.isEmpty())
        storeEnd(toplevel, S.prevToken().endPos);
    if (keepDocComments)
        toplevel.docComments = docComments;
    if (keepLineMap)
        toplevel.lineMap = S.getLineMap();
    toplevel.endPositions = this.endPosTable;
    return toplevel;
}
### 回答1: 编译原理语法分析是编译器的关键步骤之一,用于检查源码是否符合文法规则,判断语义是否正确,生成中间代码等等。其中递归下降分析法是常用的语法分析方法之一。具体说,递归下降分析法从语法的开始符号开始,通过递归调用函数来实现对语法规则的分析。在解析过程中,程序使用递归下降算法按照语法的层次进行分解,将复杂的问题分解为简单的子问题,每个子问题对应一个子程序,依次调用子程序就可以完成对整个文法的语法分析。 在Java编译器的实现中,javac采用了递归下降分析法。Java语言的语法规则十分复杂,包括各种语句、表达式、变量类型等等,因此编写一个符合Java语法的递归下降分析程序也非常复杂。总的来说,javac语法分析程序包括以下几个部分:词法分析器、语法分析器、符号表等。 词法分析器用于将源程序转化为词法单元(Token),然后传给语法分析器进行分析。语法分析器则根据Java语法规则,利用递归下降分析法来对Token序列进行分析,采用自顶向下的分析方法,逐步分析语法规则,直到最终将整个程序解析完成。在语法分析过程中,还需要使用符号表来确定变量类型,计算表达式的值等等,完成语义分析的任务。 总的来说,递归下降分析法是一种常用的语法分析方法,适用于多种编程语言的编译器实现,可以通过编译原理的学习和练习,更好地掌握这一方法,并开发出高质量的编译器。 ### 回答2: 编译原理语法分析是指将源程序转换为一种内部表示形式的过程,在此过程中,需要对源程序进行语法分析,也就是检查源程序是否符合语法规则。递归下降分析是一种常用的语法分析方法,它是基于自顶向下的语法推导方法实现的。 在进行递归下降分析时,我们需要将源程序按照相应的语法规则进行分解,然后递归分析每个生成式对应的子串,最终得到源程序的语法树。递归下降分析的一个优点是它能够直接产生语法树,因此更容易进行语义分析和代码生成等后续处理。 在Java编译器的实现中,javac使用了递归下降分析方法对源代码进行语法分析。在分析过程中,它将Java源代码分解为若干个符号,然后按照Java语法规则进行递归下降分析,最终得到语法树。与其他编译器相比,javac的递归下降分析方法具有较高的可读性和可维护性,因为它的代码与Java语法规则紧密相关。 同时,在语法分析的过程中,javac还涉及到词法分析、语法错误处理、符号表管理等方面的问题,这些都是编译原理的基础知识点,对于Java编译器的实现非常重要。 ### 回答3: 编译原理语法分析是编译器的一个重要组成部分,其作用是对程序源代码进行语法分析,将其转换为可以执行的目标代码。其中,递归下降分析法是一种常用的语法分析方法。 在递归下降分析法中,编译器会根据语法规则对源代码进行递归分析,以确定其语法正确性,并生成对应的语法树。该方法的基本思路是把一个复合语法规则拆分成多个较简单的子规则,然后通过递归调用不同的子规则来完成分析过程。这种方法可以较为高效地进行语法分析,但需要编写大量的递归函数来完成分析工作。 对于Java编译器而言,语法分析是其中一个非常重要的部分,因为Java中有严格的语法规则需要遵循。在语法分析中,Java编译器可以使用递归下降分析法进行处理,通过遍历源代码来分析其中的语法结构,生成对应的语法树,最终将其转化为可执行的目标代码。同时,在使用递归下降分析法时,Java编译器需要对不同的语法规则进行拆分和分析,并通过栈的方式来完成函数递归调用,以实现整个语法分析过程。 总之,递归下降分析法是编译原理语法分析中的一个重要方法,可以用于解析各种编程语言中的语法结构。在Java编译器中,递归下降分析法也是其中一个重要的语法分析方法,在语法分析过程中起着关键性的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlyingZCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值