简体   繁体   中英

ANTLR multiple alternatives error

Wenn I try to execute ANTLR grammar I get the following exception:

Decision can match input such as "DIGIT..LETTER" using multiple alternatives: 1, 2

My grammar looks like this:

grammar twp3;
ALPHA   : ('a'..'z'|'A'..'Z'); 
DIGIT :  ('0' .. '9');
LETTER  : ALPHA | '_';
identifier  :   LETTER ( LETTER | DIGIT )*;
number  :  DIGIT+;
type    :   primitiveType  | identifier |('any' 'defined' 'by' identifier);
primitiveType   :   'int' | 'string' | 'binary' | 'any';
typedef :   structdef | sequencedef | uniondef | forwarddef;
field   :   'optional'? type identifier ';';

The problem is by multiple usage of identifier by type and field.

Please help me to correct my grammar.

Thank you.

Let's say you're trying to parse the input "abc" (without the quotes). Now your field rule contains type identifier , and type can also match an identifier . So you could say that the parser should be able to match identifier identifier . But how should the input be "divided"? The parser could match "a" to the first identifier and "bc" to the second identifier . But it could also match "ab" to the first, and "c" to the second.

The fact that the parser can create more than one parse from a single input is the ambiguity in your grammar (the error message you encountered). And the cause of it is that you're trying to create identifiers at parse-time, while you should create them at lexer-time. So, if you create lexer tokens of identifier instead of parser tokens, all should be okay.

And your lexer should not be creating ALPHA , DIGIT and LETTER tokens. These rules should only be used by other lexer (so they should be marked as "fragment" rules).

Lastly, just like an identifier rule, you should make your number rule a lexer rule instead of a parser rule (lexer rules start with a capital, parser rules with a lower case letter):

grammar twp3;

type          : primitiveType  | Identifier | 'any' 'defined' 'by' Identifier;
primitiveType : 'int' | 'string' | 'binary' | 'any';
field         : 'optional'? type Identifier ';';

Identifier : LETTER (LETTER | DIGIT)*;
Number     : DIGIT+;

fragment ALPHA  : ('a'..'z'|'A'..'Z'); 
fragment DIGIT  : ('0' .. '9');
fragment LETTER : ALPHA | '_';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM