Удаление левой рекурсии в 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;} ;