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
の場合、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では、クラス名を大文字で始めるのが慣例です。他の人がコードを読みやすくするために、これに固執することをお勧めします。