Отладка Parsec - PullRequest
       50

Отладка Parsec

8 голосов
/ 28 февраля 2012

Я работал с parsec, и у меня проблемы с отладкой моего кода. Например, я могу установить точку останова в ghci, но я не уверен, как увидеть, сколько входного сигнала было израсходовано, или тому подобное.

Существуют ли инструменты / рекомендации по отладке кода parsec?

Ответы [ 3 ]

9 голосов
/ 28 февраля 2012

Эта страница может помочь.

Debug.trace - ваш друг, он позволяет вам выполнить некоторую отладку printf. Он оценивает и печатает свой первый аргумент, а затем возвращает свой второй. Так что если у вас есть что-то вроде

foo :: Show a => a -> a
foo = bar . quux

Вы можете отладить «значение» параметра foo, изменив foo на следующее:

import Debug.Trace(trace)

foo :: Show a => a -> a
foo x = bar $ quux $ trace ("x is: " ++ show x) x

foo теперь будет работать так же, как и раньше, но когда вы вызываете foo 1, теперь он будет печатать x is: 1 в stderr при оценке.

Для более глубокой отладки вы захотите использовать команды отладки GHCI. В частности, это звучит так, как будто вы ищете команду :force, которая вынуждает вычислять переменную и печатает ее. (Альтернативой является команда :print, которая печатает столько переменных, сколько было оценено, без дополнительной оценки.)

Обратите внимание, что :force более полезен для определения содержимого переменной, но может также изменить семантику вашей программы (если ваша программа зависит от лени).

Общий рабочий процесс отладки GHCI выглядит примерно так:

  • Используйте :break для установки точек останова
  • Используйте :list и :show context, чтобы проверить, где вы находитесь в коде
  • Используйте :show bindings для проверки привязок переменных
  • Попробуйте использовать :print, чтобы увидеть, что в данный момент связано
  • Используйте :force при необходимости, чтобы проверить ваши привязки

Если вы пытаетесь отлаживать бесконечный цикл, также полезно использовать

  • :set -fbreak-on-error
  • :trace myLoopingFunc x y

Затем вы можете нажать Ctrl-C во время цикла и использовать :history, чтобы увидеть, что зацикливается.

5 голосов
/ 28 февраля 2012

Возможно, вы сможете использовать оператор <?> в Text.Parsec.Prim, чтобы создавать лучшие сообщения об ошибках для вас и ваших пользователей. В Real World Haskell есть несколько примеров . Если у вашего парсера хорошие части, то вы можете настроить несколько простых тестов (или использовать HUnit ), чтобы убедиться, что они работают раздельно, как и ожидалось.

1 голос
/ 25 февраля 2018

Еще один полезный трюк:

_ <- many anyChar >>= fail это приведет к ошибке (Left):

unexpected end of input
the remaining 'string'

Я думаю, parserTrace и parserTracedфункции, упомянутые здесь http://hackage.haskell.org/package/parsec-3.1.13.0/docs/Text-Parsec-Combinator.html#g:1, выполняют действия, аналогичные описанным выше.

...