如何使用 JJTree 中的 AST 重现原始代码

How to reproduce the original code using an AST from JJTree

我接到了一项任务,我必须使用 JavaCC 解析器来制作编译器。我有一个合成语言的语法,我们称之为 K。给定一个输入程序,我必须能够读取该程序,创建一个 AST,然后遍历该 AST 以更清晰的方式重现原始程序上表格。

例如,给定代码:

begin a := 2
s := 0 while - a
12 begin
    s := + s * a a a := + a 2
end end

一旦我将其输入到我的程序中,我将得到一个由 Op、Const、ID 等元素组成的 AST...

但我需要能够获取代码中使用的实际数字和变量,以便我可以像这样重现代码:

begin
  a := 2
  s := 0
  while - a 12
    begin
      s := + s * a a
      a := + a 2
    end
end

我已经通读了展示如何制作 AST 的示例 here,据我所知我可以正常工作。我感到困惑的是如何从 AST 中获取生成节点的实际文本。这个问题中的人使用了 dump 方法,但这只会让你返回节点的类型。我只需要了解如何在遍历节点时从节点获取实际标识符。

非常感谢这里的一些建议。

SimpleNode class 中有一个名为 value 的字段,您可以随意使用它。在 Bart Kiers 对 this question 的回答中,您可以看到他使用值字段来存储标识符名称和常量等信息。

例如,他写

void id() #ID :
{Token t;}
{
  t=<ID> {jjtThis.value = t.image;}
}

这意味着 .id 等于 ID 的任何节点都将在其 value 字段中包含标识符(作为字符串)。

要遍历树来重现输入,你可以写一个单一的大递归方法来遍历树,也可以使用访问者。

这是单个大方法的样子

static void buildString( SimpleNode n, String indentation, StringBuilder out ) {
    swtich( n.id ) {
        ...
        case ID: out.append( n.jjtGetValue() ) ; break ;
        ...
    }
}

由于 id 字段被保护,上面的代码不会编译。您可以执行以下操作之一:

  • id 更改为 public。 (最好添加一个 public 访问器并使用它。)
  • buildString方法放在SimpleNode中class
  • Subclass SimpleNode 与您自己的 class 具有 id 访问器,并确保解析器通过使用 NODE_CLASS 选项使用该 class。同时更改 buildString 参数的类型。