使用重写规则的Antlr单子树

时间:2011-07-19 23:25:50

标签: antlr binary-tree

我有这个公式:

negationExpr         :NEGATION ^ * atom         

原子
       :'a'..'z'| 'A'..'Z';

使用上面的语法规则,如果我输入公式¬¬a,我会得到这个树结构:

¬是根节点, ¬留下孩子;一个正确的孩子

然而,我想要的是: ¬是根节点, 第二个是上述节点的唯一子节点 a是第二个¬

的唯一孩子 基本上,我看到所有的NEGATION标志都只有一个孩子,有可能吗?我知道我们可能会使用“重写规则”重组树,但我不知道该怎么做。

任何帮助或建议表示赞赏!谢谢!

2 个答案:

答案 0 :(得分:1)

重写规则可以遵循解析器规则的每个备选方案。

rule :
   alt1 -> rewriteRule1
 | alt2 -> rewriteRule2
 ...
 | altN -> rewriteRuleN;

您会发现,即使您的解析器语法正常工作,您也可能需要对其进行重组以生成正确的树。为了解决您的具体问题,我建议如下:

negationExpr :
   NEGATION negationExpr 
     -> ^(NEGATION negationExpr)
 | atom 
     -> atom;

这将在树中为每个否定运算符添加一个级别。 ^将在括号后面立即为令牌创建根,并将下一个negationExpr规则的结果添加为子项。

答案 1 :(得分:0)

Adam12的建议是一个优雅的解决方案。我只有一个关于你的(JiandongC)代码片段的评论,以及另一种构建AST的方法。

请注意,..(范围运算符)在解析器规则中无效!你需要使原子成为词法规则,或者:

atom 
  :  LETTER
  ; 

LETTER 
  :  'a'..'z' | 'A'..'Z'
  ;

关于AST的创建,你 也可以忽略偶数NEGATION个令牌,因为- -是正面的。

negationExpr 
  :  (NEGATION NEGATION)* ( NEGATION atom -> ^(NEGATION atom)
                          | atom          -> atom
                          )
  ;

如果^(NEGATION atom)令牌数量不均匀,则上述规则只构建NEGATION,否则atom将创建为单个节点(root)。