antlr - "The following sets of rules are mutually left-recursive" -
i have tried write grammar recognize expressions like:
(a + max(b) ) / ( c - average(a) ) if( > average(a), 0, 1 ) x / (max(x)
unfortunately antlr3 fails these errors:
error(210): following sets of rules mutually left-recursive [unaryexpression, additiveexpression, primaryexpression, formula, multiplicativeexpression]
error(211): derivedkeywords.g:110:13: [fatal] rule booleanterm has non-ll(*) decision due recursive rule invocations reachable alts 1,2. resolve left-factoring or using syntactic predicates or using backtrack=true option.
error(206): derivedkeywords.g:110:13: alternative 1: after matching input such decision cannot predict comes next due recursion overflow additiveexpression formula
i have spent hours trying fix these, great if @ least me fix first problem. thanks
code:
grammar derivedkeywords; options { output=ast; //backtrack=true; } ws : ( ' ' | '\t' | '\n' | '\r' ) { skip(); } ; //for numbers digit : '0'..'9' ; //for both integer , real number number : (digit)+ ( '.' (digit)+ )?( ('e'|'e')('+'|'-')?(digit)+ )? ; // boolean operatos , : 'and'; or : 'or'; not : 'not'; eq : '='; neq : '!='; gt : '>'; lt : '<'; gte : '>='; lte : '<='; comma : ','; // token functions if : 'if'; max : 'max'; min : 'min'; average : 'average'; variable : 'a'..'z' ('a'..'z' | '0'..'9')* ; // operators lparen : '(' ; rparen : ')' ; div : '/' ; plus : '+' ; minus : '-' ; star : '*' ; expression : formula; formula : functionexpression | additiveexpression | lparen! a=formula rparen! // first problem ; additiveexpression : a=multiplicativeexpression ( (minus^ | plus^ ) b=multiplicativeexpression )* ; multiplicativeexpression : a=unaryexpression ( (star^ | div^ ) b=unaryexpression )* ; unaryexpression : minus^ u=unaryexpression | primaryexpression ; functionexpression : f=functionoperator lparen e=formula rparen | if lparen b=booleanexpression comma p=formula comma s=formula rparen ; functionoperator : max | min | average; primaryexpression : number // used scientific numbers | digit | variable | formula ; // boolean stuff booleanexpression : orexpression; orexpression : a=andexpression (or^ b=andexpression )* ; andexpression : a=notexpression (and^ b=notexpression )* ; notexpression : not^ t=booleanterm | booleanterm ; booleanoperator : gt | lt | eq | gte | lte | neq; booleanterm : a=formula op=booleanoperator b=formula | lparen! booleanterm rparen! // second problem ;
error(210): following sets of rules mutually left-recursive [unaryexpression, additiveexpression, primaryexpression, formula, multiplicativeexpression]
- means if parser enters unaryexpression
rule, has possibility match additiveexpression
, primaryexpression
, formula
, multiplicativeexpression
, unaryexpression
again without ever consuming single token input - cannot decide whether use rules or not, because if uses rules, input same.
you're trying allow subexpressions in expressions sequence of rules - need make sure path consume left parenthesis of subexpression. formula
alternative in primaryexpression
should changed lparen formula rparen
, , rest of grammar adjusted accordingly.
Comments
Post a Comment