2012-02-28 12 views
8

He estado trabajando con parsec y tengo problemas para depurar mi código. Por ejemplo, puedo establecer un punto de interrupción en ghci, pero no estoy seguro de cómo ver qué parte de la entrada se ha consumido, o cosas por el estilo.Depuración de Parsec

¿Existen herramientas/directrices para ayudar a depurar el código parsec?

+2

Cuando se ejecuta un programa de análisis - que debe devolver un 'a' De cualquier ParseError - imprimir la ParseError mostrará usted la posición de origen y cualquier mensaje de error. Tener su entrada de muestra en un editor de texto es probablemente la forma más fácil de ver dónde corresponde la posición de origen, aunque podría escribir su propia función de arrojar errores para capturar el resto de la entrada e imprimir su contenido inicial ('getInput' devuelve el entrada restante). –

Respuesta

8

This página podría ayudar.

Debug.trace es su amigo, le permite esencialmente hacer algo de depuración printf. Evalúa e imprime su primer argumento y luego devuelve el segundo. Así que si usted tiene algo así como

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

Puede depurar el 'valor' del parámetro de foo cambiando foo a lo siguiente:

import Debug.Trace(trace) 

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

foo ahora funcionará de la misma manera como lo hizo antes, pero cuando llame al foo 1, ahora imprimirá x is: 1 en stderr cuando se evalúe.

Para una depuración más profunda, querrá usar los comandos de depuración de GHCI. Específicamente, parece que está buscando el comando :force, que fuerza la evaluación de una variable y la imprime. (La alternativa es el comando :print, que imprime tanto de la variable como se ha evaluado, sin evaluar más.)

Tenga en cuenta que :force es más útil para averiguar el contenido de una variable, sino que también puede cambiar la semántica de su programa (si su programa depende de la pereza).

Un general GHCi flujo de trabajo de depuración es como la siguiente:

  • Uso :break a establecer puntos de interrupción
  • Uso :list y :show context para comprobar dónde se encuentra en el código
  • Uso :show bindings para comprobar las asociaciones de variables
  • Intente con :print para ver los enlaces actuales
  • Use :force si es necesario para ver sus fijaciones

Si usted está tratando de depurar un bucle infinito, sino que también ayuda a utilizar

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

A continuación, puede golpear Ctrl-C durante el ciclo y usa :history para ver lo que está sucediendo.

4

Es posible que pueda usar the <?> operator en Text.Parsec.Prim para generar mejores mensajes de error para usted y sus usuarios. Hay algunos examples en Real World Haskell. Si su analizador tiene buenas subpartes, puede configurar algunas pruebas simples (o use HUnit) para asegurarse de que funcionen por separado como se esperaba.

+0

Sí, supongo que rociar abundantemente '' es probablemente lo mejor que podría hacer. Estaba esperando que hubiera herramientas específicamente diseñadas para depurar el parsec. – Xodarap

0

Otro truco útil:

_ <- many anyChar >>= fail esto generará un error (Left) de:

unexpected end of input 
the remaining 'string' 
Cuestiones relacionadas