Thread safety 用Flex编写可重入词法

Thread safety 用Flex编写可重入词法,thread-safety,flex-lexer,lexical-analysis,reentrancy,Thread Safety,Flex Lexer,Lexical Analysis,Reentrancy,我是flex的新手。我正试图用flex编写一个简单的可重入lexer/scanner。lexer的定义如下。我遇到如下所示的编译错误(yyg问题): 可重入的 对于可重入lexer,所有通信都必须包括扫描程序中包含的状态 在程序中的任何地方(例如main)都可以通过特殊功能访问状态变量,扫描仪将通过这些功能访问状态变量。例如,在原始的可重入.l中,可以执行以下操作: yyscan_t scanner; yylex_init(&scanner); yyset_in(fopen(argv[1

我是flex的新手。我正试图用flex编写一个简单的可重入lexer/scanner。lexer的定义如下。我遇到如下所示的编译错误(yyg问题):

可重入的
对于可重入lexer,所有通信都必须包括扫描程序中包含的状态

在程序中的任何地方(例如
main
)都可以通过特殊功能访问状态变量,扫描仪将通过这些功能访问状态变量。例如,在原始的
可重入.l
中,可以执行以下操作:

yyscan_t scanner;
yylex_init(&scanner);
yyset_in(fopen(argv[1], "rb"), scanner);
yylex(scanner);
yylex_destroy(scanner);
我已重命名了
scanner
,以避免在操作中与
yyscanner
混淆。与一般的C代码不同,您的所有操作都发生在一个名为
yylex
的巨大函数中,该函数通过名称
yyscanner
传递给您的扫描器。因此,
yyscanner
可用于所有操作。此外,
yylex
有一个名为
yyg
的局部变量,它保存整个状态,大多数宏都方便地引用
yyg

虽然您确实可以使用
yyin
宏在
main
中定义
yyg
,就像您在自己的答案中所做的那样,但不建议这样做。对于可重入lexer,宏仅用于操作

要查看这是如何实现的,您可以始终查看生成的代码:


/* 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;
...
}

flex文档中的
reentrant
选项有更多内容,其中包括一个干净的编译示例。(谷歌“flex可重入”,并寻找
flex.sourceforge
链接。)与bison不同,flex有一个相当直接的重入模型。我强烈建议将reentrantflex与yacc/bison一起使用,而不是与yacc/bison一起使用?我在内部遇到了一个崩溃,似乎yy_cp在分配给yyg->yy_c_buf_p之后是一个空指针。很难通过注释进行调试。我在OP中的reentrant.l中的
main()
中发布的内容对我很有用。我知道这很旧,但我一直在尝试使用lex。我发现,如果我使用BEGIN或任何start条件宏,它们仍然会收到yyg未声明的消息。我和你一样,能够让这个简单化的main()纯lexer工作。我将尝试在我的函数中定义yyg,以查看这是否修复了尝试更改stat条件的其他函数的yyg。
yyscan_t scanner;
yylex_init(&scanner);
yyset_in(fopen(argv[1], "rb"), scanner);
yylex(scanner);
yylex_destroy(scanner);

/* 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;
...
}