【问题标题】:How to reproduce the original code using an AST from JJTree如何使用 JJTree 中的 AST 重现原始代码
【发布时间】:2018-04-12 23:57:18
【问题描述】:

我的任务是我必须使用 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

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

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

【问题讨论】:

  • 也许你可以看看这个链接:github.com/jamiebuilds/the-super-tiny-compiler
  • 尽管该链接很酷,但我只是想弄清楚如何从 JJTree 的 AST 中获取与令牌关联的 ID。 Javascript 在这里对我没什么用。

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


【解决方案1】:

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

例如,他写道

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类中
  • 使用您自己的具有 id 访问器的类对 SimpleNode 进行子类化,并通过使用 NODE_CLASS 选项确保解析器使用该类。还要更改 buildString 的参数类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 2020-07-20
    • 2021-10-17
    • 2021-01-09
    • 2011-07-05
    • 1970-01-01
    相关资源
    最近更新 更多