2011-12-16 56 views
2

我有以下ANTLR的语法规则:ANTLR的条件重写

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

但是如果我有“3 | 1 | 2 | 6”这导致在一个平面树,3, 1, 2, 6所有BINOR节点的孩子。我真正想要的是能够在任何模式匹配

expression2 
or 
^(BINOR expression2 expression2) 

我该如何改变重写,以便这些是2模式?

编辑:

如果我使用自定义的重写,我沿着

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

可是电话想,如果我这样做是与“1 | 2 | 3”产生的树只有一个有两个孩子的BINOR节点是1和3,所以缺少2个节点。

非常感谢

回答

1

你接近,这会工作:

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

但这首选,因为它不使用任何自定义代码:

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

和输入"3"到AST:

enter image description here

但是你原来的尝试:

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

产生平树(假设你有output=AST;你选项)。它为"3|1|2|6"以下AST:

enter image description here

如果“看到”平树,我猜你使用ANTLRWorks解释,这不显示AST,但您解析的解析树。解释器也相当麻烦(不处理谓词,不评估自定义代码),所以最好不要使用它。改用ANTLRWorks调试器,它就像一个魅力一样(我的答案中的图像来自调试器)!