正如删除左递归中所解释的,有两种方法可以删除左递归。
- 使用一些过程修改原始语法以删除左递归
- 原来写的文法没有左递归
人们通常使用 ANTLR 删除(没有)左递归的方法是什么?我使用 flex/bison 作为解析器,但我需要使用 ANTLR。我唯一担心使用 ANTLR(或一般的 LL 解析器)是左递归删除。
- 实际上,在 ANTLR 中去除左递归有多严重?这是使用 ANTLR 的亮点吗?或者,在 ANTLR 社区中没有人关心它?
- 我喜欢 AST 生成 ANTLR 的想法。在快速简便地获得 AST 方面,哪种方法(在 2 种删除左递归方法中)更可取?
添加
我对以下语法做了一些实验。
E -> E + T|T T -> T * F|F F -> 整数 | (五)
左递归删除后,我得到以下一个
E -> TE' E'-> 空 | + TE' T -> 英尺' T'-> 空 | *英尺'
我可以提出以下 ANTLR 表示。尽管它相对简单明了,但似乎没有左递归的语法应该是更好的方法。
语法 T; 选项 { 语言=Python; } 开始返回 [值] : e {$value = $e.value}; e 返回 [值] : EP { $value = $t.value 如果 $ep.value != 无: $value += $ep.value } ; ep 返回 [值] :{$值=无} | '+' tr = ep { $value = $t.value 如果 $r.value != 无: $value += $r.value } ; t 返回 [值] : f tp { $value = $f.value 如果 $tp.value != 无: $value *= $tp.value } ; tp 返回 [值] :{$值=无} | '*' fr = tp { $value = $f.value; 如果 $r.value != 无: $value *= $r.value } ; f 返回 [int 值] : INT {$value = int($INT.text)} | '('e')' {$value = $e.value} ; INT : '0'..'9'+ ; WS: (' '|'\n'|'\r')+ {$channel=HIDDEN;} ;