ここでは、Racc を使っていくうえで遭遇しそうなバグについて書きます。 ただ、徐々に減ってはいますが、現時点ではまだまだracc自身のバグの可能性も高いです。 もし「これはバグに違いない!」というエラーに遭遇したらメールをください。 そのときは、規則ファイルなどもつけてくださるようお願いします。
また、racc コマンドに -v オプションをつけてコンパイルすると、内部情報が "ファイル名.output" に出力されます。このファイルの情報はデバッグには 必須ですから、デバッグ中は常に-vgをつけてコンパイルすることをおすすめします。
一番ありがちな問題は、衝突でしょうか。 衝突があると、yacc同様にraccもコンパイル後に「衝突がある」とメッセージをだすので すぐわかります。.outputファイルにはさらに詳しい情報が出力されます。それをどうやって 解決するか、とかそういうことに関しては…それなりの本を読んでください。とても ここに書けるような単純な話ではありません。(おすすめはNutshellのlex&yacc)
結構あるのが、racc独自の問題です。たとえば、next_token に関係するものです。 特に注意したいのは、「スキャンが終了したら必ず[false, false]を送る」と いうことです。これは自分自身いまだに忘れます。
最後に論理的なバグの修正。
raccに-gオプションをつけてコンパイルすると、デバッグ用のコードが付加されます。
ここで、パーサクラスのインスタンス変数 @yydebug を true にしておいてから
do_parse を呼ぶと、デバッグ用メッセージを出力します。パーサがシフト/還元していく
様子が直接見えますので、「LALRを知っていれば」、完全に現在の状態を把握できます。
yaccでは%がいっぱいでてきますが、raccでは%は出てきません。それから、 Cは変数に型があるためにそれを指定する文法がたくさんありますが、Rubyは 型無しですからそっち関係のものはなくなっています。
yaccでは終端記号(トークン)を事前に指定しますが、raccでは左辺にこないものを自動的に 終端記号とみなします。ということはつまり、非終端記号nontermをnotermと書きまちがったが ために、それが終端記号とみなされて、妙なことになる可能性があるということです。 これを防止するためには、.outputファイルを出力させて、変なものが終端記号になって いないか(もちろんその逆も)チェックするとよいでしょう。
は = を使います。
バージョン 0.10 からは全体の構造が class ... rule ... end のようになりました。
規則部分は yacc とほぼ同じですが、最大の違いは、規則の最後にセミコロンが必須なことです。
%precは=をつかいます。
yacc ではコメントは /* ... */ だけですが racc では #...(行末) もあります。
yacc ではユーザーコードを分類する必要はありませんが、racc ではパーサがクラスなので、 配置する場所によってユーザーコードを分類しています。ユーザーコードの指定方法も 0.9 で ---- を使うように大きく変わったので気をつけてください。