第四章 自顶向下语法分析方法
作者:@cherish.
课程学习内容为作者从学校的PPT处摘抄,仅供自己学习参考,若需转载请注明出处:https://www.cnblogs.com/cherish-/p/16375121.html
自顶向下语法分析方法
确定的自顶向下语法分析思想
-
从分析树的顶部(根节点)向底部(叶节点)方向构造分析树,可以看成是从文法开始符号推导出词串的过程。
-
每一步推导中,都需要做两个选择
- 替换当前句型中的那个非终结符
- 用该非终结符的那个候选式进行替换
-
非终结符的选择:最左推导(left most)
- 总是选择每个句型的最左非终结符进行替换
-
候选产生式的选择
- 根据输入流中的下一个终结符,选择最左非终结符的一个候选式
- 不确定的自顶向下:穷举产生式
- 确定的自顶向下:选择唯一可能推导出输入串的规则进行推导
FIRST()-串首(终结)符号集
定义:设文法,则
特别地,,约定。
- 同一非终结符的多个产生式,若右部的
FIRST
集无交集,则推导是确定的。
【例】
设文法,则
FIRST(Ap) = {c , a}
FIRST(Bq) = {d , b}
FIRST(cA) = {c}
FIRST(A) = {c , a}
FOLLOW(A)-非终结符的后继(终结)符号集
定义:设文法,则
或者;若或者上述模式中的,则句末符。
FOLLOW(A)
是由任意句型中紧邻非终结符号之后出现的终结符号组成的集合。- 如果对非终结符,有一条空规则,则的
FOLLOW
集合和的非空右部的FIRST
集合两两相交为空,可以使用确定的最左推导。
【例】
SELECT(A )-产生式的可选集
使用统一的方法来选择使用规则,即当某规则右部能推导出空时,将其FIRST
和FOLLOW
这两个集合合并考虑,以确定在什么情况下选择该规则。
定义:设文法,则
称为规则的选择集,它是和组成,是终结符号集的子集。
LL(1)文法
定义:文法是的,当且仅当对每个的两个不同产生式,满足,其中不能同时推导出。
L
——Left to right parsing 从左至右分析token;L
——Left-most derivation 最左推导;1
——只需向右看1
个符号便可以决定选择那个产生式进行推导。- 确定的,无二义的。
LL(1)文法的判别
判别依据:依定义,文法是的,当且仅当任意两个左部相同的产生式其SELECT
集的交集为空。
若存在非终结符的多个产生式,必须计算SELECT()
集。
为此,需要:
- 判别,仅当中所有非终结符全部可推导出空,且无非空的终结符;
- 求产生式右部
FIRST
集,若产生式右部可推导出,则还需要计算产生式左部FOLLOW
集。
以下的各种计算,应当视为一般性算法,而不是判别该文法的必需步骤
判定非终结符是否能推出空串
以文法为例;建立如图所示的表:
- 的非终结符,直接标记
Yes
,并划掉其所有产生式; - 若干一个非终结符的所有产生式右侧至少有一个非的终结符,它就不可能推导出。直接标记为
No
,并划掉其所有产生式。剩下的产生式中,但凡右侧有一个非的终结符,也不可能推导出。这样的产生式也划掉。 - 在余下的产生式中,把所有能的非终结符,替换成。化简,结果为的,标记为
Yes
,否则标记为No
。
求FIRST(X)的算法
假定。
-
若;
-
若;
-
对于所有形如规则,且;
-
对于所有形如规则,:
如果,则;
如果,则;
-
重复步骤4,直到不再扩大为止。
求FIRST()的算法
前提:。
,置。计算:
-
如果,则;
-
如果则
-
如果则
求FOLLOW(A)的算法
- 置;置;
- 若有产生式,则;
- 若有产生式或,且,则;
- 重复2、3,直到不再扩大为止。
非LL(1)文法到LL(1)文法的等价变换
非LL(1)文法:
- 若文法含有左公共因子,一定不是
LL(1)
文法 - 若文法含有直接或间接左递归,一定不是
LL(1)
文法
非文法文法的等价变换:
- 提取左公共因子
- 消除左递归
- 消除直接左递归
- 消除间接左递归
提取左公因子
- 对形如进行等价变换为:,进一步变换为:;
- 对形如进行等价变换为:;
- 注:若中仍含左公共因子,再次提取,直至所有的产生式不再有左公共因子。
【例】
文法中不含左公共因子只是文法的必要条件
- 文法一定不含有左公共因子
- 不含左公共因子的文法不一定是文法
递归文法
设文法,形如的规则称为文法的直接递归规则。特别地,如果时则称为文法的直接左递归规则。如果时,则称为文法的直接有递归规则。
设文法,如果存在推导,则规则称为文法的间接递归规则。特别地,如果时则称为文法的间接左递归规则。如果时,则称为文法的间接有递归规则。
- 递归规则,左递归规则,右递归规则
- 递归文法,左递归文法,有递归文法
消除直接左递归:
- 把直接左递归改为右递归
- 如,;
- 改为:;
【例】
消除间接左递归:
- 间接左递归 直接左递归右递归
消除文法中一切左递归的算法(无有害规则,无空产生式)
将中的(非终结)符号按任意顺序线性排列,如,
for(i = 1 ; i <= n ; ++i){
for(j = 1 ; j <= i - 1 ; ++j){//以A1 , A2 , ... , Ai-1的产生式代入Ai产生式
若Ai的产生式为: Ai → δ1|...|δk
则形如Ai → Ajλ的产生式变为:Ai → δ1λ|...|δkλ
}
消除Ai的直接左递归
}
删除无用产生式
【例】
递归下降分析法
基本思想:
- 将每个非终结符编写成一个递归子程序,完成选择规则、推导和匹配的功能;
- 若非终结符有多个产生式,则根据产生式的
SELECT
集选择相应的规则推导,对规则依次调用右部非终结符的子程序或匹配终结符,为非终结符则调用对应的子程序,若为终结符,则与当前token
匹配。匹配成功则调用词法分析程序取下一个token
,匹配失败或当前token
不属于任何SELECT
集时,报告语法错误。 - 按照递归子程序法构造的语法分析程序是由一个总控子程序和一组非终结符对应的递归子程序组成的。
表驱动分析法
- 输入栈:以串末端为底,栈内为未匹配部分;初始状态为,为要是别的串;
- 分析栈:推导过程产生的句型未匹配部分;初始状态为;
- 分析表:若,则;
- 输出:的最左推导或报告语法错误。
【例】
作者:cherish.
出处:https://home.cnblogs.com/u/cherish-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)