So I've been using X-Text and playing with Syntactic Predicates.
The classic example is the dangling else problem, where the solution given is to greedily parse the else statement, i.e. don't terminate the inner expression, like so:
IfStatement:
'if' condition=Expression 'then' then=Expression
(=>'else' else=Expression)?;
I have a grammar of processes, where two may be combined to create one big process with a binary operator, for example
process 1 + process 2
affords the choice between process 1 and process 2
In addition, processes may call other processes:
process 1 -> process 2
means do process 1, then do process two.
In my grammar, the following:
process 1 -> process 2 + process 3
should be interpreted as
(process 1 -> process 2) + process 3
However, considering this as a dangling else problem, the resolution everyone gives provides me the wrong solution. How then, in X-Text can I say, "if it makes sense to, and the program still parses, jump out of the inner statement at the earliest possible opportunity"
Here is a snippit of my grammar for clarity:
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"
;
Obviously if I put the '=>' on the "+" then it will consume that greedily, resulting in the wrong AST. How do I make it "look ahead" for a "+" symbol, and then split the statement into two if it sees that?