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

时间:2018-04-12 23:57:18

标签: java compiler-construction abstract-syntax-tree javacc

我的任务是完成一项任务,我必须使用JavaCC解析器来编写代码。我有一个编写语言的语法,我们称之为K.给定一个输入程序,我必须能够读取该程序,创建一个AST,然后遍历该AST以更清洁地重现原始程序形式。

例如,给定代码:

Uint32* buffer = new Uint32[width * height];

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

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

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

我已经阅读了示例here,其中显示了如何制作AST,据我所知,我有这个工作。我感到困惑的是如何获得生成节点的实际文本退出AST。此问题中的人使用了dump方法,但这只会让您返回节点的类型。我只需要了解如何在迭代它们时从节点获取实际标识符。

我真的很感激这里有一些建议。

1 个答案:

答案 0 :(得分:0)

SimpleNode课程中有一个名为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。 (最好添加一个公共访问器并使用它。)
  • buildString方法放在SimpleNode类
  • 使用您自己的类的SimpleNode子类,该类具有id的访问器,并确保解析器使用NODE_CLASS选项来使用该类。还要更改buildString参数的类型。