Nov. 1st, 2011
attoparsec-enumerator, забавное
Nov. 1st, 2011 12:48 pmТри парсера : ( Read more... )
и их использование:( Read more... )
Второй и третий работают. Первый глючит - пропускает куски потока. Потому как после разбора не сохраняет остаток буфера, прочитанного енумератором и не отдает его при продолжении, а начинает разбор уже со свежепрочитанного буфера.
А нужен именно первый, для того, чтобы посылать по одной команды на девайс и читать и парсить ответы. Т.е. один цикл работы связки enumerator $$ iteratee на каждый ответ от девайса.
Либо использовать не enumerator, а более сложную реализацию - пакет iteratee, который умеет из Iteratee посылать команды обратно в Enumerator, используя исключения и их перехват.
Либо забить и сделать в лоб, т.к. тут на самом деле Iteratees нужны только для сушения мозга и удобства комбинирования парсеров и прочих фильтров потоков.
и их использование:( Read more... )
Второй и третий работают. Первый глючит - пропускает куски потока. Потому как после разбора не сохраняет остаток буфера, прочитанного енумератором и не отдает его при продолжении, а начинает разбор уже со свежепрочитанного буфера.
А нужен именно первый, для того, чтобы посылать по одной команды на девайс и читать и парсить ответы. Т.е. один цикл работы связки enumerator $$ iteratee на каждый ответ от девайса.
Либо использовать не enumerator, а более сложную реализацию - пакет iteratee, который умеет из Iteratee посылать команды обратно в Enumerator, используя исключения и их перехват.
Либо забить и сделать в лоб, т.к. тут на самом деле Iteratees нужны только для сушения мозга и удобства комбинирования парсеров и прочих фильтров потоков.
Haskell, гротесковое
Nov. 1st, 2011 08:57 pmЕнумераторы-итератии наконец заработали так, как я себе это представлял.
Ошибок было две:
Ключевая: надо было IO action лифтить внутрь iteratee и там всю работу и выполнять. А не внутри IO дергать енумератор с итератее-парсером и доставая результат:
( Read more... )
Вторая ошибка: в протоколе одного девайса после строки данных идет \r\n. в протоколе другого только \r. Строки разделены пустыми строками как бог на душу положит.
Я пишу парсер на attoparsec таким образом:
Таймауты, впрочем, вообще не обрабатываются - пакет serialport на них возвращает пустые строки. Дойдут руки - буду разбираться как это исправлять, кроссплатформенным образом.
И да, я вспомнил, зачем же я это все делал: меня задрало не иметь под руками прототипа софта, который можно единообразно запустить как винде, так и на линуксе и который бы работал с висящими на ком-порту девайсами согласно разнообразных от фонаря придуманных протоколов.
Ошибок было две:
Ключевая: надо было IO action лифтить внутрь iteratee и там всю работу и выполнять. А не внутри IO дергать енумератор с итератее-парсером и доставая результат:
( Read more... )
Вторая ошибка: в протоколе одного девайса после строки данных идет \r\n. в протоколе другого только \r. Строки разделены пустыми строками как бог на душу положит.
Я пишу парсер на attoparsec таким образом:
do skipWhile isSpace_w8 --пропускаем whitespace data <- ReadData --читаем строку данных skipWhile isSpace_w8 --пропускаем whitespace (т.е. - перенос строки) return dataТак вот, skipWhile, что характерно - будет ждать данных пока не придет хоть что-нибудь, отличающееся от предиката. Если девайс не гонит данные непрерывным потоком - то это повисает до истечения таймаута.
Таймауты, впрочем, вообще не обрабатываются - пакет serialport на них возвращает пустые строки. Дойдут руки - буду разбираться как это исправлять, кроссплатформенным образом.
И да, я вспомнил, зачем же я это все делал: меня задрало не иметь под руками прототипа софта, который можно единообразно запустить как винде, так и на линуксе и который бы работал с висящими на ком-порту девайсами согласно разнообразных от фонаря придуманных протоколов.