编译原理学习笔记(四)预测分析器(1)
来源:互联网 发布:刚开淘宝店铺怎么装修 编辑:程序博客网 时间:2024/04/27 17:03
词法分析是为语法分析做准备的,词法分析器提取词法单元后返回给语法分析器用以进行语法分析。龙书在第四章中详细阐述了语法分析的部分。语法分析有自顶向下和自底向上两类方法,自顶向下是由产生式不断推导,直到匹配了整个输入串的过程,自底向上是通过字符串归约直到得到开始符的过程。今天主要学习了自顶向下的预测分析法。
预测分析法是递归下降分析法的一种特例,因此要先说到递归下降分析法。
递归下降分析由一组过程组成,每个非终结符有一个对应的过程。从开始符起执行过程,直到过程体扫描了整个输入串。
例如如下简单产生式:
S -> b
b->num + b| num
匹配2+3+5的过程就是:
从开始符S推导,推导得b,再由b第一个推导得到num+b,左边是num属于终结符(词法单元),右边可以继续推导,再次推导,尝试num+b发现无法匹配,因此选择另一个匹配num。自此输入串已扫描完毕。
其中的一个问题就在于,对于输入的串,应该选择哪一个产生式,这里涉及一个文法:LL(k)文法。第一个L表示从左往右扫描输入串,第二个L代表产生式从左往右推导,k表示在进行产生式选择时,需要往前看至少k个字符。比如上面的匹配,只需往前看一个字符,如果是’+’则可以做出选择。所以上面的文法是LL(1)文法。递归下降分析法应用于LL(1)文法则称为预测分析法。
依然用之前的的NC程序为例子,这里构造了一个语法表,描述产生式:
//配置文件grammar.txt
start \I
id \O\INT
addrs \G|\M|\X|\Y|\Z|\S|\T|\F
instruct #addrs\NUM#instruct|$
stmt \N\INT#instruct\END
end \I
program #start#id#stmt+#end
每行两个字符串,第一个为产生式名(非终结符),第二个为其推导。\X表示以X为名的词法单元,#X表示以X为名的非终结符。$表示空字符。
这里依然使用类似于词法分析部分的思想,构造一个语法单元,建立一个语法表存储语法单元的类型和其他信息。
//语法单元(非终结符/词法单元/空标记)struct syn_unit{ string token; lex_token*lex; enum term_type { LEX, NONTERMINATOR, EMPTY }; int id; term_type type; syn_unit() :token("$"), type(EMPTY){ ; }; syn_unit(string s, lex_token* l, int i, term_type t):token(s),lex(l),id(i),type(t){ ; } bool operator==(const syn_unit& els){ return els.token == token && els.type==type; } bool operator!=(const syn_unit& els){ return els.token != token && els.type != type; }};
语法单元中存储标记token和类型:词法单元、非终结符、空符。词法单元相当于终结符,非终结符可以继续推导,空符一般是结束符。
为了描述产生式,构造类型如下:
//产生式struct production{ //格式:非终结符-> |{词法单元 ∪ 非终结符} string token; syn_unit src; vector<vector<syn_unit>> dst; set<lex_token*>FIRST; bool set_down;//是否已设置好了FIRST集合 map<lex_token*,int> drivetable;//驱动表public: production(string,string,lex_parser*); void set_first(map<string, production*>&mesh);};
src,dst表示src->dst这个产生式,dst中包含语法单元串。FIRST集合是实现预测分析的一个基础,它存储着选择这个产生式的判断依据。(比如上面那个简单的例子,S选择b的依据是num,b二选一的依据是’+’)。FIRST集合构造方法见龙书140页。粗略理解就是一个串的可能开头字符的集合。
驱动表是预测分析法的核心(当然还有别的实现方法,不限于表驱动),对于一个当前推导出的非终结符,以及输入的词法单元,选择其应选的产生式。表驱动构造算法见143页。
语法分析部分架构:
//语法分析class nc_parser{ map<string, production*>mesh_table;//映射表 lex_parser*lex;public: nc_parser(string filename,lex_parser*);//先有词法表 才有语法表 void initial();//初始化:建立完整的FIRST集合,标识id等 void translate(string code,string);};
目前只建立了架构,实现部分的代码尚未测试,留作下次补全。
- 编译原理学习笔记(四)预测分析器(1)
- 编译原理学习笔记(四)预测分析器(2)
- 编译原理:LL(1)文法 语法分析器(预测分析表法)
- 编译原理:LL(1)文法 语法分析器(预测分析表法)
- 编译原理学习(一)词法分析器
- 编译原理(词法分析器)
- 编译原理----词法分析器实现(C)
- Java 实现词法分析器(编译原理)
- 编译原理(一)词法分析器
- 编译原理 - 课程设计(简易语法分析器)
- 编译原理 - 课程设计(简易词法分析器)
- 编译原理―词法分析器(Java)
- (编译原理)java实现词法分析器
- 编译原理学习笔记11——(三个臭皮匠顶上—— 构造预测分析表)——2014_1_27
- 简单词法分析器的实现原理(编译原理)
- 编译原理实现预测分析法(LL(1))
- 编译原理(预测分析法)
- 编译原理学习之 --- lex 语法分析器
- 当spring 容器初始化完成后执行某个方法
- geoserver跨版本跨环境迁移
- Distributed System: Hadoop MapReduce框架的角色和Job提交过程
- linux tar命令
- java多线程:10、阻塞队列【Condition】
- 编译原理学习笔记(四)预测分析器(1)
- Spark ML 分布式机器学习(一):iPython+spark安装与环境变量配置
- iOS 安全模型浅析(三) ---- 数据保护和全盘加密
- Linux 搭建 redis 单机环境
- 我是如何通过添加一条命令学习redis源码的
- Linux内核如何装载和启动一个可执行程序
- 深入浅出Java并发包—锁机制
- sublime text 3 unable to save permission denied
- 游戏服务器防护的一种实现方法(IOCP)