JavaCC解释器(AST到符号表)

时间:2014-05-25 16:12:29

标签: compiler-construction abstract-syntax-tree javacc semantic-analysis symbol-table

我对如何创建javacc解释器非常困惑,特别是如何从之前生成的AST树构建符号表。

这样的东西,从这个AST:

> Program
>  Id
>  Id
>  Id
>  VarDecl
>   Type
>   Id
>  Stl
>   Id
>   NewInt
>    IntLit
>  Sta
>   Id
>   IntLit
>   ParseArgs
>    Id
>    IntLit
>  Sta
>   Id
>   IntLit
>   ParseArgs
>    Id
>    IntLit
(…)

到此表

=== Symbol table ===
Name    Type    Init    Values
----    ----    ----    ------
args    args[]  true    2   12  8
x        int[]  true    2   4   0

以此输入为例

class gcd {
  public static void main(String[] args) {
    int[] x;
    x = new int[2];

    x[0] = Integer.parseInt(args[0]);
    x[1] = Integer.parseInt(args[1]);
    if (x[0] == 0)
      System.out.println(x[1]);
    else
      while (x[1] > 0) {
        if (x[0] > x[1])
          x[0] = x[0] - x[1];
        else
          x[1] = x[1] - x[0];
      }
    System.out.println(x[0]);
  }
}

我现在拥有的只是创造了AST。

我的主要问题是如何定义然后逐一比较树上的类型。

任何帮助都会很棒,包括理论。

感谢。

1 个答案:

答案 0 :(得分:3)

简单的答案是“走树,建立符号表”。

当您递归 down 树时,您将遇到范围构造;为遇到的每个这样的节点构建一个范围,并推送到范围堆栈的顶部。当您访问该节点的声明子节点时引入了一个作用域,在作用域堆栈顶部的作用域中插入声明的定义。当您从引入范围的节点返回时,弹出范围堆栈。 Voila:词汇范围语言的符号表。所有这些都独立于JavaCC,在编译器书籍中得到了很好的解释。建议你拿一个并仔细阅读。

使用命名空间的语言并不容易,但可以加入到这种结构中。有些语言在范围之间具有更复杂的关系,而这并不容易。

现在,要为Java做这个...类型系统的细节是复杂而神秘的,并且知道类型的语法意味着什么的复杂性非常复杂,尤其是。模板类型。没有编译器书可以帮助你;如果构建自己的符号表,则需要解释Java参考手册。期待这很困难;这是为了其他所有人。

当您遇到软件包引用时,您会发现其中一个“不那么容易嵌套”的范围问题;要解析包含包引用的模块的名称,首先必须找到引用包的源文件或类文件,并为 构建符号表。这实际上意味着在为一个文件构建符号表的过程中,您可能必须进入文件系统,解析文件[作为文本或类]并在继续之前构建符号表。

结论:对于符号表构建器,Java充满了不便之处。

(我构建了程序分析工具。我们花了几天时间才能将所有各种Java方言都解析为解析,部分原因是我们拥有非常好的解析机制;我们花了几个月的时间来构建一个通过Java 1.7编写适当的符号表,我们正在研究Java 1.8)。

如果您确实想要使用AST和符号表,那么获得/使用其他人的解析器/名称类型解析器要好得多。想到JDT AST机器。我公司也在这个领域提供工具。