Как правильно добавить IO в парсер attoparsec?

Я хочу выполнить некоторую трассировку/отладку в моем парсере attoparsec. Вот минимальный [не] рабочий пример:

import Data.Text as T
import Data.Attoparsec.Text
import Data.Attoparsec.Combinator
import Control.Applicative ((<*), (*>))

parseSentences :: Parser [T.Text]
parseSentences = many1 $ takeWhile1 (/= '.') <* char '.' <* skipSpace

parser :: Parser [T.Text] 
parser = do
    stuff <- parseSentences
--    putStrLn $ "Got stuff: " ++ show stuff

    tail <- takeText
--    putStrLn $ "Got tail: " ++ show tail

    return $ stuff ++ [tail, T.pack "more stuff"]

main = do
    let input = T.pack "sample. example. bang"
    print $ parseOnly parser input

Что мне нужно сделать, чтобы использовать действия ввода-вывода в моем парсере?


person wiz    schedule 10.04.2012    source источник


Ответы (1)


Если бы вы использовали библиотеку Parsec, у вас была бы возможность использовать монадный преобразователь Parsec для смешивания команд ввода-вывода и парсера в вашем коде.

Attoparsec, однако, является чистым синтаксическим анализатором, поэтому вам придется использовать Debug.Trace.trace для вывода сообщений на терминал в целях отладки.

parser = do
  stuff <- parseSentences
  tail <- takeText
  return .
    trace ("Got stuff: " + show stuff) .
    trace ("Got tail: "  + show tail) $
    stuff ++ [tail, T.pack "more stuff"]

Сообщения будут напечатаны, когда будет оценено связанное значение (здесь результат выражения stuff ++ ...).

person dflemstr    schedule 10.04.2012
comment
Хорошо, тогда следи. Но как я могу сделать это между запросами парсера, как в исходном коде? Есть ли какая-то неоперативная вещь, которую можно передать для трассировки и получить от нее результат? - person wiz; 13.04.2012