111
湖南大学信息科学与工程学院 软件工程系 杨金民 2018 编译原理 Compiler Principles 第四章 语法分析

编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

  • Upload
    others

  • View
    30

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

湖南大学信息科学与工程学院

软件工程系 杨金民

2018

编译原理Compiler Principles

第四章 语法分析

Page 2: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

纵观全局

• 语言的规约1:词法单元的模式(串接结构,一维线性结构);

词法单元的模式 → 正则表达式 → DFA → 词法分析程序;

• 语言的规约2:上下文无关类的语法(嵌套结构:树形结构);

语法规则 → 上下文无关文法 → 推导 → 语法分析程序;

• 语言的规约3:上下文有关的语法:例如:1)变量先定义,后

使用规则,就近归属规则;2)函数调用中的参数个数,顺序,

类型的匹配规则;3)类型一致性规则;语义分析;

Page 3: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

嵌套性 → 树形结构

include “my_head.h” int g_num; int main( int argc, char *argv ) { char szBuf [128]; char *psz = "Hello"; int p = 2;

g_num = 189; MyFun( p ); if (p > 0) { int p; p = strcpy(szBuf, psz); } return 0;}

root 块

函数块1main

函数块2MyFun

函数块3strcpy

if块1 while块2

if块1 if块2 while块3

Page 4: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

控制语句→ 树形结构

if (i >j *k) then i+=10;else if (i >2) then i+=5;

stmt1

thenif elseexpr1 stmt2

语法分析树:

stmt3

thenif expr2 stmt4

Page 5: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

表达式的计算过程 → 树形结构

position = initial + rate * 60

=+[id,1]

*[id,2][60][id,3]

语法分析树:

[id,1] [=,] [id,2] [+,] [id,3] [*,] [60]

Page 6: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

本章要解决的问题

if (i >j *k) then i+=10;else if (i >2) then p = i+r*60;

=+id1

*id260id3

语法分析树:

验证词法单元的实例流(一维线性结构,串式结

构)符合语法规约,得出 树形结构的语法分析树

Page 7: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

树状结构有什么好处

if (i >j *k) then i+=10;else if (i >2) then p = i + r * 60;

=+id1

*id260id3

语法分析树直白了处理过程;

语法分析树直白了逻辑关系;

stmt

thenif elseexpr stmt stmt

thenif expr stmt

Page 8: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

第四章 语法分析

• 1. 上下文无关文法;

• 2. 推导;

• 3. 自顶向下语法分析– 递归下降分析– LL(1)分析

• 4.自底向上语法分析– LR(0)分析– SLR(1)分析– LR(1)分析– LALR(1)分析

Page 9: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

语言中的词法单元

词法

预定义符 自定义符

保留字 运算符 标点符 特义符 变量 常量

数据变量 函数变量if while int

预定义符:相互独立,没有相交性。

; “ ...

id

语法主要通过预定义符来体现和标识。

Page 10: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自定义符的标识

符号表:

row_id name type class v_class row_num

1 return 预定义 保留字 120

2 ( 预定义 标点符号 120

3 initial 自定义 局部变量 int 120

4 <= 预定义 运算符 float 120

5 10 自定义 常量 数值 120

6 ? 预定义 标点符号 120

id,3

id,5

Page 11: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

词法分析与语法分析对比

• 词法分析:如何从字符流切分识别为词法单元流。

return ( initial <= 10 ) ? 100 : ( position + initial ** 2 ) ;

forward

lexemeBegin匹配语言的词法单元的正则表达式

return ( initial 10<= ) ? position...

forward

position匹配语言的语法的文法,生成语法分析树

• 词法分析:如何从词法单元流生成语法分析树。

Page 12: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

上下文无关的文法

词法 语法 语言

定义(类概念) 正则表达式 文法

实例词素 句子

所有实例的集合叫语言

运算|,联接,*

推导:从根往下的细化过程

归约:从叶往上的归纳过程

Page 13: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

上下文无关文法,与之匹配的输入串对应的语法树

E→ E + T | T

T→ T * F | F

F→ (E) | id

观察与分析:这个文法 反映出了树型结构; 反映出了运算的优先级;

输入串: id + idE

id

+E T

FT

F

id

运算表达式的文法:

Page 14: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

上下文无关文法的实例

E→ E + T | T

T→ T * F | F

F→ (E) | id

观察与分析:这个文法 反映出了树型结构; 反映出了运算的优先级;

输入串: id * id;

T

id

*T F

F

id

E

Page 15: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法的实例(组合)

E

id

+E T

id + id *id

*T F

F

id

T

F

id

id + idE

id

+E TFT

F

id

id * id

T

id

*T F

F

id

E

E→ E + T | T

T→ T * F | F

F→ (E) | id

Page 16: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法的实例(组合)

E→ E + T | T

T→ T * F | F

F→ (E) | id

id + idE

id

+E TFT

F

id

(id + id)

id

+

E

E TFT

F

id

F( )

TE

Page 17: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法的实例(组合)

(id + id) *id (id + id)

T

id

*T F

F

id

E

id

+

E

E TFT

F

id

F( )

TE

id * id

T

id

*T F

E

id

+

E

E TFT

F

id

( )F

Page 18: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

上下文无关文法

E→ E + T | T

T→ T * F | F

F→ (E) | id

观察与分析:这个文法 反映出了树型结构; 反映出了运算的优先级; 反映出了运算的交换律; 具有开放性、灵活性,适应性; 具有高度抽象性; 具有全覆盖性;

E

id

+E T

id + id * id

*T F

F

id

T

F

id

Page 19: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

对上下文无关文法的特性认识

E→ E + T | T

T→ T * F | F

F→ (E) | id

id + id * idE

id

+E T*T F

F

id

T

Fid

开始符号;树根

非终结符号:展开关系;

产生式: 从左到右:推导,分析;

从右到左:规约,归纳;

的 语法分析树

对输入串的推导

表达式输入串

Page 20: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

什么叫语法分析

E→ E + T | T

T→ T * F | F

F→ (E) | id

语法分析器

对词法分析后的源程序:输入串(符号串);

验证输入串符合文法吗?

不符号的话,就说明源程序有语法错误;

符合的话,推导出输入串的语法分析树。输入串:id + idE

id

+E TFT

Fid

如何推导?

文法:

理想状态:对符号串从左到右逐个扫描一趟,

就能完成。

Page 21: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法中平行关系的扩展

E→ E + T | E - T | T

T→ T * F | T F | F

F→ (E) | id

运算优先级最低

运算优先级次低

高级

运算优先级最低的,在最后处理,自然应该在树根。

文法本身自然应该是树型结构;

Page 22: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

上下文无关文法

开始符号; 树根

终结符号,非终结符号; 层次结构

产生式: 头部(一个符号),产生式体:符号串|终结符号|ε;

非终结符号表达了语言的层次结构;

• E→ E + T | E - T | T

• T→ T * F | T / F | F

• F→ (E) | id

① E→ E + T ② E→E - T ③ E→ T④ T→ T * F ⑤ T→ T / F ⑥ T→ F⑦ F→ (E) ⑧ F→ id

Page 23: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法的实例(组合)

输入串:(id + id)E

E

id

+E TFT

F

id

F( )

T

(id + id) *id

T

id

*T F

E

id

+

E

E TFT

F

id

( )F

id + id+id

id

F+ TE

TF

id

+E TE

idF

Page 24: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

2. 基于文法的推导

推导:从根往下,任用产生式,进行细化的过程,直至树的叶

结点不含非终结符号,仅含终结符号。

一步推导:任用一个产生式,对树中的某个(非终结符)叶结

点深化一层。

E E

+E T

*T F

E

+E T

Page 25: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析之一:基于文法对输入串的最右推导

① E→ E + T ② E→ T③ T→ T * F ④ T→ F⑤ F→ (E) ⑥ F→ id

输入串:

E E

+E T

*T F

E

+E T

*T F

E

+E T

id

文法:

id + id *id

Page 26: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析之一:基于文法对输入串的最右推导

*T F

E

+E T

idF*T F

E

+E T

idFid

* F

E

+E T

idT

Fid

T

Fid

① E→ E + T ② E→ T③ T→ T * F ④ T→ F⑤ F→ (E) ⑥ F→ id

输入串:文法:id + id *id

Page 27: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析之二:基于文法对输入串的最左推导

E E

+E T

E

+E T

E

+E T

TF

T

① E→ E + T ② E→ T③ T→ T * F ④ T→ F⑤ F→ (E) ⑥ F→ id

输入串:文法:id + id *id

Page 28: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析之二:基于文法对输入串的最左推导

* F

E

+E T

idT

Fid

T

Fid

E

+E T

T

Fid

* F

E

+E T

T

Fid

T

① E→ E + T ② E→ T③ T→ T * F ④ T→ F⑤ F→ (E) ⑥ F→ id

输入串:文法:id + id *id

Page 29: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

基于文法推导中的概念

推导后,树中的叶结点,从左至右,组成的符号串,叫句型

(sentential form)。

如果句型中不含非终结符号,自然只含终结符号,那么就叫句

子(sentence)

文法G,由它生成的语言L(G),自然就是所有句子的集合。

最左推导(leftmost derivation):对树中的叶结点,总是选择最左的非终结符号叶结点,来执行推导。

最右推导(rightmost derivation):对树中的叶结点,总是选择最右的非终结符号叶结点,来执行推导。

Page 30: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

概念:句型,句子,最右句型

E E

+E T

E+T

E

+E T

T

Fid

id+T

* F

E

+E T

idT

Fid

T

Fid

id+id*idE

句型: 树的叶节点从左到右构成的串 句子: 只含终结符的句型

最左句型: 最左推导中出现的句型

最右句型: 最右推导中出现的句型

Page 31: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的最右推导的特性

*T F

E

+E T

id* F

E

+E T

idT

Fid

T

Fid

*T F

E

+E T

idFid

*T F

E

+E T

idF

id+id*id

E+T*id

id+id*id

E+F*id

id+id*id

E+id*id

id+id*id

id+id*id

最右句型

推导是从输入串的最右端(即末尾)开始逐一来匹配:不切实际输入串

Page 32: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的最左推导的特性

* F

E

+E T

idT

Fid

T

Fid

E

+E T

T

Fid

* F

E

+E T

T

Fid

T * F

E

+E T

T

Fid

TFid

id+id *id

id+T

id+id *id

id+T*F

id+id *id

id+id* F

id+id*id

id+id*id

最左句型

推导是从输入串的最左端(即起始)开始逐一来匹配:切合实际输入串

Page 33: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法的二义性

• 如果某个句子:有多个最左推导,或者多个最右推导。

• 例如文法:E→E+E | E*E | (E) | id; 句子: id + id * id

id

+

E

E E

*E E

id id

E

*E

id

E

EE +

id id

不是想要的原因:将+和*等同看待,没有区分优先级

Page 34: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

比较两个文法

文法1:E→E+E | E*E | (E) | id;

文法2: E→ E + T | T

T→ T * F | F

F→ (E) | id

*是+的子结点;

(E) | id 又是*的子结点,

体现了优先级;E

+E T

TE +

+E T

TE +

+和*是平行关系

类似于正则表达式的*运算

句型:E+T+T+T+T = E(+T)*

E→ E + T涵盖了*运算

Page 35: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法 VS 正则表达式

• 并运算在文法中也有;

• 连接运算 → 产生式;

• *运算 → 递归 :E→ E+T;

用正则表达式表达的,用文法

都能表达。超集与子集的关系。

b

start 0 1 2b

3a b

(a|b)*abb

a文法:

A0→aA0 |bA0 |abb

Page 36: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法 比 正则表达式更加强大

• 或运算在文法中也有;

• 连接运算 → 产生式;

• *运算 → 递归 :E→ E+T;

用正则表达式表达的,用文法

都能表达。超集与子集的关系。

E→ E + T | TT→ T * F | F

F→ (E) | id

对于输入串:(((id + id) * id+idid)*id+id)*id

括号配对的语法,正则表达式无法表达。

E→ E + T | T T→ T * F | F F→ (E) | id

Page 37: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法比正则表达式强大,但效率要低

E→ E + T | T

T→ T * F | F

F→ (E) | id

(id + id) * id;

E

+

E

T

*T

id

F

E

)(

T

T

id

F id

F

效率显然要比正则表达式的低。

语法树中出现了很多非终结符

Page 38: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

4.3 文法设计

消除文法的左递归;

提取左公因子。

消除文法的二义性;

4.3节的知识,都是4.4 节 “自顶向下的语法分析”中遇到和

要解决的问题,因此,融合到4.4节中去,不单独讲。这样显

得更加实在,有针对性。

Page 39: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

4.4节. 基于自顶向下和最左推导的语法分析

* F

E

+E T

idT

Fid

T

Fid

E

+E T

T

Fid

* F

E

+E T

T

Fid

T * F

E

+E T

T

Fid

TFid

id+id *id

id+T

id+id *id

id+T*F

id+id *id

id+id* F

id+id*id

id+id*id

最左句型

推导是从输入串的最左端(即起始)开始逐一来匹配:切合实际输入串

Page 40: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

3、自顶向下、最左推导下的语法分析例子

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt E

已知文法G:

对于输入串:

Page 41: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

Page 42: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

Page 43: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

thenif expr stmt E

Page 44: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

thenif expr stmt EE2

Page 45: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

thenif expr stmt EE2

Page 46: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else stmt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

thenif expr stmt EE2 S1 stmtelse

Page 47: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

thenif expr stmt EE2 S1 stmt

S2

else

Page 48: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析例子(cont.)

if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else smt | ε

stmt

thenif expr stmt

E1

E

已知文法G:

对于串

thenif expr stmt EE2 S1 stmt

S2

ε所有叶结点都为终结符!

Page 49: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

基于自顶向下和最左推导的语法分析,遇到的问题之一:左递归

对带左递归的文法:

E→ E + id | id

输入串:

E

+E id4

E

+E id4

+E id3

E

+E id4

+E id3

+E id2

自顶向下的最左推导:

最左句型:E+id4 E+id3+id4 E+ id2 + id3 + id4

推导是从输入串的最右端开始逆向逐一来匹配:不切合实际

id1 + id2 + id3 + id4

Page 50: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

基于自顶向下和最左推导的语法分析,遇到的问题之一:左递归

对带左递归的文法:

E→ E + id | id id1 + id2 + id3 + id4

输入串:

最左句型:

id1+ id2 + id3 + id4

推导是从输入串的最右端开始逆向逐一来匹配:不切合实际

E

+E id4

+E id3

+E id2

id1

Page 51: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

解决办法:消除左递归

带左递归的文法:E→ id E'E'→+ id E' |

消除左递归后的文法:

E→ E + id | id

E

+E id4

+E id3

+E id2

id1

E

id1 E'

id2+ E'

id3+ E'

id4+ E'

id1 + id2 + id3 + id4输入串:

Page 52: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

解决办法:消除左递归

带左递归的文法:E→ id E'E'→+ id E' |

消除左递归后的文法:

E

id1 E'

E

id1 E'

id2+ E'

自顶向下的最左推导:

最左句型:id1E' id1+id2E' id1 + id2 + id3E'

E→ E + id | id

E

id1 E'

id2+ E'

id3+ E'

变成了从输入串的最左端开始顺向逐一来匹配:切合实际

Page 53: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

解决办法:消除左递归

带左递归的文法:E→ id E'E'→+ id E' |

消除左递归后的文法:

最左句型:

E→ E + id | id

E

id1 E'

id2+ E'

id3+ E'

id4+ E'

E

id1 E'

id2+ E'

id3+ E'

id1 + id2 + id3E'

Page 54: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

消除左递归的特性

带左递归的文法:E→ id E'E'→+ id E' |

消除左递归后的文法:

当某个非终结符的产生式含左递归时:

将该非终结符的所有产生式放到一起;

其产生式分两类:含左递归的, 不含左递归的;

E→ E + id | id

好处:实现了对输入串从左至右逐一匹配;

代价:多引入了一个非终结符,语法树变得复杂,效率低

Page 55: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

解决办法:消除左递归

带左递归的文法:

E→ E + id | id

E

+E id4

+E id3

+E id2

id1

id1 + id2 + id3 + id4输入串:

Page 56: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

解决办法:消除左递归

带左递归的文法:E→ id E'E'→+ id E' |

消除左递归后的文法:

E→ E + id | id

E

id1 E'

id2+ E'

id3+ E'

id4+ E'

id1 + id2 + id3 + id4输入串:

Page 57: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

消除左递归例子1:严格按照公式处理

E→ E + T | T

T→ T * F | F

F→ (E) | id

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:E→ TE'E' → +TE' | ε

T→ FT'T'→ * F T' | ε

Page 58: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

消除间接左递归例子2(书上例4.20)

文法: S → Aa | b;

A→Ac | Sd | ε

解:把A代入S得:

S → Aca |Sda | a| b; 这里还含A,再要进一步消A,死循环,不行;

直接左递归;

间接左递归;

Page 59: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

消除间接左递归例子2(书上例4.20)

文法: S → Aa | b;

A→Ac | Sd | ε

解:反过来,把S代入A得:

A→Ac | Aad | bd | ε ,只有A了,可行;

严格按照公式消除左递归:

A→bdA' | εA';

A'→cA' | adA' | ;

即:A→bdA' | A';

A'→cA' | adA' | ;

Page 60: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

基于自顶向下和最左推导的语法分析,遇到的问题之二:左公因子

stmt→ if expr then stmt | if expr then stmt else stmt | other

stmt

thenif elseexpr stmt stmt

thenif expr stmtS1E2

S2E1

thenif expr stmt

thenif expr stmtS1E2 S2

E1

stmt

else stmt

对于串 if E1 then if E2 then S1 else S2

看到if时,是选第一个产生式,还是第二个?不好决策!不同选择,导致不同结果

Page 61: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

当含左公因子时的解决办法:提取左公因子

stmt→ if expr then stmt | if expr then stmt else stmt | other

对于输入串 if E1 then if E2 then S1 else S2

stmt → if expr then stmt E | otherE → else stmt | ε

stmt

thenif expr stmt

thenif expr stmtS1E2 stmt

S2

E1E

else

E

ε

Page 62: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

对提取左公因子的认识——要彻底

stmt→ if expr then stmt | if expr then stmt else stmt | other

是指某个非终结符,它有多个产生式,其产生式体的左端有公因子;

导致在推导时,有多个产生式匹配,不知道选哪个才对。

解决办法:把非公因式部分单独拿出来,新引入一个非终结符,来

表达它,注意 。

策略:把差异部分,延后再来确定;

代价:新引入了一个非终结符;

stmt → if expr then stmt E | otherE → else stmt | ε

Page 63: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

提取左公因子的一般化表述

如果非终结符A的产生式:A→ β1 | β2 | β3 |

那么就为左公因子,将该产生式变换为:

A→ A’ |

A'→β1 | β2 | β3

其中,β1 , β2 ,β3 ,没有左公因子。

的左端不含

Page 64: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

提取左公因子的例子

S → +id | -id | T+(id)| T-(id) | -(id) | T-idT → (id) × T | (id)

S → M id | TME | −E | T-idT → E × T | EE → ( id )M → + | −

文法:

观察:文法中的非终结符E和M都是指终结符,因此,可将其置换

S → +id S → -id S → T+(id)S → T-(id) S → -(id)S → T-id

T → (id) × TT →(id)

T是以“(”开头

Page 65: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

提取左公因子的例子(cont.)

S → +id S → -id S → T+(id)S → T-(id) S → -(id)S → T-id

T → (id) × T T →(id)

S → +id S → -P S → TQ

P → id | (id)Q →+(id) | -(id) | -id

T → (id) R

R → × T |

Q →+(id) Q →-N

N →(id) | id

Page 66: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

随堂测试1

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

id + id * id

已知文法G:

对于输入串自顶向下的语法分析,写出每一步推导。

Page 67: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下、最左推导的语法分析中遇到的问题之三:有多个产生式可选,到底选哪个?

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

id + id * id E

id

+T E'

*

T

F

F T'

id ε F T'

id

E'ε

T'ε

已知文法G: 对于串 其语法分析树:

推导时,对一个非终结符,当有多个产生式供选择时,到底选

择哪一个产生式呢?

Page 68: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

观察与分析:寻求解决问题的突破口

选择F→ (E) ,还是F→id呢?E

T E'

F T'?

当前输入符与F→id匹配,不与F→ (E)

匹配,自然只能选F→id。

id + id * id

输入串:E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:

Page 69: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

观察与分析:寻求解决问题的突破口

E

T E'F T'id ?

是选择T'→ * F T' ,还是T'→ ε呢?

选T'→ * F T' 不行,因为当前输入符'+'与该产生式的第一个符号'*'不匹配。选T'→ε行吗?

id + id * id

输入串:E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:

Page 70: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

观察与分析:寻求解决问题的突破口

E

T E'F T'id ?

不能选T'→ * F T',那么选T'→ε行吗?

可行的条件是紧随T'之后的E’在推导后,其第一个终结符必须

是'+', 来与当前输入符'+'匹配。

id + id * id

输入串:E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:

引出了求FOLLOW(T')的idea.

Page 71: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

观察与分析:寻求解决问题的突破口

id + id * id

输入串:E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:

选择E' → +TE' 还是E' → ε呢?

E

T E'F T'id ε

Page 72: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

对接下来的推导步的观察

E

+T E'

TF T'

id ε F T'E'

选择F→ (E) 还是F→id呢?

id + id * id

输入串:E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:

Page 73: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

E

+T E'

TF T'

id ε F T'E'

选择T'→ * F T' 还是T'→ ε呢?

?id

对接下来的推导步的观察

id + id * id

输入串:E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:

Page 74: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

E

+T E'

*

T

F

F T'

id ε F T'

id

E'ε

T'ε?

选择F→ (E) 还是F→id呢?

对接下来的推导步的观察

id + id * id

输入串:E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

文法:

Page 75: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

对刚才观察进行归纳与提升:形式化处理

选择A的哪一个产生式?是问题的关键。

对于A→和 A→β, FIRST()的含义是从推导得到的串的第一

个终结符的集合

对于A→和 A→β, 如果FIRST() FIRST(β) = , 那么只要查

看下当前输入符a,是在FIRST()中, 还是 在FIRST(β)中,就

知道要选A→ 还是A→ β。

对于A→和 A→, FOLLOW(A)是指紧跟在A后面的终结符号的

集合。如果当前输入符a在FOLLOW(A)中,又不在 FIRST()中,

就可选A→

Page 76: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FIRST()和FOLLOW( )的求法

开始符号S

终结符号

第1层非终结符号

第2层非终结符号

第n层非终结符号...FIRST() FOLLOW( )

语法分析树推导完成,输入串的末尾符也已匹配完毕,当前输入

符自然为'$', 因此FOLLOW(S) += {$};

初始时:所有产生式:FIRST()=, 所有非终结符:FOLLOW( )=;

Page 77: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FIRST()求法:对非终结符号,由低到高排序,逐一扫描其产生式, 计算每一产生式的FIRST()

算法:对于A→X1X2...Xn。

ε_stand = true;i = 1;while (ε_stand AND i ≦ n) { FIRST() += FIRST(Xi) - ε if εFIRST(Xi) then ε_stand = false; else i++;}if (ε_stand AND i == n+1) then FIRST() += ε ;

F→id FIRST(F) = {id}F→ (E) FIRST(F) = { ( }T'→ε FIRST(T') = { }T'→ * F T' FIRST(T') = { * }T→ FT' FIRST(T) =FIRST(F) ={id, ( }E' → ε FIRST(E') = { }E' → +TE' FIRST(E') = { + }E→ TE' FIRST(E) =FIRST(T) ={id, (}

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

Page 78: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

当一个非终结符号C有多个产生式时:A→1,...., A→n,FIRST(C)=FIRST(1) ...FIRST(n)

F→id FIRST(F) = {id}F→ (E) FIRST(F) = { ( }T'→ε FIRST(T') = {}T'→ * F T' FIRST(T') = {*}T→ FT' FIRST(T) =FIRST(F) = {id, ( }E' → ε FIRST(E') = {}E' → +TE' FIRST(E') = {+}E→ TE' FIRST(E) =FIRST(T) = {id, (}

FIRST(F)={ id, ( }

FIRST(T')={ *, }

FIRST(E')={ +, }

Page 79: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FOLLOW()求法

对于产生式:A→BC,

FOLLOW(C) += FOLLOW(A);

FOLLOW(B) += FIRST(C) - ,

如果ε FIRST(C), 那么进一步有FOLLOW(B)+=FOLLOW(A);

算法:

对非终结符,由高到低依次排序;

然后逐一计算每个非终结符的FOLLOW()。设当前非终结符

为C,对右部含C的所有产生式,分别计算FOLLOW(C).

Page 80: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FOLLOW()求法举例(cont.) 文法: FIRST(E) ={(,id}

FIRST(E') = {+, ε};FIRST(T) = {(,id}FIRST(T')={*, ε}FIRST(F) = {(, id}

非终结符由高到低排序为: E, E', T, T', F:

1)计算FOLLOW(E), 右部含E的产生式有:F→ (E)由F→ (E) FOLLOW(E) += { ) } = { ), $ };

2)计算FOLLOW(E'), 右部含E'的产生式有:E→ TE',E' → +TE':由E→ TE' FOLLOW(E') += FOLLOW(E)={ ), $ }由E' → +TE' FOLLOW(E') += FOLLOW(E'),没意义;

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

Page 81: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FOLLOW()求法举例(cont.)

3)计算FOLLOW(T), 右部含T的产生式有:E→ TE',E' → +TE':

由E→ TE' FOLLOW(T) += FIRST(E') - = {+}因FIRST(E') FOLLOW(T) += FOLLOW(E) = { +, ), $}

由E' → +TE' FOLLOW(E') += FIRST(E') - ,在上面已处理

因FIRST(E') FOLLOW(T) += FOLLOW(E') = { +, ), $ }

文法: FIRST(E) ={(,id}FIRST(E') = {+, ε};FIRST(T) = {(,id}FIRST(T')={*, ε}FIRST(F) = {(, id}

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

Page 82: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FOLLOW()求法举例(cont.)

4)计算FOLLOW(T'), 右部含T'的产生式有T→ FT' , T'→ * F T',

由T→ FT' FOLLOW(T') += FOLLOW(T) = {+, ), $}

由T'→ * F T' FOLLOW(T') += FOLLOW(T'),没意义

文法: FIRST(E) ={(,id}FIRST(E') = {+, ε};FIRST(T) = {(,id}FIRST(T')={*, ε}FIRST(F) = {(, id}

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

Page 83: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FOLLOW()求法举例(cont.)

5)计算FOLLOW(F), 右部含F的产生式有T→ FT' , T'→ * F T':

由T→ FT' FOLLOW(F) += FIRST(T') - = { * }

因FIRST(T') FOLLOW(F) += FOLLOW(T) = {*,+ , ), $}由T'→ * F T' FOLLOW(F)+= FIRST(T')-,在上面已处理

因FIRST(T') FOLLOW(F) += FOLLOW(T') = {*, +, ), $}

文法: FIRST(E) ={(, id}FIRST(E') = {+, ε};FIRST(T) = {(,id}FIRST(T')={*, ε}FIRST(F) = {(, id}

E→ TE'E' → +TE' | εT→ FT'T'→ * F T' | εF→ (E) | id

Page 84: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FIRST()和FOLLOW( )在推导决策中的作用

对于产生式:A→和A→

id + id * id

当前符a

输入串:

FIRST() FIRST(β) = aFIRST(): 选A→aFIRST(β): 选A→β

FIRST() FOLLOW(A )= aFIRST(): 选 A→aFOLLOW(A): 选A

注意:FIRST():由A的产生式A→决定;

FOLLOW(A): 与A的产生式无关,只与右部中含A的产生式有关

对于产生式:A→和A→β

Page 85: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

推导决策的推广延伸

对于非终结符A的所有产生式:A→1,A→2,...., A→n

仅只存在两种情形:

1,1,...,n都不为;

1,1,...,n中仅只一个为;设n=

FIRST(1) FIRST(2) ... FIRST(n) =

aFIRST(i): 选A→i , 1≦i≦n

FIRST(1) FIRST(2) ... FIRST(n-1) FOLLOW(A )=

aFIRST(i): 选 A→ i, , 1≦i≦n-1

aFOLLOW(A): 选A

Page 86: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

FIRST()和FOLLOW( )的用途—— 换一种说法

对于产生式:A→ | β p = id + id * id;

当前输入符a

输入串

aFIRST() OR (εFIRST() and aFOLLOW(A))

自顶向下的语法分析中,设当前输入符为a,要推导的非终结符A:

产生式A→能被选用的条件为:

Page 87: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

文法G不是LL(1)文法的条件

对于文法G,有产生式A→ | β,如果FIRST() FIRST(β) ,

就无法决策选A→ 还是A→β,那么G就不是LL(1)文法。

对于文法G,有A→和A→,如果 FIRST() FOLLOW(A )

就无法决策选A→ 还是A→,那么G就不是LL(1)文法。

Page 88: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

LL(1)预测分析表

非终结符输入符

id + * ( ) $

E E→TE' E→TE'E' E'→+TE' E'→ε E'→εT T→FT' T→FT'T' T'→ε T'→*FT' T'→ε T'→εF F→id F→(E)

E→ TE'E' → +TE' E' →εT→ FT'T'→ * F T'T' → εF→ (E) F→ id

A→能被选用条件:aFIRST() OR (εFIRST() and aFOLLOW(A))

FOLLOW(E) = {),$}FOLLOW(E') = {),$}FOLLOW(T) = { +, ), $}FOLLOW(T') = {+,), $} FOLLOW(F) = {*, +, ),$}

FIRST(E) ={(, id}FIRST(E') = {+, ε};FIRST(T) = {(,id}FIRST(T')={*, ε}FIRST(F) = {(, id}

Page 89: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

判断文法G是不是LL(1)文法的判别

非终结符输入符

id + * ( ) $

E E→TE' E→TE'E' E'→+TE' E'→ε E'→εT T→FT' T→FT'T' T'→ε T'→*FT' T'→ε T'→εF F→id F→(E)

LL(1)预测分析表中的某个格子(cell)中,如果有两个产生式,

那么就存在产生式选取冲突问题,说明这个文法就不是LL(1)

文法。

Page 90: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

对FIRST( )和FOLLOW( )的认识

FIRST(), FOLLOW()都是刻画文法特征的一种人为定义,其值

与输入串无关。仅只有在对输入串进行语法分析时,才与当前输

入符关联起来。

FIRST(A):由A的产生式(即左部为A)决定;

A可能有多个产生式:A→1,A→2,...., A→n

然后求:FIRST(A)= FIRST(1)FIRST(2) ...FIRST(n)

对于A,有用的是:FIRST(1), FIRST(2), ..., FIRST(n)

FIRST(A)的作用仅仅是为了随后求FIRST(X),FOLLOW( )

要用到.

FIRST(A)指所有可能的情况下,得到的结果的集合。

Page 91: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

对FIRST()和FOLLOW()的认识(cont.)

FOLLOW(A):向前看符号,针对文法,而不是针对输入串。

注意:指所有可能的情况下,得到的结果的集合。

FOLLOW(A): 与A的产生式无关,只与左部中含A的产生式有

关。

Page 92: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

对LL(1)预测分析表的认知

非终结符输入符

id + * ( ) $

E E→TE' E→TE'E' E'→+TE' E'→ε E'→εT T→FT' T→FT'T' T'→ε T'→*FT' T'→ε T'→εF F→id F→(E)

预测分析表是从文法得出的,是元信息。

表中的某个格子中,如果有不止一个产生式,那么

该文法就不是LL(1)文法。

预测表解决了产生式的选择问题。

Page 93: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下的语法分析

语言的文法中,每个非终结符号:有一个过程(函数)。首先调用开始符号A的过程:void A() { 选择A的某个产生式:A→X1X2...Xk; for i = 1 to k) { if (Xi是一个非终结符) 调用Xi( ); if (Xi == 当前的输入符号a) 读入下一个输入符号; else 发生了一个错误,错误处理; }}

E

id

+T E'

*

T

F

F T'

id ε F T'

id

E'ε

T'ε

Page 94: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

基于栈的自顶向下语法分析

E

id

+T E'

*

T

F

F T'

id ε F T'

id

E'ε

T'ε

E E' T

E' T' F

E' T'

E' E' T +

E' T' F

E' T' F

E' T'

E' T' F *

Page 95: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

预测分析中的错误恢复

• 错误恢复

– 当预测分析器报错时,表示输入的串不是句子。

– 使用者希望预测分析器能够进行恢复处理后继续语法分析过

程,以便在一次分析中找到更多的语法错误。

– 恢复可能不成功,之后找到的语法错误可能是假的。

– 错误恢复时可用的信息:栈里面的符号,待分析的符号

• 两类错误恢复方法:

– 应急模式(恐慌模式)

– 短语层次的恢复 该部分,学生自己看书,自学!

Page 96: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

总结:自顶向下、最左推导的语法分析LL(1)

对文法作消除左递归,提取左公因子处理,

对每个产生式,计算FIRST();

对每个非终结符号,计算FOLLOW();

填写预测分析表;

判断其是否是LL(1)文法;

对输入串推导出语法分析树;

一定要彻底!

自顶向下最左推导中的问题:对于一个非终结符号,当存

在多个产生式时,推导中选用哪个产生式?

Page 97: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

总结:自顶向下、最左推导的语法分析LL(1)

对文法做消除左递归处理,做提取左公因子处理,都只是形式

上的处理,不会改变文法的语义。

消除左递归和提取左公因子,都会新引入非终结符,增加产生

式,使得语法分析树变复杂,于是语法分析效率降低。

当文法G的产生式中,存在直接或者间接左递归,或者某个非终

结符的产生式存在左公因子时,那么该文法就不是LL(1)文法;

文法G因存在左递归或者左公因子而不是LL(1)文法。对文法G做消

左递归和提左公因子处理后,得到文法G', 可能是LL(1)文法;

Page 98: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

4、自底向上、从左到右的语法分析LR

前面讲完了三个topic:

上下文无关文法;

基于推导的语法分析;

自顶向下、最左推导的语法分析(书上4.4节);

接下来将第四个topic:

自底向上、从左到右的语法分析LR,从书上4.5节开始

Page 99: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

动机:对输入串id + id *id执行最右推导进行观察

*T F

E+E T

idFid

E+T E+T*F E+T*id E+F*id

* F

E+E T

idTF

id

T

E

*T F+E T

id*T F

E+E T

idF*T F

+E TE

+E TE

* F

E+E T

idTF

id

TF

id

* F

E+E T

idTF

id

TF

E+id*id T+id*id F+id*id id+id*id

Page 100: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下:最左推导与最右推导对比

E

+T E'

*

T

F

F T'

id ε F T'

id

E'ε

T'ε

id + id * id输入串:

id

* F

E

+E T

idT

Fid

T

Fid

最左推导 最右推导

树不简洁,繁杂;

切合实际:对输入串,基于从左到右逐一匹配,来推导

树简洁;

不切合实际:基于从右到左逐一匹配,来推导

question: 两者的优点能不能两者兼得?

Page 101: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

自顶向下:最左推导对比最右推导

E

+T E'

*

T

F

F T'

id ε F T'

id

E'ε

T'ε

id + id * id输入串:

id

* F

E

+E T

idT

Fid

T

Fid

最左推导 最右推导

树不简洁,繁杂

原因:消除左递归和提取左公因子,都

引入了新的非终结符号,新的产生式

树相对简洁;

Page 102: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

4.5 自底向上的语法分析

• 执行最右推导

E→ E + T | TT→ T * F | FF→ (E) | id

id + id *id输入串:文法:

Page 103: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

推导:对产生式,用右边代替左边:细化。最右推导。对输入串(id + id *id)

*T F

E+E T

idFid

E+T E+T*F E+T*id E+F*id

* F

E+E T

idTF

id

T

E

*T F+E T

id*T F

E+E T

idF*T F

+E TE

+E TE

* F

E+E T

idTF

id

TF

id

* F

E+E T

idTF

id

TF

E+id*id T+id*id F+id*id id+id*id

Page 104: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

反过程——自底向上,从左到右的语法分析归约:对产生式,用左边代替右边:归纳。

移入:将当前输入符移到栈中

id+id*id

* F

E+E T

idTF

id

TF

id idid

* F

E+E TTF

TF

栈:

输入串:

id

* F

E+E T

idTF

id

TF

id

+id*id

F

+id*id

归约:将产生式右边从栈中弹出,再将产生式左边非终结符号压到栈中:即左部替换右部

* F

E+E T

idTF

id

T

T

+id*id

E→ E + T | TT→ T * F | FF→ (E) | id

Page 105: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

反过程——自底向上,从左到右的语法分析(2)

* F

E+E T

idTF

id

E

+id*id

* F

E+E T

idTF

id

E+

id*id

移入

* F

E+E T

idTF

E+F

*id

归约

* F

E+E T

idTF

id

E+id

*id

移入

E→ E + T | TT→ T * F | FF→ (E) | id

归约

Page 106: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

反过程——自底向上,从左到右的语法分析(3)

* F

E+E T

idT

E+T

*id

归约

* F

E+E T

idT

E+T*

id

移入

* F

E+E T

idT

E+T*id

移入

Page 107: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

反过程——自底向上,从左到右的语法分析(4)

E+E T

* FT

E+T*F

归约

E+E T

E+T

归约

E

归约

句柄总是出现在栈顶 最右句型

id* FT

E+E T

Page 108: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

把栈与输入串连接起来观察E→ E + T | TT→ T * F | FF→ (E) | id

id + id *id输入串:文法:

idE+T*

E+T*id E+T*F E+T E

*idE+id *idE+F *idE+T

id+id*id移入

+id*idF +id*id +id*idT +id*idE id 规约 规约 规约

id*idE+ 移入 规约

规约 规约

规约 移入

移入 规约

句柄

Page 109: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

概念

idE+T*

E+T*id E+T*F E+T E

*idE+id *idE+F *idE+T

id+id*id移入

+id*idF +id*id +id*idT +id*idE id 规约 规约 规约

id*idE+ 移入 规约

规约 规约

规约 移入

移入 规约

句子句型

最右句型格局:栈+剩余输入串

句柄

Page 110: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

基于移入—规约的语法分析框架

E→ E + T | TT→ T * F | FF→ (E) | id

id + id *id $

移入

输入串:

文法:

当前符

$ 栈: 规约 接受

报错

操作:

? ?

Page 111: 编译原理 Compiler Principles 第四章 语法分析 - hnu.edu.cncsee.hnu.edu.cn/Content/UploadFiles/2004213/Files/...纵观全局 • 语言的规约1:词法单元的模式(串接结构,一维线性结构);词法单元的模式

移入—规约语法分析要解决的问题——冲突

规约/规约冲突

*idE+T

遇到格局:

移入/规约冲突

如何决断?

选移入,还是归约?

选哪个产生式进行归约?

idea:跟踪栈中栈顶句柄的满足程度。句柄没有形成,就移入

解题思路(技术路线):利用DFA

E→ E + T E→T