使用 parsec 解析数据列

Parsing columns of data with parsec

我正在编写一个解析器来扫描数字列。像这样:

T   LIST2   LIST3   LIST4
1   235 623 684
2   871 699 557
3   918 686 49
4   53  564 906
5   246 344 501
6   929 138 474

第一行包含列表的名称,我希望我的程序解析与标题中完全相同数量的数据(以排除标题或列数不一致的数组)。

我写了这个程序:

title = do
  tit <- many1 alphaNum
  return tit

digits = do
  dig <- many1 digit
  return dig

parseSeries = do 
    spaces
    titles <- title `sepBy` spaces
    let nb = length titles
    dat <- endBy (count (nb-1) (digits `sepBy` spaces)) endOfLine
    spaces
    return (titles,concat dat)

main = do
    fichier <- readFile ("test_list3.txt")
    putStrLn $ fichier
    case parse parseSeries "(stdin)" fichier of
            Left error -> do putStrLn "!!! Error !!!"
                             print error
            Right (tit,resu) -> do  
                                mapM_ putStrLn  tit
                                mapM_ putStrLn  (concat  resu)

但是当我尝试用这种数据解析文件时,出现以下错误:

!!! Error !!!
"(stdin)" (line 26, column 1):
unexpected end of input
expecting space or letter or digit

我是解析新手,不明白为什么会失败?

你知道我的解析器出了什么问题吗?

您的程序执行的操作与您预期的不同。关键部分就在这里:

parseSeries = do 
    spaces
    titles <- title `sepBy` spaces
    let nb = length titles

    -- The following is the incorrect part
    dat <- endBy (count (nb-1) (digits `sepBy` spaces)) endOfLine
    spaces
    return (titles,concat dat)

我相信你真正想要的是:

parseSeries = do 
    spaces
    titles <- title `sepBy` spaces
    let nb = length titles

    let parseRow = do
            column  <- digits
            columns <- count (nb - 1) (spaces *> digits)
            newline
            return (column:columns)
    dat <- many parseRow
    return (titles, dat)