3

それほど複雑ではない言語のパーサーが必要です。唯一の問題は、パーサーが不正な入力を受け取ったときにエラーを発生させたくないということです。むしろ、Web ブラウザーの HTML パーサーが行うのと同じように、入力を可能な限り意味のあるものにして、そのまま続行することを望んでいます。

私は当然、パーサー ジェネレーターを使用することを考えていましたが、それらを使用した経験はあまりなく、Bison と Antlr で見たすべての例は、構文エラーが発生するとすぐにあきらめる脆弱なパーサーを特徴としています。これはそれらで実行可能ですか、それとも手動でロールすることを検討する必要がありますか? 言語を考えると、おそらく(私が思うに)それほど難しくはないでしょう。

4

2 に答える 2

1

チェックポイントを念頭に置いて文法を設計する必要があります。チェックポイントとは、Cのセミコロン、Pythonの改行、またはCOBOLのピリオドを意味します(例として)。このチェックポイントは、最初に見つかったエラー以外のものを報告できるように、回復するコンパイラの数です。

私はBisonを使用していませんが、YACCを使用するとエラー処理をオーバーライドでき、同等のGNUツールが少なくとも古いUNIXクランカーと同じくらい強力であることを願っています。

私は以前に設定ファイルYACC文法でこれを行いました。次の正しく形成されたセグメントがあるとします。

item = "bread" {
    quantity = 7
    price = 1.50
    taxrate = 10
}

そして、いくつかの奇妙な理由で、ユーザーは「量」のつづりを間違えて、それを間違ってレンダリングします。コールバックのその時点で、チェックポイントに到達するまでそれ以上の処理を妨げるエラーフラグを立てることができます。パーサーを続行させ(さらなるエラーをキャッチして無視し)、破損した構文での誤った成功に応答してコールバックが何もしないことを確認します。

これは、閉じ中括弧までのすべてのスタンザを単に無視するか、または価格のデフォルト値を設定し、改行までのみ無視することによって(少なくとも部分的に形成されたオブジェクトを取得するために)可能性があります。

ただし、チェックポイントに到達したらエラーフラグをリセットするだけで、処理を続行できます。

私はまだユーザーに通知されていることを確認します。顧客が望まないデータを続行することは悪い形式と見なされることがあります:-)。

于 2009-05-06T04:04:01.450 に答える
1

一般的なケースで、パーサージェネレーターを使用してそれを行うことができるかどうかはわかりません。少なくとも、完全に自動化された方法ではありません。次の不正な式を考えてみましょう。

a - b + c ) * d

パーサーはこれで何をすべきでしょうか? 最初の不正なトークンである閉じ括弧に遭遇すると、ユーザーがどこかで開き括弧を意図していたことを推測できるかもしれませんが、どこでしょうか? それを置くことができる場所は、異なる値になります。

代わりに、以前に起こったことはすべて起こらなかったふりをすることができます. その後、

* d

これはまだ不正です。

于 2009-05-06T03:01:13.957 に答える