Итак, я использую X-Text и играю с синтаксическими предикатами.XText Dangling Else - Другой вариант
Классическим примером является оборванных еще проблема, где решение дано это жадностью разобрать заявление другого, то есть не прекратить внутреннее выражение, например, так:
IfStatement: 'if' condition=Expression 'then' then=Expression (=>'else' else=Expression)?;
У меня есть грамматики процессов, в которых два могут быть объединены, чтобы создать один большой процесс с бинарным оператором, например process 1 + process 2
дает возможность выбора между процессом 1 и 2 процесса
Кроме того, процессы могут вызывать другие процессы: process 1 -> process 2
означает, что процесс 1, затем выполните процесс два.
В моей грамматике, следующее: 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" ;
Очевидно, что если я надену «=>» на «+», он будет потреблять это жадно, что приведет к неправильному АСТ. Как заставить «смотреть вперед» на символ «+», а затем разделить заявление на два, если он это увидит?