Взаимно рекурсивный левый калькулятор - PullRequest
2 голосов
/ 04 мая 2019

Когда я пытаюсь скомпилировать мою грамматику калькулятора antlr4, оказывается, что она остается рекурсивной. Мне нужно изменить это, чтобы исправить.

Я пытался переписать правила и использовать разные места в скобках, но все они не работают. Вот моя последняя версия правил ошибок:

Parser:

expression: INT | DECIMAL | arithmetic;
arithmetic: expression OPERATION expression;

Лексер:

OPERATION: SUB | ADD | MULT | DIV;
SUB: '-';
ADD: '+';
MULT: '*';
DIV: '/';
DPOINT: '.';
INT: SUB? NUMBER+;
DECIMAL: SUB? NUMBER+ DPOINT NUMBER+;

Я ожидаю, что компиляция будет успешной, но возникает следующая ошибка:

ANTLR Tool v4.4 (/tmp/antlr-4.4-complete.jar)
hZH.g4 -o /home/heng/workspace/Ultimate ZH Compiler/target/generated-sources/antlr4 -listener -no-visitor -encoding UTF-8
error(119): hZH.g4::: The following sets of rules are mutually left-recursive [expression, arithmetic]
1 error(s)

BUILD FAIL

Как я могу изменить свои правила для успешной сборки?

1 Ответ

3 голосов
/ 04 мая 2019

Неправильные левые рекурсивные правила не поддерживаются, но прямая левая рекурсия есть. Итак, попробуйте это:

expression
 : expression OPERATION expression
 | INT 
 | DECIMAL
 ;

Я бы не позволил лексеру сопоставить - с числом, но пусть это будет обработано парсером, например так:

expression
 : SUB expression
 | expression ( MULT | DIV ) expression
 | expression ( ADD | SUB ) expression
 | INT 
 | DECIMAL
 | OPAR expression CPAR
 ;

SUB: '-';
ADD: '+';
MULT: '*';
DIV: '/';
INT: NUMBER+;
DECIMAL: NUMBER+ '.' NUMBER+;
OPAR: '(';
CPAR: ')';

Также обратите внимание, что я дал * и / более высокий приоритет, переместив их выше + и -.

...