Ich habe mit Parsec gearbeitet und habe Probleme, meinen Code zu debuggen. Zum Beispiel kann ich einen Haltepunkt in Ghci setzen, aber ich bin nicht sicher, wie man sieht, wie viel von der Eingabe verbraucht worden ist, oder solche Sachen.
Gibt es Tools / Richtlinien, die beim Debuggen von Parsec-Code helfen?
Diese Seite könnte helfen.
Debug.trace
ist dein Freund, es erlaubt dir, einige printf
debugging durchzuführen. Es wertet aus und druckt sein erstes Argument und gibt dann sein zweites Argument zurück. Also wenn du sowas wie
Sie können den "Wert" des foo-Parameters debuggen, indem Sie foo
folgendermaßen ändern:
foo funktioniert nun genauso wie zuvor, aber wenn Sie foo 1
aufrufen, wird% ce_de% jetzt auf stderr gedruckt, wenn es ausgewertet wird.
Für ein tiefergehendes Debugging sollten Sie die Debugging-Befehle von GHCI verwenden. Genauer gesagt klingt es so, als würden Sie nach dem Befehl x is: 1
suchen, der die Auswertung einer Variablen erzwingt und sie ausgibt. (Die Alternative ist der Befehl :force
, der so viele der Variablen ausgibt, wie ausgewertet wurden, ohne sie zu bewerten.)
Beachten Sie, dass :print
hilfreicher beim Herausfinden der Inhalte einer Variablen ist, aber auch die Semantik Ihres Programms ändern kann (wenn Ihr Programm von Faulheit abhängt).
Ein allgemeiner GHCI-Debugging-Workflow sieht ungefähr so aus:
:force
, um Haltepunkte festzulegen :break
und :list
, um zu überprüfen, wo Sie sich im Code befinden :show context
, um die Variablenbindungen zu überprüfen :show bindings
, um zu sehen, was gerade gebunden ist :print
, wenn nötig, um Ihre Bindungen zu überprüfen Wenn Sie versuchen, eine Endlosschleife zu debuggen, hilft es auch,
zu verwenden:force
:set -fbreak-on-error
Dann kannst du :trace myLoopingFunc x y
während der Schleife treffen und Ctrl-C
benutzen, um zu sehen, was Looping ist.
Sie können möglicherweise Der Operator <?>
in Text.Parsec.Prim, um bessere Fehlermeldungen für Sie und Ihre Benutzer zu erstellen. Es gibt einige Beispiele in Real World Haskell. Wenn Ihr Parser gute Unterteile hat, können Sie einige einfache Tests durchführen (oder verwenden Sie HUnit ), um sicherzustellen, dass sie separat arbeiten wie erwartet.
Ein weiterer nützlicher Trick:
_ <- many anyChar >>= fail
Dies erzeugt einen Fehler ( Left
) von: