From 0e2fd1015bc2d6b39ae0b33a00f1ae64cee528b5 Mon Sep 17 00:00:00 2001 From: Leonid Date: Tue, 4 Jan 2022 14:43:38 +0300 Subject: [PATCH] [#121] Fixed duplicating of end of input in unexpected and expecting sections --- parsec.cabal | 7 +++++++ src/Text/Parsec/Error.hs | 7 ++++++- test/issue121.hs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/issue121.hs diff --git a/parsec.cabal b/parsec.cabal index ef5deec7..f934abd0 100644 --- a/parsec.cabal +++ b/parsec.cabal @@ -129,6 +129,13 @@ test-suite parsec. else build-depends: semigroups +test-suite parsec-issue121 + default-language: Haskell2010 + type: exitcode-stdio-1.0 + main-is: issue121.hs + hs-source-dirs: test + build-depends: base, parsec, containers + test-suite parsec-issue127 default-language: Haskell2010 type: exitcode-stdio-1.0 diff --git a/src/Text/Parsec/Error.hs b/src/Text/Parsec/Error.hs index a4066473..734e7c2d 100644 --- a/src/Text/Parsec/Error.hs +++ b/src/Text/Parsec/Error.hs @@ -187,7 +187,12 @@ showErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEndOfInput msgs (unExpect,msgs2) = span ((UnExpect "") ==) msgs1 (expect,messages) = span ((Expect "") ==) msgs2 - showExpect = showMany msgExpecting expect + cleanedExpect | containsEofInSysUnExpect = filter (\msg -> messageString msg /= msgEndOfInput) expect + | otherwise = expect + where + containsEofInSysUnExpect = (null unExpect && not (null sysUnExpect)) && null (messageString $ head sysUnExpect) + + showExpect = showMany msgExpecting cleanedExpect showUnExpect = showMany msgUnExpected unExpect showSysUnExpect | not (null unExpect) || null sysUnExpect = "" diff --git a/test/issue121.hs b/test/issue121.hs new file mode 100644 index 00000000..544122d6 --- /dev/null +++ b/test/issue121.hs @@ -0,0 +1,37 @@ +module Main (main) where + +import Data.Map (fromList) +import Text.Parsec + +sepBy1Try p sep = do + x <- p + xs <- many (try $ sep *> p) + return (x : xs) + +key = + try (string "byr") + <|> try (string "cid") + <|> try (string "eyr") + <|> try (string "ecl") + <|> try (string "hgt") + <|> try (string "hcl") + <|> try (string "iyr") + <|> try (string "pid") + +passportKV = try $ do + k <- key + char ':' + v <- many1 (try alphaNum <|> try (char '#')) + return (k, v) + +passportLine = sepBy1Try passportKV space + +passport = do + lines <- sepBy1Try passportLine endOfLine + return $ fromList [kv | line <- lines, kv <- line] + +passports = sepBy1 passport (try (endOfLine *> endOfLine *> pure ()) <|> (endOfLine *> eof *> pure ())) + +main = do + let raw = "byr:2001 iyr:2011\necl:brn\npid:487702556 hcl:#602927\nhgt:167cm eyr:2026\n" + print $ parse passports "(poop)" raw