工作进度2--预处理器的设计

 因为项目需求,自己需要实现一个类似于CPP的预处理器。
今天花了大半天的时间在考虑怎样实现这个预处理器。
自己需要实现的这个预处理器的形式跟C语言的有些类似,包括如下一些预处理命令:
define
ifdef
include
ifndef
line
undef
else
elif
endif
resetall
....
蓝色字体的命令是跟C语言中的相应预处理命令同名且含义相同的元素,如 define与C语言中的 #define的功能是

一样的, include则对应于 #include

而红色字体的命令,如 resetall(这是一个用来恢复默认的编译器行为的命令),严格来说,已经不能算是预处理命

令,而是用来指导控制编译器工作行为的一些 directives了(像 resetall这样的 directives在自己要实现的语言

中还有一些),因此对其的处理是不能够在预处理阶段完成的。

以C语言为例,这些directives就类似于C语言中的 #pragma 命令。在C语言中,我们可以通过 #pragma来影响

编译器的工作行为,如
#pragma warning(disable:1401)   // 从此行开始,禁止编译器报出编号为1401的警告信息
#pragma pack(4)            // 从此行开始,在为structure, union分配内存时,以16字节对齐

可以看出,这些 #pragma命令虽然是假预处理命令之形,但实际上对它们的处理已经不可能在预处理阶段完成. 只

不过形式上来看这些 #pragma命令与常规的预处理命令是一样的.

这样就引入了一定的复杂性,为了便于描述,让我们假定所有符合预处理器格式的命令集合为 S, 能够在预处理阶

段实现的命令子集合为 P,需要推迟到编译阶段(词法,语法或语义阶段)实现的命令子集为 Q, S等于 PQ的并

集。可以看出,如果想为编译器引入一个独立的预处理器的话,势必只能在这个预处理器中实现 P集合中的命令, 剩

下 的 Q集合需要在其他阶段实现。

从软件设计的结构上来看,虽然引入了预处理器环节,将复杂的工作分阶段化了,却由于 S集合本身的复杂性而使这

种阶段划分作得不够彻底。

而同样可以支持预处理器功能的另外一种实现思路就是,干脆不再引入预处理器环节,而是直接在词法分析模块中

实现对集合 P的支持。这样虽然在词法模块作了更多事情,但相对来说,还保证了设计的一致性. 不过由于在词法模

块中混入了对预处理器的支持,两部分的code会相互干扰,很可能会增加维护这两个模块的工作量。

在我看来,最完美的方案就是通过修改语言的规则,把 Q集合中的命令从S集合中抽出以其他语法形式来表

示, 以确保所有 S集合中的命令都能够在预处理器阶段中实现,这样在编译器的后续阶段不需要再考虑 预处理器格式

命令
的处理了。但是这涉及到对现有语言规则的修改,而对于我要作的这个项目来说,这是不现实的,所以这种完

美方案实际上是不存在的了。

一番考虑之后,最后我还是倾向于设计一个 独立的预处理器的方案。因为我觉得确保每个模块所实现的功能

足够 高内聚低耦合,有利于模块的可维护性和可扩展性。毕竟维护一个功能单一的模块要比维护一个涉及多个功能

的模块所需精力更少一些.另外,我觉得这样也符合KISS(Keep It Simple and Stupid)的设计原则.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值