Antlr条件重写

时间:2011-12-16 15:34:45

标签: parsing antlr grammar abstract-syntax-tree

我有以下Antlr语法规则:

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

但是,如果我有“3 | 1 | 2 | 6”,则会生成一棵平面树,其中{B}成员的所有子节点都为3, 1, 2, 6。我真正想要的是能够在

上进行模式匹配
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 个答案:

答案 0 :(得分: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调试器,它就像一个魅力(我的答案中的图像来自调试器)!