Unexpected end of input with Parsec

1k views Asked by At

I try to parse the following text file with series of data between keywords :

many text many text  many text 

BEGIN
T   LISTE2
1   154
2   321
3   519
4   520
5   529
6   426
END

many text  many text  many text

By using the following haskell program

import Text.Parsec
import Text.Parsec.String
import Text.Parsec.Char
import Text.Parsec.Combinator

endOfLine :: Parser String
endOfLine =     try (string "\n") 
            <|> try (string "\r\n") 

line = many $ noneOf "\n"

parseListing = do 
  spaces
  many $ noneOf "\n"
  spaces
  cont <- between (string "BEGIN\n") (string "END\n") $ endBy line endOfLine
  spaces
  many $ noneOf "\n"
  spaces
  eof
  return cont

main :: IO ()
main = do
    file <- readFile ("test_list.txt")
    case parse parseListing "(stdin)" file of
            Left err -> do putStrLn "!!! Error !!!"
                           print err
            Right resu -> do  putStrLn $  concat resu

And when I parse my text file, I get the following error :

"(stdin)" (line 16, column 1):
unexpected end of input
expecting "\n", "\r\n" or "END\n"

I'm a newbie with parsing and I don't understand why it fail? My sequence is yet between BEGIN and END

Do you know what is wrong with my parser and how to correct it ?

1

There are 1 answers

0
Alexander VoidEx Ruchkin On BEST ANSWER

Your between will never stop, because endBy line endOfLine consumes any line and END\n too, so it will eat more and more lines until it fails. Then your parser tries to consume string "END\n" and fails too, that's why error message mentions "END\n" You must rewrite line parser to fail on END\n. For example:

parseListing :: Parsec String () [String]
parseListing = do 
    spaces
    many $ noneOf "\n"
    spaces
    cont <- between begin end $ endBy (notFollowedBy end >> line) endOfLine
    spaces
    many $ noneOf "\n"
    spaces
    eof
    return cont
    where
        begin = string "BEGIN\n"
        end = string "END\n"