对于可重入词法分析器,所有通信必须包括state,它包含在scanner.
程序中的任何位置(e.g. inside main
)您可以通过将扫描仪传递给的特殊函数来访问状态变量。E.g.,在你原来的reentrant.l
, 你可以这样做:
yyscan_t scanner;
yylex_init(&scanner);
yyset_in(fopen(argv[1], "rb"), scanner);
yylex(scanner);
yylex_destroy(scanner);
我已重命名scanner
以避免混淆yyscanner
在行动中。与一般的 C 代码相比,您的所有操作都发生在一个名为的巨大函数中yylex
,它通过名称传递给您的扫描仪yyscanner
. Thus, yyscanner
适用于您的所有操作。此外,yylex
有一个名为的局部变量yyg
保存整个状态,大多数宏方便地引用yyg
.
虽然您确实可以使用yyin
宏内main
通过定义yyg
正如您在自己的答案中所做的那样,不建议这样做。对于可重入词法分析器,宏仅用于操作。
要了解这是如何实现的,您可以随时查看生成的代码:
/* For convenience, these vars
are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
...
/* Holds the entire state of the reentrant scanner. */
struct yyguts_t
...
#define YY_DECL int yylex (yyscan_t yyscanner)
/** The main scanner function which does all the work.
*/
YY_DECL
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
...
}
还有很多关于reentrant
选项中的flex文档,其中包括一个干净的编译示例。 (谷歌 ”弯曲可重入”,并寻找flex.sourceforge
链接。)不同于bison, flex有一个相当简单的可重入模型。我强烈建议使用可重入flex with Lemon Parser,而不是与yacc/野牛.