《编译原理-龙书》练习第4章
4.2 上下文无关文法
4.2.1
1) E -> EE*
-> EE+E*
-> aa+a*
左到右依次a
2) 与1)一样,只是最后一步右到左依次a
3) E
E E *
E E +
id id id
4)无二义性,但是怎么证明呢?
5)+*组成的后缀表达式
4.2.3 如果是正则表达式,可以采用4.2.7的方法转成文法
1) (0*1+)* 根据DNF推出:
S -> 0A
S -> 1S
S -> ε
A -> 1S
2)
S -> ABA
A -> BB
B -> 0|1|ε
4.2.4
对于A->X[Y]Z,可以表示为
A->XBZ
B->Y|ε
对于A->X{YZ},可以表示为
A->XB
B->CC
C->YZ|ε
4.2.5 stmt -> if expr then stmt [ else stmt ] | begin stmt{; stmt} end
4.2.6 基本的正则表达式还剩*,表示为A->Z*,可以改写为:
A->BB
B->Z|ε
4.2.7 1)
建立一个集合表示所有非“无用符号”集合T,开始置为所有终结符号
集合A表示所有推导式,默认不打标记
for(所有没有打标记的A中推导式)
{
if( 如果右边只有T中符号集合)
{
将这个表达式打标记
表达式左边符号加入集合T
}
if(一个循环结束没有新的表达式被打标记)
循环退出
}
将开始符号加入T
2)非“无用符号”集合T会依次加入{0, B, S},所以A是无用符号
4.2.8 读懂这道题费了好大劲,不知到是因为最后一道题了还是比较晚了(2012-12-20 22:49,离世界末日不远了)
1)前2行不变,后面改为:
option -> A1|A2|...|An
A1 -> a1|b1
...
An -> an|bn
2)又花了一段时间读懂了这个题目,生成的串固定长度n,不考虑<n的串
n!*n的产生式是这样的,1)中的第一行改为:
option->Aa1|Aa2...|Aan
其中a1有n种选择(A1-An),a2有剩下的n-1种.....an为剩下的一种。
这些产生式一共包括n!个长度为n的产生式,即O(n!*n)
如果有一个O(n*2^n)的产生式序列,那么可能是n个长度为2^n的产生式,具体构造方法没想出来
4.3 设计文法
4.3.1 1)没有左公因子
2)有左递归,不能自顶向下语法分析
3)
rexpr -> rterm | E1
E1 -> +rterm | ε
rterm -> rfactor | F1
F1 -> rfactor | ε
rfactor -> rprimary | P1
P1 -> * | ε
rprimary -> a|b
4)目前没有左递归、左公因子,可以自顶向下语法分析
4.3.3 考虑 if E1 then if E2 else if E3 then MATCHED1 else MATCHED2
if E3 then MATCHED1 else MATCHED2不能确定跟前面两个if中的哪个匹配
4.4 自顶向下的语法分析
0 | 1 | $ | |
S | S->0T | ||
T | T->S1 | T->1 |
消除左递归
S -> aX
X -> STX |ε
T -> +|*
a | + | * | $ | |
S | aX | |||
X | STX | ε | ε | ε |
T | + | * |
4.4.5 感觉可以识别aaaaaa,为啥不行呢?
aaaaaa aSa
aaaaa Sa
aaaaa aSaa 如果可以向前看4个输入符号,则可以识别aaaaa,否则,会继续采用S -> aSa
aaaa Saa aSaaa
aaa aSaaaa
aa Saaaa aSaaaaa
a Saaaaa 需要回溯,回溯到一定程度就可以识别
4.4.6 1)如果产生式左边只能生成ε,则将其在文法中所有出现的地方删除即可
否则,就是类似T -> X | ε,这种情况下,将T在其他推导中出现的地方用这两个替换
这样有可能粗先左递归或左公因子。
2)
S -> aSbS => S -> aaSbSbaSbS | abSaSbbSaS | aSbS
S -> bSaS => S -> baSbSaaSbS | bbSaSabSaS | bSaS
S -> ε
综合得到S -> aaSbSbaSbS | abSaSbbSaS | aSbS | baSbSaaSbS | bbSaSabSaS | bSaS
4.4.7 1)如果有A=》B,则将B进行替换,替换为B可推导得到的表达式
2)E -> E+T | T T -> T*F | F F->(E) | id 进行替换如下:
T -> T*F | (E) | id
E -> E+T | T*F | (E) | id
3)一步推导得到的环可以直接删除,如果是多步,不失一般性,假设为2步,由于文法中不存在ε,所以必然存在这样的推导:
A->B B->A,我们可以爱用上面方法将B去掉,并去掉一步环。
4.4.8 根据4.4.7不难得到,但是得到的结果有左递归
4.4.9 如果n*n的表能够构造成功直到j-i=n-1,说明串在这个语言中
4.5 自底向上的语法分析
4.5.1 S -> 0S1 | 01
1)000111 最右推导:S -> 0S1 -> 00S11 -> 000111
最中间的01
2)00S11 最右推导: S -> 0S1 ->00S11
中间的0S1
4.5.2 S -> SS+ |SS* | a
1)SS+A*+ SS+
2)SS+a*a+ SS+
3)aaa*a++ a
4.5.3
1)
$ 000111$
$0001 11$
$00S 11$
$00S1 1$
$0S 1$
$0S1 $
$S $
2)
aaa*a++
Saa*a++
SSa*a++
SSS*a++
SSa++
SSS++
SS+
S
4.6 LR语法分析技术介绍:简单LR技术
4.6.1
1) 0,0S,00S....
2)
4.6.2 S -> SS+| SS* | a
采用图4-33中算法处理
(1) S`->S
(2) S -> SS+
(3) S -> SS*
(4) S -> a
0 | 1 0S | 2 0a | 3 1S | 4 3+ | 5 3* |
S`->.S S->.SS+ S->.SS* S->.a |
S`->S. S->S.S+ S->S.S* S->.a 1$ = accept |
S->a. |
S->SS.+ S->SS.* |
S->SS+. | S->SS*. |
采用算法4.46
FOLLOW(S) = {+, *,a $} FOLLOW(+)={+, *, a} FOLLOW(*)={+, *, a} FOLLOW(a)={+, *, a}
a | + | * | $ | S | |
0 | s2 | 1 | |||
1 | s2 | acc | 3 | ||
2 | r4 | r4 | r4 | ||
3 | s4 | s5 | |||
4 | r2 | r2 | r2 | ||
5 | r3 | r3 | r3 |
没有发现哪个ACTION既有归约又有移入操作,应该是SLR文法
4.6.3
栈 | 符号 | 输入 | 动作 |
0 | aa*a+$ | 移入 | |
02 | a | a*a+$ | 归约S->a |
01 | S | a*a+$ | 移入 |
012 | Sa | *a+$ | 归约S->a |
013 | SS | *a+$ | 移入 |
0135 | SS* | a+$ | 归约S->SS* |
01 | S | a+$ | 移入 |
012 | Sa | +$ | 归约S->a |
013 | SS | +$ | 移入 |
0134 | SS+ | $ | 归约S->SS+ |
01 | S | $ | 接收 |
对于下面两题
LL(1)文法特点:需要满足4.4.3中的三个条件
SLR(1)文法特点:在输入某个表示串以后,有移入/规约冲突或规约/规约冲突
LL文法是LR文法的一个真子集,而不是SLR的
4.6.5
S`->S
S -> AaAb | BbBa
A ->ε
B ->ε
构造LR(0)自动机
0
S`->.S
S->.AaAb
S->.BbBa
A->.ε
B->.ε
1 0S
S`->S
没法继续构造下去
4.6.6
FIRST(SA)与FIRST(A)都包含{a}。所以不是LL(1)的
4.6.7 1)
S -> Aibi n个
Ai -> ajAi n^2-n个
Ai -> aj n^2-n个
2)考虑其中某个i和j
index | 项集 |
贡献数量 |
|
0 |
S`->.S S->.Aibi Ai->.ajAi Ai->.aj |
1 |
S`->.S S->.A1b1 ... S->.Anbn A1->.a2A1... A1->.anA1... ... An->.a1An... An->.an-1An |
1 0->S |
S`->S. | 1 | S`->S. |
2 0->Ai |
S->Ai.bi | n | n个S->Ai.bi |
3 0->aj |
Ai->aj.Ai Ai->aj. Ai->.ajAi Ai->.aj |
n |
对于a1 A2->a1.A2... An->a1.An A2->.ajA2 A2->.aj ...an |
4 2->bi |
S->Aibi. | n | n个S->Aibi. |
5 3->Ai, 6Ai |
Ai->ajAi. | n*(n-1) |
对于a1 输入A2...An |
6 3->aj,6->aj |
Ai->aj.Ai Ai->.ajAi Ai->.aj |
n*n |
对于a1 输入a1,a3...an A2->aj.A2 A2->aj. |
这样算下来是2n*n+2n+2
结果应该是2^n+n^2+n,看来我算错了,求高手指点
如果势2^n那说明状态数量太多了,手工构造太困难了,做4.6练习过程感觉中间太容易出错了(手动计算的情况)
4.6.8
4.6.9
index | 项集 | |
0 |
S'->.S S->.AS S->.b A->.SA A->.a |
|
1 0->S |
S'->S. A->S.A A->.SA A->.a |
->$ accept |
2 0->A |
S->A.S S->.AS S->.b A->.SA A->.a |
|
3 0->a 1->a 2->a 5->a 7->a |
A->a. | |
4 0->b |
S->b. | |
5 1->S 5->S 7->S |
A->S.A A->.SA A->.a |
|
6 1->A 5->A 7->A |
A->SA. | |
7 2->S |
S->AS. A->S.A A->.SA A->.a |
|
8 2->A 8->A |
S->A.S S->.AS S->.b |
|
9 8->S |
A->AS. |
FIRST(A)、FIRST(S)、FOLLOW(A)、FOLLOW(S)都是{a,b},7可能有冲突,因为当前状态输入a的情况下,不能确定按S->AS.规约还是移入a。
4.7 更强大的LR语法分析器
学习编译原理真是个痛并快乐的过程,网上说龙书翻译的还行,个人感觉也是如此,只是学习的时候如果希望从头读一遍就理解是不可能的,通常要看3-4次才能理解,而且每次阅读的时候都会有新的收获。
学习4.7.5的时候怎么都想不明白例4.64怎么得出的自发向前看符号,再回头看一遍4.7,并且手动构造下LR项集族,马上明白了。
学习这一节最重要的是理解4.7.2开头对于算法4.53的解释,明白了以后这一节基本也就没问题了
为理解4.7.5中算法执行过程,构造例4.6的规范LR项集族
index | 项集 | GOTO |
0 |
S`->.S ,$ S->.L=R ,$ S->.R ,$ L->.*R ,= L->.id ,= R->L ,$ |
|
1 | ||
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
7 | ||
8 | ||
8 |
4.7.1 FIRST(S) = {a}
S'->S
S->SS+
S->SS*
S->a
构造LR项集族如下
index | 项集 | GOTO |
0 |
S`->.S , $ S->.SS+ ,a S->.SS* ,a S->.a ,a |
|
1 0->S |
S'->S. ,$ S->S.S+ ,a/+ S->S.S* ,a/* S->.a ,a/+/* |
|
2 0->a |
S->a. ,a | |
3 1->S |
S->SS.+ ,a/+ S->SS.* ,a/* S->.A ,a/+/* |
|
4 1->a |
S->a. ,a/+/* | |
5 3->+ |
S->SS+. ,a/+ | |
6 3->* |
S->SS*. ,a/* | |
LALR项集族只需要将上面2/4合并即可
4.7.3 算法4.6.3前后看了至少5遍,稍微有了些理解
INIT | 1 | 2 | ||
0 | S'->.S | $ | $ | $ |
1 |
S'->S. S->S.S+ S->S.S* |
a | a | a |
2 | S->a. | a | a | a |
3 |
S->SS.+ S->SS.* |
a/+/* | a/+/* | |
4 | S->SS+. | a/+ | ||
5 | S->SS*. | a/* |
4.7.4/4.7.5 类似例4.58
index | 项集 | GOTO |
0 |
S`->.S ,$ S->.L=R ,$ S->.R ,$ L->.*R ,= L->.id ,= R->L ,$ |
|
1 | ||
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
7 | ||
8 | ||
8 |
《编译原理-龙书》练习第4章相关推荐
- 《编译原理-龙书》练习第2章
第2章 一个简单的语法制导翻译器 2.2 语法定义 主要描述了"上下文无关文法" 2.2.1 1) S1 = aa+ S2 = S1a* 2) * + a ...
- 《编译原理-龙书》练习第3章
3.1 词法分析器的作用 3.1.1 float limitedSquare ( x ) { float x ; r ...
- 编译原理 龙书第4章 作业3
4.2.1 考虑上下文无关文法: S→S S + | S S * | a, 以及串aa+a* 1)给出这个串的一个最左推导 S→S S * →S S + S * →a S + S * →a a + S ...
- 编译原理 龙书 笔记
DFA NFA CFG DFA的定义: A = ( Σ, S, s0, F, N ) Σ: 输入字母表(alphabet),是一个输入字符的集合. S:状态的集合s0: 初始状态F:终止状态集合 F ...
- DirectX12 3D游戏开发实践(龙书)第四章 Direct3D的初始化
目录 Direct3D的初始化 预备知识 Direct3D概述 组件对象模型 纹理格式(Textures Formats) 交换链和页面翻转 深度缓冲 资源与描述符 多重采样技术的原理 利用Direc ...
- 编译原理(龙书):第一章部分题目参考答案
目录 1.1.1 1.1.2 1.1.3 1.1.4 1.6.1 1.6.3 1.6.4 1.1.1 What is the difference between a compiler and an ...
- dx12 龙书第十九章学习笔记 -- 法线贴图
本章需要掌握的内容:①法线贴图②TBN坐标系 1.使用法线贴图的动机 左图是使用法线贴图后的结果,右图是没有使用法线贴图(使用法线插值)的结果.可以明显感知到,高光在右图中是分布在一条直线上的,并没有 ...
- dx12 龙书第十二章学习笔记 -- 几何着色器
如果不启用曲面细分(tessellation)这一环节,那么几何着色器(geometry shader)这个可选阶段便会位于顶点着色器与像素着色器之间.顶点着色器以顶点作为输入数据,而几何着色器的输入 ...
- DirectX12 3D游戏开发实践(龙书)第五章 渲染流水线
渲染流水线 渲染流水线 3D视觉即错觉? 模型表示 计算机色彩基础 颜色运算 不透明度 XXX位颜色 渲染流水线概述 输入装配器阶段 顶点 图元拓扑 点列表 线条带 线列表 三角形带 三角形列表 具有 ...
最新文章
- 揭秘全球首次互联网8K直播背后的技术实现
- 分摊、分配、定期重过账
- 数字语音信号处理学习笔记——语音信号的数字模型(2)
- 自定义异常throw
- mysql8连接java_JAVA连接MYSQL8.0问题
- 中兴智能视觉大数据报道:张学友,你一定要多开演唱会啊!
- python完成非线性拟合
- 王煜全:AI独角兽必须进行业务升级 否则必死无疑
- 工业场景知识图谱落地实战
- tkintertools 模块实战一:任务清单小工具
- 打印机用计算机名慢,“电脑连上打印机就超级慢”的解决方案
- python谱聚类算法_Python机器学习高级算法!谱聚类(Spectal Clustering)算法分析和实例详解...
- awk 字符串转时间戳
- ChatGPT ,能替代程序员吗?
- 中国特色词汇汉译英 - A
- 课程作业2-大一纯网页课程作业——垃圾分类网站设计
- NIRec:An Efficient Neighborhood-based Interaction Model for Recommendation on Heterogeneous Graph
- 一步步教你用 WebVR 实现虚拟现实游戏
- ABAP 创建、修改、删除内部交货单(VL31N/VL32N)
- 059 提权与反弹shell
热门文章
- 骷髅创意设计灵感_20种创意旅行应用程序设计,激发您的灵感
- 特征预处理和特征生成 (一)数字特征
- 华为机试【连续出牌数量】
- 浏览器源代码下载图片原图,手把手教学
- ssh远程出错Add correct host key in /home/xxx/.ssh/known_hosts to get rid of this message
- 向产品宣战——开发者眼中的Android UI Design
- php 黄页,PHPCMS企业黄页
- 小熊维尼项目冲刺 第二天
- 如何使用Tableau进行预测分析
- 深入理解Android:卷II