ANTLR 使用的推荐模式是让 Parser 构造一个抽象语法树,然后构建 Tree walkers(AKA 树语法)来处理它们。
我试图弄清楚为什么我的树语法不起作用,并且很想使用 ANTLRWorks 的调试器,就像我将它用于解析器本身一样。解析器的输入是“源代码”,但树解析器的输入是解析器的 AST 结果。我看不到如何将其作为输入来测试树语法。
目前尚不清楚是否有一种方法可以在 ANTLRWorks 中测试树语法。如果可以做到,将不胜感激指向正确方向的指针。
ANTLR 使用的推荐模式是让 Parser 构造一个抽象语法树,然后构建 Tree walkers(AKA 树语法)来处理它们。
我试图弄清楚为什么我的树语法不起作用,并且很想使用 ANTLRWorks 的调试器,就像我将它用于解析器本身一样。解析器的输入是“源代码”,但树解析器的输入是解析器的 AST 结果。我看不到如何将其作为输入来测试树语法。
目前尚不清楚是否有一种方法可以在 ANTLRWorks 中测试树语法。如果可以做到,将不胜感激指向正确方向的指针。
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.jar
and 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的副本。所有这些都涵盖得相当透彻,并提供了大量示例来帮助您入门。
有一种使用 AntlrWorks 的方法:
如果您确定您正在构建的 AST 没有问题(使用 ANTLRWORKS 调试器),那么树遍历测试与测试任何其他应用程序没有什么不同。例如,如果您要发出 Java 代码,请使用 Eclipse 的调试器对其进行测试,或者使用普通的日志消息...