使用 Flex 编写可重入词法分析器
我是弯曲的新手。我正在尝试使用 Flex 编写一个简单的可重入词法分析器/扫描器。词法分析器定义如下。我遇到了如下所示的编译错误(yyg 问题):
reentrant.l:
/* 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;
}
编译错误:
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.)
I'm newbie to flex. I'm trying to write a simple re-entrant lexer/scanner with flex. The lexer definition goes below. I get stuck with compilation errors as shown below (yyg issue):
reentrant.l:
/* 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;
}
Compilation errors:
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.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于可重入词法分析器,所有通信都必须包含状态,它包含在扫描器中。
在程序中的任何位置(例如在
main
内),您都可以通过将扫描器传递到的特殊函数来访问状态变量。 例如,在您原来的reentrant.l
中,您可以这样做:我已重命名
scanner
以避免与yyscanner
混淆> 在行动中。与一般的 C 代码相比,您的所有操作都发生在一个名为yylex
的巨大函数中,该函数通过名称yyscanner
传递给您的扫描器。因此,yyscanner
可用于您的所有操作。此外,yylex
有一个名为yyg
的局部变量,它保存整个状态,并且大多数宏方便地引用yyg
。虽然您确实可以通过定义
yyg
来使用main
中的yyin
宏,就像您在自己的答案中所做的那样,但不建议这样做。对于可重入词法分析器,宏仅用于操作。要了解这是如何实现的,您可以随时查看生成的代码:
flex 文档中还有更多关于可重入 选项的信息,其中包括一个干净的编译示例。 (Google“flex 可重入”,并查找
flex.sourceforge
链接。)与 bison 不同,flex 具有一个相当简单的可重入模型。我强烈建议将可重入 flex 与 Lemon 解析器,而不是使用 yacc/bison。For a reentrant lexer, all communication must include the state, which is contained within the scanner.
Anywhere in your program (e.g. inside
main
) you can access the state variables via special functions to which you will pass your scanner. E.g., in your originalreentrant.l
, you can do this:I have renamed
scanner
to avoid confusion withyyscanner
in the actions. In contrast with general C code, all your actions occur within a giant function calledyylex
, which is passed your scanner by the nameyyscanner
. Thus,yyscanner
is available to all your actions. In addition,yylex
has a local variable calledyyg
that holds the entire state, and most macros conveniently refer toyyg
.While it is true that you can use the
yyin
macro insidemain
by definingyyg
as you did in your own Answer, that is not recommended. For a reentrant lexer, the macros are meant for actions only.To see how this is implemented, you can always view the generated code:
There is lots more on the
reentrant
option in the flex docs, which include a cleanly compiling example. (Google "flex reentrant", and look for theflex.sourceforge
link.) Unlike bison, flex has a fairly straight-forward model for reentrancy. I strongly suggest using reentrant flex with Lemon Parser, rather than with yacc/bison.