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

标签 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

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

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

谢谢!

最佳答案

问题确实在于无限递归。您的ast解析器调用operation首先解析器。但后来operation解析器调用ast再次回来。等等。 <*>用于解析的运算符也运行解析器。与 <|> 的差异说明以非常非正式的方式:<*>按顺序一一运行解析器是否 <|>运行第一个解析器,只有在失败时才运行第二个解析器。

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

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

关于haskell - 为什么这个 Parsec 解析器会进入无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43891738/

相关文章:

haskell - 为什么 Haskell/GHC 可执行文件的文件大小如此之大?

haskell - 如何在 Haskell 中使用 rpar 策略并行评估元组?

haskell - Parsec 解析器在 many1 和 manyTill 组合器上失败

haskell - Parsec-Haskell,格式化解析错误

parsing - 解析器返回值的自定义 ADT 与树

haskell - 为什么 (++) 可以用于使用 map 预先添加和附加?

haskell - 为什么某些函数调用在没有类型应用程序的情况下无法工作?

haskell - 具有两个参数的构造函数的应用样式解析器

parsing - 如何使用 Parsec 通过特定字符串分隔字符串

haskell - 为什么 Haskell 不允许这种声明?