从 Flex 输出中删除默认 YY_DECL

Remove default YY_DECL from Flex output

在手动设置编译器读取 header 文件的顺序时,我能够回避这个问题。在这种情况下,我可以用正确的定义来欺骗默认的 "pearl",但是当我无法控制包含 header 的顺序时,这...工程表面的天才:

/* Default declaration of generated scanner - a define so the user can
 * easily add parameters.
 */
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
/* %if-c-only Standard (non-C++) definition */

extern int yylex \
               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);

#define YY_DECL int yylex \
               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
/* %endif */
/* %if-c++-only C++ definition */
/* %endif */
#endif /* !YY_DECL */

这是在header文件中定义的,但是我YY_DECL的定义被复制到*.c文件中。

文档说:

(If your environment supports function prototypes, then it will be "int yylex( void )".) This definition may be changed by defining the "YY_DECL" macro. For example, you could use:

#define YY_DECL float lexscan( a, b ) float a, b;

to give the scanning routine the name lexscan, returning a float, and taking two floats as arguments. Note that if you give arguments to the scanning routine using a K&R-style/non-prototyped function declaration, you must terminate the definition with a semi-colon (`;').

是的,没错,正是我所缺少的!如果不能使用 70 年代消亡的 non-standard C 语法,我将如何生活?然而,文档公然谎称如果你声明 YY_DECL 会发生什么:实际上它会被忽略,除非你设法在 Flex 生成的任何代码被编译之前向编译器欺骗一个不同的 header已编译。

我现在正要编写一个 sed 调用来修补 Flex 的输出。请告诉我实际上可以在没有这种 "instrumentation".

的情况下修复它

如果您想更改原型以添加包含额外状态的参数,使用 Flex 的 "extra data" 功能 yyextra 通常更容易。这避免了 YY_DECL.

的刺激

另一方面,如果你想更改生成的词法分析器的名称(因为,例如,你想导出一个名为 yylex 的包装器),那么一个粗糙但有效的技术是将

#define yylex my_name

序言和

#undef yylex

在结语中。 (显然这些不应该放在头文件中。)

我同意 YY_DECL 宏远不是配置 yylex 原型的理想方式。我的抱怨一直是,一旦你有了 yylex 的参数(就像你对可重入词法分析器所做的那样),那么你需要正确地命名它们,而正确的名称没有记录在案,因此可能会发生变化,使得等待未来的不兼容。