当手动设置编译器读取头文件的顺序时,我能够回避这个问题。在这种情况下,我能够用正确的定义欺骗默认的“珍珠”,但是当我无法控制包含标题的顺序时,这......工程界面的天才:
/* 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 */
这是在标头文件中定义的,但我对YY_DECL
的定义被复制到*.c
文件中。
文档说:
(如果您的环境支持函数原型,那么它将是“int yylex(void)”。)可以通过定义“YY_DECL”宏来更改此定义。例如,您可以使用:
#define YY_DECL float lexscan( a, b ) float a, b;
给扫描程序命名为lexscan,返回一个浮点数,并将两个浮点数作为参数。请注意,如果使用K& R样式/非原型函数声明为扫描例程提供参数,则必须使用分号(“;”)终止定义。
是的,对,就是我错过的!如果不能使用七十年代死亡的非标准C语法,我将如何生活?然而,文档公然地说明了如果你声明YY_DECL
会发生什么:实际上它会被忽略,除非你设法在编译Flex生成的任何代码之前欺骗编译器的不同标头。
我现在正处于调用Flex输出的sed
调用的地方。请告诉我,实际上可以在没有这种“仪器”的情况下修复它。
答案 0 :(得分:1)
如果您想更改原型以添加包含额外状态的参数,则通常更容易使用Flex的"extra data"功能yyextra
。这避免了YY_DECL
的烦恼。
另一方面,如果你想改变生成的词法分析器的名称(因为,例如,你想导出一个名为yylex
的包装器),那么粗略但有效的技术就是
#define yylex my_name
在序言和
中#undef yylex
在结语中。 (显然这些不应放在头文件中。)
我同意YY_DECL
宏远不是配置yylex
原型的理想方式。我的抱怨一直是,一旦你有yylex
的参数(就像你对折返词法分子那样),那么你需要正确的名字,正确的名字没有记录,因此可能会有变化,未来在等待中不相容。