Previous: Token Positions, Up: Lexical
純粋な、つまり再入可能な、構文解析器を生成するために、
%pure_parser
をBison宣言すると、広域変数yylval
と
yylloc
を使えなくなります
(see A Pure (Reentrant) Parser)。
このような構文解析器では、2つの広域変数の代わりに、
yylex
への引数として渡されるポインタを使います。
yylex
を次のように宣言し、
これらのポインタを通して情報を受け渡しする必要があります。
yylex (lvalp, llocp) YYSTYPE *lvalp; YYLTYPE *llocp; { ... *lvalp = value; /* 値をBisonスタックに積む。 */ return INT; /* トークン型を返す。 */ ... }
文法ファイルがテキスト中の位置を参照するための‘@’機能を
使っていない場合は、YYLTYPE
は定義されません。
この場合、第2引数を省略し、yylex
は
1個の引数をともなって呼び出されます。
再入可能な構文解析器を使っている場合、
再入可能な方法で構文解析器に追加の引数を渡す方法があります。
そのためには、マクロYYPARSE_PARAM
を変数名として定義します。
すると、関数yyparse
は、定義された名前で、型がvoid *
の
追加の引数を受け取ります。
yyparse
を呼び出すときに、オブジェクトの番地を
void *
型にキャストして渡します。
文法のアクションは、ポインタを適切な型へのポインタへキャストし、
逆参照して、オブジェクトの内容を参照できます。
例を示します。
%{ struct parser_control { int nastiness; int randomness; }; #define YYPARSE_PARAM parm %}
次のように構文解析器を呼び出します。
struct parser_control
{
int nastiness;
int randomness;
};
...
{
struct parser_control foo;
... /* foo
に正しいデータを記憶 */
value = yyparse ((void *) &foo);
...
}
文法アクションの中では、データを参照するために次のような式を使います。
((struct parser_control *) parm)->randomness
yylex
に追加の引数を渡したい場合には、
YYPARSE_PARAM
と同様に、マクロYYLEX_PARAM
を定義します。
例を示します。
%{ struct parser_control { int nastiness; int randomness; }; #define YYPARSE_PARAM parm #define YYLEX_PARAM parm %}
そして、yylex
が追加の引数、parm
の値を受け取るように、
yylex
を定義する必要があります
(型YYLTYPE
のどの引数が渡されるかに応じて、
引数の合計が2個または3個になります)。
引数を正しいオブジェクト型として宣言できます。すなわちvoid *
として
宣言し、上記の番地を参照できます。
YYPARSE_PARAM
を使わずに、‘%pure_parser’を使って、
再入可能な構文解析器を生成することも可能です。
その場合、引数をつけずにyyparse
を呼び出すべきです。