为什么我不能在 yyerror (Yacc) 中使用 yytext
Why can't I use yytext inside yyerror (Yacc)
我的分析仪有点问题。 I.m 试图在我的 yyerror 中使用 yytext 但它向我显示此错误,你能帮我吗?
您不能在解析器中使用 yytext
,因为它是由词法分析器定义的。
事实上,您通常不应该在解析器中使用 yytext
,因为它的值对解析没有意义。您尝试使用它来提供错误消息中的上下文几乎是唯一合理的用途,即使这样也存在一定的歧义,因为您无法判断错误标记是当前 yytext
中的标记还是之前的标记令牌,当解析器获得其先行令牌时被覆盖。
无论如何,如果你想在你的解析器中引用 yytext
,你需要声明它,这通常需要把
extern char* yytext;
进入你的 bison 语法文件。由于唯一可以合理使用 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
可能不精确,因为它可能引用错误后标记的行号,它可能与错误位于不同的行(甚至可能被分开来自多行评论的错误)。
作为使用 yytext
和 yylineno
的外部声明的替代方法,您可以自由地将 yyerror
的实现放在扫描器定义中而不是语法定义中。你的语法文件应该已经有一个yyerror
的前向声明,所以它放在哪个文件中并不重要。如果你把它放在扫描器文件中,全局扫描器变量已经被声明了。
我的分析仪有点问题。 I.m 试图在我的 yyerror 中使用 yytext 但它向我显示此错误,你能帮我吗?
您不能在解析器中使用 yytext
,因为它是由词法分析器定义的。
事实上,您通常不应该在解析器中使用 yytext
,因为它的值对解析没有意义。您尝试使用它来提供错误消息中的上下文几乎是唯一合理的用途,即使这样也存在一定的歧义,因为您无法判断错误标记是当前 yytext
中的标记还是之前的标记令牌,当解析器获得其先行令牌时被覆盖。
无论如何,如果你想在你的解析器中引用 yytext
,你需要声明它,这通常需要把
extern char* yytext;
进入你的 bison 语法文件。由于唯一可以合理使用 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
可能不精确,因为它可能引用错误后标记的行号,它可能与错误位于不同的行(甚至可能被分开来自多行评论的错误)。
作为使用 yytext
和 yylineno
的外部声明的替代方法,您可以自由地将 yyerror
的实现放在扫描器定义中而不是语法定义中。你的语法文件应该已经有一个yyerror
的前向声明,所以它放在哪个文件中并不重要。如果你把它放在扫描器文件中,全局扫描器变量已经被声明了。