有谁知道在 ANTLRWorks 中调试树语法的方法

发布于 2024-08-08 05:33:31 字数 244 浏览 5 评论 0原文

ANTLR 使用的推荐模式是让解析器构造一个抽象语法树,然后构建树遍历器(又称树语法)来处理它们。

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

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

The recommended pattern for ANTLR usage is to have the Parser construct an Abstract Syntax Tree, and then build Tree walkers (AKA tree grammars) to process them.

I'm trying to get to the bottom of why my tree grammar isn't working and would love to use ANTLRWorks' debugger the same way I used it for the parser itself. The input to the parser is the "source code", but the input to a tree parser is the AST result of the parser. I don't see how to make that available as input to test the tree grammar.

It's not clear that there is a way to test a tree grammar in ANTLRWorks. If it can be done, a pointer in the right direction would really be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暗地喜欢 2024-08-15 05:33:32

有一种使用 AntlrWorks 的方法:

  1. 在 AntlrWorks 中编写语法
  2. 生成其代码(这与从命令行运行 Antlr 相同,无需调试)
  3. 自己编写一个类似于 使用 AntlrWorks 进行调试常见问题解答
  4. 编写树语法
  5. 选择调试 Antlrworks(这与从运行 Antlr 相同)带有调试标志的命令
  6. 行运行存根程序,直到连接到 antlrworks,因此您可以调试树语法
  7. 返回打开树语法的 antlrworks,然后调试远程
  8. 解决问题...:)

There is a way to use AntlrWorks:

  1. Write your grammar in AntlrWorks
  2. Generate its code (this is the same as running Antlr from the commandline w/o debug)
  3. Write yourself a stub similar to what was suggested on the Debugging with AntlrWorks faq
  4. Write your tree grammar
  5. Select debug Antlrworks (this is the same as running Antlr from the commandline with the debug flag.
  6. Run the stub program. The program will block until antlrworks is connected, so you can debug the tree grammar
  7. Go back to antlrworks that has your tree grammar open, and Debug Remote
  8. Solve issues.... :)
幻想少年梦 2024-08-15 05:33:32

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

If you're sure that the AST you're building is fine (with ANTLRWORKS debugger), the tree-walking testing is not different than testing any other app. If you're emitting Java Code for example, use Eclipse's debugger to test it, or plain log messages...

萌吟 2024-08-15 05:33:31

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

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

[更新] 假设您使用的是 Java 目标(如果情况并非如此,请告诉我们),以下是有关入门的更多详细信息:

当您在 ANTLRWorks 中测试非树解析器时,有一个后台进程可以从您的语法文件生成 Java 代码,然后使用该代码来解析您的输入。当您在自己的应用程序中使用解析器时,必须使用 ANTLR(具体来说,org.antlr.Tool 类)来生成 Java 代码,然后将其包含在您的应用程序中。 ANTLRWorks 有一个菜单选项,可以帮助您入门。就我而言,我的 ant 构建文件中有一个目标,该目标根据我的语法生成 Java 代码,并将这些 Java 源文件放在应用程序的其余部分可以找到它们的位置。我的 ant 目标看起来像这样:

<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.jarantlr.jar,以及 antlr.out.dir 需要指向您希望生成的源代码所在的目录(例如,build/antlr/src/org/myorg/antlr/parser,如果您的解析器语法指定包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>

在这里,我们编译应用程序源(在 src.dir 中)以及生成的 ANTLR 代码(在 antlr.dir 中)。 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 参考(如果您要使用 ANTLR)。所有这些内容都非常全面地涵盖,并提供了大量示例来帮助您入门。

The ANTLRWorks debugger should work fine with your tree grammar. If I recall correctly, you need to use the ANTLR code generation tool with the "-debug" flag (I'm using the Java target), then, where you create your tree parser instance, use the debug constructor that takes a port as an argument. In my case, the default port didn't work, so I arbitrarily picked 35505.

Fire up ANTLRWorks, open your tree grammar, click "Run"->"Debug Remote...", set the port to the same value used in the constructor for your tree parser, and you should be able to connect the debugger to your running application. See the ANTLR 3 Debugging FAQ for details.

[Update] Assuming you're using the Java target (let us know if that's not the case), here's more detailed information on getting started:

When you're testing your non-tree parser in ANTLRWorks, there's a behind-the-scenes process that generates Java code from your grammar file, then uses that code to parse your input. When you use your parser in your own application, you have to use ANTLR (specifically, the class org.antlr.Tool) to generate Java code that you can then include in your application. ANTLRWorks has a menu option for this, which should get you started. In my case, I have a target in my ant build file that generates the Java code from my grammars and puts those Java source files in a place where the rest of my application can find them. My ant target looks something like this:

<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>

The property antlr.tool.classpath needs to contain stringtemplate.jar and antlr.jar, and antlr.out.dir needs to point to the directory where you want the generated source code to go (e.g., build/antlr/src/org/myorg/antlr/parser, if your parser grammars specify the package org.myorg.antlr.parser).

Then, when you compile the rest of your application, you can use something like:

<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>

Here, we compile our application sources (in src.dir) along with the generated ANTLR code (in antlr.src.dir, which in this example would be build/antlr/src).

As far as using the generated code in your application (i.e., outside ANTLRWorks), you'll need to do something like:

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();

I strongly recommend getting a copy of The Definitive ANTLR Reference if you're going to be using ANTLR. All of this is covered pretty thoroughly, with plenty of examples to get you started.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文