【问题标题】:Role of yylval in lex and yaccyylval 在 lex 和 yacc 中的作用
【发布时间】:2019-10-16 15:15:36
【问题描述】:

我看到很多例子,其中一些将 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; }

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

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

【问题讨论】:

    标签: c parsing grammar yacc lex


    【解决方案1】:

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

    在您的具体示例中,标记 INT 具有语义值,即读取的整数值。由于 yacc 代码中没有 %type/%union 声明,因此语义值只是获取默认的 int 类型,这对于保存整数值是很好的。

    【讨论】:

      【解决方案2】:

      取自here(推荐阅读):

      在普通(不可重入)解析器中,令牌的语义值 必须存储到全局变量 yylval 中。当您使用 语义值只有一种数据类型,yylval 就是这种类型。

      这意味着,与令牌关联的值存储在该特定变量中。

      【讨论】:

      • @borakur:它用于将词法分析器中的标记的语义值传递给解析器。
      猜你喜欢
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多