raccのparser.rbとcparseの違い

さらに引き続き(raccのエラー回復モードは頑張りすぎ?tecsgen の Exerb版, Jruby 版の障害について)、raccのparser.rbとcparseの動作の違いを調べています.

昨日は、parser.rbがエラー回復モードで、定義された文法を満たすトークンの並びを得ようとして、(入力が終わっているのに)延々と次のトークンを得ようとして、無限ループに陥っているようだと書きました。
このことを指して「頑張りすぎ」と評していました。

そして、同じ不完全な内容の入力(不完全故に文法エラーになる)に対して、正常終了して文法エラーを報告するcparseは「頑張らない」ようにしているのではないかと予想していました.

今回、cparseを用いて、同じくtecsgen -yを指定してデバッグ表示させて見たところ、以外な結果になりました。

celltype tTaskMain {};

に対して、’}’を読み込むと文法エラーになります。
そしてエラー回復モードに入ります。

ここでcparseの場合、いったん読み込んだトークンを
捨てて、$endというトークンを読み込みます。
その次のトークンとして「}」を読み込みます。
後は、入力の通りにトークンを読み込みます。

エラー回復モードに入ったときに(入力には存在しない)仮想的なトークンを読み込んでいます。

この影響で、必要なトークンが不足しているために発生した文法エラーから回復することができていました。

先日以下の入力なら、parser.rbでも無限ループにはいらないと書きました.

celltype tTaskMain {}};

cparseの場合、エラー回復モード時に、あたかも上記のような入力がされていたかのように振る舞います。

$endが追加されるのは、他の文法エラーになる入力でも確かめてみました。

最初の私の予想(入力の終わりを特別扱いして、頑張らない)は外れていました。
cparseが採用しているエラー回復処理の方針は、どこかで聞いた覚えがあるのですが、思い出せません。またちょっとググってみても分かりませんでした。

(追記)
上の書き方ですと、parser.rbとcparse.soがまるっきりエラー回復モードのやりかたが違っているように受け取られるかも知れません。
しかし、rubyとC言語の違いはありますが、アルゴリズムとしては、(私が今まで調べて、理解した範囲では)どちらも同じに見えます。
動作の違いは、微妙な判定条件の違いとか、参照するテール(テーブルはそれぞれ用に作成されます)の内容の違いによるのではないかと感じています。

“raccのparser.rbとcparseの違い” への1件の返信

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です