简体   繁体   中英

ANTR error(208): The following token definition can never be matched because prior tokens match the same input:

I am new here and I am also new at ANTLR. I am getting this error for a long time and I couldn't find the reason for it. Please help me!!

error(208): MPL.g:16:1: The following token definition can never be matched because prior tokens match the same input: CHAR, IF, ELSIF, ELSE, THEN, PRINT

    grammar mpl;
INT :   ('0'..'9')+;
FLOAT:   ('0'..'9')+ '.' ('0'..'9')*;
INTEGER :   'int';
FLOT    :   'float';
CHARAC  :   'char';
BEGIN   :   'begin';
END :   'end';
VAR :   ('a'..'z'|'A'..'Z')+('0'..'9')*;
CHAR    :       ('a'..'z'|'A'..'Z')+;
IF  :   'if';
ELSIF   :   'elsif';
ELSE    :   'else';
ENDIF   :   'end if';
THEN    :   'then';
PRINT   :       'print';
SEMICOLON:  ';';
COLONS  :   ':';
OPERATOR: ('+'|'-'|'*'|'/');
RELATIONAL: ('=='|'<'|'>'|'>='|'<='|'!=');
ASSIGN: '=';

program :   BEGIN decleration* statement* END;
decleration :   int|float|char;
int :   INTEGER COLONS (VAR(ASSIGN INT)?)+ SEMICOLON;
float   :   FLOT COLONS (VAR(ASSIGN FLOAT)?)+ SEMICOLON;
char    :   CHARAC COLONS (VAR(ASSIGN CHAR)?)+ SEMICOLON;

statement : ifstatement|assign|print;
statement2:  assign|print;
condition
    :   identifier RELATIONAL identifier THEN;
ifstatement:    IF condition
    statement2*
    (ELSIF condition statement2*)* (ELSE statement2*)? ENDIF SEMICOLON;      
identifier: VAR|INT|FLOAT|CHAR;
print   :   PRINT identifier SEMICOLON;
assign  :   VAR ASSIGN equation;
equation:   (VAR|INT|FLOAT|CHAR)| (VAR|INT|FLOAT|CHAR) OPERATOR (VAR|INT|FLOAT|CHAR);

The error message says what the problem is: you have certain lexer rules and they cannot be matched because another lexer rule already matches the same input. Now also keep in mind that ANTLR4 matches rules like this:

  1. The rule with the longest match wins (greedy matching).
  2. If two or more rules match the same input then the one first appearing in the grammar wins.

Now check your grammar against this process and you will notice that your VAR lexer rule matches all what IF , ELSE and so on would match. But since VAR appears before the others in the grammar it will always win for input like if etc. The consequence should be clear now: move the "catch all" rule VAR behind your keyword rules ( IF , THEN etc.).

Another thing you should keep in mind is that such keywords never will be matched as part of your VAR rule. If you need to support (in special circumstances) keywords as identifiers then search in SO for solutions, as this has been discussed before already.

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