Parsec - 改进 "between" 的错误消息

Parsec - improving error message for "between"

我正在学习秒差距。我有这个代码:

import Text.Parsec.String (Parser)
import Control.Applicative hiding ((<|>))
import Text.ParserCombinators.Parsec hiding (many)

inBracketsP :: Parser [String]
inBracketsP = (many $ between (char '[') (char ']') (many $ char '.')) <* eof

main :: IO ()
main =  putStr $ show $ parse inBracketsP "" "[...][..."

结果是

Left (line 1, column 10):
unexpected end of input
expecting "." or "]"

此消息没有用(添加 . 不会解决问题)。我希望像 ']' expected 这样的东西(只有 ] 解决了这个问题)。

使用秒差距可以轻松实现吗?我已经看到 SO 问题 Parsec: error message at specific location,这很鼓舞人心,但我更愿意坚持使用 between 组合器,如果可能的话,没有手动前瞻或其他过度工程(某种)。

您可以通过在终端上附加一个空标签来隐藏终端,使其不显示在预期的输入列表中 (parser <?> ""):

inBracketsP :: Parser [String]
inBracketsP = (many $ between (char '[') (char ']') (many $ (char '.' <?> ""))) <* eof

-- >>> main
-- Left (line 1, column 10):
-- unexpected end of input
-- expecting "]"

megaparsec中还有一个hidden combinator达到同样的效果