要在此中考虑左递归:
foo ::= alphanum
| foo "." alphanum
| alphanum "(" foo ")"
您可以先将其重写为:
foo ::= alphanum ("(" foo ")")?
| foo "." alphanum
然后,您可以使用替换的标准技巧计算出左递归:
x ::= x y | z
用:
x ::= z x'
x' ::= y x' | â
换言之:
x ::= z y*
用
x
=
foo
,
y
=
"." alphanum
和
z
=
alphanum ("(" foo ")")?
,变成:
foo ::= alphanum ("(" foo ")")? ("." alphanum)*
那么我相信你的解析器可以是这样的,因为
?
0或1
Maybe
~
optional
和
*
~零或更多~
[]
~
many
:
parser = do
prefix <- Simple <$> alphanum
maybeParens <- optional (constant "(" *> parser <* constant ")")
suffixes <- many (constant "." *> alphanum)
let
prefix' = case maybeParens of
Just content -> Paren prefix content
Nothing -> prefix
pure $ foldl' Dotted prefix' suffixes