Antlr4 有一个新类 ParseTreeWalker。但我该如何使用它呢?我正在寻找一个最小的工作示例。我的语法文件是“gram.g4”,我想解析文件“program.txt”
到目前为止,这是我的代码。 (这假设 ANTLR 已经运行了我的语法文件并创建了所有gramBaseListener, 语法分析器等):
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 http://www.antlr.org/api/Java/index.html)缺乏示例。网上有很多教程,但大多是针对 ANTLR 版本 3 的。少数使用版本 4 的教程不起作用或已经过时(例如,没有 parser.init() 函数,并且像 ANTLRInputStream 这样的类已被弃用)
预先感谢任何可以提供帮助的人。
对于语法中的每个解析器规则,生成的解析器将具有具有该名称的相应方法。调用该方法将开始解析该规则。
因此,如果您的“根规则”被命名为start
然后你就开始解析gramParser.start()
它返回一个ParseTree
。然后可以将这棵树送入ParseTreeWalker
与您想要使用的侦听器一起使用。
总而言之,它可能看起来像这样(由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
}
}
当然你必须更换<listener>
随着你的实施BaseListener
还有一点:在 Java 中,类名以大写字母开头是一种惯例,我建议您坚持这一点,以便使代码对其他人更具可读性。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)