我的分析仪遇到问题。我正在尝试在我的yyerror中使用yytext,但它向我显示了此错误,您可以帮我吗?
您无法在解析器中使用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
可能是不精确的,因为它可能引用错误之后的令牌的行号,该行号可能与错误位于不同的行(甚至可能与错误分开很多评论行)。
作为使用yytext
和yylineno
的外部声明的替代方法,您可以自由地将yyerror
的实现放入扫描仪定义而不是语法定义中。您的语法文件应该已经有yyerror
的前向声明,因此放置在哪个文件中都没有关系。如果将其放入扫描程序文件中,则将已经声明了全局扫描程序变量。