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

问题描述 投票:0回答:1

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

“错误”

“

yacc
1个回答
0
投票

您无法在解析器中使用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的前向声明,因此放置在哪个文件中都没有关系。如果将其放入扫描程序文件中,则将已经声明了全局扫描程序变量。

© www.soinside.com 2019 - 2024. All rights reserved.