Parsec 输入意外结束

Unexpected end of input with Parsec

我尝试用关键字之间的一系列数据解析以下文本文件:

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

通过使用以下 haskell 程序

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

当我解析我的文本文件时,出现以下错误:

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

我是解析新手,不明白为什么会失败? 我的序列还在 BEGINEND

之间

你知道我的解析器出了什么问题以及如何纠正它吗?

你的 between 永远不会停止,因为 endBy line endOfLine 会消耗任何行, END\n 也会,所以它会吃掉越来越多的行,直到它失败。 然后你的解析器尝试使用 string "END\n" 但也失败了,这就是错误消息提到 "END\n" 的原因 您必须重写行解析器才能在 END\n 上失败。例如:

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"