I’m a beginner using ANTLR. I’m just doing the following for test purposes and try to understand the way it works and produce errors:
INTEGER_NUMBER : ('0'..'9')+;
integer_number: INTEGER_NUMBER;
decimal_number: (integer_number '.' integer_number) | ('.' integer_number);
regular_number: decimal_number|integer_number;
I have the following warning on the “regular_number” rule : Decision can match input such as “INTEGER_NUMBER ‘.’ INTEGER_NUMBER” using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input.
What exactly does it means ?
Ok I have edited this post to include the code that reproduce this error
program :(price)*;
INTEGER_NUMBER : ('0'..'9')+;
INFO_PRICE : 'OLD PRICE';
FRACTION_NUMBER : '1/16'|'1/8'|'3/16'|'1/4'|'5/16'|'3/8'|'7/16'|'1/2'|'9/16'|'5/8'|'11/16'|'3/4'|'13/16'|'7/8'|'15/16';
CURRENCY : 'EUR'|'USD'|'GBP';
integer_number : INTEGER_NUMBER ;
decimal_number : (integer_number? '.') integer_number ;
fraction_number : (integer_number ((' ')+))? FRACTION_NUMBER;
regular_number : decimal_number|integer_number ;
numerical_number :regular_number|fraction_number;
non_numerical_number : INFO_PRICE ((' ')*) ('+'|'-') ((' ')*)(numerical_number)((' ')*) CURRENCY;
price : numerical_number |non_numerical_number;
WS : (' ' | '\t' | '\f')+ {$channel=HIDDEN;};
NL :('\r' '\n' | '\r' | '\n') {$channel=HIDDEN;};
and the error know is this one
error(201): /ANTLR – Tuto 1/src/Test.g:37:2: The following alternatives can never be matched: 2
|—> : decimal_number|integer_number ;
As already mentioned in the comments, there’s nothing wrong with the grammar you posted.
The error you mention occurs with the following grammar:
When the parser tries to match a
regular_numberfor the input string"123", it does not know which alternative to choose. Bothdecimal_numberandinteger_numbermatch"123". Hence the error message:EDIT
From within the
regular_numberrule, the string"123.456"could be parsed as:or as:
Why not define a DECIMAL_NUMBER in the lexer:
?
That should fix that problem.
There are more issues though:
when the rule above tries to handle input like
"2 1/8", the2from it could be a part of yourfraction_numberincluding the1/8, but it could also be handled as aregular_numberfollowed by afraction_number.Also, you shouldn’t define spaces inside your parser rules, you’ve put them on the HIDDEN channel in the lexer, so they won’t be “seen” by the parser.
Having said all that, this would be a possible alternative grammar that probably does what you want:
EDIT II
When encountering the (sub) string
1011 1/16,1011is tokenized as anINTEGER_NUMBER, the space is put on the HIDDEN channel (and is therefor not present in the token-stream that is being passed to the parser), and1/16is tokenized as aFRACTION_NUMBER.For
101 11/16the same applies:101is aINTEGER_NUMBERand11/16aFRACTION_NUMBER.To emphasize: when you put spaces and line breaks on a different channel (like the HIDDEN channel), they are not present in the token stream that the parser operates on. So it makes no sense to use these tokens in parser rules: they’re never going to be matched.
HTH