Antlr4 - 是否有使用 ParseTree Walker 的简单示例?
Antlr4 - Is there a simple example of using the ParseTree Walker?
Antlr4 有一个新的 class 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() 函数,并且 class像 ANTLRInputStream 这样的 es 已经贬值了)
在此先感谢任何可以提供帮助的人。
对于语法中的每个解析器规则,生成的解析器都会有一个具有该名称的对应方法。调用该方法将按照该规则开始解析。
因此,如果您的 "root-rule" 被命名为 start
,那么您将通过 gramParser.start()
开始解析,其中 returns a 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 中,类名以大写字母开头是一种惯例,我建议您坚持这一点,以使代码对其他人更具可读性。
此示例应适用于 ANTLR 4.8。
在示例下方,您可以找到设置 Java 环境、API 和监听器的参考资料。
public class Launch {
public static void main(String[] args) {
InputStream inputStream = null;
MyprogramLexer programLexer = null;
try {
File file = new File("/program.txt");
inputStream = new FileInputStream(file);
programLexer = new MyprogramLexer(CharStreams.fromStream(inputStream)); // read your program input and create lexer instance
} finally {
if (inputStream != null) {
inputStream.close();
}
}
/* assuming a basic grammar:
myProgramStart: TOKEN1 otherRule TOKEN2 ';' | TOKENX finalRule ';'
...
*/
CommonTokenStream tokens = new CommonTokenStream(programLexer); // get tokens
MyParser parser = new MyParser(tokens);
MyProgramListener listener = new MyProgramListener(); // your custom extension from BaseListener
parser.addParseListener(listener);
parser.myProgramStart().enterRule(listener); // myProgramStart is your grammar rule to parse
// what we had built?
MyProgram myProgramInstance = listener.getMyProgram(); // in your listener implementation populate a MyProgram instance
System.out.println(myProgramInstance.toString());
}
}
参考文献:
Antlr4 有一个新的 class 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() 函数,并且 class像 ANTLRInputStream 这样的 es 已经贬值了)
在此先感谢任何可以提供帮助的人。
对于语法中的每个解析器规则,生成的解析器都会有一个具有该名称的对应方法。调用该方法将按照该规则开始解析。
因此,如果您的 "root-rule" 被命名为 start
,那么您将通过 gramParser.start()
开始解析,其中 returns a 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 中,类名以大写字母开头是一种惯例,我建议您坚持这一点,以使代码对其他人更具可读性。
此示例应适用于 ANTLR 4.8。
在示例下方,您可以找到设置 Java 环境、API 和监听器的参考资料。
public class Launch {
public static void main(String[] args) {
InputStream inputStream = null;
MyprogramLexer programLexer = null;
try {
File file = new File("/program.txt");
inputStream = new FileInputStream(file);
programLexer = new MyprogramLexer(CharStreams.fromStream(inputStream)); // read your program input and create lexer instance
} finally {
if (inputStream != null) {
inputStream.close();
}
}
/* assuming a basic grammar:
myProgramStart: TOKEN1 otherRule TOKEN2 ';' | TOKENX finalRule ';'
...
*/
CommonTokenStream tokens = new CommonTokenStream(programLexer); // get tokens
MyParser parser = new MyParser(tokens);
MyProgramListener listener = new MyProgramListener(); // your custom extension from BaseListener
parser.addParseListener(listener);
parser.myProgramStart().enterRule(listener); // myProgramStart is your grammar rule to parse
// what we had built?
MyProgram myProgramInstance = listener.getMyProgram(); // in your listener implementation populate a MyProgram instance
System.out.println(myProgramInstance.toString());
}
}
参考文献: