以下解析器为任何输入进入无限循环。
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
问题出在操作解析器的某个地方。我认为它与备用解析相关,但我不理解它。
你能解释一下问题是什么吗?
谢谢!
答案 0 :(得分:4)
问题实际上是无限递归。您的ast
解析器首先调用operation
解析器。但随后operation
解析器再次调用ast
。等等。用于解析的<*>
运算符也运行解析器。以非正式的方式解释与<|>
的区别:<*>
逐个运行解析器,无论<|>
是否运行第一个解析器,只有失败才运行第二个。
operation = Operation <$> ast <*> operator <*> ast
ast = operation <|> number <|> identifier
基本上,即使重新安排解析器,您的方法也行不通。请参阅类似问题的答案以获得解释:Megaparsec: Not able to parse arithmetic string