2023/03/02
error recovery
やったこと
- タイガーブック、構文解析器のエラー回復とテスト追加
- 本屋に行った
構文解析器がエラー回復できるように error 記号を使った生成規則を追加した。
タイガーブックによると同期トークンが続かない error を含む生成規則は、エラー回復をしてもエラーが連鎖して発生する可能性があるためなるべく避けるべきらしい。
通常の LR 構文解析ではスタックの状態と先読み記号から shift/reduce が決定されるが、エラー回復ではとりあえず error 記号が shift できるようになるまでスタックを pop してから先読み記号が現われるまで入力を捨てるため、通常の LR 構文解析の時とは違い次の入力が適切ならば reduce するということが起きず、還元した後に来る入力によっては連鎖的にエラーが発生する。
エラー回復のために記述を増やしていったら error 記号を含む生成規則が結構な量になってしまったが、きちんと複数のエラーを報告するようにできたから良し (Burke-Fischer の方がこういう場合よさそうなんだけどなぁ) 。
error 記号を含む生成規則の action では例外を発生させるとそこで解析の処理自体が終わってしまうため、エラーの発生箇所を標準出力に流しているのだが、そうすると一つ以上の構文エラーを見つけて標準出力に報告したがエラー回復によって最後まで解析できてしまった場合とこれ以上還元できずに解析が失敗する場合とで挙動が異なることが気になる。
これは構文解析のフェーズではなく次のフェーズで error 記号を含む AST は弾くみたいな感じで対処するのかな?
岡本太郎展の予習として『自分の中に毒を持て』を買いにいった。 中古で買えればいいなと思ってブックオフで探したが無かったので結局新品で買った。 当日までに読むぞー!
思ったこと
ocamlyacc でエラー発生箇所を知るために、 error 記号を含む生成規則の action で Parsing.rhs_end_pos n
を使う。
これはドキュメントにも書いてあるが生成規則の右辺の n 番目の記号が見つかったファイル上での位置 (position) を教えてくれる。
行の最初の記号の位置が 0 から始まるため rhs_end_pos
を使って +1 したものを使う必要がある。
これで error 記号の位置を n で指定すれば、解析に躓いた記号の位置が分かる。
Dune でテストを書く方法についてのメモを残しておく。
- テストの方法には Inline Tests, Custom Tests, Cram Tests の 3 種類がある
- GitHub を見ていると OUnit を使ったテストが多い
- Inline Tests は library のみで使える
- Custom Tests ではテスト対象プログラムの標準出力と期待される出力の差分をチェックするテストが書ける、 lexer と parser は解析結果を標準出力させてこの方法でテストするようにした
- テスト内で外部ファイルを読み込む場合は
dune
に(deps (glob_files ../../example_program/*))
のような記述が必要 (参考: Dependency Specification)
今日の英会話
日本人の 35 % がパンデミック以来、海外旅行に行くつもりがないという調査結果。 海外旅行系の話題になると海外に行ったことがないので話題が少なくて因る。