编译原理----算符优先级的分析(自底向上)

简介: 编译原理----算符优先级的分析(自底向上)

自底向上分析的分类如下所示:

算符优先关系表的构造

算符优先分析只规定算符之间的优先关系,也就是只考虑终结符之间的优先关系。

(一)若有文法G,如果G没有形如A->..BC..的产生式,其中B和C为非终结符,则称G为算符文法。

以下例子中G就是算符文法(没有连在一起的非终结符)

E->T|E+T|E-T

T->F|T*F|T/F

F->(E)|i

(二)



这里就用=,< 和 > 代替:


(1)a=b,当且仅当G中含有形如A--->..ab...或A---->...aBb...的产生式


(2)a<b,当且仅当G种含有形如A--->...aB...的产生式,且B能多步推导出右侧式子



(3)a>b,当且仅当G中含有形如A--->...Bb...的产生式,且B能多步推导出右侧式子



这里理解起来也很简单,a<b,那么a就要小于B推导出的式子中最前面的终结符b,a>b同理


这里的推导较为复杂,我们可以演化出下面这一方法:



这样a<b,a>b的定义就为:


a<b,当且仅当G种含有形如A--->...aB...的产生式,且a小于B的FIRSTVT集合中的所有终结符


a>b,当且仅当G中含有形如A--->...Bb...的产生式,且B的LASTVT的所有终结符大于b

构造规则:


FIRSTVT:


(1)若有T->a...或T->Ra...,则aFIRSTVT(T)


(2)若有aFIRSTVT(R),且有产生式T->R...,则aFIRSTVT(T)


LASTVT:


(1)若有T->...a或T->...aR,则aLASTVT(T)


(2)若aLASTVT(R),且产生式T->...R,则aLASTVT


(三)设有一个不含产生式的算符文法G,如果任一终结符对(a,b)之间至多只有<,>,=3种关系种的一种成立,则称G是一个算符优先文法。即,两个终结符之间的优先关系是有序的,允许有a>b,b<a同时存在,但是不允许有a<b,a>b,a=b3种关系中的任一两种关系同时存在。


示例:

FIRSTVT集合:


(1)首先根据E->E+T|T的E->E+T,可得(注:行代表终结符,列代表非终结符)



(2)再看E->E+T|T 的E->T,需要把T的FIRSTVT元素放到E中,但是此时T中没有✔元素,所以



(3)T->T*F|F中的T->T*F



(4)T->T*F|F中的T->F,而F没有✔项



(5)F->(E)|i 中的F->(E)



(6)F->(E)|i 中的F->i



这是第一遍遍历式子,因为表有变化,所以要继续进行遍历,直到表不变

(1)首先根据E->E+T|T的E->E+T,可得



(2)再看E->E+T|T 的E->T,需要把T的FIRSTVT元素放到E中



(3)T->T*F|F中的T->T*F



(4)T->T*F|F中的T->F,将F中的✔项放到T中



表依旧有改变,继续遍历,直到没有出现新的内容



所以得出结论:

E(FIRSTVT)={+,*,{,},i}


T(FIRSTVT)={*,(,i}


F(FIRSTVT)={(,i}

LASTVT的操作步骤同理,得到:



接下来继续回到算符优先关系中


竖列表示在前面的终结符,横列表示在后面的终结符



针对a=b


F->(E)|i,这里的“(”和“)”遵循a=b的定义,即A->..aBb...



针对a<b,就是要找到a后面跟的非终结符,这个非终结符中的FIRSTVT集合的元素就是满足要求的元素。


E->E+T|T中的+T,T(FIRSTVT)= {*,(,i}


T->T*F|F中的*F,F(FIRSYVT) = {(,i}


F->(E)|i中的(E,E(FIRSTVT)= {+,*,{,},i}



针对a>b,就是要找到a前面跟的非终结符,这个非终结符中的LASTVT集合的元素就是满足要求的元素:


E->E+T|T中的E+


T->T*F|F的T*


F->(E)|i 的E)

最终得到:

总结:

对于a<b,就要找终结符后面的非终结符(*F)的FIRSTVT集合(F的FIRSTVT集合)

对于a>b,就要找终结符前面的非终结符(F*)的LASTVT集合(F的LASTVT集合)

构造优先函数

例如:

其的优先函数为:这里假设列为f,行为g,接着由大的指向小的

构造优先函数表

对应的优先函数表如图所示,这里的数字代表的是可经过的结点数:

f+从f+出发,算一个经过的节点,再到g+,也算一个经过的节点,所以总数为2

f*可以经过以下4个节点

目录
相关文章
|
29天前
|
算法
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
|
4月前
|
自然语言处理 算法 编译器
编译原理复习四:编译器结构 消除左递归、左公因子 最右推导 寻找句柄讲解(附题目和答案)
编译原理复习四:编译器结构 消除左递归、左公因子 最右推导 寻找句柄讲解(附题目和答案)
131 0
|
开发工具
彻底搞清游戏开发中的循环逻辑
循环是游戏开发中一定会用到的逻辑,不论是你想控制移动,或者进行遍历,亦或者不停的去执行某一段逻辑,都需要使用循环。那么对于循环的使用你彻底了解了吗?今天这篇文章就帮助你彻底的弄懂微信小游戏开发中的循环的用法。
155 0
|
算法
算法设计与分析/数据结构与算法实验4:添加括号数目问题
算法设计与分析/数据结构与算法实验4:添加括号数目问题
172 0
算法设计与分析/数据结构与算法实验4:添加括号数目问题
|
数据可视化 算法
大白话理解递归本质,可视化递归过程
大白话理解递归本质,可视化递归过程
196 0
|
存储 算法
经典算法---算法概念引入
任何被明确定义的计算过程可以称作算法,它将某个值活一组值作为输入,并产生莫格值或一组值作为输出。所以算法可以被称作将输入转为输出的一系列的计算步骤。 这样的概况是比较抽象和标准的,其实说白了就是步骤明确的解决问题的方法。由于是在计算机中执行,所以通常先用伪代码表示,清晰的表达出思路和步骤。这样真正执行的时候,就可以使用不同的语言来实现出相同的兄啊过给。 概况的说,算法就是解决问题的工具。在描述一个算法时,我们关注的是输入与输出。也就是说只要把原始数据和结果描述清楚了,那么算法所作的事情也就清楚了。
经典算法---算法概念引入
|
机器学习/深度学习 存储 算法
算法系统学习-牛刀小试几个小Case(非递归算法)
该系列是基于有一定语言基础(C,C++,Java等等)和基本的数据结构基础进行的算法学习专栏,如果觉得有点吃力 😥 ,建议先了解前提知识再学习喔!本个专栏会将用更容易理解的表达去学习算法,如果在一些表述上存在问题还请各位多多指点
114 0
|
存储 缓存 Java
详解降低确定「记忆化容器大小」的思维难度 & 利用「对偶性质」构造有效状态值|Java 刷题打卡
详解降低确定「记忆化容器大小」的思维难度 & 利用「对偶性质」构造有效状态值|Java 刷题打卡
|
算法
算法----编程之魂
为什么各大公司那么重视算法呐,在考察员工是否合格时,数据结构,算法尤为看的重要呐,刚开始,我不懂,后来,我懂了 懂了,因为效率,编程的性能的提高需要算法,你编程的性能提不高,就是垃圾。
1115 0