编译原理(三)语法分析:5.自上而下语法分析


【编译原理博客列表】》》》》》》


一、自上而下分析的一般方法

1.描述

用推导的方法分析输入序列(记号流):
对任何一个输入序列ω,从S开始进行最左推导,直到得到一个合法的句子或发现一个非法结构。
在推导的过程中,从左到右扫描输入序列,并试图用一切可能的方法,自上而下建立它的分析树。
自上而下分析是一种试探的过程,是反复使用不同产生式谋求与输入序列匹配的过程。
在这里插入图片描述

2.问题

  • 公共左因子:若有A→αβ1|αβ2,则会虚假匹配和大量回溯;造成分析效率低、语义动作难以恢复、以及出错位置的报告不确切等。
  • 左递归:若有A→Aα,则死循环使分析无法进行下去。

二、消除左递归

1.定义

定义3.9
若文法G中的非终结符A,对某个文法符号序列α存在推导A=+>Aα,则称G是左递归的。若G中有形如A→Aα的产生式,则称该产生式对A直接左递归

2.消除直接左递归

(1)算法3.1 消除直接左递归

  • 输入:G中所有的A产生式(含直接左递归)
  • 输出:等价的不含直接左递归的G’
  • 方法:
  1. 首先,整理A产生式为如下形式:
    A A α 1 A α 2 . . . A α m β 1 β 2 . . . β n A→ Aα_1|Aα_2|...|Aα_m|β_1|β_2|...|β_n
    其中αi非空,βj均不以A开始。
  2. 然后用下述产生式代替A产生式:
    A β 1 A β 2 A . . . β n A A → β_1A' |β_2A'| ...|β_n A'
    A α 1 A α 2 A . . . α m A ε A'→ α_1A' | α_2 A' | ... | α_m A' |ε

例如:
考虑: A A α β A→Aα|β ,产生的语言: β α βα*
替换为: A β A A→βA' A α A ε A'→αA'|ε

注意:ε也算,如 A A α β ε A→Aα|β|ε ,替换为 A β A A A→βA'|\textcolor{blue}{A'} A α A ε A'→αA'|ε

(2)例子

例3.17 用算法3.1消除算术表达式文法的直接左递归:
在这里插入图片描述

在这里插入图片描述

2.消除左递归

(1)算法3.2 消除左递归

  • 输入:无回路文法G
  • 输出:无左递归的等价文法G’
  • 方法:
  1. 将非终结符合理排序:A1,A2,…,An;
for i in 2..n 
loop for  j in 1..i-1
	loop
		①用Aj→δ1|δ2|...|δk的右部替换每个形如Ai→Ajγ产生式中的Aj,
		得到新产生式:Ai→δ1γ|δ2γ|...|δkγ;
		②消除Ai产生式中的直接左递归;
	end loop; 
end loop;

核心思想:将左递归产生式(不是直接左递归的非终结符)右部展开(即替换左部)到其他产生式中

注意:若G产生句子的过程中出现A=>+A的推导,则无法消除左递归

(2)例子

例3.18 用算法3.2消除文法S→Aa|bA→Ac|Sd|ε中的左递归。

① 将S的右部展开在A中,得到:
A→Ac|Aad|bd|ε
② 消除新产生式中的直接左递归,得到:
S→ Aa | b
A→ bdA' | A'
A'→ cA' | adA' | ε

三、提取左因子

1.算法3.3 提取文法的左因子

  • 输入:文法G
  • 输出:等价的无左因子文法G’
  • 方法:

重复下述过程,直到所有A产生式候选项中不再有公共前缀

  1. 重排A产生式: A α β 1 α β 2 . . . α β n γ A→αβ_1|αβ_2|...|αβ_n|γ
  2. 并用 A α A γ A→αA'|γ A β 1 β 2 . . . β n A'→β_1|β_2|...|β_n 取代原A产生式。

注意:既有左递归又含左因子?先消除左递归。

2.例子

例3.20 考察悬空else文法:S→iCtS|iCtSeS|aC→b

S→iCtSS'|a
S'→ε|eS
C→b

四、递归下降分析

1.概念

一个非终结符是一个子程序

  1. 直接以程序的方式模拟产生式产生语言的过程;
  2. 每个产生式对应一个子程序,产生式右边的非终结符对应子程序调用,终结符则与输入序列匹配;
  3. 它对文法的限制是不能有公共左因子和左递归
  4. 它是一种非形式化的方法,只要能写出子程序,用什么样的方法和步骤均可。

2.方法

  1. 消除文法中的公共左因子和左递归
  2. 构造文法的状态转换图并且化简
  3. 将转换图转化为EBNF表示;
  4. 从EBNF构造子程序。

(1)文法的状态转换图:每个非终结符对应一个状态转换图

  • 为非终结符A建立一个初态和一个终态;
  • 为A→X1X2…Xn构造从初态到终态的路径,边标记为X1,X2,…,Xn。
  • 根据识别同一集合的原则,化简转换图。

(2)状态图的化简

  • 标记相同的路径可以合并;
  • 标记为A的边可等价为标记ε的边转向A转换图的初态;
  • ε边连接的两个状态可以合并;
  • 不可区分的状态可以合并。

(3)文法的扩展BNF(EBNF)表示

① { }:重复0或若干次(while)
② [ ]:可选择(if或while)
③ |:括弧( )之内的或关系(case)
④ ( ):改变运算的优先级和结合性

3.例

递归下降分析的文法:
L→E;L|ε
E→E+T|E-T|T
T→T*F|T/F|T mod F|F
F→(E)|id|num

(1)消除左递归后的等价文法:

L →E;L|ε
E →TE'
E'→+TE'|-TE'|ε
T →FT'
T'→*FT'|/FT'| mod FT'|ε
F →(E)|id|num 

(2)构造文法的状态转换图并且化简

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

(3)文法的扩展BNF(EBNF)表示

L → { E; }
E → T { (+|-) T }
T → F { (*|/|mod) F }
F → ( E ) | id | num  
发布了411 篇原创文章 · 获赞 144 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/sandalphon4869/article/details/103789192