Reputation: 12289
I have the little grammar below. node
is the start production. When my input is (a:b)
I get an error: line 1:1 extraneous input 'a' expecting {':', INAME}
Why is this?
EDIT - I forgot that the lexer and parser run as a separate phases. By the time the parser runs, the lexer has completed. When the lexer runs it has no knowledge of the parser rules. It has already made the TYPE/INAME decision choosing TYPE per @bart's reasoning below.
grammar g1;
TYPE: [A-Za-z_];
INAME: [A-Za-z_];
node: '(' namesAndTypes ')';
namesAndTypes:
INAME ':' TYPE
| ':' TYPE
| INAME
;
Upvotes: 1
Views: 107
Reputation: 170138
That is because the lexer will never produce an INAME
token. The lexer works in the following was:
Because the input "a"
and "b"
both match the TYPE
and INAME
rules, the TYPE
rule wins because it is defined first. It doesn't matter if the parser is trying to match an INAME
rule, the lexer will not produce it. The lexer does not "listen" to he parser.
You could create some sort of ID
rule, and then define type
and iname
parser rules instead:
ID: [A-Za-z_];
node
: '(' namesAndTypes ')'
;
namesAndTypes
: iname ':' type
| ':' type
| iname
;
type
: ID
;
iname
: ID
;
Upvotes: 1