昨日の続きで、TECSジェネレータでの文法定義と、CDLファイルでのエラーになる書き方を調べています。
今回も途中報告です。
前回に書いたerror-7.cdlは、以下の文法の記述に誤りがある場合のテスト-ケースでした.
文法定義
celltype
: CELLTYPE celltype_name ‘{‘ celltype_statement_list ‘}’ ‘;’
error-7.cdlの内容
celltype TaskMain {
/* attributeの定義が空でならsyntax error */
/* attr {
x = 0;
};
*/
};
これはコメントを無視すると、以下と同等です。
celltyope TaskMain {};
文法定義と比較すると、celltype_statement_listという要素が不足しているため、文法エラーとなります。
実際、raccの生成したパーザはこの文法エラーを認識して、on_error()を呼び出しています.
ここで、on_error()とは、raccを用いてパーザを作成する人が、エラー処理を行うために自由に定義できるメソッドです。
on_error()でパース自体を中止することもできます。
また中止せずに、raccが生成したパーザにエラー回復モードで処理を続行させることができます。
エラー回復モードは、文法エラーが見つかった箇所を、エラーだとは認識しつつも、そこに正しい記述があったものとみなして、パース処理をつづけることです。
今回の文法定義の場合を例にとると、celltype_statement_listが存在するべきところに、「}」があったため、エラーとなります.
この後エラー回復モードで処理を続けようとして、「}」をcelltype_statement_listだとみなします。
文法では、この後に「}」と「;」がこの順番に記述されていなければなりません。
しかし、入力としては「;」しか存在しません。
raccは入力の終わりを$endというトークンとして扱います。
しかし、これが来ても、文法エラーが解消されません.パーザは次の入力を求めますが、実際の入力は終わっているので、$endしか渡してもらえません.
結局ここで無限ループが発生してしまいます。
実は、同じエラー内容でも以下の場合は、パーザは文法エラーを報告し、正常に終了します.
(文法としてはエラーになるが、正常終了する場合の記述)
celltyope TaskMain {}};
最初の「}」が来た時点でエラーと判断されますが、エラー回復モードになっても「}」、「;」と続くため、celltypeの文法定義に合致し、エラー回復モードは終了します。その後入力の終わり$endが来て、パーザは正常終了します。
エラー回復モードが(期待するより)頑張りすぎているのかもしれません.
ただし、入力の終わりがきたら必ず打ち切るようにするには、入力の終わりを特別扱いし、どんな状態であっても終了するルーチンをつくるか、どの状態からでも入力の終わりが来たら終了する状態遷移テーブルを作成する必要があると思います。
後、raccが手本にしたyaccの仕様がどうだったのか、確認したほうがいいかな。
raccの動作が、yaccの仕様の通りであれば、on_error()で対処するのがbetterだと思います.
“raccのエラー回復モードは頑張りすぎ?” への1件の返信