web-dev-qa-db-ja.com

Antlr4-ParseTree Walkerの簡単な使用例はありますか?

Antlr4には、ParseTreeWalkerという新しいクラスがあります。しかし、どのように使用しますか?最小限の実用的な例を探しています。文法ファイルは「gram.g4」で、ファイル「program.txt」を解析したい

これが私のコードです。 (これは、ANTLRが私の文法ファイルを実行し、gramBaseListenergramLexerなど):

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のようなクラスは廃止されています)。

手伝ってくれる人は前もって感謝します。

10
john ktejik

文法のパーサールールごとに、生成されたパーサーには、その名前の対応するメソッドがあります。そのメソッドを呼び出すと、そのルールで解析が開始されます。

したがって、「ルートルール」の名前がstartの場合、gramParser.start()を介して解析を開始し、ParseTreeを返します。このツリーは、使用するリスナーとともに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
        }
    }

もちろん<listener>BaseListenerの実装に置き換える必要があります

そして、小さなサイドノードが1つだけあります。Javaでは、クラス名を大文字で始めるのが慣例です。他の人がコードを読みやすくするために、これに固執することをお勧めします。

9
Raven