c语言node类型_高阶宏的妙用技法,C语言宏你所不知道的聪明技巧

前言

什么是高阶宏?高阶宏就是以宏为参数的宏。以宏为参数的宏这就是这篇文章的重点。其实业界领先的代码库是有很多值得我们学习的,研究开源库也可以是大家学习的方向哦,通常开源库中90%的内容超出了新手对于编程知识的认知。如果你有耐心去研究,我相信一定有助于大家学会一些聪明技巧。而高阶宏也广泛应用于很多的开源库中。

问题描述

C ++是用于定义抽象的功能强大的语言,可让您摆脱冗余。函数和方法处理命令性代码的重复块。基类使您可以重用数据定义。模板可以让您几乎处理任何类型的数据。

即便如此,仍然有很多重复的现象似乎无法消除。例如,假设我们正在使用一种语言的语法。通常,解析器会生成AST(抽象语法树),然后将其传递给编译器。编译器使用Ye Olde Visitor Patterne遍历 AST(抽象语法树) 并为其生成一些较低层的表示形式。

根据您语言的丰富程度,您将有很多不同的AST(抽象语法树)类来表示不同的语法元素:文字,一元运算符,中缀表达式,语句,流控制,定义等。例如,V8(javescript的一个引擎)有40个类涵盖您可以用JavaScript表达的所有内容。这些是相对简单的类型。简化的外观有点像以下代码:

73724489a4898054c277ce679ddb6bb3.png

想想像这样的三十多个类,我们可以用C ++简化这些定义本身。每个类都足够不同,以至于只写出来就最简单,最清晰。真正乏味的地方是使用这些类的所有周围代码。为了使编译器可以根据不同的AST类轻松分派给不同的代码,通常需要定义一个类,如下所示:

b2f0a0676f430665ae13ac52289bbbbf.png

该代码确实只是重复的样板。还有更多的代码并没有写出来。对每种AST节点类型也都有一个枚举很有用,这样我们也可以switch直接对节点的类型进行访问,而不必经历访问者的所有访问。因此,您需要以下内容:

765a101383540ab1256fca9cf3b99f68.png

对于调试,也可以方便地获取AST(抽象语法树)节点类型的字符串表示形式:

30b9ed450cd8e23ea2bfe82d1b5b43ef.png

C ++通常的抽象在这里对我们无济于事:在所有这些情况下,重复都在某种类型定义或语句的中间。实际上,C ++的设计仅允许您抽象整个语句(通过创建函数)或类型(通过创建模板或基类)。

高阶宏的使用

C和C ++有一个非常有意思的东西,它不能对实际的语法元素造成任何伤害预处理。它甚至不知道声明是什么!它只是看到大量的文本。这正是我们所需要的。在我们所有的问题示例中,我们都希望能够:“对于每种AST(抽象语法树)节点类型,插入此代码块,但在某些地方插入节点的类名。”接下来我们尝试这样做:

#define DEFINE_VISIT(type)      virtual void visit##type(type* expr) = 0

这里使用到了## 连接操作符,不清楚的可以看看以往的文章,这样,我们可以将访问者类简化为:

47daa37fd91b25a14e14f992e6e89098.png

其实与以上代码相比较并没有得到什么优化,但这对于每个问题领域都是不同的。我们需要它采用一个参数,该参数是我们为每种类型生成的代码块:

d8d6d0f76049a1e334973d3db1f88ac6.png

当我们使用该AST_NODE_LIST宏时,该code参数将是什么?它必须是在预处理时可用的东西,可以带有参数,并且可以生成大量代码。那只留下一个答案:一个宏。使用AST_NODE_LIST优化我们刚刚定义访问者类,即可以优化为:

e3ce1da03fd28c9aba4f3e66b648a6fc.png

当AST_NODE_LIST展开后,将展开到DEFINE_VISIT每个AST节点类型。然后,这些反过来将扩大到定义该类游客的方法。同样,我们的枚举变为:

ce912d231502cc52f3983864a971008c.png

这就是全部。最后,将其转换为字符串的函数:

f9308ba732fddb56a36e0ea8263ceee4.png

请注意,我们在这里使用字符串化和标记粘贴,不仅是字面地替代AST节点类的名称,而且还将其用作字符串,或从中构建一个更大的名称,这摆脱了一些乏味的代码,还有另一个不错的作用。如果以后需要添加新的节点类,只需将其添加到中AST_NODE_LIST,使用的每个地方都会自动将其捡起。这样,您就不必去修改AstVisitor,AstType或者typeString()。

结束语

文章都是手打原创,每天最浅显的介绍C语言、C++,windows知识,喜欢我的文章就关注一波吧,每天带你学习C/C++不同的知识,也可以看到最新更新和之前发表的文章哦。如果你基础差,可以关注下通俗易懂,深入浅出,一个视频只讲一个知识点。视频不深奥,不需要钻研,在公交、在地铁、在厕所都可以观看,随时随地涨姿势

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值