从 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
的参数(就像你对可重入词法分析器所做的那样),那么你需要正确地命名它们,而正确的名称没有记录在案,因此可能会发生变化,使得等待未来的不兼容。
在手动设置编译器读取 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
的参数(就像你对可重入词法分析器所做的那样),那么你需要正确地命名它们,而正确的名称没有记录在案,因此可能会发生变化,使得等待未来的不兼容。