转自: http://www.cnblogs.com/BlackWalnut/p/4472122.html

  LL(K)语法分析技术是建立在预测分析的技术之上的。我们先来了解预测分析技术。考虑以下文法:

  

当使用该文法对(1*2-3)+4和(1*2-3)进行分析,前者因该调用E->E+T,而后者应该调用E->T,怎么确定到底使用哪个产生式呢?这就要使用预测分析技术来构建预测分析语法分析器,LL(k)是其一种。预测分析技术的关键是构建一个无冲突的预测分析表。所谓预测分析表就是程序可以根据当前的状态来查询该表,然后确定下一步使用哪个产生式。

  构建预测分析表要要用到两个集合,分别是first集合和follow集合。γ是终结符和非终结符组成的字符串,first(γ)是从γ中可以推到出的任意字符串中所包含的开头终结符所组成的集合。A是一个非终结符,follow(A)的意思可以直接跟在A后面的所有终结符的集合。这两个集合的求法可以描述为如下:

First集合的求法:

First集合最终是对产生式右部的字符串而言的,但其关键是求出非终结符的First集合,由于终结符的First集合就是它自己,所以求出非终结符的First集合后,就可很直观地得到每个字符串的First集合。

1.  直接收取:对形如U-a…的产生式(其中a是终结符),把a收入到First(U)中
2.  反复传送:对形入U-P…的产生式(其中P是非终结符),应把First(P)中的全部内容传送到First(U)中。  
    Follow集合的求法:
    Follow集合是针对非终结符而言的,Follow(U)所表达的是句型中非终结符U所有可能的后随终结符号的集合,特别地,“#”是识别符号的后随符。
1.反复传送:对形如U-…P的产生式(其中P是非终结符),应把Follow(U)中的全部内容传送到Follow(P)中2.  直接收取:注意产生式右部的每一个形如“…Ua…”的组合,把a直接收入到Follow(U)中。
3.直接收取:对形如“…UPA…”(P是非终结符)的组合,把First(P)直接收入到Follow(U)中。如果P的first集合包含由空(ε),则first(A)也要放入Follow(U)中。
  需要注意的是,空是只能在First集合中不能在follow集合中。
  从上面的求法中可以知道,其实first集合就是一个非终结符的等价终结符的可选集合,也就是说A可以直接推到出这些终结符,如果first集合可以为空,则说明A可以直接忽略,这个时候,为了预测A为空后的情形,我们构建了follow集合。可见,者两个完全是为了预测分析而产生的集合。
  预测分析表是一个二维表,用非终结符符标注每行,用终结符好标注每一列,根据这first和follow两个集合,我们使用如下规则构建一个预测分析表:从产生式集合中取出一个产生式A->γ,如果终结符a在first(γ)中,则讲A->γ放入(A,a)确定的位置中,如果γ可以为空且a在follow(A)中,也则讲A->γ放入(A,a)确定的位置中。这样我们根据文法以下文法得到其相应的预测分析表:
                           
                         
  如何使用这个分析表呢?要知道,我们所分析的数据是由词法分析其产生的,对于语法分析器而言,词法分析器产生的数据都是终结符。我们利用堆栈(用到堆栈的地方一般也可以用递归来解决,可以参考虎书英文版的第47页代码)来记录当前正在分析的非终结符,从词法分析器得到一个终结符a,以及栈顶的数据来查表,然后确定使用的产生式,如果产生式的右面有非终结符,将其从右到左压栈(保证每次从对产生式的最左面的非终结符开始推到,称为左推到),然后继续使用使用a对栈顶元素分析。直到找到一个产生式的右只包含终结符a,然后将a抛弃,重新读取新的终结符,继续分析。如果在过程中无法得到只包含终结符a的产生式,那么说明有语法错误。
  上面的算法过程就是一个预测分析过程我们称为LL(1)算法,第一个L是left to right parse,第二个L是leftmost derivation ,1是1-symbol lookahead.意思就是从左到右的分析词法分析器产生的数据,采用最左推到原则,每次只看超前查看一个终结符来确定后续动作。
  但是就对上面这张表而言,(Z,d)的位置有两个产生式,那么说明该文法是二义的,说明它是不是LL(K)文法。就不能使用预测分析技术来解析该语言,要使用功能更强大的LR(k)技术。
   这里介绍两种可能产生二义性的例子,第一个为左递归。查看下左图,因为first(T)正好是first(E+T)的子集合,所以,一定会产生冲突。我们使用右图来替换原来的产生式,称为消除左递归。
                                                          
  还有一种情况,我们解决的办法称为提取右因子。
                                                          
  以上就是LL(K)文法的全部,相比LR(k)文法,它的功能不够强大(我们在LR(K)中进行比较),但是想要构造一个预测分析表却十分的简单。对于某些LR(k)处理不了的情况,我们可以快速的建立相应的LL(K)分析表来解决。

现代编译原理——第二章:语法分析之LL(K)的更多相关文章

  1. Java 实现《编译原理》简单-语法分析功能-LL(1)文法 - 程序解析

    Java 实现<编译原理>简单-语法分析功能-LL(1)文法 - 程序解析 编译原理学习,语法分析程序设计 (一)要求及功能 已知 LL(1) 文法为: G'[E]: E→TE' E'→+ ...

  2. 编译原理学习笔记·语法分析(LL(1)分析法/算符优先分析法OPG)及例子详解

    语法分析(自顶向下/自底向上) 自顶向下 递归下降分析法 这种带回溯的自顶向下的分析方法实际上是一种穷举的不断试探的过程,分析效率极低,在实际的编译程序中极少使用. LL(1)分析法 又称预测分析法, ...

  3. 编译原理根据项目集规范族构造LR(0)分析表

    转载于https://blog.csdn.net/Johan_Joe_King/article/details/79058597?utm_medium=distribute.pc_relevant.n ...

  4. 编译原理LR(0)项目集规范族的构造详解

    转载于https://blog.csdn.net/johan_joe_king/article/details/79051993#comments 学编译原理的时候,感觉什么LL(1).LR(0).S ...

  5. 第二章 Javac编译原理

    注:本文主要记录自<深入分析java web技术内幕>"第四章 javac编译原理" 1.javac作用 将*.java源代码文件转化为*.class文件 2.编译流程 ...

  6. 跟vczh看实例学编译原理——三:Tinymoe与无歧义语法分析

    文章中引用的代码均来自https://github.com/vczh/tinymoe.   看了前面的三篇文章,大家应该基本对Tinymoe的代码有一个初步的感觉了.在正确分析"print ...

  7. 《编译原理》-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法

    <编译原理>-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法 此编译原理确定某高级程序设计语言编译原理,理论基础,学习笔记 本笔记是对教材< ...

  8. 《编译原理》-用例题理解-自底向上的语法分析,FIRSTVT,LASTVT集

    <编译原理>-用例题理解-自底向上的语法分析,FIRSTVT,LASTVT集 上一篇:编译原理-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法 本 ...

  9. C语言编程入门之--第二章编译环境搭建

    第二章 编译环境搭建 导读:C语言程序如何工作,首先需要编译链接成可执行文件,然后就可以运行在不同的环境中,这个“环境”的意思就是比如说,电脑,手机,路由器,蓝牙音箱等等智能设备中,其中编译器启到了关 ...

随机推荐

  1. oracle锁表+解锁

    一.锁表: LOCK TABLE tablename IN EXCLUSIVE MODE; 二.解锁 * 1.首先用dba账户登录数据库 * * 2.查出被锁定的对象 * select * from ...

  2. SOD框架的Model、连接数据库及增删改查

    using PWMIS.DataMap.Entity; using System; using System.Collections.Generic; using System.Linq; using ...

  3. c# 访问共享文件

    #region 连接共享文件夹 /// <summary> /// 连接共享文件夹 /// </summary> public bool ConnectToSharedFold ...

  4. intellij idea 相关设置

    IDEA这么高端的工具之前只是断断续续使用了一下,因为项目的开发都是在eclipse上,每次学习IDEA的使用都得上网搜索半天,今天自己整理一下,方便以后查阅. IDEA版本15.0.4 字体 界面字 ...

  5. web socket server code, 调用 shell exec child_process

    var child_process = require('child_process'); var ws = require("nodejs-websocket"); consol ...

  6. Java的注解总结

    java 1.5开始引入了注解和反射,正确的来说注解是反射的一部分,没有反射,注解无法正常使用,但离开注解,反射依旧可以使用.Java的注解详解和自定义注解: https://blog.csdn.ne ...

  7. 用户未登录或Session超时时重定向到登录页,不那么简单

    在网站开发中,我们经常有这样的场景出现: 情景1:对未登录的用户或没有权限的用户,当其想访问某个受限网页时,系统要能够自动转到登录页面.   情景2:对于用session保存用户状态的情况还有这样一种 ...

  8. java开发人员win10配置

    1.让win10的cmd支持ll命令 新建ll.bat 编辑类容为: @echo off dir3.将该文件移动到C:\Windows下. CMD里就可以用ls来代替dir命令显示目录列表了. 2.i ...

  9. 主成分分析、实例及R语言原理实现

    欢迎批评指正! 主成分分析(principal component analysis,PCA) 一.几何的角度理解PCA -- 举例:将原来的三维空间投影到方差最大且线性无关的两个方向(二维空间). ...

  10. Chrome添加Axure RP插件

    之前一直用 Firefox 浏览器浏览原型文件,一直用不惯,而且用 Firefox 的唯一目的就是看原型.其他都是用 Chrome 浏览器,来回切换,各种麻烦,然后下定决心解决 Chrome 浏览器无 ...