编译原理复习(4)语法分析--自上而下分析


要进行语法分析,必须对语言的语法结构进行描述。

采用正规式和有限自动机可以描述和识别语言的单词符号;
用上下文无关文法来描述语法规则。

总体任务:

在词法分析识别出单词符号串的基础上,分析并判定程序的语法结构是否符合语法规则。

语法分析器地位:
在这里插入图片描述

语法分析器的功能

输入

Token序列:词法分析产生的输出,是各个单词都正确的源程序,是一个有限序列

功能

按照语言的语法构成规则(文法产生式), 识别输入的符号串能否构成一个句子。
根据文法的产生式规则,从开始符号出发,看能否推导出这个输入串匹配的句子。这就需要建立与输入串匹配的语法分析树。

输出

分析树:如何表示? 
错误处理信息:定位、继续编译

语法分析方法分类

自上而下分析法

从文法的开始符号出发,向下推导(使用最左推导) ,尽可能使用各种产生式,推导出与输入串匹配的句子(为输入串建立一棵语法树)。

递归下降分析、预测分析(LL)

存在问题:

① 分析过程本质是一个试探过程。一个非终结符有多个候选式会带来复杂的回溯问题。
② A → Aα , 会进入死循环。
③ 虚假匹配难消除
④ 效率低
⑤ 不能定位出错位置

所以,使用自顶向下分析,先改造文法,消除左递归和回溯

自下而上分析法

从输入符号串开始,逐步进行归约(最右推导的逆过程),直至归约到文法的开始符号。

算符优先分析
LR分析(LR(0)、SLR(1)、LR(1)、LALR)

LL(1)分析法

左递归的消除

1.直接左递归消除
在这里插入图片描述
在这里插入图片描述
2. 消除左递归
一个文法消除左递归的条件:

不含以ε为右部的产生式
不含回路。

方法过程:
(1)排序:文法所有VN排序,按顺序执行。
(2)替换
在这里插入图片描述
(3)化简(2)所得的文法,去除那些从开始符号
出发永远无法到达的非终结符的产生规则.

例题:
在这里插入图片描述
解:
1)把文法G的所有非终结符按任意顺序排列,并编号

R、Q、S

2)按上面的排列顺序,对这些非终结符进行遍历
3)将当前处理的非终结符中的序号小于等于它的非终结符按规则3)进行替换(序号大于的按规则2)处理)

R:
R的右部中的非终结符有S;
S的下标大于R,可以暂时不处理;
所以此时R改写为:R  →  Sa | a

----------------------------------------------
Q:
Q的右部中的非终结符有R;
R的下标小于Q,将R的右部替换进来;
所以此时Q改写为:Q  →  Sab | ab | b;
S的下标大于Q,可以暂时不处理;
所以此时Q改写为:Q  →  Sab | ab | b;

-----------------------------------------
S:
S的右部中的非终结符有Q;
Q的下标小于S,将Q的右部替换进来;
所以此时S改写为:S  →  Sabc |abc | bc | c
S的下标等于S,可以暂时不处理;
所以此时S改写为:S  →  Sabc |abc | bc | c

4)消除i序号的非终结符的直接左递归(如果存在的话)

S  →  Sabc |abc | bc | c
∴  X = abc,Y = abc | bc | c
∴ 直接消除左递归的结果是:
S  →  abcS' | bcS' | cS'
S'  → abcS' | ε

5)删除其中不可达的非终结符,这里就是Q、R了

∴ 最终消除左递归的结果是

S  →  abcS' | bcS' | cS'
S'  → abcS' | ε

消除回溯,提取公共左因子

回溯产生的真正原因是:

某非终结符对应多个侯选式,它们左边部的第一个终结符相同(公共左因子),从而导致语法分析器选择了错误的侯选式。

消除回溯必须保证:

   对文法的任何非终结符,当要它去匹配输入串时,能够根据它所面临的输入符号准确地指派它的一个候选去执行任务,并且此候选的工作结果应是确信无疑的。

若此候选获得成功匹配,那么,这种匹配决不会是虚假的;
若此候选无法完成匹配任务,则任何其它候选也肯定无法完成。

消除回溯方法:文法,提取公告左因子。

反复使用“提取公共左因子”的方法来改造文法,使得文法的每个非终结符号的各个候选式的首终结符两两不相交,来避免回溯。

FIRST(终结首符集)
在这里插入图片描述

消除回溯,就是:

采用提取左公共因子的方法使得非终结符的每个候选α的FIRST尽量不相交。
求法,例FIRST(X):
若X本身是终结符,则FIRST(X) = {X}
若X是非终结符,把产生式右边第一个是终结符的,全加到FISRT(X)中
若X→Y…是一个产生式且Y∈VN, 则把FIRST(Y)中的所有非ℇ元素都加到FIRST(X)中
若X→Y1Y2…Yk是一个产生式,Y1,…,Yi-1都是非终结符,而且对于任何j,1≤j≤i-1,FIRST(Yj)都含有ℇ(即Y1…Yi-1⇒ ℇ )*,  则 FIRST(Yj)中的所有非ℇ—元素都加到FIRST(X)中
特别是,若所有的FIRST(Yj)均含有ℇ ,j=1,2,…,k,则把ℇ加FIRST(X)中。

FOLLOW(后随符号集)
在这里插入图片描述
当非终结符A面临a时, 且a不属于A的任何侯选FIRST集,但A的某个候选FIRST中含ε,只有当a ∈ FOLLOW(A)时才能自动进行匹配。

FOLLOW集构造方法:

(1)对于文法的开始符号S, 置#于FOLLOW(S)中;
(2)若A→αBβ是一个产生式,
则把FIRST(β){ℇ}加至FOLLOW(B)中;
(3)若A→αB是一个产生式 ,
或A→αBβ是一个产生式而β⇒ℇ(即ℇ∈FIRST(β)),
则把FOLLOW(A)加至FOLLOW(B)中。

LL(1)文法

对于一个LL(1)文法,可以对其输入串进行有效的无回溯的自上而下分析。

判断条件:

(1)文法不含左递归(产生式右边的最左为非终结符)
(2)任一个非终结符的各个产生式的候选FIRST集两两不相交
(3)每个非终结符A,若它的某个候选FIRST集有ε,则
			FIRST(A) ∩ FOLLOW(A) =  空集

预测分析表每个项目最多只有一个产生式,也可以判断是LL(1)文法。

LL(1)的含义:

第一个L是指从左至右扫描输入串;
第二个L是最左推导;
1代表分析时每一步只需向前查看一个符号。

LL(1)文法的自上而下分析

有效的无回溯的。
在这里插入图片描述
对非终结符A进行匹配,此时面临的输入符号为a:
(1)若a∈first( αi ),则指派αi去执行匹配任务;

(2)若a不属于任何一个候选首符集,则
若ℇ∈first( αi ),且a∈follow(A),则让A与ℇ自动匹配;
否则,a的出现是一种语法错误.

递归下降分析程序构造

实现思想

对应文法中每个非终结符编写一个递归过程,
每个过程的功能是识别由该非终结符推出的串,
当某非终结符的产生式有多个侯选时,
能够按LL(1)形式可唯一地确定选择某个侯选进行推导。

基本构造方法

基本构造方法:

对文法的每个非终结符号,
都根据其产生式的各个候选式的结构,
为其编写一个对应的子程序(或函数),
该子程序完成相应的非终结符对应的语法成分的识别和分析任务.

子程序功能:

对某个非终结符,用规则的右部符号串去匹配输入串。
分析过程是按文法规则自上而下
一级一级地调用有关子程序来完成

ADVANCE / SYM / ERROR

ADVANCE:把输入串指示器IP指向下一个输入符号,
即读入一个单字符号
SYM: IP当前所指的输入符号
ERROR,出错处理子程序

例:
在这里插入图片描述

   PROCEDURE  F;
   IF SYM=‘i’ THEN ADVANCE
   ELSE
	   IF SYM=(’ THEN
	   BEGIN
	       ADVANCE;
		 E;
		 IF SYM=)’ THEN ADVANCE
		     ELSE ERROR
	   END
	   ELSE ERROR;
主程序:
PROGRAM PARSER;
BEGIN
    ADVANCE;
    E;
    IF SYM <>’#’ THEN 
        ERROR
END;

扩充的巴科斯范式:
在元符号 ” → “ 或 “ ::= ” 和 “ | ” 的基础上:
{α} 表示 a* (闭包运算)
{α}0n 表示: 可任意重复 0 到 n 次。 0跟n 可以随意改
[α] 表示: α | ε

语法图

在这里插入图片描述

优缺点

优点:

简单直观,易于构造.

缺点:

(1)对文法要求高,必须满足LL(1)文法;
(2)由于递归调用多,所以速度慢占用空间多.

预测分析程序

预测分析器模型:
在这里插入图片描述分析表——M[A,a]形式的矩阵表示

矩阵元素M[A,a]存放内容:一条A的产生式或出错标志;
矩阵元素—实际是相应的分析动作
(即所选用的推导的产生式)。

分析栈——用于存放分析过程中的文法符号。

总控程序

功能:
	依据分析表和分析栈联合控制输入字符串的识别和分析,  
  	它在任何时候都是根据当前分析栈的栈顶符号X和当前的
  	输入字符a来执行控制功能。

构造分析表的方法

(1)对每个A → α,执行第2步和第3步;
(2)对每个终结符 a ∈FIRST(α),把A → α加至M[A,a]中;
(3)若ε∈FIRST(α),则对任何b ∈FOLLOW(α),把   A  → α加至M[A,b]中;
(4)把所有无定义的位置上标上“出错标志”。

预测分析过程

初始化:依次把’#’和文法开始符号压入分析栈,
     栈顶符号X 将输入串第一个符号读入a;
(1)若X = a = ' # ' 分析成功,停止分析
(2)X = a ≠ ’ # “ ,X从栈顶弹出,a指向下一个输入符号
(3)若X是一个非终结符,查看分析表。
		M [X , a] 存放着一个关于X的产生式,X弹出栈顶,产生式右部符号串按反序,压入栈(若右部是ε,只弹出,不压入)

贴个链接:
构造FIRST跟FOLLOW集
https://blog.csdn.net/qq_42583263/article/details/105813689?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162479844116780261985404%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162479844116780261985404&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-2-105813689.first_rank_v2_pc_rank_v29_1&utm_term=follo%E9%9B%86%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95&spm=1018.2226.3001.4187

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值