0

構成ファイル用のパーサーを作成しようとしていますが、パーサーがフリーズするという奇妙なエラーが発生します。コードはここで見ることができます。デバッガーで実行しましたが、次の行で発生するようです

p_server_entry = many settings *> pure ()

「純粋な()」の評価で。つまり、デバッガーの動作が信頼できる場合、p_server_entry から戻ろうとすると失敗するようです。「pure ()」ステートメントを削除して、単純に「[()]」を返そうとしました (そして明らかに型シグネチャを調整しました) が、同じ場所でハングしているようです。Parsec が左再帰をサポートしていないことは知っていますが、ここでそれが行われているとは思いませんか?

私がやっていることは、Parsec を使用して、ユーザー状態を介してレコードを入力することです。戻り値については、構成レコードが状態から取得され、解析の結果として返されるため、すべての関数から () を返すだけです。ハングの原因となるファイルの例は次のとおりです。

[server]
port = 80

これをテストするには、ghci で Parser.hs ファイルを実行し (ただし、プログラムをコンパイルして実行しても同じ結果が得られます)、次のようにします。

:m + Data.Monoid
parseConfigFile "test.config" mempty

どなたでもご協力いただければ幸いです。

編集:これは以前とほぼ同じように機能していたことに言及する必要があります。特別な解析ツリーを返すことから、単純に構成構造を直接更新することに変更しました。

4

2 に答える 2

0

ch = satisfy (notelem)ワイルドな推測:それを他の何か(つまり、 `oneOf" something ")で変更しようとするとどうなりますか。notelemが空の文字列と一致したり、奇妙な動作をしたりする可能性があるのではないかと思います。

より一般的には、それがお尻の痛みであることは知っていますが、問題を切り分けてみてください(つまり、パーサーが失敗する最小状態を再作成します)。現在のところ(200行のコード)、評価して対処するのは少し難しいです。

于 2013-03-12T00:41:48.347 に答える
0

そして、私はそれを手に入れました。そのブランチは公開されるべきではなかったので、コードリンクを削除しますが、その要点は次のとおりです。次のような記録がありました

data Config = { port :: Int, {- ... -} }  -- "Save edits" doesn't seem to always save edits!

入力を解析し、これらの構造の 1 つを更新するパーサーを作成しました。いずれにせよ、私が欲しかったのは更新されたレコードだけだったので、実際の解析データは破棄されました。問題は、これにより情報が破棄され、コンパイラがロジックのエラーを指摘するのを妨げてしまうことでした。実際にデータを生成したステートメントごとに、

*> pure ()

ステートメントの最後で、解析されたデータを破棄します。今は必要がなくても、おそらくデータを破棄すべきではないと判断したため、解析されたものをエンコードする新しい型を作成し、更新された構成構造とともに解析ツリーを返すことになりました。

これを完了するとすぐに、問題が明らかになりました。みたいな発言がありました。

p_server_settings = case someVar of
    "server" -> many p_serverSettings
    _        -> many p_siteSettings

そして、これらのコンビネータは両方とも次のように定義されました

p_serverSettings = many settings *> pure ()
    where settings = {- bunch of possible settings -}

() リターンを削除して生成されたものを使用すると、p_server_settings が [Setting] ではなく [[Setting]] を返そうとしていることにすぐに気付きました。

many many settings

これは、入力を消費しない便利な小さなループです。

教訓: 型を破棄すると、コンパイラの手を縛ることになります。

于 2013-03-12T08:18:33.583 に答える