精品文档
装订线
装
订
线
编译原理实验报告
题目: C_minus语言词法分析器
学 院 计算机科学与技术
专 业 xxxxxxxxxxxxxxxx
学 号 xxxxxxxxxxxx
姓 名 xxxx
指导教师 xxxx
20xx年xx月xx日
C_minus语言词法分析器
一、实验目的?
? 1.理解词法分析器的设计方法:利用DFA编写相应的程序。?
2.掌握手工编写词法分析程序的方法。
3.复习熟悉以前学过的编程语言?
? 4.通过实验了解编译器词法分析的工作原理?
?二、实验原理?
?1.文法的概念,DFA的表示方法。
?2.词法分析程序的输出和输入:词法分析程序的功能是读入源程序,输出单词符号。单词符号是程序设计语言的比本语法符号,程序设计语言的单词符号一般分为如下几种:关键字,标示符,常数,运算符,界符,单词的输出是二元式的形式,需要知道二元式的表示方法,把得到的二元式写入输出文件。
转化图如下:?
?源程序
源程序?
词法分析程序?
记号文件?
?3.熟悉单词的描述工具,如正规文法,正规式,以及知道正规文法和正规式的等价性以及他们之间的互相转化。熟悉把正规文法转化为正规式,把正规式转化为NFA以及把NFA转为相应的DFA,最后再把DFA简化,DFA的状态转化为相应的子程序,最后得到词法分析器
4.C语言的基本语法。?
三、实验要求?
?1、该个词法分析器要求至少能够识别以下几类单词:?
关键字:else?if?int?return?void?while共6个,所有的关键字都是保留字,并且必须是小写;?
标识符:识别与C语言词法规定相一致的标识符,通过下列正则表达式定义:ID?=?letter?(letter?|?digit)*;?
常数:NUM?=?digit?digit*(.digit?digit*?|ε)(e(+?|?-?|ε)?digit?digit*?|ε),letter?=?a|..|z|A|..|Z|,digit?=?0|..|9,包括整数,如123等;小数,如123.45等;科学计数法表示的常数,如1.23e3,2.3e-9等;?
专用符号:+?-?*?/?<?<=?>?>=?==?!=?=,?(?)?[?]?{?}?/*?*/;?
2、分析器的输入为由上述几类单词构成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变为其对应的机内符,常数使用二进制形式,标识符使用相应的标识符表指针表示。?
3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。
四、实验结果(程序)及分析
#include<stdio.h>?
#include<stdlib.h>
#include<string.h>?
#define?N?100?
typedef?struct?{?
? char?name[30];
int?code;?
? int?addr;?
}token;//存储刚从文件中读取的字符
typedef?struct{
char?name[30];?
?int?code;?
}Keyword;?
typedef?struct?{?
? char?name[30];?
?int?code;?
?int?addr;
}symbol;?
Keyword?key[6]={{"else",1},{"if",2},{"int",3},{"return",4},{"void",5},{"where",6}};?
char?ch;//接受字符?
FILE?*source;//源文件?
FILE?*keytxt;//关键字输出文件?
FILE?*badgetxt;//标识符输出文件?
FILE?*othertxt;//其他单词输出文件?
FILE?*number;?
int?error_count;//错误的个数?
int?addr_count;//标识符表的指针?
int?lineof;//行号?
token?current;//暂时存放读入的字符?
token?zancun;
symbol?currentsymbol;?
symbol?symboltable[N];//标识符表
void?error(int?i);?
void?main()?{?
void?scan();
error_count=0;?
?addr_count=0;
error_count=0;?
?lineof=0;?
?scan();
}?
void?scan()?{
int?i=0;?
void?iskeyword();//判断关键字
void?isOthers()?//判断其他单词?
void?output_1();//关键字输出文件
void?output_2();//标识符输出文件?
void?output_others();//其他单词输出文件
void?Iszhushi();
?void?isnumber();?
?if((source=fopen("Source.txt","r"))==NULL){//打开源文件
printf("file?open?error/n");
?exit(0);
}
if((keytxt=fopen("key.txt","w"))==NULL){//打开关键字文件
printf("file?open?error/n");
?exit(0);?
?}?
if((badgetxt=fopen("badge.txt","w"))==NULL){//打开标识符文件
?printf("file?open?error/n");
?exit(0);?
?}?
if((othertxt=fopen("others.txt","w"))==NULL)?{
?printf("file?open?error\n");
?exit(0);
}
if((number=fopen("number.txt","w"))==NULL)?{?
printf("file?open?error\n");
exit(0);
}?
ch=fgetc(source);
while(ch!=EOF)?{
? ? for(i=0;i<30;i++)
current.name[i]='\0';
?if((ch>='a'?&&?ch<='z')?||(ch>='A'?&&?ch<='Z')?||?ch=='_'?)
?iskeyword();
if(ch=='\\')?
? ?Iszhushi();?
?if(ch>='0'&&?ch<='9')?
isnumber();
else
?isOthers();?
? ch=fgetc(source);
}?
?fclose(source);
fclose(keytxt);
? ?fclose(badgetxt);
? ?fclose(othertxt);
fclose(number);?
}?
void?iskeyword(){
int?i=0,k=0,j=0;
int?h=0;?
?while(((ch>='a')?&&?(ch<='z'))?||((ch>='A')?&&?(ch<='Z'))?||?ch=='_'?||?(ch>'0'?&&?ch<'9'))?{?
current.name[i]=ch;
?i++;?
ch=fgetc(source);?
}
zancun=current;
for(i=0;i<6;i++)?{?
for(j=0;j<30;j++){?
if(current.name[j]==key[i].name[j]){
h=0;
}?else{?
?h=1;
?break;
}
? }?
?if(h==0)?
break;
?}
?if(h==0) {
current.code=key[i].code;
output_1();?
}?else{?
strcpy(symboltable[addr_count].name,current.name);
symboltable[addr_count].code=10;
?symboltable[addr_count].addr=addr_count;
addr_count++;
output_2();?
}
?}?
void?isOthers(){
char?ch1;
int?i;?
?for(i=0;i<30;i++)
current.name[i]='\0';?
?switch(ch){?
?case?'+':{?
current.name[0]='+';
? ?current.code=13;
? ?current.addr=-1;
? ?output_others();
break;
? ?}
case?'-':?{
current.name[0]='-';
? ?current.code=14;
? current.addr=-1;?
? output_others();
break;
}?
?case?'*':?{?
? current.name[0]='*';?
? current.code=15;?
? current.addr=-1;
output_others();?
?break;
? }?
?case?'/':{
?current.name[0]='/';?
? current.code=16;?
? current.addr=-1;
?output_others();?
?break;?
? }?
?case'<':{?
ch1=fgetc(source);
if(ch1=='='){
current.name[0]='<';
current.name[1]='=';?
current.code=17;?
?output_others();
?break;
? }?else {?
fseek(source,-1,1);?
current.name[0]='<';
current.code=18;?
? ?current.addr=-1;
?output_others();?
break;?
?}?
}
? ?case'>':?{
ch1=fgetc(source);
? if(ch1=='=') {?
current.name[0]='>';?
current.name[1]='=';
? current.code=19;
?output_others();
?break;
}else{
? fseek(source,-1,1);?
? current.name[0]='>';
? current.code=20;?
output_others();
?break;
? ?}
}?
case'=':?{
ch1=fgetc(source);?
if(ch1=='='){
current.name[0]='=';
current.name[1]='=';
current.code=21;
current.addr=-1;
output_others();
break;
}else?{
current.name[0]='=';?
current.code=22;?
current.addr=-1;?
output_others();?
fseek(source,-1,1);
break;
}
}
case?'!':?{
ch1=fgetc(source);?
if(ch1=='='){
current.name[0]='!';
current.name[1]='=';
current.code=23;
current.addr=-1;
output_others();
break;
}else{
fseek(source,-1,1);?
?current.name[0]='!';
?current.code=24;?
current.addr=-1;
output_others();
break;
}
}
case?';':?{?
current.name[0]=';';?
current.code=25;
current.addr=-1;
?output_others();
?break;
}?
case?',':?{?
current.name[0]=',';?
current.code=26;
current.addr=-1;
output_others();
?}
?case?'(':?{
int?i=ftell(source);
char?ch1=ch;
char?ch2;
while(ch!=')'){
ch=fgetc(source);?
?}
if(ch==')')?{
current.name[0]=ch1;
current.name[1]=ch;?
current.code=27;
current.addr=-1;
output_others();?
fseek(source,i,0);?
ch2=fgetc(source);?
ch2=fgetc(source);
break;
}else{
?error_count++;
error(1);?
fseek(source,i,0);?
ch2=fgetc(source);
ch2=fgetc(source);?
break;
}
?}
case?'{':{?
current.name[0]='{';?
?current.code=28;
?current.addr=-1;?
output_others();
?break;
}
case?'}':{?
current.name[0]='}';
?current.code=28;
?current.addr=-1;
?output_others();
break;
}
case?'[':{?
? current.name[0]='[';
? current.code=29;?
current.addr=-1;
output_others();
break;?
}
case?']':?{?
? current.name[0]=']';
current.code=29;
current.addr=-1;
?output_others();
?break;
}
case'10':?{
?lineof++;?
break;
?}
}?
}?
void?Iszhushi()?{
char?ch1;
ch1=ch;
ch=fgetc(source);
if(ch=='*')?{
for(;;){?
ch=fgetc(source);?
?if(ch==EOF)?{?
? error(2);
break;
}?
if(ch=='*')?{
ch1=ch;
ch=fgetc(source);
if(ch=='\\')?{
?ch=fgetc(source);?
break;?
?}
}
}
}else{
error_count++;
?error(2);
}?
}?
void?isnumber()?{
int?k=0;
void?output_number();?
?while(ch>='0'&&?ch<='9'){
?current.name[k++]=ch;
ch=fgetc(source);
}
current.code=11;?
output_number();?
}?
void?output_1()?{
printf("关键字:<%s,%d>",current.name,current.code);
putchar(10);
fprintf(keytxt,"<%s,%d>",current.name,current.code);?
}?
void?output_2()?{?
? printf("标识符地址:<%s,%d>",current.name,addr_count);
putchar(10);?
fprintf(badgetxt,"<%s,%d>",current.name,addr_count);?
}?
void?output_others()?{?
?printf("其它单词:<%s,%d>",current.name,current.code);?
?putchar(10);fprintf(othertxt,"<%s,%d>",current.name,current.code);
}?
void?error(int?i)?{
switch(i){
case?1:printf("界符发生错误,发生在第%d行/n",lineof);
case?2:printf("注释发生错误,发生在第%d行/n",lineof);
}?
}?
void?output_number()?{?
printf("常数<%s,%d>\n",current.name,current.code);
fprintf(number,"<%s,%d>",current.name,current.code);
?}?
实验结果分析,程序运行结果截图:
关键字输出文件:?
标识符输出文件:?
数字的输出文件?
其它单词输出文件:?
售后服务方案(赠送)
1.售后服务概述
公司长期以来一直致力于提供高质量、完善的支持服务,确保用户的系统稳定运行。
公司拥有一批资深的施工人员,具有丰富的经验,能够很好的解决设备各类故障,强大的用户支持队伍和良好的用户满意度是我们的一大优势。
维护计划及承诺
?一、 项目售后服务内容承诺
我公司贯彻执行:“诚信正直、成就客户、完善自我、追求卓越”的宗旨,对于已经竣工、验收合格的项目进行质量跟踪服务,本着技术精益求精的精神,向用户奉献一流的技术和一流的维护服务。
我公司如果承接了端拾器项目,将严格遵循标书及合同的规定,在保证期内向业主提供该项目的责任和义务。在保修期之后,考虑到设备维护的连续性,建议业主与我公司签订维护合同,以确保此系统项目的正常运行所必需的技术支持和管理支持。
二、 服务与保证期
?在项目验收合格之日起,开始进行售后服务工作,包括以下几个方面:
1、售后服务期; ?2、维护人员; 3、售后服务项目; 4、服务响应时间。
? 三、 售后服务期
? 在项目验收合格之日起,即进入了售后服务期。
售后服务期=质量保证期+质量维护期
? 质量保证期:在质量保证期内,如因质量问题造成的故障,实行免费更换设备、元器件及材料。如因非质量因素造成的故障,收取更换设备、元器件及材料成本费。
质量维护期:在质量保证期之后,即自行进入质量维护期。
我方对所承担端拾器项目提供终身质量维护服务,以不高于本合同设备单价的优惠价格提供所需更换的元器件及材料,另收维护人员工本费。
四、 具体措施承诺
? 1、首先在签订项目合同的同时与客户签订售后服务保证协议书,排除客户的后顾之忧,对客户做出实事求是的、客观的承诺。
2、对已经验收合格交付用户的端拾器项目,在合同期内与用户进行联系,记录用户使用情况,系统运行状况等进行质量跟踪调查,变被动服务为主动服务。
3、对已交工的端拾器项目建立系统运行档案,并进行质量跟踪。
4、系统运行档案记录其端拾器项目运行情况、各类设备使用情况、操作人员操作水平情况及人员流动情况。
5、针对各用户单位操作人员出现的代表性问题,定期对操作人员进行技术培训或到现场培训及指导。
6、正在使用中的系统、设备出现故障时,公司维修服务人员接到报告后及时赴现场处理、维修。
7、对于运行时间较长的端拾器项目,公司维修服务人员定期与客户进行联系询问情况,定期到客户方进行巡视、检查,并做出记录,记录归档保存。
8、施工保证
将选派具有丰富经验的技术人员负责端拾器项目具体施工,保证安装质量及系统使用功能,并保证整个系统运行平稳、高效、可靠。
9、系统保修
作为项目承包单位,我公司将严格遵循招标文件及合同的规定,向业主提供端拾器项目最终验收合格之日起,在保质期范围内免费维修。
10、保修期内设备损坏,经鉴定为设备本身原因造成的故障,我方负责免费维修或者更换;同时负责在保修期内定期对设备提供保养维护服务。
总之,为使业主使用放心、使用方便、保证端拾器项目正常运行,公司全体技术、维护人员本着客户第一的原则,全心全意地为客户着想,全力以赴的进行工作,让我们共同携手,为创造美好的明天而努力工作。
五、保修服务内容及范围
我公司将为所承担的各个端拾器项目提供保修服务,有效期从项目验收后,业主在竣工报告上签字之日起。
1、 响应时间:具体的响应时间将按故障级别划分;
2、 维修地点:用户现场。
我公司负责实施的所有系统项目,在正常环境下做适当使用时所发生的故障,我公司将提供约定保修服务。非当前故障,我公司安排提供服务,但需按收费标准另收费用。
我公司的保修服务仅限于经我公司认定的合格产品。所谓不合格的产品包括:非经我公司供应的产品、非经我公司认定合格的产品及顾客不允许我公司做功能改进的产品。
下列情况所发生的系统损害不包括在保修服务范围内:
1、 使用不适当的工具进行系统维护时造成的系统设备损坏;
2、 现场环境不符合我公司建议的规范;
3、 意外、自然灾害、疏忽及不当使用、战争、暴动、罢工、雷击或电力故障、顾客搬运不当的损坏,经由非我公司人员或其授权的子承包商对系统进行修改和变动;
4.设备的维护和信息处理方式。
六、 系统维护
1、系统运行管理工作
为了保证系统能够长时间的正常运行,我们将进行完善的系统培训,同时制定各个系统项目操作规程,并配合业主制定操作人员责任界面及合理的交接班制度。
2、系统维护保养
我公司的售后服务人员在维护期内将对贵方的系统项目提供服务,使它们保持良好的运行状态。
? 3、月度保养
? 坚持月度维护保养,保证每个系统项目机械装置保持最佳工作状态。
七、维护及服务支持措施
1、电话支持服务
电话服务热线号码以我方提供给业主的号码为准(包括电话和传真号码)。如有更改,我方至少在自更改之日起3天内以电子邮件、传真、电话的方式通知业主。
2、现场排除故障或技术指导
我方在接到业主的电话支持服务请求后,如果不能通过电话支持服务解决设备或产品发生的技术故障,且经双方商议确认需要进行现场支持的情况下,我方将派专业项目技术人员及时前往现场协助业主排除故障。
3、电话咨询服务
对业主在使用设备或产品过程中产生的非故障类问题,我方提供电话咨询服务。
4、投诉受理服务
我方在公司设有用户投诉电话