[antlr-interest] Method Invocation Rule (expr.methodname()) causing mutually left-recursive grammar
Michael Cooper
tillerman35 at yahoo.com
Mon Oct 29 08:45:43 PDT 2012
I'm getting the dreaded "mutually left-recursive" error. It started when I tried to add method invocations to the mix.
What I would like is method invocations like "variable.method(arg1, arg2, arg3)" and to be able to "chain" them together like in java ("whateverwhatever".length().tostring().length().tostring().length()" returning 2
Here is the grammar snippet. Any help is appreciated.
atom[boolean eval_now] returns [InterpValue value]
: varname=IDENTIFIER //Return an ival with the type & value of a scalar variable
{ if($eval_now && interp.getContinueStatus()==0) $value=interp.getScalarValueByName($varname.text); }
| varname=IDENTIFIER '[' key_or_index=expr[eval_now] ']' //Return an ival containing the scalar type & value at the given index of an array variable, key of a map variable, or name or index of a record column
{ if($eval_now && interp.getContinueStatus()==0) $value=interp.getScalarValueByKeyOrIndex($varname.text,$key_or_index.value); }
| varname=IDENTIFIER '.' membername=IDENTIFIER //Return an ival containing the scalar type & value at the given index of an array variable or key of a map variable
{ if($eval_now && interp.getContinueStatus()==0) $value=interp.getScalarValueByMemberName($varname.text,$membername.text); }
| BOOLEAN_LITERAL //Convert literal to an ival of type boolean with given "true" or "false" value
{ if($eval_now && interp.getContinueStatus()==0) $value = new InterpValue("boolean",$BOOLEAN_LITERAL.text); }
| INTEGER_LITERAL //Convert literal to an ival of type integer with given numeric value
{ if($eval_now && interp.getContinueStatus()==0) $value = new InterpValue("integer",$INTEGER_LITERAL.text); }
| DECIMAL_LITERAL //Convert literal to an ival of type decimal with given numeric value
{ if($eval_now && interp.getContinueStatus()==0) $value = new InterpValue("numeric",$DECIMAL_LITERAL.text); }
| STRING_LITERAL //Convert literal to an ival of type
{ if($eval_now && interp.getContinueStatus()==0) $value = new InterpValue("string",$STRING_LITERAL.text); }
| '(' e=expr[eval_now] ')'
{ if($eval_now && interp.getContinueStatus()==0) $value = $e.value; }
| hasrows=consume_record[eval_now]
{ if($eval_now && interp.getContinueStatus()==0) $value = $hasrows.value; }
| f=function_call[eval_now]
{ if($eval_now && interp.getContinueStatus()==0) $value = $f.value; }
| m=method_invocation[eval_now]
{ if($eval_now && interp.getContinueStatus()==0) $value = $m.value; }
;
method_invocation[boolean eval_now] returns [InterpValue value]
@init { ArrayList<Token> method_args = new ArrayList<Token>(); ArrayList<String> method_params = new ArrayList<String>(); }
: lhs=expr[false] '.'
funcname=IDENTIFIER '('
( e1=expr[false] { method_args.add($e1.start); method_params.add($e1.text); }
( ',' e2=expr[false] { method_args.add($e2.start); method_params.add($e2.text); } )*
)?
')' { if($eval_now && interp.getContinueStatus()==0) $value=interp.methodInvocation($lhs.text,$funcname.text,method_args,method_params); }
;
More information about the antlr-interest
mailing list