【问题标题】:Parsing columns of data with parsec使用 parsec 解析数据列
【发布时间】:2015-08-09 17:31:24
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您的文件是否以换行符结尾?
  • 是的,数据数组前后都有空行。

标签: parsing haskell parsec


【解决方案1】:

您的程序正在做一些与您预期不同的事情。关键部分在这里:

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)

【讨论】:

  • 你能解释一下问题中的方法到底有什么问题吗?它只是“数字sepBy空格”与spaces *&gt; digits吗?
  • 函数*&gt;是从哪里来的?
  • &gt;&gt;相同(但具有更通用的类型签名),来自Control.Applicative
猜你喜欢
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多