1

次のタイプのブール式を解析しようとしています B1=p & A4=p | A6=p &(~A5=c)

上記の式を評価するために使用できるツリーが必要です。だから私はこれを Antlr3 で、and/or logic の Antlr パーサーの例で試しました - 論理演算子間の式を取得する方法は?

Antlr3で動作しました。次に、Antlr 4 に対して同じことを行いたいと思います。以下の文法を思いつき、コンパイルします。しかし、Java コードを書くのに問題があります。

Antlr4 文法の開始

grammar TestAntlr4;

options {
  output = AST;
}

tokens { AND, OR, NOT }

  AND : '&';
  OR  : '|';
  NOT : '~';


// parser/production rules start with a lower case letter
parse
  :  expression EOF!    // omit the EOF token
  ;

expression
  :  or
  ;

or
  :  and (OR^ and)*    // make `||` the root
  ;

and
  :  not (AND^ not)*      // make `&&` the root
  ;

not
  :  NOT^ atom    // make `~` the root
  |  atom
  ;

atom
  :  ID
  |  '('! expression ')'!    // omit both `(` and `)`
  ;

// lexer/terminal rules start with an upper case letter
ID
  :
    (
    'a'..'z'
    | 'A'..'Z'
    | '0'..'9' | ' '
    | ('+'|'-'|'*'|'/'|'_')
    | '='
  )+ 
  ;

「B1=p & A4=p | A6=p &(~A5=c)」という式のツリーを取得するための Java コード (以下のスニペット) を作成しました。子 B1=p と | を持つ & を期待しています。その子 | 演算子には子 A4=p および A6=p &(~A5=c) があります。等々。これがそのJavaコードですが、ツリーを取得する方法を理解しようとして立ち往生しています。Antlr 3でこれを行うことができました。

Java コード

String src = "B1=p & A4=p | A6=p &(~A5=c)";
CharStream stream = (CharStream)(new ANTLRInputStream(src));
TestAntlr4Lexer lexer = new TestAntlr4Lexer(stream);
parser.setBuildParseTree(true);
ParserRuleContext tree = parser.parse();
tree.inspect(parser); 
if ( tree.children.size() > 0) {
    System.out.println(" **************");
    test.getChildren(tree, parser);
}

get Children メソッドは以下のとおりです。しかし、これはトークンを抽出していないようです。

public void getChildren(ParseTree tree, TestAntlr4Parser parser ) {
   for (int i=0; i<tree.getChildCount(); i++){
       System.out.println(" Child i= " + i);
       System.out.println(" expression = <" + tree.toStringTree(parser) + ">");
       if ( tree.getChild(i).getChildCount() != 0 ) {
           this.getChildren(tree.getChild(i), parser);
       }
   }
}

Javaでパーサーを書く方法を理解するのを手伝ってくれる人はいますか?

4

1 に答える 1

3

このoutput=ASTオプションは、ANTLR 4、^および!文法で使用した演算子で削除されました。ANTLR 4は、ASTの代わりに解析ツリーを生成するため、ルールによって生成されるツリーのルートはルール自体です。たとえば、次のルールがあります。

and : not (AND not)*;

最終的には、と参照用のと子をそれぞれAndContext含むツリーになります。ツリーの操作を簡単にするために、ルールの呼び出しによって返されるコンテキストオブジェクトのリストを返す生成されたメソッドが含まれます(return type )。また、一致したトークンごとに作成されたインスタンスのリストを返す生成されたメソッドも含まれています。NotContextTerminalNodenotANDAndContextnot()notList<? extends NotContext>ANDTerminalNodeAND

于 2013-03-22T20:50:46.430 に答える