版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
语义分析程序的设计与实现语义分析程序的设计与实现语义分析程序的设计与实现语义分析程序的设计与实现编制仅供参考审核批准生效日期地址:电话:传真:邮编:语义分析程序的设计与实现班号:16姓名:张荣学号:08211627序号:26实验日期:2010-11-23一:实验内容: 2二:实验要求: 2三:实验方法: 2◆由LEX建立YACC的词法分析程序 2◆yacc原理介绍 3◆词法分析 4◆解析器如何工作 5◆Yacc环境 6◆常用代码 7第四:YACC内部名称: 7第五:运行结果(源代码见附录) 8第六:实验总结 9第七:附录 10附录一:yacc程序,加注释 10附录二:词法分析器的工作原理 13一:实验内容:编写语法分析程序,实现对算术表达式的语法分析,要求所分析的算术表达式由如下的文法产生。◆E->E+T|E-T|T◆T->T*F|T/F|F◆F->id|(E)|num二:实验要求:在对表达式进行分析的同时,输出所采用的产生式。可以采用多种方法◆编写递归调用程序,实现自顶向下的分析。◆编写LL(1)语法分析程序,要求:
编程实现算法,为给定的文法自动构造预测分析表
编程实现算法,构造LL(1)预测分析程序,◆编写语法分析程序,实现自底向上的分析,要求:
构造识别所有活前缀的DFA
构造LR分析表
编程实现算法,构造LR分析程序◆利用yacc自动生成语法分析程序,调用LEX自动生成的词法分析器程序三:实验方法:◆由LEX建立YACC的词法分析程序由LEX产生的词法分析程序可用于YACC,LEX编译程序根据LEX源程序产生词法分析程序yylex(),这个名字就是YACC所需要的词法分析程序的名字。如果YACC要调用LEX产生的词法分析程序,则在YACC源程序的第三部分用语句#include“代替函数yylex()的定义,这一yylex()就可以访问YACC中记号的名字,因为LEX的输出时候YACC输出文件的一部分,所有,每个LEX的动作都返回YACC知道的终结符。在UNIX的环境下,如果LEX源程序在中,YACC的源程序在中,可以使用以下命令得到所需要的分析程序。LexYacccc-oyaccdemo原理介绍Yacc是用可移植的C语言写成的。接受的规定类别是非常一般性的:带有去歧义规则的LALR(1)文法。Yacc提供了一个通用工具来在计算机程序的输入上施加结构。Yacc用户准备输入处理的规定;它包括描述输入结构的规则,在识别了这些规则的时候调用的代码,和做基本输入的一个低层例程。Yacc接着生成一个函数来控制输入处理。这个函数叫做解析器(parser),它调用用户提供的低层输入例程(词法分析器(analyzer))来从输入流中选取基本项目(叫做记号(token))。依据叫做文法规则的输入结构规则来组织这些记号;在识别了这些规则中的某一个的时候,接着调用为这个规则提供的叫做动作的用户代码;动作有能力返回值并使用其他动作的值。为了便利在动作和解析器之间的通信,对动作语句要做稍微的改动。在这个上下文中使用美元符号“$”作为给Yacc的一个信号。◆词法分析用户必须提供一个词法分析器来读取输入流并把记号(带有值,如果需要的话)传达到解析器。词法分析器使叫做yylex的整数值的函数。这个函数返回一个整数的记号编号,它表示读取的记号的种类。如果这个记号关联着一个值,应当把它赋予外部变量yylval。为使通信得以发生,解析器和词法分析器必须在记号编号上达成一致。编号可以由Yacc或用户来选择。在这两种情况下,使用C语言的“#define”机制允许词法分析器使用符号来返回这些编号。例如,假定在Yacc规定文件的声明段中已经定义记号名字DIGIT。它的意图是返回一个DIGIT记号编号,和等于这个数字的数值的一个值。倘若词法分析器代码位于规定文件的程序段,标识符DIGIT将被定义为与记号DIGIT关联的记号编号。这种机制导致清晰的、易于修改的词法分析器;唯一的缺点是在文法中需要避免使用任何在C语言或解析器中保留的或有意义的记号名字;例如,使用记号名字if或while就一定会导致编译词法分析器时出现严峻的困难。记号名字error保留给错误处理,不应该随便使用。同上所述,记号编号可以由Yacc或用户来选择。在缺省的条件下,编号由Yacc选择。文字字符的缺省记号编号是它在本地字符集中的字符数值。其他名字赋予从257开始的记号编号。要把一个记号编号赋予一个记号(包括文字),可以在声明段中记号或文字的第一次出现时直接跟随着一个非负整数。这个整数被接受为这个名字或文字的记号编号。不通过这种机制定义的名字和文字保持它们的缺省定义。所有记号编号都是不同的是很重要的。构造词法分析器的一个有用的工具是MikeLesk[8]开发的Lex程序。这些词法分析器设计用来与Yacc解析器紧密协调工作。这些词法分析器的规定使用正则表达式而不是文法规则。可以轻易的用Lex生成非常复杂的词法分析器,但是仍有一些语言(比如FORTRAN)不适应任何理论框架,它的词法分析器必须手工制作。◆解析器如何工作Yacc把规定文件转换成C程序,它依据给出的规定解析输入。做从规定到解析器转换的算法是复杂的,就不在这里讨论了(更多信息参见引用)。但是,解析器自身就相对简单了,理解它是如何工作的,尽管不是严格必须的,但会使错误修复和歧义处置更加易于理解。Yacc提供的解析器是由带有一个栈的有穷状态自动机组成。解析器自身还有能力读取和记住(叫做超前(lookahead)记号)下一个输入记号。当前状态总是在栈顶。有穷状态自动机的状态是一个给定的小整数标签(label);最初时,机器是在状态0下,栈只包含状态0,没有读取超前记号。机器对它只能获得四个动作,叫做移进(shift)、归约(reduce)、接受和错误。◆Yacc环境在用户向Yacc输入规定的时候,在多数系统上输出文件是叫做的一个C程序文件(因为本地文件系统惯例,它的名字在不同安装中可能是不同的)。Yacc生成的函数叫yyparse;它是整数值的函数。在调用的时候,它依次重复的调用用户提供的词法分析器yylex来获得输入记号。最终,要么是检测到一个错误,在这种情况下(如果没有错误修复是可能的)yyparse返回值1,要么词法分析器返回结束标记记号并且解析器接受。在这种情况下,yyparse返回值0。用户必须为解析器提供特定数量的环境来获得一个工作的程序。例如,同每个C程序一样,必须被定义程序调用的main(),它最终调用yyparse。此外,叫做yyerror的一个例程在检测到语法错误的时候打印一个消息。用户必须以某种形式提供这两个例程。为了减轻使用Yacc的起初努力,提供了带有缺省版本的main和yyerror的一个库。这个库的名字是依赖系统的;在很多系统上使用到装载器的-ly参数来访问这个库。到yyerror的参数是包含错误信息的字符串,通常是字符串“syntaxerror”。一般的应用可能需要更好的消息。通常,程序跟踪输入行数,并与检测到的语法错误一起打印。外部整数变量yychar在检测到错误的时候包含超前记号的编号;这对给出更好的诊断有好处。因为main程序(需要读参数等等)大多数时候是用户提供的。Yacc库只在小项目或大点的项目的早期阶段有用。外部整数变量yydebug通常设置为0。如果设置为非零的值,解析器会输出对它的动作的一个冗余的描述,包括对已经读入哪个输入符号和解析器动作是什么的讨论。依赖于操作系统,可以通过使用调试系统来设置这个变量。◆常用代码if(islower(c)){yylval=c-'a';return(LETTER);}if(isdigit(c)){yylval=c-'0';return(DIGIT);}if(c<='z'&&c>='a'||c<='Z'&&c>='A'){ yylval=c; return(ID); }第四:YACC内部名称:YACC内部名称说明yyerrorerroryyerrok、yycharYYSTYPEyydebugYACC输出文件名YACC生成的头文件,包含有记号定义YACC分析程序栈中的当前记号的值由YACC使用的用户定义的错误信息打印程序YACC错误违记号在错误处理之后,回到正常操作方式变了,记录导致错误的先行记号定义分析栈值类型的预处理器符号变量,用户置1生成有关分析动作的运行信息第五:运行结果(源代码见附录)在linix下输入的命令行依次是:Cd桌面YaccGcc–orong./rong注:Cd桌面到桌面目录下Yacc用yacc编译器编译程序到C文件Gcc–orong用C编译器生成可执行文件./rong运行可执行文件输入表达式,打印正确计算结果,否则,输出syntaxerror第六:实验总结1.用C语言实现词法分析的效率较高,但用LEX可以机械的执行程序,不用思考,虽然效率不是很高,但比较方便。Lex可以智能的读单词,并且按照最长匹配原则和优先匹配原则识别单词。Yacc则很简单的文法式进行分析,不需要定义递归的详细飞计算法则,直接修改生成式和标记符就可以应用于语法分析,简单方便,可移植性高。2.%tokenID%tokenNUM必须预先定义,否则会显示没有事先定义,此外对于C语言来说,isdigit(c)能判断一个字符是否是数字,但是,本题中要识别的是整数和记号,那么或者选用lex调用表,或者,递归的读取字符,分别判断,此时,我选择了循环判断来解决这个问题。而这段代码是属于基础代码模式。if(isdigit(c)) { yylval=c-'0'; return(NUM); } elseif(c<='z'&&c>='a'||c<='Z'&&c>='A') { yylval=c; return(ID); } elseif(c=='\n')done=1;程序,是在linix环境下,用命令行执行的,.y文件不能直接在windows环境下打开,但是,下载了ParserGenerator后,就可以直接读取.y文件,但此时不能运行yacc,还需要进行环境变量(例如PASH)的配置,才能在windows环境下使用yacc编译器。这个对于未安装虚拟机,初识linix的人使用yacc提供了很大的方便。4.通过lexyacc的编程练习,明白了词法分析和语法分析的基本操作,弄清了原理,为下一步进行语义分析打下了良好的基础。第七:附录附录一:yacc程序,加注释%{#include<>#include<>#include<>typedefstructx{inti;intc;}type;%}%union{intnum;char*id;typec;}%token<num>NUM%token<id>ID%type<c>expr,term,factor%%line:expr'\n'{if($>=0)printf("%dnum\n",$;elseprintf("id\n");};expr:expr'+'term{if($==0&&($==0)){$$.i=$+$;$$.c=0;printf("E->E+T:num\n");}else{$$.c=1;$$.i=-1;printf("E->E+T:id\n");}}|expr'-'term{if($==0&&($==0)){$$.i=$$;$$.c=0;printf("E->E-T:num\n");}else{$$.c=1;$$.i=-1;printf("E->E-T:id\n");}}|term{$$.i=$;$$.c=$;if($$.c==0)printf("E->T:num\n");elseprintf("E->T:id\n");};term:term'*'factor{if($==0&&($==0)){$$.i=$*$;$$.c=0;printf("T->T*F:num\n");}else{$$.c=1;$$.i=-1;printf("T->T*F:id\n");}}|term'/'factor{if($==0&&($==0)){$$.i=$$;$$.c=0;printf("T->T/F:num\n");}else{$$.c=1;$$.i=-1;printf("T->T/F:id\n");}}|factor{$$.c=$;$$.i=$;if($$.c==0)printf("T->F:num\n");elseprintf("T->F:id\n");};factor:ID{$$.c=1;$$.i=-1;}|'('expr')'{$$.c=$;$$.i=$;if($$.c==0)printf("F->(E):num\n");elseprintf("F->(E):id\n");}|NUM{$$.i=$1;$$.c=0;};%%main(){returnyyparse();}intyylex(void){ staticintdone=0; intc; if(done)return0; while((c=getchar())==''); if(isdigit(c)) { ungetc(c,stdin);=c-'0';scanf("%d",&yylval);printf("\nnum\n");printf("F->num:num\n"); return(NUM); } elseif(c<='z'&&c>='a'||c<='Z'&&c>='A') {=ID;printf("\nid\n");printf("F->id:id\n"); return(ID); } elseif(c=='\n')done=1; returnc;}voidyyerror(char*s){ printf("%s\n",s);}%{ /*第一节,普通的C语言声明*/#include<>#include<>%}%tokenID/*说明记号,在这里说明的记号可以用于随后的翻译规则部分和辅助过程中*/%tokenNUM%%/*文法记号声明,默认第一个产生式的左部非终结符号时候文法的开始符号*//*文法产生式和相关语义动作*/line:expr'\n'{printf("%d\n",$1);};/*表示输入是表达式后面跟一个换行符*/expr:expr'+'term{$$=$1+$3;}/*带单引号的是终结符*/|expr'-'term{$$=$1-$3;}/*$$表示和规则左部非终结属性,$i表示右部第i个文法的相关属性*/|te
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 八年级语文下册 第五单元教学实录 新人教版
- 幼儿园小班安全工作计划15篇
- 小学高级教师申报述职报告汇编5篇
- 2024-2025学年新教材高中生物 第四章 生物的变异 第四节 人类遗传病是可以检测和预防的教学实录(2)浙科版必修2
- 湖南省益阳市八年级地理下册 8.1 自然特征与农业(西北地区)知识梳理型教学实录 (新版)湘教版
- 军训心得体会23篇
- 工作业绩个人总结2022十篇
- 2024年版3D打印设备采购合同
- 2024年股权转让合同及附属协议
- 八年级语文上册 第五单元 24大道之行也教学实录 新人教版
- 拓展训练融入初中体育教学的创新策略与实施路径
- 国网安全责任清单培训
- 少儿春晚合同模板
- 医用机械外骨骼产品供应链分析
- 2024年氢工艺作业考试题库及答案(700题)
- 学校中层干部管理提升培训
- 海洋工程装备的修理与维护
- 广西柳州铁一中、南宁三中 2025届高一数学第一学期期末统考试题含解析
- 服装设计基础学习通超星期末考试答案章节答案2024年
- 2024年高等教育教育类自考-03372团体心理咨询考试近5年真题集锦(频考类试题)带答案
- 2024年二级建造师继续教育考核题及答案
评论
0/150
提交评论