yylval 在 lex 和 yacc 中的作用

Bor*_*ucu 2 c grammar parsing yacc lex

我看到很多例子,其中一些将 yytext 传递给 yylval,而另一些则没有。这是 lex 和 yacc 中简单加法器的代码

/* add.l */
digit [0-9]
%%
{digit}+ {sscanf(yytext, "%d", &yylval);
return(INT);
}
\+ return(PLUS);
\n return(NL);
. ;
%%
int yywrap() { return 1; }
Run Code Online (Sandbox Code Playgroud)

/* add.y */
/* L = {INT PLUS INT NL} */
%token INT PLUS NL
%%
add: INT PLUS INT NL { printf("%d\n", $1 + $3);}
%%
#include "lex.yy.c"
yyerror(char *s) { printf("%s\n", s); }
main() {
 return yyparse();
}
Run Code Online (Sandbox Code Playgroud)

我没有看到像 printf(yylval) 等代码。为什么代码sscanf(yytext, "%d", &yylval)存在于此。这里是否以某种方式使用了 yylval,如果我们不添加该行会发生什么?我们什么时候需要在 lex 中包含这样一行?

Chr*_*odd 7

全局yylval变量用于将与标记关联的语义值从词法分析器传递到解析器。$1符号的语义值在 yacc 操作中以、等方式访问$2,并通过分配给 来设置非终结符$$。终端来自词法分析器,它需要某种方式将语义值传递给解析器。在可重入扫描器中,yylval通常成为引用参数而yylex不是全局变量,但在其他方面具有相同的目的。

在您的具体示例中,令牌INT具有语义值,即读取的整数的值。由于yacc 代码中没有%type/声明,语义值只是获得默认类型,这对于保存整数值来说很好。%unionint