4

The documentation for Text.Megaparsec.Char.Lexer.charLiteral suggests using char '"' *> manyTill charLiteral (char '"') for parsing string literals (where manyTill is defined in the module Control.Applicative.Combinators in the parser-combinators library).

However, Control.Applicative.Combinators also defines between, which -- as far as I can see -- should do the same as the above suggestion when used like so: between (char '"') (char '"') (many charLiteral).

However, using the between parser above does not work for parsing string literals -- failing with "unexpected end of input. expecting '"' or literal character" (indicating that the ending quote is never detected). Why not?

Also, more generally, why isn't between pBegin pEnd (many p) equivalent to pBegin *> manyTill p pEnd?

4

1 回答 1

7

between l r m没有做任何壮观的事情,它真的只是尝试l然后m返回. 所以,在 中,不知道它不应该消耗. 只是不断消耗它的参数解析器接受的任何东西......这因为只是接受任何东西,这意味着它会在所有内容中搅动直到输入结束。第二个没有办法阻止它,它只需要处理剩下的东西......即,失败,因为什么没有了!rmbetween (char '"') (char '"') (many charLiteral)many charLiteral"manycharLiteralchar '"'

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

于 2020-05-06T09:19:31.250 回答