web-dev-qa-db-ja.com

字句解析器を開発するときに構文エラーにアプローチする方法は?

私は自分のアプリケーションのためにインタープリター型ドメイン固有言語を書いています。字句解析プログラムがステートメントの終わりに到達したと判断するとすぐに、各ステートメントが解析されて実行されます。一度に1つのトークンを処理し、式を評価して現在のトークンスタックを減らす再帰呼び出しを行います。

パーサーが実際にコードを解釈して実行する前に最初に構文エラーをチェックすることは直感的に理にかなっていますが、これを処理する別の方法かもしれないと思っていました。

問題のコードを実行する必要がある直前に構文がチェックされた場合はどうなりますか?これは、問題のあるコードに実際に到達するまで、無効な構文のコードに実際にフラグを立てることは発生しないことを意味します。これは、コードに欠陥があるが実行すべきではない場合、エラーの代わりに致命的ではない警告を発生させてプログラマーに通知できることを意味しますが、とにかくコードを実行させます。

たとえば、次のコードを考えてみましょう。

 1. new $a = 2
 2. new $b = 3
 3.
 4. while ($a < 10) {
 5.     $a += 3
 6.     $b += 2
 7.
 8.     if ($b < 5) {
 9.         $b = 
10.     }
11. }
12.
13. printout($a)
14. printout($b)

1行が次々に入力されると、標準インタープリターは最初の2行を実行しますが、$bに値が割り当てられておらず、致命的なエラーのためにプロセスが終了するため、9行目でエラーが発生します。

このアプローチは以下を出力します。

SyntaxError at line 9: $b = ; - Expression expected
Process terminated with exit code 1

パーサーが一度に1行ずつ構文をチェックする場合、式$b < 5trueに評価されず、障害のあるコードは実行されません。その構文は引き続きチェックされ、警告フラグが立てられます。

このアプローチは以下を出力します。

SyntaxWarning at line 9: $b = ; - Expression expected
SyntaxWarning at line 9: $b = ; - Expression expected
SyntaxWarning at line 9: $b = ; - Expression expected
11
9

障害のあるコードを実行する必要がある場合、SyntaxErrorsが無条件に発生します。唯一の違いは、コードが実行されない場合です。言語は、グラフィック生成/操作ソフトウェア用に書かれています。

インタプリタに構文警告を含める必要がありますか、それとも障害のあるコードで常に実行を終了させる必要がありますか?この決定に影響を与える要因は何ですか?

4
Mirac7

考慮すべき要素は実際には1つだけです。それは、プログラムが [〜#〜]異常終了[〜#〜] または不完全または無効な結果を生成するのがどれほど安全かということです。

スペクトルの一端は、それが単なる煩わしさであるということです。人々はプログラムを実行し、期待した結果が得られなかったことに気づき、原因を突き止めなければなりません。構文エラーメッセージが埋め込まれているメガバイトのデータを掘り下げる必要があるかもしれません。実際に害はありませんが、ユーザーが精神病で自宅の住所を知っている場合は、個人の安全上の問題が発生する可能性があります。 :-)

もう1つは、実際のダメージを引き起こすことです。これは、オールオアナッシングのアプローチを取りたい場所です。あなたの言語のドメインが、最終製品が不活性であるが中間製品の1つが有毒である化学物質を醸造するプロセスを含む場合、間違ったポイントでのABENDは、処理すべき有毒スラッジのバットを残す可能性があります。そのような場合は、実行を開始する前に、プログラムが終了する可能性が高いことを可能な限り確認する必要があります。

どちらかを実行しても、開発に大きな影響はありません。解析ツリーを生成するパーサーは、エラーが発生したという何らかの兆候を返すだけで、続行するか停止するかを簡単に決定できます。ステートメントを見つけたときに実行するユーザーは、それを防ぐためにスイッチが必要になります。無効なプログラムの実行を防ぐには、2回解析する必要があります。1回は実行を無効にし、パーサーに入力に関する苦情がない場合は、もう一度有効にします。

私自身の考えでは、あなたの言語を使用している人々がプログラムを実行せずに検証する方法を提供できるのであれば、そうすべきです。グラフィックスの操作は安全上重要ではありませんが、あなたの言語を使用してシステムを構築および統合する必要がある人々はそれをしたいと思うでしょう。開発から本番環境に移行するプロセスはますます自動化されており、検出可能な問題が発生したときに障害をスローするプログラム的な方法を提供することは、ポジティブなことです。

1
Blrfl