Home > other >  Parsec - improving error message for "between"
Parsec - improving error message for "between"

Time:10-25

I'm learning Parsec. I've got this code:

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 "" "[...][..."

The result is

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

This message is not useful (adding . won't fix the problem). I'd expect something like ']' expected (only ] fixes the problem).

Is it possible to achieve that easily with Parsec? I've seen the SO question Parsec: error message at specific location, which is inspiring, but I'd prefer to stick to the between combinator, without manual lookahead or other overengineering (kind of), if possible.

CodePudding user response:

You can hide a terminal from being displayed in the expected input list by attaching an empty label to it (parser <?> ""):

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

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

In megaparsec, there is also a hidden combinator that achieves the same effect.

  • Related