2011-12-16 10 views
2

は、私は、次のANTLRの文法規則があります。私は「3 | 1 | 2 | 6」を持っている場合ANTLR条件付き書き換え

expression1 
    : e=expression2 (BINOR^ e2=expression2)* 
    ; 

をしかし、これはBINORノードの3, 1, 2, 6すべての子どもたちと、フラットなツリーになります。私が本当に欲しいのは、これらは2パターンあるように、私は書き換えを変更するにはどうすればよいのいずれか

expression2 
or 
^(BINOR expression2 expression2) 

上のパターンマッチにできるようにするのですか?

編集:私はカスタムの書き換えを使用している場合

、私は

expression1 
    : e=expression2 (BINOR e2=expression2)* 
      -> {$BINOR != null}? ^(BINOR $e $e2*) 
      -> $e 

の線に沿って考えています。しかし私はこれを行う際に「1 | 2 | 3」結果のツリーは一つだけを持っていますBINORノードに1と3の2つの子があるため、2がありません。

expression1 
@init{boolean or = false;} 
: e=expression2 (BINOR {or=true;} expression2)* -> {or}? ^(BINOR expression2+) 
               ->  $e 
; 

をしかし、それは任意のカスタムコードを使用していないので、これは好ましい::

感謝

答えて

1

あなたが接近していた、これはうまくいく

grammar T; 

options { 
    output=AST; 
} 

expression1 
: (e=expression2 -> $e) ((BINOR expression2)+ -> ^(BINOR expression2+))? 
; 

expression2 
: NUMBER 
; 

NUMBER 
: '0'..'9'+ 
; 

BINOR 
: '|' 
; 

パーサから生成します上記の文法は入力"3|1|2|6"をASTに解析します:

enter image description here

とASTに入力"3"

enter image description here

しかし、あなたのオリジナルのtry:

expression1 
    : e=expression2 (BINOR^ e2=expression2)* 
    ; 

はないはあなたにoutput=AST;を持っていると仮定すると(フラットツリーを生成しませんオプション)。あなたが平らな木を「見る」場合

enter image description here

が、私はあなたがASTが、あなたのパースのパースツリーが表示されないANTLRWorksで通訳を、使用していると思います:それは"3|1|2|6"のため、次のASTを生成し、 。インタプリタもややバグがあります(述語を処理せず、カスタムコードを評価しません)ので、使用しないことをお勧めします。代わりにANTLRWorksデバッガを使用してください。これは魅力的です(私の答えの画像はデバッガからのものです)!