我已经搜索了很多关于这方面的东西,我没有找到任何有用的东西,真正帮助我建立一个AST.我已经知道,ANTLR 4不像ANTLR 3以前做的那样建立AST.大家说:“嘿,使用访客!",但我找不到任何例子或更详细的解释,我怎么能做到这一点...
我有一个语法必须喜欢C,但每一个命令写在葡萄牙语(葡萄牙编程语言)。我可以很容易地生成使用ANTLR 4的解析树。我的问题是:我现在需要做什么来创建AST?
顺便说一句,我正在使用Java和IntelliJ...
**EDIT 1:**我能得到的最接近的答案是使用此主题的答案:Is there a simple example of using antlr4 to create an AST from java source code and extract methods, variables and comments?但它只打印被访问方法的名称。
由于第一次尝试没有像我预期的那样对我起作用,我尝试使用ANTLR 3中的this tutorial,但我不知道如何使用StringTamplate代替ST...
阅读The Definitive ANTLR 4 Reference这本书,我也找不到任何与AST相关的东西。
**EDIT 2:**现在我有一个类来创建DOT文件,我只需要弄清楚如何正确地使用访问者
4条答案
按热度按时间3npbholx1#
好吧,让我们来构建一个简单的数学例子。构建一个AST对于这样的任务来说是完全多余的,但是它是一个展示原理的好方法。
我会用C#来做,但Java版本会非常相似。
∮语法
首先,让我们编写一个非常基本的数学语法:
非常基本的东西,我们有一个单一的
expr
规则,处理一切(优先规则等)。AST节点
然后,让我们定义一些我们将要使用的AST节点。这些都是完全自定义的,你可以用你想要的方式定义它们。
下面是我们将在此示例中使用的节点:
将CST转换为AST
ANTLR为我们生成了CST节点(
MathParser.*Context
类),现在我们需要将这些节点转换为AST节点。访问者很容易做到这一点,ANTLR为我们提供了一个
MathBaseVisitor<T>
类,所以让我们使用它。正如您所看到的,这只是一个通过使用访问器从CST节点创建AST节点的问题,代码应该是非常不言自明的(好吧,也许除了
VisitFuncExpr
的东西,但它只是一个将委托连接到System.Math
类的合适方法的快速方法)。这里你有了AST构建的东西。这就是所需要的。只要从CST中提取相关的信息,并将其保存在AST中。
AST访问者
现在,让我们来玩一下AST。我们必须构建一个AST访问者基类来遍历它。让我们做一些类似于ANTLR提供的
AbstractParseTreeVisitor<T>
的事情。在这里,我利用C#的
dynamic
关键字在一行代码中执行了一个双分派,而在Java中,您必须自己使用一系列if
语句来完成连接,如下所示:但我只是在这个例子中走捷径。
使用AST
那么,我们可以用数学表达式树做什么呢?当然是计算它!让我们实现一个表达式计算器:
一旦我们有了AST就很简单了,不是吗?
∮把所有的一切放在一起∮
最后但并非最不重要的是,我们必须实际编写主程序:
现在我们终于可以玩它了
qij5mzcb2#
我创建了一个小型的Java项目,它允许您通过在内存中编译ANTLR生成的lexer和parser来立即测试ANTLR语法。您可以通过将字符串传递给parser来解析字符串,parser将自动从中生成AST,然后可以在应用程序中使用该AST。
为了减小AST的大小,您可以使用NodeFilter,您可以向其中添加您希望在构造AST时考虑的非终端的产生式规则名称。
该代码和一些代码示例可以在https://github.com/julianthome/inmemantlr中找到
希望工具有用;-)
fcipmucu3#
我发现了两种简单的方法,重点是antlr4的TestRig.java文件中可用的功能。
1.通过终端
这是我使用相应的CPP14.g4语法文件
java -cp .:antlr-4.9-complete.jar org.antlr.v4.gui.TestRig CPP14 translationunit -tree filename.cpp
解析C的示例。如果省略filename.cpp,rig将从stdin读取。"translationunit"是我使用的CPP14.g4语法文件的起始规则名称。1.经由 java
我使用了www.example.com文件中的部分代码,让我们再次假设我们有一个C源代码字符串,我们希望从其中生成AST(您也可以直接从文件中读取)。TestRig.java file. Let's suppose again that we have a string of C++ source code from which we want to produce the AST (you can also read directly from a file).
我的进口产品有:
所有这些都要求您使用命令
java -jar yournaltrfile.jar yourgrammar.g4
生成必要的文件(lexer、parser等),然后编译所有 *. java文件。nfeuvbwi4#
我已经将Terrence Parr的书“Language Implementation Pattern”中基于antlr 3(tpdsl-code/walking/tree-grammar下的source-code)的模式“Tree Grammar”的代码转换为使用访问者和“Homogeneous AST”模式的antlr 4。
语法如下:
矢量数学. g4
访客
AST
与tpdsl-code/IR/Homo中的原始版本相比,基本上只是调整了令牌
测试类
测试输入
产量: