语义的检查

没有一个一般的方法,通常的方法是以一个语言为例子,完整地介绍语义相关的全部工作。这种思路不是太让人满意,因为这不能说明另一种语言怎么能完成这种工作。

一个角度是类型安全,即通过类型安全尽可能包住语义相关的全部工作,但类型安全和语义检查二者的等价性缺少一个证明或者证伪(即:在广泛的意义上,类型安全能否等于语义的正确?我倾向于认为不相等,语义的正确可能要大于类型安全的范围)。将语义的正确归结到类型安全,也有一种十分刻意的感觉。

此外,语义的检查还不能等于语义的正确以及编译器构造中的全部的工作,因为在语义正确之外,编译器构造可能还需要进行编译器本身的资源管理、指令序列调度,如此等等。

TAPL的理论看着似乎很连贯,实际上感觉很生硬,很多内容之间其实并无很大的联系,而是一种不断地推理,但是那个Syntax-Evaluation的二栏表引起了我的注意,感觉值得重视。TAPL主要还是类型论的发挥,对编译器构造(Compiler Construction)的讨论其实很浅很少。在反复研究 Reactor-C 后,我们可以(不太严格地)得到一个结论:类型安全的检查可以归约到AST的遍历。这是一个漂亮的结论。看了一些逻辑学的资料,这个说法似乎值得重视:元语言作为描述语言的语言,其本身应该比对象语言丰富。塔斯基的语义学似乎很有参考指导价值。

TAPL中的Syntax-Evaluation图示

最后得到了这个方法:制作一张三栏的表,其中第一栏名为“文法”(Grammar),第二栏为“检查”(Check),第三栏为“策略”(Strategy)。由于文法是有限的,例如又N个文法,那么这个表就有N行,其中第N行的第一列写第N个文法,第二列写第N个文法相关的检查的充分必要的要求(规则),第三列写编译器在处理这个文法的时候额外的特殊的要求。

可以证明,由于文法的有限性,这个表总是可以制成的。由于语言总是可以在一定程度上看成文法的实例的集合,那么语言的语义检查的完备性和这个表所列出的每个文法的检查的完备性就有某种充分必要的关联性,也即如果这个表对每个文法已经较好地列出了语义检查和编译器策略,那么源代码的检查也就可以归结为这些语义检查规则(可行性),相应地源代码的检查也就有了全部的规则(充分性),如果没有这些完整的规则,语义的检查也是不完备的(必要性)。编译器构造额外的方面则可以通过策略一栏来表述。

这里可能有这些问题:① 文法的有限性不一定成立。这种时候这个方法可能就不适用。这种情况我们先忽略,因为文法目前一般是有限的,而且由于语言来自人类输入,这个假设并不过度。② 整体不一定等于部分之和,一些语义的要求不能归结为某行文法规则。这时候仍然有处理的办法,例如将这些语义的处理归结到特殊的文法行,额外补充整体性的语义处理要求说明,如此等等。最重要的是,这个表可以明确把已经确定和未确定的语义处理要求分析确定下来。

这种对文法、语义检查、编译器构造相耦合的需求分析方法可称为“文法-检查-策略分析法”。(Grammar-Checking-Strategy Analysis,简称GCS分析

这个表大概就长这样:

文法-检查-策略分析法表格

这个方法基本上彻底解决了(程序地)一般语言的语义检查和编译器构造的需求分析和设计问题,可以应用到任何的语言。

此外,还可以推广到需要复杂协调的跨组件的系统,感觉需要分别设置不同的列,第一列只需要为可以跟踪、完备的项即可。

约束构造单元1构造单元2构造单元3构造单元4……
① 约束1的描述……构造单元1的响应和策略构造单元2的响应和策略构造单元3的响应和策略构造单元4的响应和策略……
② 约束2的描述…………
③ 约束3的描述…………
……

约束-元素-构造单元分析法表格

这种对约束、元素、软件构造单元相耦合的需求分析方法可称为“约束-元素-构造单元分析法”。(Constraints-Elements-Constructions Analysis,简称CEC分析

至此,语义检查这个问题的已经形成了一个有一定普遍性的方法。


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注