为什么"(char '"') (char '"') (many charLiteral)" 不能用于解析字符串文字?

run*_*eks 4 haskell parser-combinators megaparsec

文档Text.Megaparsec.Char.Lexer.charLiteral建议char '"' *> manyTill charLiteral (char '"')用于解析字符串文字(在库manyTill中的模块Control.Applicative.Combinators中定义parser-combinators)。

然而,Control.Applicative.Combinators也定义了between,它-只要我能看见-像这样使用时也应该这样做的上述建议:between (char '"') (char '"') (many charLiteral)

但是,使用between上面的解析器不能解析字符串文字——以“意外的输入结束。期待 '”' 或文字字符“(表示永远不会检测到结束引号)而失败。为什么不呢?

此外,更一般地说,为什么不between pBegin pEnd (many p)等于pBegin *> manyTill p pEnd?

lef*_*out 7

between l r m没有做任何事情壮观,它真的只是尝试l,然后mr与还给结果m。因此,在 中between (char '"') (char '"') (many charLiteral)many charLiteral不知道它不应该消耗". 本many只是不断消耗无论其参数解析器接受......这,因为charLiteral刚刚接受任何东西,意味着它搅动的权利,通过一切,直到输入的结束。第二个char '"'没有停止这种方式,它只是需要凑合着还剩下些什么......即失败,因为那里一无所有!

相比之下,manyTill实际上检查“直到”是否匹配,并且在不匹配时才应用内容解析器的每次迭代。因此,终止"不会传递给charLiteral,您将获得所需的行为。