Antlr4 - 是否有使用ParseTree Walker的简单示例?

时间:2018-02-01 05:17:45

标签: java antlr4

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这样的类被折旧)< / p>

提前感谢任何可以提供帮助的人。

2 个答案:

答案 0 :(得分:6)

对于语法中的每个解析器规则,生成的解析器将具有该名称的相应方法。调用该方法将开始解析该规则。

因此,如果您的“根规则”名为start,那么您将通过gramParser.start()开始解析,并返回ParseTree。然后可以将此树与您想要使用的侦听器一起输入ParseTreeWalker

总而言之,它可能看起来像这样(OPITED 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
        }
    }

当然,您必须将<listener>替换为BaseListener

的实现

只有一个小的副节点:在Java中,通常用大写字母开始类名,我建议你坚持这样做,以便让代码对其他人更具可读性。

答案 1 :(得分:1)

此示例应与 ANTLR 4.8 一起使用。

在示例下面,您可以找到用于设置Java env,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());
    }
}

参考: