《编译原理-龙书》练习第2章
2012-12-03 22:51
190 查看
第2章 一个简单的语法制导翻译器
2.2 语法定义
主要描述了“上下文无关文法”2.2.1
1)
S1 = aa+
S2 = S1a*
2) *
+
a a a
3)该文法生成的语言是由+和*组成的后缀表达式,怎么证明呢?
2.2.2 同不懂怎么证明
1)前面n个0后面n个1组成的串
2)+/-组成的关于a计算的前缀表达式
3)空串或成对出现的单个或嵌套括号组成的表达式
4)空串或a和b组成的任意表达式
5)由+连接起来的1个或多个a,可以加括号,每个a后面可以有0个或多个*
2.2.3
1)没有二义性
2)有,跟例2.1中语法一样
3)没有
4)有,ab可以随意结合
5)有,S+S和SS无法确定如何结合
2.2.4
1)S -> SS+|SS-|SS*|SS/|a
2)left -> left,expr | expr
3)right -> expr,right|expr
4)这道题中文版翻译有误,应该将书中“标识符”去掉。
expr -> expr+term | expr-term|term
term -> term*factor | term/factor|factor
factor -> digits
digits -> digitdigit|digit
5)+ -单目运算符优先级应该最高
expr -> expr+term1 | expr-term1|term1
term1 -> term1*term2 | term1/term2|term2
term2 -> -factor | +factor|factor
factor -> digits
digits -> digitdigit|digit
2.2.5 根据提示,采用数学归纳法证明如下:
如果节点数是1,显然 11 1001都能被3整除
如果节点数是2,110 10010 1111 10011001都能被3整除
假设节点数小于等于n的情况所有二进制串都能被3整除,则n+1个节点的所有串可能有以下情况
1.节点数为n的串后面加个0,记为Sn0 = Sn*2,显然能被3整除
2.SiSj,SiSj分别表示节点数为i和j的串,则SiSj = Si*2^j+Sj,根据假设,Si和Sj都能被3整除,所以SiSj能被3整除
2.2.6
背景知识 : http://baike.baidu.com/view/42061.htm
首先需要知道罗马数字的表示方法
I、V、X、L、C、D、M
分别表示1 5 10 50 100 500 1000
罗马数字上下文无关文法如下:
number -> digit digit| digit
digit -> I | V | X | L | C | D | M
2.3语法制导翻译
本小节介绍的翻译方案有2种,图2-10中的字符串属性和图2-15中的打印方式,我们练习的时候采用第一种,第二种类似练习中都考虑到了运算符优先级,比书中稍微复杂一些
2.3.1同图2-10,只是前2行不同:
expr->expr1+term expr.t = '+'|expr1.t|term.t
expr->expr1-term expr.t = '-'|expr1.t|term.t
expr->term
term->term1*factor term.t = '*'|term1.t|factor.t
term->term1/factor term.t = '/'|term1.t|factor.t
term->factor
9-5+2
expr.t = +-952
expr.t = -95 + factor.t = 2
factor.t = 9 - factor.t = 5
9-5*2
expr.t = -9*52
factor.t = 9 - expr.t = *52
factor.t = 5 - factor.t = 2
2.3.2 跟2.3.1差不多
2.3.3 求解
2.3.4 求解
2.3.5 可以分2步实现,先转成中缀,然后转成前缀
2.4 语法分析
2.4.11)
void S() { switch( lookahead ) { case +: match(+); S(); S(); break; case -: match(-); S(); S(); break; case a: match(a); break; default:report("syntax error"); } }
2)这种情况就不要用switch了,if比较适合,要注意消除递归,消除方法是在开始加一系列判断,错误处理比较复杂,下面没加,如果要加该怎么处理呢??
void S() { if(lookahead==NULL) return; if(lookahead=='(' && lookahead+1==')') {match('('); match(')');return;S()math('(')S()match(')')S()}
3)两个产生式的FIRST都是0,需要注意,不过相比较2),容易实现
void S() { if(lookahead==0) { match(0); if(lookahead!=1) S(); match(1); } else report("syntax error"); }
2.6 词法分析
这一节相对容易懂一些,练习也比较简单2.6.1
1)类似判断数字,连续读入 ‘/’ ‘/’认为是注释
2)类似判断数字,读入‘/’ ‘*’ 以后判断 ‘*’ ‘/’,否则认为是错误
2.6.2 只需要再scan函数中添加类似数字,字母的判断即可
2.6.3 只需在scan判断数字的区域中添加相关代码即可
2.7
57页的top:如果把符号表看成一颗数,top表示当前使用的叶子,书中57页第2行符号表链的顶部表示的就是这个意思2.8 生成中间代码
2.8.1package inter; import symbols.*; public class For extends Stmt { Expr expr1; Expr expr2; Expr expr3; Stmt stmt; public If(Expr x1, Expr x2, Expr x3, Stmt s) { expr1 = x1; expr2 = x2; expr3 = x3; stmt = s; if( expr2.type != Type.Bool ) expr.error("boolean required in For"); } public void gen(int b, int a) { int label1 = newlabel(); int label2 = newlavel(); emit(expr1.toString()); emit(label1+":"); Expr n=expr1.rvalue(); emit("ifFalse"+n.toString()+"goto"+label2) stmt.gen(); emit(expr3.toString()); emit("goto"+label1); emit(label2+":"); } }
2.8.2
如果没有布尔类型,可能是根据表达式计算结果的类型分类进行判断,如果势int判断是否等于0,如果字符串判断是否为空,如果指针判断是否为空指针
相关文章推荐
- 《编译原理-龙书》练习第4章
- 《编译原理-龙书》练习第6章
- 《编译原理-龙书》练习第1章
- 《编译原理-龙书》练习第5章
- 《编译原理-龙书》练习第8章
- 《编译原理-龙书》练习第3章
- 《编译原理-龙书》练习第7章
- c++primer plus 第六版 第2章 编程练习之路
- 期书预告:传说中的龙书——《编译原理,第2版》
- Java编程思想 第4版 练习题 / 第2章 一切都是对象 / 练习4
- 《统计建模与R软件》练习答案-第2章
- 第2章_基本数据类型和基本操作_编程练习Exercise2.11通过控制台进行大小写的切换
- Accelerated C++:通过示例进行编程实践——练习解答(第2章)
- Java编程思想 第4版 练习题 / 第2章 一切都是对象 / 练习5
- C++ Primer Plus(第六版)编程练习 第2章 开始学习C++
- 第2章_基本数据类型和基本操作_编程练习Exercise2.7通过创建窗口进行大小写的切换
- 【Oracle练习】①第2章 编写简单的查询语句
- C Primer Plus 编程练习代码——第2章
- Java编程思想 第4版 练习题 / 第2章 一切都是对象 / 练习6
- 《Objective-C 2.0程序设计》第2章练习