antlrantlr3antlrworks

How to get rid of the following multiple alternatives warnings in my ANTLR3 grammar?


[11:45:19] warning(200): mygrammar.g:14:57: Decision can match input such as "','" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
[11:45:19] warning(200): C:\Users\Jarrod Roberson\mygrammar.g:14:57: Decision can match input such as "','" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input

I want to be able to nest functions inside other functions.

myfunction(x) ->
  sqr(a) -> a * a,
  y -> sqr(x).

here is the line it is complaining about

function : ID '(' args ')' '->' statement (',' statement)* ;

and here is what it is considering the alternative

statement : ATOM
          | expression
          | assignment
          | function
          ;

I am using . as my statement end rule

program : (statement'.')*;

Here is what the synatx diagram looks like in ANTLRWorks

syntax diagram
(source: vertigrated.com)

I really like things to compile/work without any warnings. How do I resolve this warning condition?


Solution

  • Jarrod Roberson wrote:

    I really like things to compile/work without any warnings. How do I resolve this warning condition?

    Your parser can parse the following input:

    f(x)-> g(y)-> y*y, x=y
    

    in two different parse trees:

    enter image description here

    and:

    enter image description here

    You can fix this by forcing the parser to look ahead and make sure there is ',' statement ahead before actually matching these rules. You can do that by using a syntactic predicate (the (...)=> part) with said rule inside:

    function
      :  ID '(' args ')' '->' statement ((',' statement)=> ',' statement)* 
      ;
    

    However, you don't need the predicate if your function rule has some sort of an "end" token, which you haven't defined. From your earlier questions, and your example:

    myfunction(x) ->
      sqr(a) -> a * a,
      y = sqr(x).
    

    it seems you're using the '.' as the end of a function. If you add that to your function rule:

    function
      :  ID '(' args ')' '->' statement (',' statement)* '.'
      ;
    

    you don't need a predicate at all.