为什么我会得到"意外的输入结束"当我的解析器明确地寻找它?

时间:2015-05-21 14:06:07

标签: haskell parsec

import Control.Applicative hiding (many)
import Text.Parsec
import Text.Parsec.String

lexeme :: Parser a -> Parser a
lexeme p = many (oneOf " \n\r") *> p

identifier :: Parser String
identifier = lexeme $ many1 $ oneOf (['a'..'z'] ++ ['A'..'Z'])

operator :: String -> Parser String
operator = lexeme . string

field :: Parser (String, String)
field = (,) <$> identifier <* operator ":" <*> identifier <* operator ";"

fields :: Parser [(String, String)]
fields = many (try field) <* eof

testInput :: String
testInput = unlines
    [ "    FCheckErrors         : Boolean            ;"
    , "    FAcl                 : TStrings           ;"
    ]

main :: IO ()
main = parseTest fields testInput

运行时,这会产生:

  

解析错误(第3行,第1列):意外的输入结束

当我删除显式的eof匹配时,没有这样的解析错误:

fields = many (try field)

我也尝试了try field `manyTill` eof,但这会产生与原始代码相同的行为。

我想确保解析器消耗整个输入,我该怎么做?

1 个答案:

答案 0 :(得分:7)

问题是在eof之前有一个换行符(由unlines插入)。

所以eof必须通过lexeme运行。

fields = many (try field) <* lexeme eof

否则Parsec正试图在换行符上运行fields解析器。