Jay(yacc for java)で躓いた
Jayのサンプルを見ながら、文法定義を書いたのですが、サンプルの通り書けば動くのですが、自分なりに書くと、
トークンの定義で「a token appears on the lhs of a production」というエラーが出て動かないのです。
%{ // 間違った定義 %} %token <void> EOL %token <Double> NUM %token <ANode> stmtlist, stmt %% top : /* Empty */ | stmtlist stmtlist : stmt | stmtlist EOL stmt { $$ = $1; $1.append($3); } stmt : NUM { $$ = $1; } ...
おかしい、おかしい…と悩んでいたのですが、いくつかサンプルを比較して気づいたのです。
スキャナが返すトークンと、文法定義に使う識別子は区別しなくてはならいのです。
ですので、上の定義は、以下のように書き換えたら、うまくコンパイルできました。
%token <void> EOL %token <Double> NUM %type <ANode> stmtlist, stmt %% ...
スキャナが返すトークンが、%token。文法定義に使う識別子が、%typeです。
こんな簡単なことなのに、気づくのに時間かかりました。