Ошибка ANTR (208): Следующее определение токена никогда не может быть сопоставлено, поскольку предыдущие токены совпадают с одним и тем же входом: - PullRequest
0 голосов
/ 28 марта 2020

Я новичок здесь и я также новичок в ANTLR. Я получаю эту ошибку в течение длительного времени, и я не мог найти причину для этого. Пожалуйста, помогите мне !!

ошибка (208): MPL.g: 16: 1: Следующее определение токена никогда не может быть найдено, потому что предыдущие токены совпадают с одним и тем же входом: CHAR, IF, ELSIF, ELSE, THEN, ПЕЧАТЬ

    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);

1 Ответ

1 голос
/ 29 марта 2020

В сообщении об ошибке указано, в чем проблема: у вас есть определенные правила лексера, и они не могут быть сопоставлены, потому что другое правило лексера уже соответствует тому же вводу. Также имейте в виду, что ANTLR4 соответствует правилам следующим образом:

  1. Правило с самым длинным соответствием выигрывает (жадное соответствие).
  2. Если два или более правил соответствуют одному и тому же входу, первый, появившийся в грамматике, выигрывает.

Теперь проверьте свою грамматику на соответствие этому процессу, и вы заметите, что ваше правило лексера VAR соответствует всему тому, что будет соответствовать IF, ELSE и т. д. , Но так как VAR появляется перед другими в грамматике, он всегда будет выигрывать за ввод, такой как if et c. Теперь следствие должно быть ясным: переместите правило «поймать все» VAR за вашими правилами для ключевых слов (IF, THEN et c.).

Еще одна вещь, которую вы должны иметь в виду, это что такие ключевые слова никогда не будут соответствовать как правило VAR. Если вам необходимо поддерживать (в особых случаях) ключевые слова в качестве идентификаторов, то ищите в SO решения, как это уже обсуждалось ранее.

...