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

Why doesn't "between (char '"') (char '"') (many charLiteral)" work for parsing string literals?

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

但是,Control.Applicative.Combinators 还定义了 between,据我所知,它应该与上面的建议一样,当这样使用时:between (char '"') (char '"') (many charLiteral)

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

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

between l r m 没有做任何引人注目的事情,它实际上只是尝试 l 然后 m 然后 r 并返回 m 的结果。因此,在 between (char '"') (char '"') (many charLiteral) 中,many charLiteral 不知道它不应该使用 "many 只是不断地消耗它的参数解析器接受的任何东西……这,因为 charLiteral 只接受 任何东西 ,意味着它会搅动所有东西,直到结束输入。第二个 char '"' 无法阻止它,它只需要处理剩下的事情......即 fail 因为那里 is一无所有!

相比之下,manyTill 实际上检查“till”是否匹配, 应用内容解析器的每次迭代(如果不匹配)。因此,终止 " 不会传递给 charLiteral,您会得到所需的行为。