Леворекурсивная ошибка грамматики Antlr4

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

 grammar UPN;

    //Parser  

    expression : plus | minus | mult | div | NUMBER;  
    plus : expression expression '+';  
    minus : expression expression '-';  
    mult : expression expression '*';  
    div : expression expression '/';  

    //Lexer  
    NUMBER : '-'? ('0'..'9')+;  

antlr выдаст ошибку, потому что plus, minus, mult и div взаимно рекурсивны.
Я не знаю, как это исправить.
(Я знаю, что это происходит, потому что с этой грамматикой "выражение" может быть бесконечно зациклено, я у меня была эта проблема раньше с другой грамматикой, но я мог бы исправить это самостоятельно)

Моим единственным решением было бы ограничить грамматику следующим образом

grammar UPN;

//Parser

expression : plus | minus | mult | div | NUMBER;
exp2 : plus2 | minus2 | mult2 | div2 | NUMBER;
plus : exp2 exp2'+';
minus : exp2 exp2'-';
mult: exp2 exp2'*';
div: exp2 exp2'/';
plus2 : NUMBER NUMBER '+';
minus2 : NUMBER  NUMBER '-';
mult2: NUMBER  NUMBER '*';
div2: NUMBER  NUMBER '/';

//Lexer
NUMBER : '-'? ('0'..'9')+;  

но это не совсем то, что я хочу, потому что теперь я могу работать по максимуму с такими выражениями, как

2 3 + 5 4 - *

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


person skoelz    schedule 04.06.2014    source источник


Ответы (1)


ANTLR4 поддерживает только «прямые» леворекурсивные правила, а не «косвенные», как они есть у вас.

Попробуйте что-то вроде этого:

grammar RPN;

parse : expression EOF;

expression
 : expression expression '+'
 | expression expression '-'
 | expression expression '*'
 | expression expression '/'
 | NUMBER
 ;

NUMBER : '-'? ('0'..'9')+;

SPACES : [ \t\r\n] -> skip;

Кстати, 23+54-* не является допустимым выражением RPN: оно должно начинаться с двух чисел.

person Bart Kiers    schedule 04.06.2014
comment
Спасибо, это работает! кстати, я просто не добавил туда пробелы;) - person skoelz; 04.06.2014