【发布时间】:2023-03-05 04:38:01
【问题描述】:
在手动设置编译器读取头文件的顺序时,我能够回避这个问题。在这种情况下,我可以用正确的定义来欺骗默认的“珍珠”,但是当我无法控制包含标题的顺序时,这……工程表面的天才:
/* 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 文件中。
文档说:
(如果你的环境支持函数原型,那么它将是“int yylex(void)”。)这个定义可以通过定义“YY_DECL”宏来改变。例如,您可以使用:
#define YY_DECL float lexscan( a, b ) float a, b;
为扫描例程命名为 lexscan,返回一个浮点数,并将两个浮点数作为参数。请注意,如果您使用 K&R 样式/非原型函数声明为扫描例程提供参数,则必须使用分号 (`;') 终止定义。
是的,没错,正是我所缺少的!如果不能使用在 70 年代消亡的非标准 C 语法,我将如何生活?然而,文档公然谎报如果您声明 YY_DECL 会发生什么:实际上它会被忽略,除非您设法在 Flex 生成的任何代码被编译之前向编译器欺骗不同的标头。
我现在只需编写一个sed 调用来修补Flex 的输出。请告诉我实际上可以在没有这种“仪器”的情况下修复它。
【问题讨论】:
-
可能没有让您满意的解决方案。我同意
YY_DECL不是配置yylex原型的理想方式,尤其是因为一旦您拥有yylex的参数(就像您使用可重入词法分析器和解析器一样),那么您需要正确命名它们,并且没有记录正确的名称。但是知道为什么要更改原型会很有用。要添加额外的状态,使用yyextra 通常更容易。如果你只是想改名字,那么#define yylex my_name虽然粗暴但有效。 -
我会试试
yyextra- 不知道这个。今天会回来汇报。是的,我的目标是添加一个额外的参数,因为解析器是可重入的,我需要传递状态。 -
那么您使用的是推送解析器吗?恕我直言,这是可重入解析的最佳解决方案(以及其他原因)。我经常为此使用
yyextra,尽管有时在 yylex 的顶部分配解析状态并在发送 END 令牌后将其删除会很方便。 -
@rici 是的,我正在使用推送解析器。
-
@rici 是的,它与 yyextra 一起使用。如果你愿意,你可以发布这个作为答案,我会接受的。
标签: bison flex-lexer