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です。
こんな簡単なことなのに、気づくのに時間かかりました。