YYLEX
yylex()
函数是 Lex 生成的词法分析器的主要组成部分。该函数负责从输入中读取字符并根据定义的词法规则匹配词素(token)。这个函数一次返回一个匹配到的词素。(也就是读取字符的作用)
YYTEXT
yytext
是一个字符数组,它存储了由 Lex 词法分析器最后识别出的词素(token)【也就是上面yylex上一次识别出的词素保存在了这里】。
yytext
的长度(即词素的字符数)是由当前匹配的 Lex 规则决定的。
运行下面的代码,就会输出该单词或者数字
[a-z]+ { printf("Matched a word: %s\n", yytext); }
[0-9]+ { printf("Matched a number: %s\n", yytext); }
YYWRAP
yywrap()
: 这个函数用于控制词法分析器(Lex)何时应该停止扫描输入。
对于 yywrap
,如果你正在扫描一个文件,并且到达了文件的末尾,yywrap
会被调用。因为它返回 1,词法分析器将停止扫描。这通常用于单文件扫描。如果你想从另一个文件继续读取,你可以在 yywrap
中实现这个逻辑,并返回 0。
YYERROR
这个函数用于错误处理,当词法分析器或语法分析器遇到错误时会调用这个函数。
fprintf(stderr, "This is an error message.\n");
stderr
是标准错误输出流(Standard Error Stream)的缩写,通常用于输出错误或诊断信息。
int yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
return 0;
}
在语法规则中可以调用
stmt: expr ';' { /* do something */ }
| error ';' { yyerror("Invalid statement"); }
;
YYLVAL
yylval
是一个全局变量,通常用于在词法分析器(由 Lex 生成)和语法分析器(由 Yacc 或 Bison 生成)之间传递附加信息。当 yylex()
匹配到一个词素(token)时,yylval
可以被设置为与该词素关联的值。也常被通过 %union
定义。
①.在 Lex(词法分析) 的 .l
文件中,当某个规则被匹配时,你可以设置 yylval
的值。例如,如果你匹配到一个整数,你可以设置 yylval
为这个整数值。
[0-9]+ { yylval.intValue = atoi(yytext); return INTEGER; }
[0-9]+\.[0-9]* { yylval.floatValue = atof(yytext); return FLOAT; }
②.在 Yacc(语法分析) 或 Bison 的 .y
文件中,你可以访问 yylval
的值来执行相应的语义动作。
%union {
int intValue;
float floatValue;
}
%token <intValue> INTEGER
%token <floatValue> FLOAT
示例
/* recognize tokens for the calculator and print them out */
%{
enum yytokentype {
NUMBER = 258,
ADD = 259,
SUB = 260,
MUL = 261,
DIV = 262,
ABS = 263,
EOL = 264
};
int yylval;
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
[ \t] { /* ignore whitespace */ }
. { printf("Mystery character %c\n", *yytext); }
%%
main(int argc, char **argv)
{
int tok;
while(tok = yylex())
{
printf("%d", tok);
if(tok == NUMBER)
printf(" = %d\n", yylval);
else
printf("\n");
}
}