6

ANTLR 使用的推荐模式是让 Parser 构造一个抽象语法树,然后构建 Tree walkers(AKA 树语法)来处理它们。

我试图弄清楚为什么我的树语法不起作用,并且很想使用 ANTLRWorks 的调试器,就像我将它用于解析器本身一样。解析器的输入是“源代码”,但树解析器的输入是解析器的 AST 结果。我看不到如何将其作为输入来测试树语法。

目前尚不清楚是否有一种方法可以在 ANTLRWorks 中测试树语法。如果可以做到,将不胜感激指向正确方向的指针。

4

3 回答 3

6

ANTLRWorks 调试器应该可以很好地与您的树语法配合使用。如果我没记错的话,您需要使用带有“-debug”标志的 ANTLR 代码生成工具(我使用的是 Java 目标),然后,在您创建树解析器实例的地方,使用带有端口的调试构造函数作为一个论点。在我的情况下,默认端口不起作用,所以我随意选择了 35505。

启动 ANTLRWorks,打开树语法,单击“运行”->“调试远程...”,将端口设置为树解析器的构造函数中使用的相同值,您应该能够将调试器连接到您的运行应用程序。有关详细信息,请参阅ANTLR 3 调试常见问题解答

[更新] 假设您使用的是 Java 目标(如果不是这样,请告诉我们),这里有更多关于入门的详细信息:

当您在 ANTLRWorks 中测试您的非树解析器时,有一个幕后过程会从您的语法文件生成 Java 代码,然后使用该代码来解析您的输入。当您在自己的应用程序中使用解析器时,您必须使用 ANTLR(特别是 class org.antlr.Tool)来生成 Java 代码,然后您可以将其包含在您的应用程序中。ANTLRWorks 有一个菜单选项,可以帮助您入门。在我的例子中,我的 ant 构建文件中有一个目标,它从我的语法生成 Java 代码,并将这些 Java 源文件放在我的应用程序的其余部分可以找到它们的地方。我的蚂蚁目标看起来像这样:

<java classpath="${antlr.tool.classpath}" classname="org.antlr.Tool" failonerror="true">
    <arg value="-o" />
    <arg value="${antlr.out.dir}" />
    <arg value="${grammar.dir}/GrammarName.g" />
</java>

该属性antlr.tool.classpath需要包含stringtemplate.jarand antlr.jar,并且antlr.out.dir需要指向您希望生成的源代码所在的目录(例如build/antlr/src/org/myorg/antlr/parser,如果您的解析器语法指定了 package org.myorg.antlr.parser)。

然后,当您编译应用程序的其余部分时,您可以使用以下内容:

<javac destdir="${build.classes.dir}" debug="on" optimize="on" deprecation="${javac.deprecation}" source="${javac.source}" target="${javac.target}">
    <classpath refid="stdclasspath"/>
    <src path="${src.dir}" />
    <src path="${antlr.src.dir}" />
</javac>

在这里,我们编译我们的应用程序源代码 (in src.dir) 以及生成的 ANTLR 代码 (in antlr.src.dir,在本例中为build/antlr/src)。

至于在您的应用程序中使用生成的代码(即,在 ANTLRWorks 之外),您需要执行以下操作:

String sourceText = "a + b = foo";
ANTLRStringStream inStream = new ANTLRStringStream(sourceText);

// your generated lexer class
MyLexer lexer = new MyLexer(inStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);

// your generated parser class
MyParser parser = new MyParser(tokens);

// run the toplevel rule (in this case, `program`)
MyParser.program_return prog = parser.program();

// get the resulting AST (a CommonTree instance, in this case)
CommonTree tree = (CommonTree) prog.getTree();

// run a tree parser rule on the AST
MyTreeParser treeParser = new MyTreeParser(new CommonTreeNodeStream(tree));
treeParser.program();

如果您要使用 ANTLR,我强烈建议您获取The Definitive ANTLR Reference的副本。所有这些都涵盖得相当透彻,并提供了大量示例来帮助您入门。

于 2009-10-21T14:36:39.437 回答
2

有一种使用 AntlrWorks 的方法:

  1. 在 AntlrWorks 中编写你的语法
  2. 生成它的代码(这与从命令行运行 Antlr 无调试相同)
  3. 为自己编写一个类似于Debugging with AntlrWorks 常见问题解答中建议的存根
  4. 写下你的树语法
  5. 选择调试 Antlrworks(这与使用调试标志从命令行运行 Antlr 相同。
  6. 运行存根程序。程序会一直阻塞,直到连接了antlrworks,所以可以调试树语法
  7. 返回打开树语法的 antlrworks,然后远程调试
  8. 解决问题.... :)
于 2012-08-08T19:13:09.220 回答
0

如果您确定您正在构建的 AST 没有问题(使用 ANTLRWORKS 调试器),那么树遍历测试与测试任何其他应用程序没有什么不同。例如,如果您要发出 Java 代码,请使用 Eclipse 的调试器对其进行测试,或者使用普通的日志消息...

于 2009-10-18T16:44:04.413 回答