Remove default YY_DECL from Flex output

心已入冬 提交于 2019-12-11 15:38:04

问题


I was able to sidestep this problem when manually setting up the order in which header files are read by the compiler. In this case, I'm able to spoof the default "pearl" with the correct definition, but when I have no control of the order in which headers are included, this... genius of engineering surfaces:

/* 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 */

This is defined in the header file, but my definition of YY_DECL is copied into *.c file.

The documentation says:

(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 (`;').

Yes, right, just what I was missing! How would I live without being able to use non-standard C syntax that died in the seventies? Yet, the documentation blatantly lies about what happens if you declare YY_DECL: in reality it gets ignored, unless you manage to spoof a different header to the compiler before any of the code generated by Flex would have been compiled.

I'm at the point now where I'd just write a sed call to patch the output of Flex. Please tell me it is actually possible to fix it without this kind of "instrumentation".


回答1:


If you want to change the prototype to add a parameter containing extra state, it's usually easier to use Flex's "extra data" feature, yyextra. That avoids the irritations of YY_DECL.

On the other hand, if you want to change the name of the generated lexer (because, for example, you want to export a wrapper called yylex), then a crude but effective technique is to put

#define yylex my_name

In the prologue and

#undef yylex

in the epilogue. (Obviously these shouldn't be placed in header files.)

I agree that the YY_DECL macro is far from an ideal way of configuring the yylex prototype. My complaint has always been that once you have parameters to yylex (as you do with reentrant lexers) then you need to get their names right, and the correct names aren't documented, and therefore are subject to change, making for a future incompatibility in waiting.



来源:https://stackoverflow.com/questions/49221106/remove-default-yy-decl-from-flex-output

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!