我有这个公式:
negationExpr :NEGATION ^ * atom
原子
:'a'..'z'| 'A'..'Z';
使用上面的语法规则,如果我输入公式¬¬a,我会得到这个树结构:
¬是根节点, ¬留下孩子;一个正确的孩子
然而,我想要的是: ¬是根节点, 第二个是上述节点的唯一子节点 a是第二个¬
的唯一孩子 基本上,我看到所有的NEGATION标志都只有一个孩子,有可能吗?我知道我们可能会使用“重写规则”重组树,但我不知道该怎么做。任何帮助或建议表示赞赏!谢谢!
答案 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)。