Haskell: как остановить data.attoparsec.char8.sepby Когда входная строка пуста?
-
27-09-2019 - |
Вопрос
Я написал следующий код HASKELL
import Data.Attoparsec (Parser)
import qualified Data.Attoparsec.Char8 as A
import qualified Data.ByteString.Char8 as B
someWithSep sep p = A.sepBy p sep
Код должен работать таким образом:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Done "" [123,45,67,89]
Но так как я определил некоторое время, как в виде, написанном выше, я всегда получаю следующее поведение:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Partial _
Если я не предоставим поврежденной записи:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89f"
Done "f" [123,45,67,89]
Как я могу исправить это?
Благодаря ответу
Решение
То Partial
Конструктор не указывает сбой, просто тот анализ может продолжаться, если вы этого хотели. Вы должны взять частичный элемент и кормить его пустым бассейном (согласно документам: http://hackage.haskell.org/packages/Archive/attoParsec/0.8.1.0/doc/html/data-attoparsec-char8.html#t:result.) получить окончательный результат.
Просто чтобы показать это работает:
> let A.Partial f = A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89" in f B.empty
Done "" [123,45,67,89]
Конечно, вы, вероятно, хотите иметь заявление о случаях в конце, чтобы справиться с другими случаями.
Другие советы
ATTOPARSEC принимает вход в несколько частей. Один дает первую часть разбираться, затем дает результат от разбираться и второй кусок к подача, затем дает этот результат и третий кусок к подача Опять же, и так далее.
Вы кормите анализатор пустой строки, чтобы отметить конец ввода:
A.feed (A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89") B.empty
Done "" [123,45,67,89]
Или используйте data.attoparsec.lazy, где ленивая строка обрабатывает конец ввода для вас:
import qualified Data.Attoparsec.Lazy as L
import qualified Data.Attoparsec.Char8 as A
import qualified Data.ByteString.Lazy.Char8 as B
L.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Done "" [123,45,67,89]
(Смотрите также Этот связанный вопрос переполнения стека)