所以我一直在使用 X-Text 和句法谓词。
经典的例子是悬空 else 问题,给出的解决方案是贪婪地解析 else 语句,即不要终止内部表达式,如下所示:
IfStatement:
'if' condition=Expression 'then' then=Expression
(=>'else' else=Expression)?;
我有一个进程语法,其中两个可以组合以使用二元运算符创建一个大进程,例如
process 1 + process 2
提供进程 1 和进程 2 之间的选择
此外,进程可能会调用其他进程:
process 1 -> process 2
表示先执行进程1,然后执行进程2。
在我的语法中,以下内容:
process 1 -> process 2 + process 3
应该解释为
(process 1 -> process 2) + process 3
但是,考虑到这是一个悬而未决的问题,每个人给出的解决方案都为我提供了错误的解决方案。那么,在 X-Text 中,我怎么能说,“如果有意义,并且程序仍在解析,请尽早跳出内部语句”
为了清楚起见,这是我的语法片段:
PProc:
PProcAtomic ({Binary.left = current} '+' right=Proc)?
;
PProcAtomic returns PProc:
dotted=Dotted (fields+=Field)* type="->" proc=Proc
| bool=Bool type="&" proc=Proc
| type="(" proc=Proc ")"
| type="||" (gens+=Gen)+ "@" "[" rset=Set "]" proc=Proc
| type="|~|" (gens+=Gen)+ "@" proc=Proc
| type="[]" (gens+=Gen)+ "@" proc=Proc
| type="|||" (gens+=Gen)+ "@" proc=Proc
| type=";" (gens+=Gen)+ "@" proc=Proc
| type="[|" rset=PSet "|]" (gens+=Gen)+ "@" proc=Proc
| type="|[" rset=PSet "]|" (gens+=Gen)+ "@" proc=Proc
| type="<->" (gens+=Gen)+ "@" "[" (exprs+=Expr)+ "]" proc=Proc
| type="STOP"
| type="SKIP"
| type="CHAOS" "(" rset=PSet ")"
;
Proc:
PProc
| "namedprocess"
;
显然,如果我将 '=>' 放在“+”上,那么它会贪婪地消耗它,从而导致错误的 AST。我如何让它“向前看”一个“+”符号,然后如果它看到的话,将语句分成两部分?