Open
Description
Here is an example demonstrating that we get different error messages depending on how we parethesize a <|> b <|> c
.
import Data.Void
import Text.Megaparsec
import Text.Megaparsec.Char.Lexer
type Parser = Parsec Void String
sym :: String -> Parser ()
sym s = do
_ <- symbol (pure ()) s
pure ()
-- consumes one character, then rolls back
a :: Parser ()
a = try (sym "a" >> empty) <?> "a"
-- fails immediately (on the given input)
b :: Parser ()
b = sym "b"
-- succeeds immediately
c :: Parser ()
c = pure ()
-- |
-- >>> parseTest (leftAssociative >> sym "d") "aaa"
-- 1:1:
-- |
-- 1 | aaa
-- | ^
-- unexpected 'a'
-- expecting 'd'
leftAssociative :: Parser ()
leftAssociative = (a <|> b) <|> c
-- |
-- >>> parseTest (rightAssociative >> sym "d") "aaa"
-- 1:1:
-- |
-- 1 | aaa
-- | ^
-- unexpected 'a'
-- expecting 'b' or 'd'
rightAssociative :: Parser ()
rightAssociative = a <|> (b <|> c)