Antlr4 – 是否有使用ParseTree Walker的简单示例?
Antlr4有一个新类ParseTreeWalker。 但是我该如何使用它? 我正在寻找一个最小的工作示例。 我的语法文件是’gram.g4’,我想解析文件’program.txt’
到目前为止,这是我的代码。 (这假设ANTLR运行了我的语法文件并创建了所有的gramBaseListener , gramLexer等等):
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.*; import static org.antlr.v4.runtime.CharStreams.fromFileName; public class launch{ public static void main(String[] args) { CharStream cs = fromFileName("gram.g4"); //load the file gramLexer lexer = new gramLexer(cs); //instantiate a lexer CommonTokenStream tokens = new CommonTokenStream(lexer); //scan stream for tokens gramParser parser = new gramParser(tokens); //parse the tokens // Now what?? How do I connect the above with the below? ParseTreeWalker walker = new ParseTreeWalker(); // how do I use this to parse program.txt?? }}
我正在使用java,但我认为它与其他语言类似。
ANTLR文档( http://www.antlr.org/api/Java/index.html )是一些简短的例子。 互联网上有许多教程,但它们主要用于ANTLR版本3.使用版本4的少数教程不起作用或过时(例如,没有parser.init()函数,并且像ANTLRInputStream这样的类被折旧)
提前感谢任何可以提供帮助的人。
对于语法中的每个解析器规则,生成的解析器将具有该名称的相应方法。 调用该方法将开始解析该规则。
因此,如果您的“根规则”被命名为start
那么您将通过返回ParseTree
gramParser.start()
开始解析。 然后可以将此树与您要使用的侦听ParseTreeWalker
一起提供给ParseTreeWalker
。
总而言之,它看起来像这样(EDITED BY OP):
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.*; import static org.antlr.v4.runtime.CharStreams.fromFileName; public class launch{ public static void main(String[] args) { CharStream cs = fromFileName("program.txt"); //load the file gramLexer lexer = new gramLexer(cs); //instantiate a lexer CommonTokenStream tokens = new CommonTokenStream(lexer); //scan stream for tokens gramParser parser = new gramParser(tokens); //parse the tokens ParseTree tree = parser.start(); // parse the content and get the tree Mylistener listener = new Mylistener(); ParseTreeWalker walker = new ParseTreeWalker(); walker.walk(listener,tree); }}
************新文件Mylistener.java ************
public class Mylistener extends gramBaseListener { @Override public void enterEveryRule(ParserRuleContext ctx) { //see gramBaseListener for allowed functions System.out.println("rule entered: " + ctx.getText()); //code that executes per rule } }
当然,您必须将
替换为BaseListener
的实现
还有一个小的sidenode:在Java中,通常用大写字母开始类名,我建议你坚持这样做,以使代码对其他人更具可读性。