yacc プログラムのエラー処理
パーサーが入力ストリームを読むとき、 その入力ストリームは文法ファイルの規則と一致しない可能性もあります。
パーサーは、可能な限り早く問題を検出します。 文法ファイルにエラー処理サブルーチンがある場合、 パーサーは、再びデータを入力するか、誤ったデータを無視するか、 またはクリーンアップおよびリカバリー・アクションを開始することを許可します。 パーサーは、エラーを発見すると、例えば、 構文解析ツリー・ストレージを再利用し、シンボル・テーブルの項目を削除または変更し、 さらにそれ以後の出力の生成を避けるために、スイッチを設定する必要が出てくる場合があります。
エラーが起こると、ユーザーがエラー処理サブルーチンを準備しておかなければ、 パーサーは停止します。 入力の処理を続行してさらにエラーを検索するには、入力ストリームの中の、 パーサーがそれ以上の入力の認識を試みることができるポイントで、パーサーを再始動します。 エラーが起きたときにパーサーを再始動する 1 つの方法は、 エラーに続くトークンの一部を破棄することです。 その後、入力ストリームの中のそのポイントからパーサーを再始動します。
yacc コマンドは、 エラー処理に特殊なトークン名 error を使用します。 このトークンを、 規則ファイルの入力エラーが発生した場所に書き込んで、 リカバリー・サブルーチンを提供できるようにします。 入力エラーがこの位置で起きた場合、パーサーは、 通常のアクションでなく error トークンのためのアクションを実行します。
マクロ | 説明 |
---|---|
YYERROR | パーサーにエラー処理を開始させる。 |
YYABORT | パーサーに値 1 で戻らせる。 |
YYACCEPT | パーサーに値 0 で戻らせる。 |
YYRECOVERING() | 構文エラーが検出され、パーサーがまだ完全にリカバリーしていない場合、値 1 を戻す。 |
単一エラーで多数のエラー・メッセージが出されるのを防ぐために、 パーサーはエラーに続いて 3 個のトークンを処理するまでエラー状態でいます。 パーサーがエラー状態の間に別のエラーが発生すると、 パーサーは入力トークンを破棄して、メッセージを作成しません。
stat : error ';'
これは、エラーが起きたときはそのトークンとそれに続くすべてのトークンを、次のセミコロンが見つかるまで無視するように、パーサーに指示します。 エラーの後から次のセミコロンの前までの、すべてのトークンは破棄されます。 セミコロンを検出すると、パーサーはこの規則を縮小して、 関連するすべてのクリーンアップ・アクションを実行します。
エラー訂正の準備
input : error '¥n'
{
printf(" Reenter last line: " );
}
input
{
$$ = $4;
}
;
yyerrok;
パーサーは、このステートメントを発見すると、エラー状態を離れて、 通常に処理を始めます。 エラー・リカバリーの例を、次に示します。
input : error '¥n'
{
yyerrok;
printf(" Reenter last line: " );
}
input
{
$$ = $4;
}
;
ルック・アヘッド・トークンのクリア
yyclearin ;