zell
zell

Reputation: 10204

ANTLR error: Decision can match input using multiple alternatives

I do not see how to handle the error of a ANTLR grammar:

****************error message*********
Decision can match input such as "{'+', '-'} IDENT" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
 |---> add: mult (('+'|'-') mult)*;
***************************************

This is mostly copied from the example of Scott, but I do not see why his works well but mine got stuck and how to get out of it?

---------------following Sample.g----------------

grammar Sample;

options { 
  language = Java;
}


 program
      :  'program' IDENT '='
          (constant| variable)*
          'begin'
          (statement)*
          'end' IDENT '.'
      ; 

constant:
       'constant' IDENT ':' type ':=' expression ';' 
      ;

type: 'integer';

variable: 'var' IDENT (',' IDENT)* ':' type  ';';


statement: 'var' IDENT ':=' INTEGER ';' ;

//expression

term: IDENT |'(' expression ')'|INTEGER;
negation: 'not'* term;
unary: ('+'|'-')* negation;
mult: unary (('*'|'/'|'mod') unary)*;

[XXX Errorfor the following line]

add: mult (('+'|'-') mult)*;
relation: add (('='|'/='|'<'|'<=') add)*;
expression: (relation ('and'|'or') relation)*;


END : 'end';

CONSTANT : 'constant';

INTEGER: '0'| (('1'..'9') ('0'..'9')*);   

IDENT: ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9')*;

WS: ('\n'|' '|'\t'|'r'|'\f')+ {$channel=HIDDEN;};

Upvotes: 1

Views: 1275

Answers (2)

Bart Kiers
Bart Kiers

Reputation: 170148

You've misplaced a parenthesis in:

expression: (relation ('and'|'or') relation)*;

making your grammar ambiguous: the parser cannot decide when it sees a - IDENT if it should be a part of an add- or unary-rule.

For example, your rule expression now matches this:

relation ('and'|'or') relation relation ('and'|'or') relation

i.e., two relation rules directly placed after each other. If the parser now stumbles upon input like this:

- A - B

the parser "sees" two possibilities to parse this input:

1 (unary expression & unary expression)

enter image description here

2 (unary & add expression)

enter image description here

It should be:

expression: relation (('and'|'or') relation)*;

instead, so the there can never be 2 successive expressions (and no ambiguity!).

Upvotes: 2

Favonius
Favonius

Reputation: 13974

  1. It is good to mention the source web page from where you have picked up the code. I think here it is Antlr3xtut.

This is mostly copied from the example of Scott, but I do not see why his works well but mine got stuck and how to get out of it?

This is because you copied incorrectly.

Instead of correct code as mentioned below:

expression
    :   relation (('and' | 'or') relation)*
    ;

You have copied:

expression: (relation ('and'|'or') relation)*;

Are you able to spot the error? For example the placement of '(' just before the relation. And because of that you are getting the error Decision can match input such as "{'+', '-'} IDENT" using multiple alternatives:

enter image description here

Solution

Replace you expression rule with what is given in scotts sample.

Upvotes: 2

Related Questions