《编译器设计》读书笔记——上下文相关分析

将每条语句放到实际的上下文中进行考虑,从而检测类型和约定方面的错误,这种分析一般被称为“上下文相关分析”(context-sensitive analysis),以区别于语法分析,或者称为"语义推敲"(semantic elaboration)。

概述

被编译的程序中的某个名字x,在编译器能够为涉及x的计算输出可执行的目标机代码之前,以下问题是须被回答的:

  • x中存储了什么种类的值?
  • x有多大呢?
  • 如果x是一个过程,它需要获得哪些参数呢?
  • 对于x的值来说,其生命周期有多长?
  • 谁负责分配x的空间(并初始化它)?

编译器必须根据源语言的规则和源程序,推导出这些问题的答案及其它信息,但这些问题中有许多(如果不是全部)都超出了上下文无关语法,为了解决这些问题,编译器必须深入研究程序的语义,词法分析和语法分析处理的只是程序的形式,而语义分析则进入了上下文相关分析的领域。

类型

一种抽象范畴,规定了其所有成员共有的性质。常见的类型包括整数,列表和字符串。

类型系统

一些类型是程序设计语言预定义的,其他的类型则是程序员构建的。程序设计语言中类型的集合,以及使用类型来规定程序行为的规则,总称为类型系统(type system)。

类型系统的目标

与上下文无关语法相比,利用类型系统可以在更精确的层次上规定程序的行为。

  1. 确保运行时的安全性

    安全性是使用强类型语言的一个重要原因,如果语言的实现能够保证在程序执行之前捕获大多数类型相关的错误,这将简化程序本身的设计和实现。如果一个语言中每个表达式都能分配一个无歧义的类型,这种语言称为强类型语言。如果每个表达式都可以在编译时确定类型,我们称这种语言为静态类型的(statically typed),如果某些表达式只能在运行时确定类型,称这种语言为动态类型的(dynamically typed)。还有另两种语言:无类型语言,如汇编代码或BCPL语言;和弱类型语言,及类型系统较为贫乏的语言。

  2. 提高表达力

    具有良好结构的类型系统允许语言设计者更精确地规划程序的行为,从而可以加入一些上下文无关语法不可能表示的特性,比如运算符重载(operator overloading)。

  3. 生成更好的代码

    设计完善的类型系统为编译器提供了程序中每个表达式的详细信息,通常利用这一信息进行转换可以生成更高校的代码。

  4. 类型检查

    为避免运行时类型检查的开销,编译器必须分析程序,为每个名字和表达式分配一种类型。它必须检查这些类型,以确保类型在相应上下文中的使用是合法的。总而言之,这些活动通常称为类型检查,不过这是个误称,它将类型推断和识别类型相关错误的不同活动放在了同一个名称下。

类型系统的组件

  1. 基础类型

    用于表示下述数据种类中的一些或全部:数字,字符和布尔值。几乎所有的语言都包含了一些功能,用于根据其基础类型来构建更复杂的类型。

  2. 复合类型和构造类型

    基础类型通常对硬件直接处理的数据提供了足够的抽象,但其通常不足以表示程序所需的信息。为复合或聚合对象构建新类型的能力,是许多程序设计语言的一个基本特性。

  3. 类型等价性

    用于判断两种不同类型声明是否等价的机制,一般认为有两种通用的方法,一种是名字等价性(name equivalence, 该规则断言两个类型等价的充分必要条件是二者同名),另一种是结构等价性(structural equivalence, 该规则断言两个类型等价的充分必要条件是二者有相同的结构)。

  4. 用于推断的规则

    一般来说,用于推断类型的规则会对每个运算符规定操作数类型和结果类型之间的映射。类型推断规则可以指出类型错误。

  5. 推断表达式的类型

    推断类型的目标是为程序中出现的每个表达式分配一个类型。这要求所有变量都有生命,所有的常量都可以推断出类型,而所有函数的类型信息都是可以获得的。在简单情形下,表达式的类型推断可以从表达式的结构直接承袭而来。

  6. 类型推断的过程间相关问题

    表达式的类型推断固有地依赖于形成可执行程序的其他过程。

属性语法框架

属性语法(attribute grammar)是用于上下文相关分析的一种形式化机制,也称为属性化的上下文无关语法(attributed context-free grammar)。其包含了一个上下文无关语法,外加一组规定了某些计算的规则,每个规则都通过其它属性的值定义了一个值或属性

综合属性

完全根据结点本身的属性,其子结点的属性和常量定义的属性

继承属性

完全根据结点本身的属性,其兄弟结点的属性及其父结点的属性(外加常量)定义的属性。

求值的方法

  1. 动态方法

    这种技术使用特定的属性化语法分析树的结构,来确定求值次序。一种相关的方案是建立属性依赖关系图,对其拓扑排序,使用拓扑次序对属性进行求值。

  2. 无关方法

    在这一类方法中,求值的次序与属性语法和特定的属性化语法分析树都是无关的。这种风格的求值方法包括:从左到右重复多趟(直到所有属性的值都确定为止),从右到左重复多趟和从左到右与从右到左交替多趟处理。

  3. 基于规则的方法

    依赖于对属性语法的静态分析,来构造出一个求值次序。

有环的属性语法会导致有环的属性依赖关系图,若编译器使用属性语法,那么它必须以适当的方式处理环。

特设语法制导转换

在这种方案中,编译器编写者提供在语法分析时需要执行的代码片段。每个片段,即操作都直接关联到语法中的某个产生式。每次语法分析器发现自身处于语法中的特定位置时,都会调用对应的操作,以完成相应的任务。

posted @ 2018-08-07 13:23  Mu001999  阅读(510)  评论(0编辑  收藏  举报