Parsing 左右递归解析器
这是一种进化 我需要用megaparsec解析一个数据结构,比如Parsing 左右递归解析器,parsing,haskell,megaparsec,Parsing,Haskell,Megaparsec,这是一种进化 我需要用megaparsec解析一个数据结构,比如 data Foo = Simple String Dotted Foo String Paren String Foo 我想把它解析成字符串 foo ::= alphanum | foo "." alphanum | alphanum "(" foo ")" 例如,字符串“a(b.c).d”应解析为虚线(Paren“a”(虚线(简单的“b”)“c”))“d” 我的问题是,这同时是左递归和
data Foo =
Simple String
Dotted Foo String
Paren String Foo
我想把它解析成字符串
foo ::= alphanum
| foo "." alphanum
| alphanum "(" foo ")"
例如,字符串“a(b.c).d”
应解析为虚线(Paren“a”(虚线(简单的“b”)“c”))“d”
我的问题是,这同时是左递归和右递归的
对于第一种和第三种情况,我在编写解析器方面没有问题:
parser :: Parser Foo
parser
= try (do
prefix <- alphanum
constant "("
content <- parser
constant ")"
pure $ Paren prefix content
)
<|> Simple alphanum
解析器::解析器Foo
分析器
尝试
prefix用于在以下情况下排除左递归:
foo ::= alphanum
| foo "." alphanum
| alphanum "(" foo ")"
您可以先将其改写为:
foo ::= alphanum ("(" foo ")")?
| foo "." alphanum
然后,您可以使用替换的标准技巧计算出左递归:
x ::= x y | z
与:
换言之:
x ::= z y*
使用x
=foo
,y
=“alphanum
,z
=alphanum(“(“foo”)”),
,即:
foo ::= alphanum ("(" foo ")")? ("." alphanum)*
那么我相信您的解析器可以是这样的,因为?
~零个或一个可能是~可选的
和*
~零个或多个[]~很多
:
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
parser=do
前缀
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