Parsing 是否可以强制回溯所有选项?

Parsing 是否可以强制回溯所有选项?,parsing,haskell,text-parsing,parsec,megaparsec,Parsing,Haskell,Text Parsing,Parsec,Megaparsec,我需要解析函数声明的语法 foo x = 1 Func "foo" (Ident "x") = 1 foo (x = 1) = 1 Func "foo" (Label "x" 1) = 1 foo x = y = 1 Func "foo" (Ident "x") = (Label "y" 1) 我已经编写了这个解析器 module SimpleParser where import Text.Parsec.String (Parser) import Text.Parsec.Lang

我需要解析函数声明的语法

foo x = 1 
Func "foo" (Ident "x") = 1

foo (x = 1) = 1 
Func "foo" (Label "x" 1) = 1

foo x = y = 1 
Func "foo" (Ident "x") = (Label "y" 1)
我已经编写了这个解析器

module SimpleParser where
import Text.Parsec.String (Parser)
import Text.Parsec.Language (emptyDef)
import Text.Parsec
import qualified Text.Parsec.Token as Tok
import Text.Parsec.Char
import Prelude

lexer :: Tok.TokenParser ()
lexer = Tok.makeTokenParser style
  where
    style = emptyDef {
              Tok.identLetter    = alphaNum
             }

parens :: Parser a -> Parser a
parens = Tok.parens lexer

commaSep :: Parser a -> Parser [a]
commaSep = Tok.commaSep1 lexer

commaSep1 :: Parser a -> Parser [a]
commaSep1 = Tok.commaSep1 lexer


identifier :: Parser String
identifier = Tok.identifier lexer

reservedOp :: String -> Parser ()
reservedOp = Tok.reservedOp lexer

data Expr = IntLit Int | Ident String | Label String Expr | Func String Expr Expr | ExprList [Expr] deriving (Eq, Ord, Show)


integer :: Parser Integer
integer = Tok.integer lexer

litInt :: Parser Expr
litInt = do
  n <- integer
  return $ IntLit (fromInteger n)

ident :: Parser Expr
ident = Ident <$> identifier

paramLabelItem = litInt <|> paramLabel

paramLabel :: Parser Expr
paramLabel = do
  lbl <- try (identifier <* reservedOp "=")
  body <- paramLabelItem
  return $ Label lbl body

paramItem :: Parser Expr
paramItem = parens paramRecord <|> litInt <|> try paramLabel <|> ident

paramRecord :: Parser Expr
paramRecord = ExprList <$> commaSep1 paramItem

func :: Parser Expr
func = do
  name <- identifier
  params <- paramRecord
  reservedOp "="
  body <- paramRecord
  return $ (Func name params body)


parseExpr :: String -> Either ParseError Expr
parseExpr s = parse func "" s
我知道它试图像
Func“foo”(标签“x”1)
那样解析此代码,但失败了。但是失败之后,为什么它不能像
Func“foo”(Ident“x”)=1那样解析它呢

parseExpr "foo x = 1"
Left (line 1, column 10):
unexpected end of input
expecting digit, "," or "="
有什么办法吗

我还尝试交换
ident
paramlab

paramItem = parens paramRecord <|> litInt <|> try paramLabel <|> ident
paramItem = parens paramRecord <|> litInt <|> try ident <|> paramLabel

以下是我如何理解Parsec回溯的工作原理(和不工作):

在:

如果
a
成功但
d
失败,Parsec不会返回并尝试
b
。一旦
a
解析成功,c就会将整个选择视为已解析,并转到
d
。它将永远不会返回到尝试
b
c

出于同样的原因,这也不起作用:

(try (try a <|> try b <|> c)) >> d

现在,如果
a
成功,但
d
失败,将尝试
b>>d

Mabye应该有一个组合器。
(try a <|> try b <|> c)
(try a <|> try b <|> c) >> d
(try (try a <|> try b <|> c)) >> d
try (a >> d) <|> try (b >> d) <|> (c >> d)