编译原理:LL(1),LR(0),SLR(1),LALR(1),LR(1)对比

LL(1)定义:一个文法G是LL(1)的,当且仅当对于G的每一个非终结符A的任何两个不同产生式 A→α|β,下面的条件成立:SELECT( A→α)∩SELECT( A→β)=dd,其中,  α|β不能同时 ε.

  解释:LL(1)的意思是,第一个L,指的是从左往右处理输入,第二个L,指的是它为输入生成一个最左推导1指的是向前展望1个符号

  LL(1)文法是上下文无关文法的一个子集。它用的方法是自顶向下的(递归式的处理)。它要求生成的预测分析表的每一个项目至多只能有一个生成式

  上面的定义说的是,任何两个不同的产生式 A→α和 A→β,选择A→α或者 A→β是不能有冲突的,即SELECT( A→α)∩SELECT( A→β)=,具体来说,就是,

  第一:First( A→α) ∩First( A→β)=,首符集不能有交集,否则当交集中的元素出现时,选择哪个产生式进行推导是不确定的,(这其中也包含了α|β不能同时ε,否则交集就是{ε}不为空);

  第二:若任何一个产生式β,有ε属于First(β),应有First(A)∩Follow(A)为空(当ε属于First(β),则A有可能被空串代替,那么就要看A的下一个字符,即Follow集,即要求Follow集和First集不能相交,否则可能发生冲突)。

LR文法:定义:如果某一文法能够构造一张LR分析表,使得表中每一个元素至多只有一种明确动作,则该文法称为LR文法。

拓展:由上面的定义可以看到,LL(1)和LR文法都是无二义性的:

(1)LL(1)要求生成的预测分析表的每一个项目至多只能有一个生成式,即对于读头下的每一个字符,都可以明确地选择哪个产生式来推导

(2)LR文法要求每一步都有明确的动作,移进和归约都是可确定的,没有二义性。

比较两大类型(自顶向下 vs 自底向上)的文法的特点:
1.首先LL(1)分析法是自上而下的分析法。LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法。
2.自上而下:从开始符号出发,根据<产生式规则>推导给定的句子。用的是推导
3.自下而上:从给定的<句子规约>到文法的开始符号。用的是归约
4.自上而下就是一种试探过程,怎么试探?需要你写出它的FIRST()集与FOLLOW()集。

写出这两个集合后根据LL(1)预测分析表构造规则画出LL(1)分析表。现在基本完成了大半,

当计算机输入句子时,分析程序便会根据输入去和预测分析表进行匹配,如果每步都能够匹配成功则说明符合该语法规则,分析成功。

FIRST()集:其实是终结符的集合,看该非终结符A能不能产生以它里面的某个符号开头的句子。(这也是自上而下分析法的思想)
5.自下而上就是把句子变成非终结符,在把非终结符变成非终结符,这样不断的进行如果能到根节点则成功。

  

  • LL(1)就是向前只搜索1个符号,即与FIRST()匹配《预测分析表》,如果FIRST为空则还要考虑Follow。
  • LR需要构造一张LR分析表,此表用于当面临输入字符时,将它移进,规约(即自下而上分析思想),接受还是出错。
  • LR(0)找出句柄前缀,构造分析表,然后根据输入符号进行规约

  不考虑先行,只要出现终结符就移进,只要出现归约状态,就无条件归约,这样子可能出现归约-移进,归约-归约冲突。

  •  SLR(1)使用LR(0)时若有归约-归约冲突,归约-移进冲突,所以需要看先行,则只把有问题的地方向前搜索一次。

SLR(1)定义:满足下面两个条件的文法是SLR(1)文法

  a.对于在s中的任何项目 A→α.Xβ,当X是一个终结符,且X在Follow(B)中时,s中没有完整的项目B→r.
  b.对于在s中的任何两个完整项目A→α.和 B→β.,Follow(A)∩Follow(B)为空。

解释:

a.当X是一个终结符且X出现在读头上,对于项目 A→α.Xβ应该采用移进,若有完整的项目B→r.且Follow(B)中有X,当X出现在读头上时,此时应该归约,

于是,就产生了移进和归约冲突b.假设Follow(A)∩Follow(B)为{ X },对于A→α.,若Follow(A)[A后面的元素]出现时,应该归约,

同理B也一样,于是,会产生归约-归约冲突,SLR(1)是为了消除LR(0)的两个冲突。

LR(1)1.在每个项目中增加搜索符。2.举个列子如有A->α.Bβ,则还需将B的规则也加入。

LALR(1)就是假如两个产生式集相同则将它们合并为一个,几合并同心集

总结:

  • 见到First集就移进,见到Follow集就归约。
  • LR(0):见到First集就移进,见到终态就归约
  • SLR(1)见到First集就移进,见到终态先看Follow集,与Follow集对应的项目归约,其它报错。
  • SLR分析法包含的展望信息是体现在利用了Follow(A)信息,可以解决“归约-归约”冲突
  • SLR分析法没有包含足够的展望信息,不能完成解决“移进-归约”冲突,需要改进。
    下面是LR(0),SLR(1),LALR(1),LR(1)文法处理能力的比较,圆圈越大说明能力越强。

endl;

编译系统中的LR与LL理解的更多相关文章

  1. 编译系统中的 NFA/DFA算法理解

    1.问题概述 NFA 和 DFA浅析---要深入了解正则表达式,必须首先理解有穷自动机. 有穷自动机(Finite Automate)是用来模拟实物系统的数学模型,它包括如下五个部分: 有穷状态集St ...

  2. C#中对IDisposable接口的理解

    http://blog.sina.com.cn/s/blog_8abeac5b01019u19.html C#中对IDisposable接口的理解 本人最近接触一个项目,在这个项目里面看到很多类实现了 ...

  3. js中的回调函数的理解和使用方法

    js中的回调函数的理解和使用方法 一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为 ...

  4. [BS-18] 对OC中不可变类的理解

    对OC中不可变类的理解 OC中存在很多不可变的类(如NSString,NSAttributedString,NSArray,NSDictionary,NSSet等),用它们创建的对象存在于堆内存中,但 ...

  5. oracle中 connect by prior 递归算法 -- 理解

    oracle中 connect by prior 递归算法 -- 理解 http://blog.163.com/xxciof/blog/static/7978132720095193113752/  ...

  6. MVC架构中的Repository模式 个人理解

    关于MVC架构中的Repository模式   个人理解:Repository是一个独立的层,介于领域层与数据映射层(数据访问层)之间.它的存在让领域层感觉不到数据访问层的存在,它提供一个类似集合的接 ...

  7. 关于MySQL中的自联结的通俗理解

    关于MySQL中的自联结的通俗理解 前言:最近在通过SQL必知必会这本书学习MySQL的基本使用,在学习中也或多或少遇到了点问题,我也正好分享给大家,我的这篇博客用到的所有表格的代码都是来自SQL必知 ...

  8. 关于Autosar中的NM模块的理解

    本篇文章主要介绍AutoSar中关于NM模块的理解. 阅读本篇文章希望达到的目的: 1. NM(网络管理)是用来做什么的: 2. AutoSar中网络管理的原理: 3.项目实例介绍 1. NM(网络管 ...

  9. Spring中Bean及@Bean的理解

    Spring中Bean及@Bean的理解 Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法: 一.Bean是啥 1.Java面向对象,对象有方法和属性, ...

随机推荐

  1. Appium移动自动化测试之获取appPackage和appActivity

    方法一:直接打开Appium,点击左上角机器人图标 选择apk所在位置,如图所示,这里以ContactManager.apk为例 方法二:利用dex2jar和jd-gui这两个工具反编译apk文件 这 ...

  2. ABP JTable如何手动刷新子表数据

    function getSubMaster() { _$masterTable.find('.jtable-child-table-container').jtable('reload'); }

  3. libcurl 函数curl_easy_perform在release下崩溃的问题

    今天遇到一个很奇怪的问题: 工程中用到了libcurl, debug可以正常运行,release每次都崩溃,断到curl_easy_perform这一行.堆栈中也得不到有用信息,于是GOOGLE一番, ...

  4. 自定义View(三)实现简单的可拖动、可缩放的ImageView

    实现技术主要用到1.多点触摸  2.matrix的矩阵,平移.缩放 根据手指的数量判断是进行的拖动.还是缩放动作 package com.bi.xintest; import android.cont ...

  5. laravel中日志为daily时如何设置最大保存天数

    在laravel中,日志设置为daily时,默认保存七天的日志,超过则清除七天前的日志.可修改默认的设置,假如要保存30天的日志,则配置如下: 在配置文件config/app.php中添加如下代码: ...

  6. 合并两个排好序的链表(c++)

    #include<iostream> struct node{ int payload; node* next; node(int payload){this->payload=pa ...

  7. 关于spring boot jar包与war包的问题

    此文为转载:http://mrlee23.iteye.com/blog/2047968 在开发调试完成之后,可以将应用打成JAR包的形式,在Eclipse中可以直接使用Maven插件的package命 ...

  8. oracle pl/sql split函数

    在软件开发过程中程序员经常会遇到字符串的拼接和拆分工作. 以java开发为例: 前台传入字符串拼接形式的一个JSON数据,如:"1001,1002,1003",这可能代表了一组序号 ...

  9. 【转】如何理解c和c++的复杂类型声明

    转自:http://blog.chinaunix.net/space.php?uid=22889411&do=blog&id=59667 曾经碰到过让你迷惑不解.类似于int * (* ...

  10. oracle10g、oracle client和plsql devement 三者之间的关系

    oracle10g是服务器,如果本机安装了oracle10g,没有必要安装oracle client,只要配置好DNS,就可以使用plsql devement连接     当然你也可以同时安装orac ...