Vie*_*iet 6 lexical-analysis thread-safety reentrancy flex-lexer
我是弯曲的新手.我正在尝试用flex编写一个简单的重入词法分析器/扫描器.词法分析器的定义如下.我遇到编译错误,如下所示(yyg问题):
/* Definitions */
digit [0-9]
letter [a-zA-Z]
alphanum [a-zA-Z0-9]
identifier [a-zA-Z_][a-zA-Z0-9_]+
integer [0-9]+
natural [0-9]*[1-9][0-9]*
decimal ([0-9]+\.|\.[0-9]+|[0-9]+\.[0-9]+)
%{
#include <stdio.h>
#define ECHO fwrite(yytext, yyleng, 1, yyout)
int totalNums = 0;
%}
%option reentrant
%option prefix="simpleit_"
%%
^(.*)\r?\n printf("%d\t%s", yylineno++, yytext);
%%
/* Routines */
int yywrap(yyscan_t yyscanner)
{
return 1;
}
int main(int argc, char* argv[])
{
yyscan_t yyscanner;
if(argc < 2) {
printf("Usage: %s fileName\n", argv[0]);
return -1;
}
yyin = fopen(argv[1], "rb");
yylex(yyscanner);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
vietlq@mylappie:~/Desktop/parsers/reentrant$ gcc lex.simpleit_.c
reentrant.l: In function ‘main’:
reentrant.l:44: error: ‘yyg’ undeclared (first use in this function)
reentrant.l:44: error: (Each undeclared identifier is reported only once
reentrant.l:44: error: for each function it appears in.)
Run Code Online (Sandbox Code Playgroud)
cdu*_*001 11
对于折返词法分析器,所有的通信必须包括状态,其被包含在所述内扫描器.
程序中的任何位置(例如内部main)都可以通过要通过扫描仪的特殊功能访问状态变量.例如,在你的原文中reentrant.l,你可以这样做:
yyscan_t scanner;
yylex_init(&scanner);
yyset_in(fopen(argv[1], "rb"), scanner);
yylex(scanner);
yylex_destroy(scanner);
Run Code Online (Sandbox Code Playgroud)
我已重命名,scanner以避免yyscanner在行动中混淆.与通用C代码相比,所有操作都在一个名为的函数中发生,该函数yylex通过名称传递给扫描器yyscanner.因此,yyscanner您可以使用所有操作.另外,yylex有一个调用的局部变量yyg保存整个状态,大多数宏方便参考yyg.
虽然您可以通过在自己的答案中定义来使用yyin内部宏,但不建议这样做.对于可重入词法分析器,宏仅用于操作.mainyyg
要查看如何实现,您始终可以查看生成的代码:
/* 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;
...
}
Run Code Online (Sandbox Code Playgroud)
Flex文档中的reentrant选项还有很多,其中包括一个干净的编译示例.(谷歌" flex reentrant ",并寻找链接.)与野牛不同,flex有一个相当直接的重入模型.我强烈建议使用折返弯曲与柠檬分析器,而不是与YACC /野牛.flex.sourceforge