2012-02-28 11 views
8

私はparsecで作業していましたが、コードのデバッグに問題があります。たとえば、ghciでブレークポイントを設定することはできますが、どれだけの入力が消費されたか、そのようなことを確認する方法はわかりません。Parsecのデバッグ

parsecコードのデバッグに役立つツールやガイドラインはありますか?

+2

あなたはパーサを実行すると - が表示されますParseErrorのを印刷する - それは 'どちらかとParseErrorのA'を返す必要がありますソースの位置とエラーメッセージが表示されます。あなたのサンプル入力をテキストエディタで行うことは、おそらくソース位置がどこに対応しているかを見る最も簡単な方法ですが、入力の残りをキャプチャして初期の内容を表示する独自のエラースロー機能を書くこともできます( 'getInput'は残りの入力)。 –

答えて

8

Thisページが参考になる場合があります。

Debug.traceは、それはあなたが、本質的に、いくつかのprintfデバッグを行うことができます、あなたの友達です。最初の引数を評価して出力し、2番目の引数を返します。あなたは

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を呼び出すと、評価時にstderrにx is: 1が出力されるようになりました。

詳細なデバッグについては、GHCIのデバッグコマンドを使用することをお勧めします。具体的には、:forceコマンドを探しているように聞こえます。これは変数の評価を強制し、それを出力します。代わりに:printコマンドを実行すると、評価された変数の多くが出力され、それ以上評価されることはありません。

変数の内容を調べるのに役立ちますが、あなたのプログラムのセマンティクス(あなたのプログラムが怠惰に依存する場合)。

一般GHCiのデバッグワークフローは、このようなものになります。あなたは、コード

  • 使用:show bindingsのどこにいるかの変数バインディングを確認するためにチェックするために、ブレークポイント
  • 使用:list:show contextを設定するために使用:break

    • :printを試してみてください。現在バインドされているものを見る
    • 0を使用してくださいあなたは無限ループをデバッグしようとしている場合は、あなたのバインディング

    をチェックするために、必要に応じて、それはまた、あなたがヒットすることができ

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

    を使用するのに役立ちますループ中にCtrl-Cを使用し、ループの内容を確認するには:historyを使用してください。

  • 4

    あなたは、あなたとあなたのユーザーのためのより良いエラーメッセージを作るためにText.Parsec.Primでthe <?> operatorを使用することができるかもしれません。 Real World Haskellにはexamplesがあります。あなたのパーサーが良いサブパーツを持っているならば、あなたはいくつかの簡単なテストをセットアップして(あるいはHUnitを使って)、期待通りに動作するようにすることができます。

    +0

    ええ、私はおそらく ''を自由に振りかけるのがおそらく私ができることだと思います。しかし、parsecをデバッグするために特別に設計されたツールが存在することを期待していました。 – Xodarap

    0

    別の有用なトリック:

    _ <- many anyChar >>= failこれはのエラー(Left)が生成されます:

    unexpected end of input 
    the remaining 'string'