170 likes | 533 Views
Decaf 语言编译器的实现(二). --语法分析器的实现. 主要内容. YACC 的使用方法 PP2 实验要求. YACC 的使用方法. 概述 YACC 源程序的结构 YACC 源程序的写法. YACC 概述. YACC -- A Compiler Compiler. LEX 源程序. YACC 源程序. LEX. YACC. 语法分析的输出. 词法分析程序 yylex(). 语法分析程序 yyparse(). 输入串. 单词符号串. YACC 源程序的结构. 说明部分 %% 语法规则部分 %% 程序段部分. 说明部分的写法.
E N D
Decaf语言编译器的实现(二) --语法分析器的实现
主要内容 • YACC的使用方法 • PP2实验要求
YACC的使用方法 • 概述 • YACC源程序的结构 • YACC源程序的写法
YACC概述 • YACC--A Compiler Compiler LEX源程序 YACC源程序 LEX YACC 语法分析的输出 词法分析程序yylex() 语法分析程序yyparse() 输入串 单词符号串
YACC源程序的结构 说明部分 %% 语法规则部分 %% 程序段部分
说明部分的写法 说明部分的内容如下: %{ 头文件 宏定义 数据类型定义 全局变量定义 %} 语法开始符定义 语义值类型定义 终结符定义 运算符优先级及结合性定义
语法开始符号的定义 %start 非终结符 注:若没有上述说明,YACC自动将第一条语法规则左部的非终结符作为语法开 始符。 语义值类型的定义 %union定义语义值的类型; %type定义文法符号的语义值类型; %token在定义终结符号时也可以定义语义值类型。 %union { int ival; double dval; } %type <ival> iexp %token <dval> CONST // %token CONST // %type <dval> CONST
终结符的定义 %token <语义值类型> 终结符名 编号 %token DIGIT LETTER %token BEGIN 100 注:1.非终结符不需要特别说明,如果需要说明语义值类型则用%type语句; 2.文字字符终结符不需要特别说明,它们的编号取其在字符集中的值; 3.在规则中出现文字字符时用单引号括起来。 运算符优先级和结合性的定义 以%left和%right定义结合性; 以排列顺序定义优先级; 在语法规则中,以%prec辅助定义优先级 %left ‘+’ ‘-’ expr:expr ‘-’ expr %left ‘*’’/’ | expr ‘*’ expr %% | expr ‘/’ expr expr:expr ‘+’expr; | NAME;
语法规则部分的写法 语法规则的书写格式 左部(非终结符):右部(文法符号串);stat: /*empty*/; 可以把左部相同的规则集中在一起书写; 语义动作 YACC在进行归约前,先完成用户提供的语义动作; 语义动作要符合C语言文法; 使用以$开头的伪变量存取语义值。 expr:’(’expr’)’ {$$ = $2};
解决二义性和冲突的方法 消除二义性的两条规则: • 1.出现移进/归约冲突时,进行移进; • 2.出现归约/归约冲突时,用先出现的规则进行归约; stat : IF bexp THEN stat | IF bexp THEN stat ELSE stat ; 用结合性和优先级解决冲突; • 规则的结合性就是规则右部最后一个非终结符的优先级和结合性; • 如果使用了%prec子句,则优先级和结合性由%prec子句决定; • 对于无优先级和结合性的规则,用规则1、2解决; • 对于有优先级和结合行的规则,用如下的规则解决:出现移进/归约冲突时,输入符号的优先级大于规则的优先级则移进,若输入符号的优先级小于规则的优先级则归约,若二者的优先级相同,左结合则归约,右结合则移进,无结合则出错。
错误处理 遇到错误就终止语法分析; 遇到错误继续进行分析,为此YACC提供了一个保留 的终结符error: • 把error写在规则的右部,跳过出错的部分,继续分析; stat: error ; • error后跟一个符号,跳过输入串,直到指定符号出现再继续分析。 stat: error ’;’ ;
程序段部分的写法 • 主程序main() • 用户在其中调用语法分析程序yyparse()。 • 错误信息报告程序yyerror() • YACC库提供了一个简单的报错程序。 • 词法分析程序yylex() • 一般是用LEX提供的yylex()程序。 • 其它程序段
PP2:语法分析器的实现 • 实验目的:用bison工具生成一个语法分析器,对词法分析输出的单词符号串进行分析,并依次输出归约时所用的各条规则。 • 实验环境:Windows操作系统,VC 6.0,语法分析程序生成工具bison。 scanner.h 词法分析程序的头文件 不需要改动 scanner.l 词法分析程序 需要改动 parser.h 语法分析程序的头文件 不需要改动 parser.y 语法分析程序 需要改动 main.c 主程序及其它函数 不需要改动
实验重点和难点 • bison工具的使用 请仔细阅读bision.info文档。 • 从BNF到规则的转换 在Decaf_language.rtf文档中,只给出了语法的BNF描述,这种描述并不能直接被YACC识别,而是要经过适当的改写。请大家在做实验前仔细研究一下我们给出的例子。 • 对输出格式的要求 在我们给出的例子中,要求按照归约的顺序依次输出各规则。这是基本要求,请大家一定要保证程序的输出与答案相同。如果大家还想输出语法树等其它形式的结果,请在readme.txt中给出说明,并输出到单独的文件中。
二义性和冲突的解决方法 通过对规则的调整消除冲突; 使用%left、%right和%prec等子句来解决冲突。 • 出错处理 YACC缺省的出错处理是遇到错误时输出错误信息,并停止分析, 这是基本要求; 大家可以利用YACC提供的error终结符,跳过一部分符号后继续 分析,并修改yyerror()函数以输出更全面的出错信息,我们将把 这些视为一种扩展; 考虑到出错处理大家的差别可能比较大,请一定在readme.txt中 给出说明。 • 语法和语义 在PP2中,不要求进行语义处理; 在PP2中,语法正确的程序都应被识别,语义错误暂不考虑。
实验要求 • 1. 与实验有关的文档和程序已经发给你们, 文件的说明在readme.txt文件中。 • 2. 请同学们把程序文件整理到一个目录下,编写readme.txt,打包成zip文件(zip文件名为“自己的学号.zip”),发email给我。 • 3. 提交PP2的时间为7月5日至7月9日,迟交的本次实验没有成绩。 • 4.检查实验的主要标准是程序的输出与标准答案相符合的程度。欢迎同学们对Decaf语法进行扩展,扩展部分要在readme.txt中指出。如果扩展正确,可以适当加分。
谢谢! ^-^