antlr - XText Dangling Else - The Other Option -
so i've been using x-text , playing syntactic predicates.
the classic example dangling else problem, solution given greedily parse else statement, i.e. don't terminate inner expression, so:
ifstatement: 'if' condition=expression 'then' then=expression (=>'else' else=expression)?;
i have grammar of processes, 2 may combined create 1 big process binary operator, example process 1 + process 2
affords choice between process 1 , process 2
in addition, processes may call other processes: process 1 -> process 2
means process 1, process two.
in grammar, following: process 1 -> process 2 + process 3
should interpreted
(process 1 -> process 2) + process 3
however, considering dangling else problem, resolution gives provides me wrong solution. how then, in x-text can say, "if makes sense to, , program still parses, jump out of inner statement @ earliest possible opportunity"
here snippit of grammar 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 put '=>' on "+" consume greedily, resulting in wrong ast. how make "look ahead" "+" symbol, , split statement 2 if sees that?
when describing operator-based expressions, ambiguities can eliminated without =>
predicate writing chains of parser rules , avoiding back-references rules lower in chain. operator precedence controlled order of rules in chain.
in case ambiguity caused frequent back-reference proc
rule. can avoid writing this:
pproc returns proc: pprocadvanced ({binary.left = current} '+' right=pprocadvanced)*; pprocadvanced returns proc: pprocatomic | dotted=dotted (fields+=field)* type="->" proc=pprocadvanced | bool=bool type="&" proc=pprocadvanced | type="||" (gens+=gen)+ "@" "[" rset=set "]" proc=pprocadvanced | type="|~|" (gens+=gen)+ "@" proc=pprocadvanced | type="[]" (gens+=gen)+ "@" proc=pprocadvanced | type="|||" (gens+=gen)+ "@" proc=pprocadvanced | type=";" (gens+=gen)+ "@" proc=pprocadvanced | type="[|" rset=pset "|]" (gens+=gen)+ "@" proc=pprocadvanced | type="|[" rset=pset "]|" (gens+=gen)+ "@" proc=pprocadvanced | type="<->" (gens+=gen)+ "@" "[" (exprs+=expr)+ "]" proc=pprocadvanced; pprocatomic returns proc: "(" proc ")" | type="stop" | type="skip" | type="chaos" "(" rset=pset ")";
here back-reference "(" proc ")"
, prefixed opening parenthesis , free of ambiguity.
Comments
Post a Comment