博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
COOL编译器-第二次作业-parser(PA3)实现
阅读量:5931 次
发布时间:2019-06-19

本文共 2228 字,大约阅读时间需要 7 分钟。

注意: COOL编译器实现是一门网络公开课,地址是,可能要FQ

可以在里面找到所需要的开发环境(虚拟机镜像等)和相关的资料说明.如果你感兴趣,可以一同学习

和讨论.

 

1. 作业目标

实现parser,给了两个工具,parser生成器--Bison和操作树结构的包parser的输出是一个abstract syntax tree(AST),

我们需要做的是结合AST构造的API,再使用Bison中的semantic actions来构建这个AST。

2. 参考资料

a. Cool语言的语法结构,在The Cool Reference Manual中

 

b. 树结构的包的使用方法,在 Tour of Cool Support Code中

c. Bison官方文档,

3. 环境准备

copy作业文件夹:

  • cd 到你的到你的workspace下
  • make -f /usr/class/cs143/assignments/PA3/Makefile

4. 实际工作

修改cool.y,分为两个部分:

  • 声明部分基本完成,但还是需要做以下几个部分:

I. 为你引入的新的非终结符添加额外的类型声明;

II. 终结符的部分已经基本完成;

III. 需要操作符添加优先级声明;

  • rule部分,基本全部需要你完成。

5. 测试parser

make parser

./myparser -p good.cl //加上-p可以查看分析过程

#然后查看输出文件cool.output

使用./checkparser.sh good.cl命令来比对你实现的parser和正确parser之间

的分析结果的差异。

6. 关于输出的结构

输出的是一个AST,你的semanic actions也应该是在构造一个AST,它的根应该是program类型。

然后逐级向下构造各结点。

7. 关于错误处理

需要提供error非终结符,需要至少提供以下两种错误恢复功能:

a. 如果一个类的定义有语法错误,但这个类正确的结束定义了;而下一个类的定义是正确的,

parser能够跳过错误的类,重新从下一个正确的类开始分析。

b. 类似的,parser能够从feature中的error中恢复过来,继续分析下一个feature。

8. 注意事项

a. 关于优先级声明,只能用在表达式上。

b. let语法是二义性的语法,需要注意由它引起的shift-reduce冲突。可以利用bison中产生式的优先级声明

c. 注意注释掉所有print语句。。。


实践笔记:

  1. cool_tree.aps文件是各个树结点构造函数的声明文件,需要看一下
  2. cool_tree.cc文件包括着上面文件中函数的实现代码,而且还包括列表结点的操作
  3. 要注意结点构造构造函数所需要的参数,如上面的single_Cases所需要的是case类型,而真正生成case类型的函数是branch()函数,所以正确的写法应该是single_Cases(branch(id, type, expr))
  4. 每一个semantic action都包含两个步骤,首先,标记位置信息;然后,构造AST树结点。
  5. ID一定要以小写开头,TYPEID一定是大写开头
  6. 每一行不一定要用分号做结束。可以参考class和feature的语法
  7. 函数体中,出现单行expr时,不能加分号结尾。一定要加分号的话,需要用{}把expr括起来。
  8. 正确的reflexer, refparser等文件都在/home/compilers/cool/lib/.i686下可以找到
  9. 使用方法: reflexer good.cl | refparser
  10. 关于error处理,没有想像中复杂,只需要在expr分支下加一个error语句就可以,不用action;对应class,feature等的错误处理也可以相应进行
  11. 有一点需要注意,语法定义一定要使用左递归,原因不明....记住[formal, [,formal]*]定义一定要用左递归。。。。
  12. expr_list: expr_list ',' expr 而不能写成 expr_list: expr ',' expr_list
  13. 关于错误处理,单一地使用error是不足以达到恢复的效果,需要用error和其它的符号组成一个整体的错误处理语法,来达到跳过发生这行的效果
  14. 比如在let语法中需要加入error IN expr和error ',' expr_let_part_2这两个错误处理语法,来达到匹配整个出错的行,忽略它,进行下一行处理。
  15. 再如block语法中需要加入error ';'来达到匹配整个行的效果。
  16. 关于let语法,它是一个循环的语法,let x : int, y : int in x ==> let x :int in let y: int in x,在构造时需要把let语法分成三个部分:
  17. part1: let id : type [<- expr]
  18. part2: [,id : type[<-expr]]*
  19. part3: in expr

代码:

上文中提到的所有文件都在我的github里可以找到,其实也只需要看cool.y文件就可以了,所有的改动都是围绕这个文件:

转载于:https://www.cnblogs.com/btchenguang/archive/2012/08/21/2648562.html

你可能感兴趣的文章
建造者模式
查看>>
C++ BigInt模板手打
查看>>
项目中测试工具的使用【暨软件工程实践第五次个人作业】
查看>>
关于JDK配置以及DOS窗口执行指令
查看>>
【C++ Primer】第五章 循环和关系表达式
查看>>
网易游戏2011招聘笔试题
查看>>
排列组合【转】
查看>>
C#获取xml指定节点的值(包括子节点)
查看>>
OFFICE 2007 序列号
查看>>
android网络编程
查看>>
cf #308 div2
查看>>
Ajax_数据格式_XML
查看>>
php中mysqli 处理查询结果集的几个方法
查看>>
英文操作系统 Myeclipse Console 乱码问题
查看>>
ubuntu12.04启动错误:Checking Battery State 。。。
查看>>
非常可乐
查看>>
angular源码分析3-$provide
查看>>
vuecli结合eslint静态检查
查看>>
面向对象程序设计-设计模式的一些简单概念
查看>>
JavaScript性能优化大家多多评论谢谢
查看>>