之前,我没有仔细阅读yacc生成的代码。现在,我看到了一个这样的代码片段:
#define yyparse ol_parser_parse
我知道
int yyparse (void)
因此,此宏定义应解释为:代码中的每个“ ol_parser_parse”都将替换为“ yyparse”。我写了一些测试代码:
#include <stdio.h>
#define yyparse ol_parser_parse
void yyparse()
{
printf("hello world\n");
}
void main()
{
ol_parser_parse();
}
成功了! 但是根据关于"macro definition"的定义:
#define <identifier>(<parameter list>) <replacement token list>
对此我感到困惑。谁能帮我解释一下?预先感谢!
答案 0 :(得分:2)
这是执行替换后编译器看到的代码:
#include <stdio.h>
void ol_parser_parse()
{
printf("hello world\n");
}
void main()
{
ol_parser_parse();
}
在这一点上没有什么神秘的。 #define
之后的每一行上的每个“ yyparse”实例都变成“ ol_parser_parse”。
在文档中 identifier 表示要替换的东西,而替换令牌列表是您要替换的东西。您也可以使用参数,例如:
#define TIMES_TWO(n) ((n) * 2)
您可以在哪里做
int x = TIMES_TWO(3);
等同于:
int x = ((3) * 2);
在多余的括号中,因此您可以执行此操作而不会弄乱操作顺序:
int x = TIMES_TWO(1 - 5);
如果没有括号,它将显示为:
int x = 1 - 5 * 2;
哪个计算为1 - 10
,这不是您想要的。
有效使用#define
来隐藏否则很难看的实现细节是一门艺术。如果可以使用ol_parser_parse
宏,则不必担心名称yyparser
。这使实现者可以自由地重命名该函数和相应的宏,而无需破坏所有代码。