Parsing 左右递归解析器

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” 我的问题是,这同时是左递归和

这是一种进化

我需要用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”

我的问题是,这同时是左递归和右递归的

对于第一种和第三种情况,我在编写解析器方面没有问题:

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