2012-02-28 10 views
8

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

Есть ли инструменты/рекомендации по отладке кода парсера?

+2

При выполнении синтаксического анализа - он должен возвращать 'Либо ParseError Ā' - печать на ParseError покажет вы являетесь исходной позицией и любыми сообщениями об ошибках. Наличие образца ввода в текстовом редакторе, вероятно, является самым простым способом увидеть, где соответствует исходная позиция, хотя вы можете написать свою собственную функцию броска ошибок, чтобы захватить остальную часть ввода и распечатать ее исходное содержимое ('getInput' возвращает оставшийся вход). –

ответ

8

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

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, чтобы увидеть, что происходит.

4

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

+0

Да, я предполагаю, что разбросанное '', наверное, лучшее, что я мог сделать. Надеюсь, что будут инструменты, специально разработанные для отладки parsec. – Xodarap

0

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

_ <- many anyChar >>= fail это вызовет ошибку (Left) от:

unexpected end of input 
the remaining 'string'