独家思维导图!让你秒懂编译原理(二)——第二章 高级语言及其语法描述

独家思维导图!让你秒懂编译原理(二)——第二章 高级语言及其语法描述

2.1 程序语言的定义

程序语言是一个记号系统
程序语言由两方面定义:

  • 语法
  • 语义
  • 语用

2.1.1 语法

程序本质上是一定字符集(字母表)上的字符串(有限序列)。
语法:一组规则,用它可以形成和产生一个合式(well-formed)的程序(形式上正确的程序)。

词法规则:单词符号的形成规则。

  • 单词符号是语言中具有独立意义的最基本结构。一般包括:常数、标识符、基本字、算符、界符等。
  • 描述工具:有限自动机

语法规则:语法单位的形成规则。

  • 规定了如何从单词符号形成语法单位;
  • 语法单位通常包括:表达式、语句、分程序、过程、函数、程序等;
  • 描述工具:上下文无关文法

语法规则和词法规则定义了程序的的形式结构,是判断输入字符串是否构成一个形式上正确的程序的依据。
定义语法单位的意义属于语义问题。

2.1.2 语义

对于语言来说,不仅要给出它的词法、语法规则,而且要定义它的单词符号和语法符号的意义。离开了语义的语言只是一堆符号的集合。各种语言中有形式上完全相同的语法单位,含义却不相同。

  • 语义:对某种语言,定义一组规则,用它可以定义一个程序的意义,称为语义规则。

  • 描述方法:
    自然语言描述:隐藏错误、二义性和不完整性

  • 形式描述:操作语义(PL/1)、 指称语义(ADA)、 代数语义(PASCAL)。

目前大多数编译程序使用基于属性文法的语法制导翻译方法来分析语义。

2.1.3 程序语言的基本功能和层次结构

  • 程序语言的基本功能:描述数据和对数据的运算

所谓程序,本质上说是描述一定数据的处理过程。

2.1.4 程序的层次结构

在这里插入图片描述

自上而下看上述层次结构:

顶端是程序本身,它是一个完整的执行单位。
一个程序通常是由若干个子程序分程序组成的,它们常常含有自己的数据(局部名)
子程序或分程序是由语句组成的。而组成语句的成分则是各种类型的表达式
表达式是描述数据运算的基本结构,它通常含有数据引用、算符和函数用。

自下而上看上述层次结构:

我们希望通过对下层成分的理解来掌握上层成分,从而掌握整个程序。在下节中我们将综述程序语言各层次的结构和意义。

2.2 高级语言的一般特性

2.2.1 高级语言的分类

  • 强制式语言(Imperative Languge)也称过程式语言:命令驱动,面向语句
    e.g. FORTRAN、C、Pascal,Ada
  • 应用式语言(Applicative Language):注重程序所表示的功能,而不是一个语句接一个语句地执行
    e.g. LISP、ML
  • 基于规则的语言(Rule-based Language):检查一定的条件,当它满足值,则执行适当的动作
    e.g. Prolog
    = 面向对象语言(Object-Oriented Language):封装性、继承性和多态性
    e.g. Smalltalk,C++,Java

2.2.2 程序结构

FORTRAN

在这里插入图片描述

  • 一个程序由一个主程序段和若干辅程序段组成。
  • 辅程序段可以是子程序、函数段或数据块。
  • 每个程序段有一系列的说明语句和执行语句组成。各段可以独立编译。
  • 模块结构,没有嵌套和递归
  • 各程序段中的名字相互独立,同一个标识符在不同的程序段中代表不同的名字。

PASCAL

  • PASCAL程序本身可以看成是一个操作系统所调用的过程,过程可以嵌套和递归。
  • 一个PASCAL过程:
    过程头;
    说明段(由一系列的说明语句组成);
    begin
    执行体(由一系列的执行语句组成);
    end
    在这里插入图片描述
  • 作用域:一个名字能被使用的区域范围称作这个名字的作用域。
  • 允许同一个标识符在不同的过程中代表不同的名字。
  • 名字作用域规则–“最近嵌套原则”
  • 一个在子程序B1中说明的名字X只在B1中有效(局部于B1);
  • 如果B2是B1的一个内层子程序且B2中对标识符X没有新的说明,则原来的名字X在B2中仍然有效。如果B2对X重新作了说明,那么,B2对X的任何引用都是指重新说明过的这个X。
  • PASCAL提供了丰富的数据类型和运算方式,它允许用户动态地申请和退还存贮空间。

ADA

在这里插入图片描述

  • 程序包(package):把数据和操作代码封装在一起,支持数据抽象。
  • 一个程序包分为两部分:
    可见的规范说明部分,它定义了程序包外面可以访问的对象。
    程序包体,它实际定义程序包的实现细节。

JAVA

在这里插入图片描述
Java是一种面向对象的高级语言

  • 类(Class)
  • 继承(Inheritance)
  • 多态性(Polymorphism)和动态绑定(Dynamic binding)

2.2.3 数据类型与操作

一个数据类型通常包括以下三种要素:

  • 用于区别这种类型数据对象的属性
  • 这种类型的数据对象可以具有的值
  • 可以作用于这种类型的数据对象的操作

1) 初等数据类型

  • 数值类型:整型、实型、复数、双精度, 运算:+,-,*,/等
  • 逻辑类型:布尔运算:∨,∧,┑
  • 字符类型:符号处理
  • 指针类型
标识符与名字
  • 标识符:以字母开头的,由字母数字组成的字符串。

这个定义是从形式上规定的,因此标识符是语法概念

  • 标识符与名字两者有本质区别:
    标识符是语法概念
    名字有确切的意义和属性(语义概念)

自己的一点理解:
名字:标识程序的对象。有意义和属性,代表一个抽象的存储单元,名字具有语义色彩,只有当标识符与程序中某个对象联系在一起才能称为名字。
因此,有全局名,局部名
但没有全局标识符和局部标识符

在这里插入图片描述

Jordan在特定的情况下可以分别表示篮球运动员乔丹,和国家约旦。
Jordan本身是个标识符,当标识符与环境绑定后就可以作为名字。

  • 名字:
    值:单元中的内容
    属性:类型和作用域
  • 名字的性质的说明方式:
    由说明语句来明确规定的
    隐含说明:FORTRAN 以I,J,K,…N为首的名字代表整型,否则为实型。
    动态确定:走到哪里,是什么,算什么

2) 数据结构

1 数组

逻辑上,数组是由同一类型数据所组成的某种n维矩形结构,沿着每一维的距离,称为下标。

  • 数组可变与不可变:编译时能否确定其存贮空间的大小。
  • 访问:给出数组名和下标值
  • 存放方式: 按行存放,按列存放

数组元素地址计算
数组A[10,20]的A[1,1]为a,各维下标为1,按行存放,那么A[i,j]地址为:
a+(i-1)*20+(j-1)
数组元素地址计算公式
在这里插入图片描述

内情向量

把数组的有关信息记录在一个“内情向量”中,每个数组的内情向量必须包括:维数,各维的上、下限,首地址,以及数组(元素)的类型
在这里插入图片描述

2 记录
  • 逻辑上说,记录结构由已知类型的数据组合在一起的一种结构。
    record { char NAME[20];
    integer AGE;
    bool MARRIED;
    } CARD[1000]
  • 访问:复合名 CARD[k].NAME
  • 存储:连续存放
  • 域的地址计算:相对于记录结构起点的相对数OFFSET。
3 字符串、表格、栈
  • 字符串:符号处理、公式处理
  • 表格:本质上是一种记录结构
  • 线性表:一组顺序化的记录结构
  • 栈:一种线性表,后进先出,POP, PUSH

三 抽象数据类型

  • 一个抽象数据类型包括:
    数据对象的一个集合;
    作用于这些数据对象的抽象运算的集合;
    这种类型对象的封装,即,除了使用类型中所定义的运算外,用户不能对这些对象进行操作。
  • 程序设计语言对抽象数据类型的支持
    Ada语言通过程序包(package)提供了数据封装的支持
    Smalltalk、C++和Java语言则通过类(Class)对抽象数据类型提供支持。

2.2.4 语句与控制结构

1.表达式

  • 表达式由运算量(也称操作数,即数据引用或函数调用)和算符(操作符)组成。

  • 形式:
    中缀 X*Y
    前缀 -A
    后缀 P↑

  • 表达式形成规则
    (1)变量(包括下标变量)常数是表达式;
    (2)若E1、E2为表达式,θ是一个二元算符,则E1θE2是表达式(一般采用中缀形式);
    (3)若E是表达式,θ为一元算符,则(或)是表达式;
    (4)若E是表达式,则(E)是表达式。

算符的优先次序
  • 一般的规定
    PASCAL:左结合A+B+C=(A+B)+C
    FORTRAN:对于满足左、右结合的算符可任取一种,如A+B+C就可以处理成(A+B)+C,也可以处理成A+(B+C)。
  • 注意两点:
    代数性质能引用到什么程度视具体的语言不同而不同;
    在数学上成立的代数性质在计算机上未必完全成立。

多数语言中,算术算符和逻辑算符的优先顺序一般规定如下(自高至低排列,同级算符列于同一行):

在这里插入图片描述

2.语句

赋值语句:

A := B

  • 名字左值:该名字代表的那个单元(地址)称为该名字的左值。(所代表的存贮单元的地址)
  • 右值:一个名字的值称为该名字的右值。(所代表的存贮单元的内容)
控制语句:

在这里插入图片描述

说明语句:

定义各种不同数据类型的变量或运算,定义名字的性质。

简单句和复合句

简单句:不包含其他语句成分的基本句
复合句:句中有句的语句

2.3 程序语言的语法描述

几个概念:

  • 字母表︰一个有穷字符集,记为∑
  • 字母表中每个元素称为字符
  • ∑上的(也叫字符串、符号串) 是指由∑中的字符所构成的一个有穷序列
  • 不包含任何字符的序列称为空字(空串),记为ε
    用∑*表示∑上的所有字的全体,包含空字ε
    例如: 设 ∑={a, b},
    则 ∑*={ε,a,b,aa,ab,ba,bb,aaa,…}
    在这里插入图片描述

注:UV不等于VU 当二者中包含空串时可交换

V*和V+有时候相等,有时候不相等,区别在于,如果V中间原来没有空字,闭包中包含空字,正规闭包没有空字(正规闭包不含空串)

在这里插入图片描述

2.3.1 上下文无关文法

文法: 描述语言的语法结构的形式规则
He gave me a book.
在这里插入图片描述
在这里插入图片描述
注:
产生式集合给出了一个非终结符的定义(→定义为)
说明这个非终结符由怎样的非终结符和终结符构成
即只要左边是非终结符,就能产生任何符
( V T ∪ V N ) (V_T∪V_N) (VTVN)表示终结符和非终结符组成的字符集合
( V T ∪ V N ) ∗ (V_T∪V_N)^* (VTVN)表示该集合中的符号所组成的字的全体
在这里插入图片描述
在这里插入图片描述

表示一个文法时,通常只给出开始符号和产生式,如上例,可表示为:
G(E): E → i | E+E | E*E | (E)

在这里插入图片描述

把一个字符串中的一个终结符的一次出现(不是所有一起替换)替换成候选

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

要证明是一个句子,必须证明它只有终结符,即只有{i,+,*,(,)},然后再证明他能从文法开始的符号推出来。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
2.3.2 语法树与二义性
用一张图表示一个句型的推导,称为语法树
在这里插入图片描述
在这里插入图片描述

  • 文法的二义性:如果一个文法存在某个句子对应两颗不同的语法树,则说这个文法是二义的。

G(E): E → i|E+E|E*E|(E) 是二义文法。

  • 语言的二义性:一个语言是二义性的,如果对它不存在无二义性的文法。
  • 对于语言L,可能存在G和G’,使得L(G)=L(G’)=L,但可能其中一个为二义的,一个为无二义的。
  • 二义性问题是不可判定问题,即不存在一个算法,它能在有限步骤内,确切地判定一个文法是否是二义的。
  • 可以找到一组无二义文法的充分条件。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    描述程序设计语言时,对于上下文无关文法的限制 :
    1 不含P→P形式的产生式
    2 每个非终结符P必须有用处
    即:
    在这里插入图片描述

2.3.3 形式语言鸟瞰

  • Chomsky于1956年建立形式语言体系,他把文法分成四种类型:0,1,2,3型。
  • 与上下文无关文法一样,它们都由四部分组成,但对产生式的限制有所不同。

0型(短语文法,图灵机):

产生式形如: α → β α→β αβ
其中: α ∈ ( V T ∪ V N ) ∗ α∈ (V_T∪V_N)^* α(VTVN)且至少含有一个非终结符; β ∈ ( V T ∪ V S ) ∗ β∈ (V_T∪V_S)^* β(VTVS)

1型(上下文有关文法,线性界限自动机):

产生式形如: α → β α→β αβ
其中: ∣ α ∣ ≤ ∣ β ∣ |α| ≤ |β| αβ,仅 S → ε S→ε Sε 例外。

左边一定比右边短

2型(上下文无关文法,非确定下推自动机):

产生式形如: A → β A → β Aβ
其中: A ∈ V N ; β ∈ ( V T ∪ V N ) ∗ A∈ V_N;β∈ (V_T ∪ V_N)^* AVNβ(VTVN)

3型(正规文法,有限自动机):

右线性文法

非终结符要出现,只能在定义式的最右边。

产生式形如: A → α B 或 A → α A → αB 或 A → α AαBAα
其中: α ∈ V T ∗ ; A , B ∈ V N α∈ V_T^*;A,B∈V_N αVTABVN

左线性文法

非终结符要出现,只能在定义式的最左边。

产生式形如: A → B α 或 A → α A → Bα 或 A → α ABαAα
其中: α ∈ V T ∗ ; A , B ∈ V N α∈ V_T^*;A,B∈V_N αVTABVN

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
程序设计语言不是上下文无关语言,甚至不是上下文有关语言。
L 7 = α c α ∣ α ∈ ( a ∣ b ) ∗ L7={αcα| α∈(a|b)*} L7=αcαα(ab)不能由上下文无关文法产生,甚至连上下文有关文法也不能产生,只能由0型文法产生。

  • 标识符引用
  • 过程调用过程中,“形-实参数地对应性”(如个数,顺序和类型一致性)

现今程序设计语言的语言结构,用上下文无关文法描述就足够了。

猜你喜欢

转载自blog.csdn.net/m0_46413065/article/details/115275354