3

汎用言語をできるだけ早く(Lexで)解析しているときにエラーをキャッチする必要がありますか、それともより便利な場所で(Yaccで)より多くの情報を提供する必要がありますか?さまざまな言語がこの問題をどのように解決しますか?

4

2 に答える 2

3

一般に、エラーが複雑になるほど、エラーをアサートするためのコードは複雑になります。レクサーとパーサーは(実際には)かなり単純であるため、単純なエラーをキャッチします。

  1. レクサーは、トークンを構成するはずの無効な文字シーケンスをキャッチします
  2. Bison / Yaccなどの構文解析ツールは、構文とステートメントを構成するトークンの無効なシーケンスをキャッチします。

複雑なエラーは通常、実行時に他の場所で、またはコンパイル時にさまざまな変換で発生します。例としては、存在しない関数/メソッドの参照が含まれる場合があります。クロージャスコープ/バインディング、オブジェクトと参照識別子、引数の有効性、オーバーロード、およびその他の言語に依存するもののトン。

その非常に狭いトークン/構文範囲外のものはすべて、AST分析または中間コード生成のツールの外にあります(または処理する必要があります)。

検討:

a.b();
ab();

両方とも、両方のステートメントが有効なオブジェクト指向言語のレクサー/パーサーを通過する必要があります。エラーはありますか?

  1. 言語がかなり静的であり、識別子がコンパイル時に解決できる場合、 コンパイラはコンパイル時にこれをアサートする可能性があります。

  2. 両方のステートメントをID解決コードに置き換えて、実行時に実行し、コンパイラエラーではなく実行時エラーを生成することができます。

実行時とコンパイル時の解決とセマンティクスの違いは微妙で、言語ごとに大きく異なる可能性があります。

エラーは通常、エラーであることがわかっていて、最も多くの情報を持っている場合にキャッチされます。これは言語と実装によって異なります。

于 2010-02-03T13:02:19.950 に答える
0

エラー処理は、字句解析と構文解析の両方で実行する必要があります。無効な文字などのトークンエラーは、スキャナー自体ができるだけ早くキャッ​​チする必要があります。ただし、構文エラーなどのエラーはスキャナーでキャッチできないため、パーサーで処理されます。

于 2010-02-03T12:47:39.090 に答える