消除无用符号和空产生式

  • 消除无用符号
  • 消除空产生式
  • 消除单一产生式
  • 消除左递归

消除无用符号

消除无用符号算法:
对于任意上下文无关文法G=(V,T,P,S),w∈L(G),X∈V,若存在a,b∈(VUT)*使得S经过若干步推出aXb,aXb经过若干步推出w,则称X为有用符号,否则为无用符号。

  1. 首先计算“产生的”符号集N:每个T中的符号都是产生的,若A→a∈P且a中符号都是产生的,则A是产生的。
    伪代码:
for (int i=0;i<V.num;i++)for(int j=0;j<v.num;j++)//v表示V的拷贝if(p中存在v[j] →a&&a中的每个符号都属于N){将v[j]从v中删除并加到N中,同时跳出内层循环}
  1. 接着计算“可达的”符号集M:开始符号S是可达的,A→a∈P且A是可达的,则a中的符号都是可达的。
    伪代码:
Reach(S){if(P中存在S→a){将a中的所有字符加入到M中,if(a中存在非终结符B)Reach(B)}return }
  1. 最后先消除全部非“产生的”符号,在消除全部非“可达的”符号,剩下的都是有用符号。最后将无用字符和无用产生式都删除
    伪代码:
for(int i=0;i<Q.num;i++){//Q是VUT的集合for(int j=0;j<N.num;j++){if(Q[i]不在N中)将其加入到非“产生的”符号集N1中}}
//  消除全部非“可达的”符号
for(int i=0;i<N1.num;i++){for(int j=0;j<M.num;j++){if(N1[i]不在M中)将其加入到无用符号集NM中}}
//消除产生式和无用符号,因结构类似只写了一个
for(int i=0;i<P.num;i++){if(P[i]个产生式中含有NM符号集的元素)将该条产生式删除}}

注意产生集和可达集不能颠倒顺序,否则会消除不干净

消除空产生式

消除ε产生式:称形如A→ε的产生式为ε产生式。
思路:

  1. 由文法推出满足定义(A∈V,且A能在有限步推出ε)的非终结符集合V1。
伪代码:for(int i=0;i<V.num;i++)for(int j=0;j<V.num;j++){if(左部为V[i]的产生式右部所有符号都在V1中)将V[i]加入V1中,跳出内层循环;
  1. 若产生式B→a0B1…Bkak∈P,其中aj∈(VUT)*,Bi∈V1,那么用ε和Bi本身代替Bi。然后将这些产生式都加入到新的产生式集合中,不满足上述产生式的直接将空产生式扣除后加入到新产生式集合中。若有S→ε,则引入S|→ε|S。S|为新的开始符号。
伪代码:for(int i=0;i<P.num;i++)if(存在产生式B→a0B1...Bkak∈P,aj∈(VUT)*,Bi∈V1)以Bi或者空代替Bi,并将形成的产生式加入到P|中;else if(产生式左部属于V1)将ε产生式去除后将其加入P|中;            else if(若有S→ε)引入S|→ε|S。S|为新的开始符号;}

消除单一产生式

思路:如果存在产生式A→B,则将B作为A的子节点加入图集合X中,若存在B→C,则同样将C作为B的子节点加入到X中。所有的非终结符都进行这样的处理,然后对图集合X进行遍历,所有子节点加入到祖宗节点的链集合中,比如A的子节点有B、C、D,则将B、C、D加入A的链集合中。对于每个非终结符的链集合中若存在非终结符(假设为B),且B→w属于P ,w不属于V,则将A→w加入到P|中。遍历所有的链集合后便完成了单一产生式的消除。

伪代码:
for(int i=0;i<P.num;i++)if(存在单一产生式(A→B))
将B作为A的子节点加入到图中;
遍历图找到每个非终结符的链集合;
遍历每个非终结符的链集合:
如果非终结符的链集合不为空(例如B在A的链集合中):且B→w属于P,w不属于V;将A→w加入到P|中;
如果非终结符的链集合为空则不进行处理。

消除左递归

消除左递归:间接左递归和直接左递归。首先消除间接左递归,转化为直接左递归,在消除所有的直接左递归。

1.消除直接左递归:形如A→Aa。
对于A→Aa|b(b可为空)。因为推导结束后一定有个b在开始位置,故改为:A→bB,B→aB。

2.消除间接左递归:形如:P→Aa,A→Pb。
首先对所有的非终结符进行随机编号排序。
1)若消除过程中出现了直接左递归,就按照直接左递归的方法,来消除。
2)若产生式右部最左的符号是非终结符,且这个非终结符序号大于等于左部非终结符,则暂不处理(后面会处理到)
3)若序号小于左部的非终结符,则用之前求到的式子的右部来替换

伪代码:
所有非终结符按任意顺序排列编号[V1,…,Vn]
按上面的排列顺序,对这些非终结符进行遍历
for(int i = 1; i <= n; ++i) {for(int j = 1; j <= n - 1; ++j) {遍历产生式,若V[j]序号小于等于产生式右部非终结符按规则3)进行替换(序号大于的按规则2)处理) }消除i序号的非终结符的直接左递归(如果存在的话)
}
这里需要注意的是,消除左递归后会产生空产生式和无用符号,
所以消除左递归后需要在将空产生式和无用符号处理一遍。

个人笔记——消除无用符号·消除空产生式·消除单一产生式·消除左递归相关推荐

  1. 消除左递归c++代码_python实现文法左递归的消除

    前言 继词法分析后,又来到语法分析范畴.完成语法分析需要解决几个子问题,今天就完成文法左递归的消除. 没借鉴任何博客,完全自己造轮子. 开始之前 文法左递归消除程序的核心是对字符串的处理,输入的产生式 ...

  2. 自顶向下分析消除左递归的方法

    左递归产生的原因是产生式的左右有相同的非终结符,具体来说就是形如 A→Aα | β 这时自顶向下分析将成为死循环,消除左递归的方法是引入符号A'和ε A→βA' A'→αA' | ε 以上是直接左递归 ...

  3. getchar消除回车符号

    当程序中使用了scanf和getchar,通过键盘输入 "字符串" 后按 "回车",回车会保留在输入缓冲区中,这就会给程序造成影响,那怎么解决呢?我们通过函数g ...

  4. 编译原理-提取左公因子---消除左递归(自己看)

    参考: https://blog.csdn.net/liyun123gx/article/details/19924993 https://blog.csdn.net/hxfghgh/article/ ...

  5. 编译原理 --- 语法分析概念,自上而下分析面临的问题以及如何消除左递归问题

    第一部分 --- 语法分析基本概念 1.上面这个箭头 --> 符号表示的意思是P被 α 定义 A是一个非终止符,γ是一个和α,β属于同一个集合的元素 1.一个双箭头符号表示的是直接推出,而一个双 ...

  6. 【C++实现】编译原理 免考小队 消除一切左递归

    背景 期末考试免考,冲! 实验名称 消除一切左递归 实验时间 2020年5月27日 到 2020年5月31日 院系 信息科学与工程学院 组员姓名 Chocolate.kry2025.钟先生.leo.小 ...

  7. Java黑皮书课后题第7章:7.15(消除重复)使用下面的方法头编写方法,消除数组中重复出现的值。编写一个测试程序,读取10个数,调用该方法,并显示以一个空格分隔的不同数字

    7.15(消除重复)使用下面的方法头编写方法,消除数组中重复出现的值.编写一个测试程序,读取10个数,调用该方法,并显示以一个空格分隔的不同数字 题目 题目描述与运行示例 破题 代码 21.11.11 ...

  8. 消除左递归c++代码_【每日算法Day 85】图解算法:一行代码解决约瑟夫环的变体...

    题目链接 LeetCode 390. 消除游戏[1] 题目描述 给定一个从 到 排序的整数列表. 首先,从左到右,从第一个数字开始,每隔一个数字进行删除,直到列表的末尾. 第二步,在剩下的数字中,从右 ...

  9. 消除文法左递归-编译原理

    下面是消除左递归公式: 下面是对a,B的解释 下面举个例子: 1.把2式带入1式 然后消除左递归: 注意:把1式带入2式也可以.

  10. 编译原理复习四:编译器结构 消除左递归、左公因子 最右推导 寻找句柄讲解(附题目和答案)

    需要原卷和答案请点赞关注收藏后评论区留言私信~~~ 下面对编译原理中一些常见的概念以及算法小题的讲解,这部分可能单独出题考试,也有可能混在大题中出现 一.编译器结构 题目如下 The phases o ...

最新文章

  1. jquery中如何以逗号分割字符串_百度知道
  2. php 位 逻辑,php – 在Laravel中放置菜单逻辑的位置?
  3. 静态页面被拦截解决办法
  4. ios uitableview 积累
  5. 灯火阑珊处,都市夜归人
  6. 经典DOS游戏皇帝攻略(曾经的回忆)
  7. 蓝桥杯官网题库【简单题解析】持续更新
  8. Linux内核开发-入门篇
  9. 《编译学习计划【第一季】》- C语言中的qsort函数
  10. 猎人网吧的游戏更新VBS(转)
  11. 为不同分辨率的手机创建界面
  12. Canvas3——绘制渐变图形与绘制变形图形
  13. 为什么结构方程模型路径系数很大却不显著?
  14. 苹果自带输入法怎么换行_Iphone手机原生输入法的5个技巧,学会了,才知道这么牛...
  15. MySQL | 常见面试题练手及总结
  16. 手机python代码写好了怎么运行-如何优雅的在手机上进行Python编程
  17. 三国志战略版:斩首骑——张辽与王元姬不得不说的故事
  18. Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程
  19. 《架构师杂志》评述:Scott Guthrie
  20. 如何学习网页制作。。。

热门文章

  1. 【rzxt】巧用电池小工具 电量问题全掌握
  2. 织梦个人网站即时到账支付插件
  3. Optical Flares for Mac/win(AE镜头光晕耀斑插件) ​
  4. 【jq练习】层次选择器
  5. PowerVR SDK
  6. speedoffice文档中怎么删除页眉页脚
  7. 如何打开计算机本地组策略编辑器
  8. 【无标题】通信系统的有效性和可靠性
  9. 如何对自己定义的目标进行分解
  10. python 对称加密_常见加密方式及Python实现