编译 lex 生成的文件时 errno.h(及更多)错误

error in errno.h (and more) when compiling lex generated files

我目前收到错误消息:

In file included from /usr/include/errno.h:35:0,
                 from lex.yy.c:21:
/usr/include/x86_64-linux-gnu/bits/errno.h:50:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘extern’
 extern int *__errno_location (void) __THROW __attribute__ ((__const__));
 ^

(连同许多其他)当尝试使用以下命令编译由 lex 生成的文件时:

gcc lex.yy.c

lex.l(文件传递给lex生成lex.yy.c)来源:

%%
"hello world"   printf("goodbye");
.               ;
%%

当我尝试编译任何由 lex 或 flex 生成的文件(我都试过了)时会出现此问题

正如我所提到的,还有更多的错误,但修复这个错误可能会解决其他一些错误。在查找 errno.h 的一些常见错误并没有找到任何用处之后,我在这里提问。

我正在使用 Ubuntu 16.04 LTS。如果您愿意 like/need 有关该问题的更多信息,请告诉我,我会尽力提供帮助。

感谢任何建议:)

编辑'rici':

我的lex.yy.c文件的前21行如下:

    #line 3 "lex.yy.c"

    #define  YY_INT_ALIGNED short int

    /* A lexical scanner generated by flex */

    #define FLEX_SCANNER
    #define YY_FLEX_MAJOR_VERSION 2
    #define YY_FLEX_MINOR_VERSION 6
    #define YY_FLEX_SUBMINOR_VERSION 0
    #if YY_FLEX_SUBMINOR_VERSION > 0
    #define FLEX_BETA
    #endif

    /* First, we deal with  platform-specific or compiler-specific issues. */

    /* begin standard C headers. */
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <stdlib.h>
    /* end standard C headers. */

为@sepp2k 编辑:

我使用 vimdiff 比较了这两个文件。

在我的文件中但不在你的文件中的内容:

#ifdef __cplusplus

/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST

#else   /* ! __cplusplus */

/* C99 requires __STDC__ to be defined as 1. */
#if defined (__STDC__)

#define YY_USE_CONST

#endif  /* defined (__STDC__) */
#endif  /* ! __cplusplus */

#ifdef YY_USE_CONST

===============================================================

#include <string.h>
#include <errno.h>
#include <stdlib.h>
#line 476 "lex.yy.c"

你的文件里没有我的文件里没有的东西

任何其他差异似乎只是格式差异。

我还在标准C程序中测试了四个头文件(现在明白你的意思了),我可以确认是errno.h导致了错误。

包含 errno.h 的 C 语言的 hello world 引发了以下错误:

In file included from /usr/include/errno.h:35:0,
                 from test.c:2:
/usr/include/x86_64-linux-gnu/bits/errno.h:50:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘extern’
 extern int *__errno_location (void) __THROW __attribute__ ((__const__));
 ^
In file included from test.c:4:0:
/usr/include/stdio.h:13:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘int’
 int printf(const char* __restrict, ...);
 ^

为@rici 编辑:

这是我 运行 "gcc lex.yy.c" 时抛出的错误的完整转储: https://gist.github.com/raygarner/0601e57f5be21e16e0ae4ee34643b121

为@sepp2k 编辑:

早些时候,我在 VM 中全新安装的 debian 9 上测试了这个完全相同的编译过程,在修复 errno.h 后,我在 Ubuntu 上遇到了与我在这里做的完全相同的错误

这是它的样子:

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

正如我们在评论中发现的那样,最初的错误是由于您的系统 errno.h 出现问题,您通过重新安装文件修复了该问题。

解决了这个问题后,您的代码将可以正常编译,但不会 link 作为独立应用程序,因为缺少 yywrapmain 函数。您可以通过定义 yywrap 或使用 %option noyywrap 来修复前者。后者可以通过定义一个 main 函数或 link 对定义 main 的目标文件进行修复(如果词法分析器是已经定义了自己的 main 函数的更大项目的一部分)。

您还可以通过 linking -lfl 来解决这两个问题,它定义 yywrapmain 函数以从标准输入或从 argv 然后将生成的标记打印到标准输出。当然,这仅对测试有用,因为在实际项目中,您想要做的比在主要项目中做的更多。