【问题标题】:Remove default YY_DECL from Flex output从 Flex 输出中删除默认的 YY_DECL
【发布时间】: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


【解决方案1】:

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

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

#define yylex my_name

在序幕和

#undef yylex

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 2012-08-21
    • 2017-10-19
    • 1970-01-01
    相关资源
    最近更新 更多