Удаление левой рекурсии в ANTLR

Как объясняется вУдаление левой рекурсии Есть два способа удалить левую рекурсию.

Измените исходную грамматику, чтобы удалить левую рекурсию, используя некоторую процедуруНапишите грамматику изначально, чтобы не было левой рекурсии

Что люди обычно используют для удаления (не имея) левой рекурсии с помощью ANTLR? Я использовал flex / bison для парсера, но мне нужно использовать ANTLR. Единственное, что меня беспокоит при использовании ANTLR (или LL-парсера в целом) - это удаление левой рекурсии.

В практическом смысле, насколько серьезным является удаление левой рекурсии в ANTLR? Является ли это showtopper в использовании ANTLR? Или никто не заботится об этом в сообществе ANTLR?Мне нравится идея поколения АНТЛР АСТ. С точки зрения быстрого и простого получения AST, какой метод (из двух методов удаления левой рекурсии) предпочтительнее?добавленной

Я провел некоторый эксперимент со следующей грамматикой.

E -> E + T|T
T -> T * F|F
F -> INT | ( E )

После удаления левой рекурсии я получаю следующий

E -> TE'
E' -> null | + TE'
T -> FT'
T' -> null | * FT'

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

grammar T;

options {
    language=Python;
}

start returns [value]
   : e {$value = $e.value};
e returns [value]
   : t ep  
     {
       $value = $t.value
       if $ep.value != None:
         $value += $ep.value
     }
   ;
ep returns [value]
   : {$value = None}
   | '+' t r = ep 
     {
       $value = $t.value
       if $r.value != None:
            $value += $r.value
     }
   ;
t returns [value]
  : f tp 
    {
      $value = $f.value
      if $tp.value != None:
        $value *= $tp.value
    }
  ;
tp returns [value]
  : {$value = None}
  | '*' f r = tp 
    {
      $value = $f.value;
      if $r.value != None:
        $value *= $r.value
    }
  ;
f returns [int value]
  : INT {$value = int($INT.text)}
  | '(' e ')' {$value = $e.value}
  ;

INT :   '0'..'9'+ ;
WS: (' '|'\n'|'\r')+ {$channel=HIDDEN;} ;

Ответы на вопрос(4)

Ваш ответ на вопрос