正如删除左递归中所解释的,有两种方法可以删除左递归。
- 使用一些过程修改原始语法以删除左递归
- 原来写的文法没有左递归
人们通常使用 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;} ;