为什么这个Parsec解析器进入无限循环?

时间:2017-05-10 11:53:01

标签: haskell parsec

以下解析器为任何输入进入无限循环。

data Ast
    = Number Int
    | Identifier String
    | Operation Ast BinOp Ast
    deriving (Show, Eq)

data BinOp = Plus | Minus
    deriving (Show, Eq, Enum)

number = Number <$> read <$> many1 digit

identifier = Identifier <$> many1 letter

operator = choice $ mkParser <$> [(Plus, '+'), (Minus, '-')]
  where mkParser (f, c) = f <$ char c

operation = Operation <$> ast <*> operator <*> ast

ast :: Parser Ast
ast = operation <|> number <|> identifier

问题出在操作解析器的某个地方。我认为它与备用解析相关,但我不理解它。

你能解释一下问题是什么吗?

谢谢!

1 个答案:

答案 0 :(得分:4)

问题实际上是无限递归。您的ast解析器首先调用operation解析器。但随后operation解析器再次调用ast。等等。用于解析的<*>运算符也运行解析器。以非正式的方式解释与<|>的区别:<*>逐个运行解析器,无论<|>是否运行第一个解析器,只有失败才运行第二个。

operation = Operation <$> ast <*> operator <*> ast
ast       = operation <|> number <|> identifier

基本上,即使重新安排解析器,您的方法也行不通。请参阅类似问题的答案以获得解释:Megaparsec: Not able to parse arithmetic string