bison
どのトークンが認識されたかを知る必要はありません。その情報は実質的にスタック状態の一部であるためです。ただし、デバッグが有効になっている場合、bison テーブルには各リダクションの右側のエンコードされたバージョンが含まれているため、組み込みのトレース機能で人間が判読できるトレースを生成できます。
理論的には、この情報も使用できますが、bison はフレックス トークン番号を連続したシーケンスに変換し (よりコンパクトな解析テーブルを可能にするため)、それらを元に戻す方法を提供しないため、希望どおりにはなりません。だから退屈だろう。
より良い解決策は、現在無視しているセマンティック値を使用することです (整数バリアントがあると仮定して)。セマンティック値を割り当てるコストは取るに足らないものです。なぜなら、bison ではすべてのトークンのセマンティック値を何かに初期化する必要があるからです。
したがって、もっともらしいフレックス/バイソンソリューションは次のようになります。
フレックス
%union {
int intval;
/* ... other semantic values */
}
%%
/* All the other rules come first */
/* Default rule which just passes any character through to bison
* (see note)
*/
. { return (yylval.intval = yytext[0]); }
バイソン
/* This declaration is only necessary because these tokens
* have a semantic value
*/
%token <intval> '-' '+' '!'
%%
unaryOperation
: '!' { $$ = new UnaryOP($1); }
| '+' { $$ = new UnaryOP($1); }
| '-' { $$ = new UnaryOP($1); }
;
注: トークン名を削除しました。これはNOT
、1 文字のトークンを使用して自分自身を表すスタイルを好むためですPLUS
。MINUS
ここでの違いは、フレックス ルールもセマンティック値を (同じ数値に) 設定することです。演算子が複数文字の場合、それも可能です:
フレックス
'!=' { return (yylval.intval = NOTEQUAL); }