Почему я получаю неожиданный конец ввода, когда мой синтаксический анализатор явно ищет его?

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, но это приведет к тому же поведению, что и исходный код.

Я хочу убедиться, что синтаксический анализатор потребляет весь ввод, как я могу это сделать?


person Jens Mühlenhoff    schedule 21.05.2015    source источник


Ответы (1)


Проблема в том, что перед eof есть новая строка (вставленная unlines).

Так что eof надо прогнать через lexeme.

fields = many (try field) <* lexeme eof

В противном случае Parsec пытается запустить синтаксический анализатор fields на новой строке.

person Jens Mühlenhoff    schedule 21.05.2015