使用 Flex 和 Yacc 时未声明 yylineno
yylineno undeclared when using Flex and Yacc
我正在尝试为编译器课程构建一个迷你编译器,我正在 https://github.com/rabishah/Mini-C-Compiler-using-Flex-And-Yacc and https://github.com/vikash002/C---mini-Compiler 浏览 GitHub 和许多其他此类迷你编译器的代码。
当我克隆它们并使用代码运行它们时
$ lex c.l
$ yacc c.y
$ gcc y.tab.c -ll -ly
我收到这个错误提示
In file included from c.y:140:
c.l: In function ‘yylex’:
c.l:6:3: error: ‘yylineno’ undeclared (first use in this function); did you mean ‘yyleng’?
6 | [ \n] { yylineno = yylineno + 1;}
| ^~~~~~~~
| yyleng
c.l:6:3: note: each undeclared identifier is reported only once for each function it appears in
c.y: At top level:
c.y:157:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
157 | yyerror(char *s) {
| ^~~~~~~
c.y:157:1: warning: conflicting types for ‘yyerror’
c.y:8:6: note: previous declaration of ‘yyerror’ was here
8 | void yyerror(const char *s);
| ^~~~~~~
c.y: In function ‘yyerror’:
c.y:158:25: error: ‘yylineno’ undeclared (first use in this function); did you mean ‘yyleng’?
158 | printf("%d : %s %s\n", yylineno, s, yytext );
| ^~~~~~~~
| yyleng
我还在学习 Fex 和 Yacc,当我在网上查看时,我看到 yylineno 是它们中的默认变量。我什至尝试将其初始化为 1,但出现相同的错误。
知道我哪里出错了吗?或者这是与较新版本的 Flex 和 Yacc 相关的错误?
如有任何帮助,我们将不胜感激。
是的,跟你的flex版本有关运行ning。
与 lex 和非常旧版本的 flex 不同,您可能遇到的任何 flex 都不会定义(或初始化)yylineno
,除非您 运行 它处于 lex 兼容模式(不真正推荐)或请求 flex 跟踪行号(强烈推荐但不是由您使用的源代码完成)。
所以你有以下选项,大致按照我的偏见排序:只做其中一个!它们彼此不兼容。
将 %option yylineno
添加到 c.l
文件的开头。然后将第5行改为:
[ \t\n] ;
并删除第 6 行(具有模式 [ \n]
的规则)。这删除了递增 yylineno
的操作,这是必需的,因为 %option yylineno
要求 Flex 构建一个自行跟踪行号的扫描器。
在文件开头的#include
语句之后(即第4行左右)在c.y中添加如下行:
extern int yylineno = 1;
这将声明全局 yylineno
变量并对其进行初始化。在此选项中,您不要求 Flex 生成跟踪行号的扫描仪。所以你将不得不自己做。
一个稍微好一点的选择(但需要更多的工作)是将整个代码中 yylineno
的名称更改为其他名称。这样您就不必担心意外启用行号跟踪。 (但就个人而言,我会从一开始就启用行号跟踪,如选项 1 中所示。)
运行 通过在调用 lex
时添加 -l
命令行选项来在 lex 兼容模式下进行 flex(这实际上是 flex):
lex -l c.l
意见如下。 您已被警告。
说了这么多,我真的建议如果你想复制代码,找一些真正知道如何编写解析器的人编写的代码,而不是从随机复制糟糕的、未完成的和可能有错误的代码 GitHub 存储库。一般来说,复制别人的错误是一种糟糕的学习编程的方法。自己编写代码显然在短期内更耗时,但更有教育意义,你最终只需要处理自己的错误。
我正在尝试为编译器课程构建一个迷你编译器,我正在 https://github.com/rabishah/Mini-C-Compiler-using-Flex-And-Yacc and https://github.com/vikash002/C---mini-Compiler 浏览 GitHub 和许多其他此类迷你编译器的代码。
当我克隆它们并使用代码运行它们时
$ lex c.l
$ yacc c.y
$ gcc y.tab.c -ll -ly
我收到这个错误提示
In file included from c.y:140:
c.l: In function ‘yylex’:
c.l:6:3: error: ‘yylineno’ undeclared (first use in this function); did you mean ‘yyleng’?
6 | [ \n] { yylineno = yylineno + 1;}
| ^~~~~~~~
| yyleng
c.l:6:3: note: each undeclared identifier is reported only once for each function it appears in
c.y: At top level:
c.y:157:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
157 | yyerror(char *s) {
| ^~~~~~~
c.y:157:1: warning: conflicting types for ‘yyerror’
c.y:8:6: note: previous declaration of ‘yyerror’ was here
8 | void yyerror(const char *s);
| ^~~~~~~
c.y: In function ‘yyerror’:
c.y:158:25: error: ‘yylineno’ undeclared (first use in this function); did you mean ‘yyleng’?
158 | printf("%d : %s %s\n", yylineno, s, yytext );
| ^~~~~~~~
| yyleng
我还在学习 Fex 和 Yacc,当我在网上查看时,我看到 yylineno 是它们中的默认变量。我什至尝试将其初始化为 1,但出现相同的错误。
知道我哪里出错了吗?或者这是与较新版本的 Flex 和 Yacc 相关的错误?
如有任何帮助,我们将不胜感激。
是的,跟你的flex版本有关运行ning。
与 lex 和非常旧版本的 flex 不同,您可能遇到的任何 flex 都不会定义(或初始化)yylineno
,除非您 运行 它处于 lex 兼容模式(不真正推荐)或请求 flex 跟踪行号(强烈推荐但不是由您使用的源代码完成)。
所以你有以下选项,大致按照我的偏见排序:只做其中一个!它们彼此不兼容。
将
%option yylineno
添加到c.l
文件的开头。然后将第5行改为:[ \t\n] ;
并删除第 6 行(具有模式
[ \n]
的规则)。这删除了递增yylineno
的操作,这是必需的,因为%option yylineno
要求 Flex 构建一个自行跟踪行号的扫描器。在文件开头的
#include
语句之后(即第4行左右)在c.y中添加如下行:extern int yylineno = 1;
这将声明全局
yylineno
变量并对其进行初始化。在此选项中,您不要求 Flex 生成跟踪行号的扫描仪。所以你将不得不自己做。一个稍微好一点的选择(但需要更多的工作)是将整个代码中
yylineno
的名称更改为其他名称。这样您就不必担心意外启用行号跟踪。 (但就个人而言,我会从一开始就启用行号跟踪,如选项 1 中所示。)运行 通过在调用
lex
时添加-l
命令行选项来在 lex 兼容模式下进行 flex(这实际上是 flex):lex -l c.l
意见如下。 您已被警告。
说了这么多,我真的建议如果你想复制代码,找一些真正知道如何编写解析器的人编写的代码,而不是从随机复制糟糕的、未完成的和可能有错误的代码 GitHub 存储库。一般来说,复制别人的错误是一种糟糕的学习编程的方法。自己编写代码显然在短期内更耗时,但更有教育意义,你最终只需要处理自己的错误。