为什么我不能在yyerror(Yacc)中使用yytext

时间:2019-12-20 17:56:56

标签: yacc

我的分析仪出现问题。我正在尝试在我的yyerror中使用yytext,但它向我显示了此错误,您可以帮我吗?

error

yyerror declaration

1 个答案:

答案 0 :(得分:1)

您不能在解析器中使用yytext,因为它是由词法分析器定义的。

实际上,您通常不应该在解析器中使用yytext,因为它的值对解析没有意义。您尝试使用它在错误消息中提供上下文只是唯一合理的用法,即使那样也存在一定的歧义,因为您无法分辨出错误的令牌是当前yytext中的令牌还是之前的令牌。令牌,当解析器获得其超前令牌时,该令牌将被覆盖。

无论如何,如果您想在解析器中引用yytext,则需要对其进行声明,这通常需要放入

extern char* yytext;

进入您的野牛语法文件。由于您可以合理使用yytext的唯一位置是yyerror,因此您可以将该函数的定义更改为:

void yyerror(const char* msg) {
  extern char* yytext;
  fprintf(stderr, "%s at line %d near '%s'\n", msg, nLineas, yytext);
}

请注意,您可以通过flex自动跟踪行号,因此不需要跟踪自己的nLineas变量。只需添加

%option yylineno

在Flex文件的顶部,并且全局变量yylineno将在词法分析期间自动维护。如果要在解析器中使用yylineno,则还需要为其添加一个extern声明:

extern int yylineno;

同样,在解析器中使用yylineno可能是不精确的,因为它可能引用错误之后的令牌的行号,该行号可能与错误所在的行不同(甚至可能与错误分开)。出现很多注释错误)。


作为使用yytextyylineno的外部声明的替代方法,您可以自由地将yyerror的实现放在扫描程序定义而不是语法定义中。您的语法文件应该已经有yyerror的前向声明,因此放置在哪个文件中都没有关系。如果将其放入扫描程序文件中,则将已经声明了全局扫描程序变量。