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

来源:互联网 发布:生意参谋数据分析2017 编辑:程序博客网 时间:2024/05/17 02:43
 因为项目需求,自己需要实现一个类似于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)的设计原则.
原创粉丝点击