我尝试用 antlr3.4 做一些树到树的转换
关于布尔表达式的(对于这个问题)是“AND”和“OR”被允许绑定到 n 个表达式。解析器阶段创建这样的东西
(OR
(AND (expr1) (expr2) (expr3)
(OR (AND (expr4))
(AND (expr5))
(AND (expr6))
)
)
)
不幸的是,“AND”和“OR”的 AST 节点只绑定到一个表达式。(这是没用的,但是嘿 - 调用规则 andExpr 和 orExpr)
我试图将它们踢出(意思是用它们的子节点替换它们)但在树语法中没有这样做。(顺便说一句:在纯 java 中使用深度优先树遍历/修改,但这不是我的意图)
我尝试使用谓词,但似乎无法正确使用。
这是解析未修改的流的语法
start :
orExpr^ EOF!
;
orExpr :
^(OR r+=andExpr+ ) -> ^(OR $r)
;
andExpr :
^(AND unaryExpr+ )
;
notExpr:
^( NOT unaryExpr)
;
unaryExpr :
.+ // it gets more complicated below this
;
我尝试了一个谓词来捕捉一个子节点的情况,但未能通过未修改的 n>1 情况
orExpr @init { int N = 0; }
:
( ^(OR (r+=andExpr {N++;})+ ) {N==1}? -> $r)
;
任何想法如何正确地做到这一点?
编辑:附件是几乎相同的解析器语法......
start
: '('! orExpr^ ')'! EOF! ;
orExpr
: a+=andExpr ( OR_T a+=andExpr )* -> ^(OR $a+ ) // 'AND' and 'OR' are multivalent
;
andExpr
: u+=unaryExpr ( AND_T u+=unaryExpr )* -> ^(AND $u+ )
;
notExpr
: NOT_T unaryExpr -> ^( NOT unaryExpr)
;
unaryExpr
: '('! orExpr ')'! // -> ^( BRACE orExpr), brace not needed in the ast (but needed for propper parsing)
| notExpr
| internal^ // internal is very complex in itself
;