编译原理词法分析器实验文档
编译原理词法分析实验报告

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的:1.熟悉编译原理中词法分析的基本概念和原理;2.掌握正则表达式的使用方法;3.实现一个简单的词法分析器。
二、实验内容:1.设计一个简单的编程语言,包含如下几种类型的词法单元:关键字、标识符、常量、运算符和界符。
2.使用正则表达式定义每种词法单元的模式。
3.设计一个词法分析器,将源代码中的每个词法单元识别出来并输出。
三、实验步骤:1. 确定编程语言的词法单元类型和正则表达式模式,定义相应的单词类型(如 TokenType)和模式(如 regex)。
2. 实现一个词法分析器的类 Lexer,包含以下方法:(1)一个构造方法,用于初始化词法分析器的输入源代码。
(2) 一个getNextToken方法,用于获取源代码中的下一个词法单元。
3. 在getNextToken方法中,使用正则表达式逐个识别源代码中的词法单元,并返回相应的Token对象。
4. 设计一个Token类,包含以下属性:词法单元类型、词法单元的值和位置信息等。
5.在主程序中使用词法分析器,将源代码中的每个词法单元识别出来并输出。
四、实验结果:1.设计一个简单的编程语言,包含如下词法单元类型(示例):(1) 关键字:if、else、while、for等;(2)标识符:变量名等;(3)常量:整数、浮点数、字符串等;(4)运算符:+、-、*、/、=等;(5)界符:(、)、{、}、;等。
2. 实现一个词法分析器,识别出源代码中的每个词法单元,并输出相应的Token对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
编译原理实验--词法分析器

实验一词法分析器设计【实验目的】1.熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。
2.复习高级语言,进一步加强用高级语言来解决实际问题的能力。
3.通过完成词法分析程序,了解词法分析的过程。
【实验内容】用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字,运算符,标识符,常数以及界符)输出。
【实验流程图】【实验步骤】1.提取pl/0文件中基本字的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE];int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {printf("%s\t",wsym[m]);m=14;n=k+1;} }2.提取pl/0文件中标识符的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE]=" ";int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {m=14;n=k+1;}}if(m==13) for(m=0;a[m]!=NULL;m++) printf("%c ",a[m]);3.提取pl/0文件中常数的源代码while((ch=fgetc(stream))!='.'){while(ch>='0' && ch<='9'){num=10*num+ch-'0';ch=fgetc(stream);}if(num!=0) printf("%d ",num);num=0;}4.提取pl/0文件中运算符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case'+': printf("+ ");break;case'-': printf("- ");break;case'*': printf("* ");break;case'/': printf("/ ");break;case'>': if(fgetc(stream)=='=')printf(">= "); else printf("> ");break;case'<': if(fgetc(stream)=='=')printf("<= "); else printf("< ");break;case':': printf(":= ");break;case'#': printf("# ");break;case'=': printf("= ");break;default: break;}ch=fgetc(stream);5.提取pl/0文件中界符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case',': printf(", ");break;case';': printf("; ");break;case'(': printf("( ");break;case')': printf(") ");break;default: break;}ch=fgetc(stream);}【实验结果】1.pl/0文件(222.txt)内容const a=10;var b,c;procedure p;beginc:=b+a;end;beginread(b);while b#0 dobegincall p;write(2*c);read(b)endend .2.实验运行结果【实验小结】1.了解程序在运行过程中对词法分析,识别一个个字符并组合成相应的单词,是机器能过明白程序,定义各种关键字,界符。
编译原理实验报告——词法分析器(内含源代码)

编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
编译原理词法分析器实验报告最终版

学院(系)名称:计算机工程系姓名学号专业班级实验项目实验一:词法分析课程名称编译原理课程代码 03102432013年 4月28 日第 1、2 节实验时间实验地点第一教学楼1508 2013年5月 7 日第1 、2 节批改意见成绩教师签字: 实验内容:实现标准C语言词法分析器实验目的:1(掌握程序设计语言词法分析的设计方法;2(掌握DFA的设计与使用方法;3(掌握正规式到有限自动机的构造方法;实验要求:1(单词种别编码要求基本字、运算符、界符:一符一种;标识符:统一为一种;常量:按类型编码;2(词法分析工作过程中建立符号表、常量表,并以文本文件形式输出;3(词法分析的最后结果以文本文件形式输出;4(完成对所设计词法分析器的功能测试,并给出测试数据和实验结果;5(为增加程序可读性,请在程序中进行适当注释说明;6(整理上机步骤,总结经验和体会;7(认真完成并按时提交实验报告。
实验步骤:1.基本思想:从源程序中依次读入字符并解析,与关键字、运算符、结束符进行比较,得出其中的关键字,并将它存入到数组中去。
2.程序源代码:#include<stdio.h>#include<cstring>#include<stdlib.h>#define MaxSize1 17//关键字的个数#define MaxSize2 20//运算符的个数#define MaxSize3 4//结束符的个数//数据结构struct TNode{char value[20]; //存放标识符的值int number; //存放标识符的种别码char description[20];//描述}KeyWords[MaxSize1],Operation[MaxSize2],EndOperation[MaxSize3];//存放关键字的数组char*WordsBuff[MaxSize1]={"const","long","float","double","void","main", "if","else","then","break","int","char","include","for","while","printf","scanf"};//存放运算符的数组char*OperationBuff[MaxSize2]={"+","-","*","/","+=","-=","*=","++","--","<","<=",">",">=","<>","=","(",")","#","{","}"}; char EndOperationBuff[MaxSize3]={' ',';','\n','\t'};//存放词法分析程序输出的结果TNode Table1[500];TNode Variable[100];//标识符表TNode Const[100];//关键字数组初始化void inputKeyWords(char * buff[],int size) {//关键字编码从1-sizefor(int i=0;i<size;i++){strcpy(KeyWords[i].value,buff[i]);KeyWords[i].number=i+1;strcpy(KeyWords[i].description,"关键字");}}//运算符数组初始化void inputOperation(char * buff[],int size){//运算符编码从50-(50+size)for(int i=0;i<size;i++){strcpy(Operation[i].value,buff[i]);Operation[i].number=i+50;strcpy(Operation[i].description,"运算符");}}//结束符数组初始化void inputEndOperation(char buff[],int size) {//结束符编码从100-(100+size);for(int i=0;i<size;i++){EndOperation[i].value[0]=buff[i]; EndOperation[i].value[1]='\0';EndOperation[i].number=i+100;strcpy(EndOperation[i].description,"结束符"); }}//输出数据结构数组中的信息void outputInfo(TNode a[],int size){for(int i=0;i<size;i++){printf("(%d",a[i].number);printf("\t");printf("%s)",a[i].value);printf("\t");printf(a[i].description);printf("\n");}}void outInfoToFile(TNode a[],int size,FILE *out) {//将词法分析程序的结果输出到文件中去for(int i=0;i<size;i++){fprintf(out,"(%d",a[i].number);fprintf(out,"\t");fprintf(out,"%s)",a[i].value);fprintf(out,"\t");fprintf(out,a[i].description);fprintf(out,"\n");}}//从文件中读取一个字符//返回文件中读取的字符char getChar(FILE *fp){char ch=fgetc(fp);return ch;}//判读是否是运算符int isOperation(char a[]) {//返回i表示是运算符在运算符数组中的位置//返回-1表示不是运算符int result;for(int i=0;i<MaxSize2;i++){result=strcmp(a,Operation[i].value); 第4页共12页if(result==0){return i;break;}}return -1;}//判读是否是关键字int isKeyWords(char a[]){//返回i表示在关键字表中的位置//返回-1表示不是关键字int result;for(int i=0;i<MaxSize1;i++){result=strcmp(a,KeyWords[i].value); if(result==0){return i;break;}}return -1;}//判读是否是结束符int isEndOperation(char a){//返回i表示是结束符在结束符表中的位置//返回-1表示不是结束符for(int i=0;i<MaxSize3;i++){if(a==EndOperation[i].value[0]){return i;break;}}return -1;}//判读是否是字符int isChar(char a) { //返回1表示是字符//返回0表示不是字符第5页共12页if(a>='a'&&a<='z') return 1;else if(a>'A'&&a<='Z') return 1;elsereturn 0;}//判读是否是数字int isDigit(char a) {//返回1表示是数字//返回0表示不是数字if(a>='0'&&a<='9') return 1;elsereturn 0;}int count=0;//记录结果表中的关键字及运算符等表项个数,用于返回 int count1=0;//记录标识符的表项个数int count2=0;//记录常量的表项的个数//从屏幕上面获得字符并解析,返回在结果表中的表项 int start1(FILE *in) {char buff[20];//用于保存单词的缓冲区char nextchar[2];char temp[20];//用于保存变量或常量的类型数组int i=0;//缓冲区指针int a;//比较的结果指针char op[3];//用于保存第一个运算符op[2]='\0';nextchar[0]=fgetc(in);nextchar[1]='\0';while(nextchar[0]!=EOF){if(isChar(nextchar[0])){buff[i]=nextchar[0];i++;nextchar[0]=fgetc(in);}else if(isDigit(nextchar[0])){buff[i]=nextchar[0];i++;nextchar[0]=fgetc(in);}else if(nextchar[0]=='\r'||nextchar[0]=='\n')第6页共12页{buff[i]='\0';a=isKeyWords(buff);if(a!=-1&&i>0){strcpy(Table1[count].value,KeyWords[a].value);Table1[count].number=KeyWords[a].number;strcpy(Table1[count].description,KeyWords[a].description); count++;//计数器加一i=0;//清空缓冲区}else if(i>0){if(isChar(buff[0])){//是标识符strcpy(Variable[count1].value,buff);Variable[count1].number=count1;strcpy(Variable[count1].description,"标识符");count1++;//计数器加一i=0;//清空缓冲区}else if(isDigit(buff[0])){//是常量strcpy(Const[count2].value,buff);Const[count2].number=count2;strcpy(Const[count2].description,"常量"); count2++;//计数器加一i=0;//清空缓冲区}}else{//缓冲区为空~}//处理回车符与换行符nextchar[0]=fgetc(in);}else if(isEndOperation(nextchar[0])!=-1) {buff[i]='\0';a=isKeyWords(buff);if(a!=-1&&i>0)第7页共12页{strcpy(Table1[count].value,KeyWords[a].value);Table1[count].number=KeyWords[a].number;strcpy(Table1[count].description,KeyWords[a].description); strcpy(temp,KeyWords[a].value);count++;//计数器加一i=0;//清空缓冲区}else if(i>0){if(isChar(buff[0])){//是标识符strcpy(Variable[count1].value,buff);Variable[count1].number=count1;strcpy(Variable[count1].description,"标识符");count1++;//计数器加一i=0;//清空缓冲区}else if(isDigit(buff[0])){//是常量strcpy(Const[count2].value,buff);Const[count2].number=count2;strcpy(Const[count2].description,"常量");count2++;//计数器加一i=0;//清空缓冲区}}else{//缓冲区为空~}nextchar[0]=fgetc(in);}else if((a=isOperation(nextchar))!=-1){//首先输出缓冲区中的数据buff[i]='\0';a=isKeyWords(buff);if(a!=-1&&i>0){strcpy(Table1[count].value,KeyWords[a].value);Table1[count].number=KeyWords[a].number;strcpy(Table1[count].description,KeyWords[a].description); 第8页共12页count++;//计数器加一i=0;//清空缓冲区}else if(i>0){if(isChar(buff[0])){//是标识符strcpy(Variable[count1].value,buff);Variable[count1].number=count1;strcpy(Variable[count1].description,"标识符"); count1++;//计数器加一i=0;//清空缓冲区}else if(isDigit(buff[0])){//是常量strcpy(Const[count2].value,buff);Const[count2].number=count2;strcpy(Const[count2].description,"常量"); count2++;//计数器加一i=0;//清空缓冲区}}else{//缓冲区为空~}//处理运算符op[0]=nextchar[0];nextchar[0]=fgetc(in);if(nextchar[0]!='@'){if(isOperation(nextchar)!=-1){op[1]=nextchar[0];if((a=isOperation(op))!=-1){//输出双目运算符strcpy(Table1[count].value,Operation[a].value);Table1[count].number=Operation[a].number;strcpy(Table1[count].description,Operation[a].description); count++;//计数器加一//读取下一个字符nextchar[0]=fgetc(in);第9页共12页}else{//错误的双目运算符strcpy(Table1[count].value,op);Table1[count].number=-1;strcpy(Table1[count].description,"未定义的运算符");count++;//计数器加一//读取下一个字符nextchar[0]=fgetc(in);}}else{//输出一元运算符op[1]='\0';a=isOperation(op);strcpy(Table1[count].value,Operation[a].value);Table1[count].number=Operation[a].number;strcpy(Table1[count].description,Operation[a].description); count++;//计数器加一}}}}return count;}void main(){inputKeyWords(WordsBuff,MaxSize1); inputOperation(OperationBuff,MaxSize2); inputEndOperation(EndOperationBuff,MaxSize3); FILE *in,*out;bool Flag=true;while(Flag){printf("源文件的位置:C:\\input.txt\n");if((in=fopen("C:\\input.txt","r"))==NULL) {printf("读取源文件失败~\n");exit(0);}if((out=fopen("C:\\out.txt","w"))==NULL){printf("打开文件失败~\n");第10页共12页exit(0);}int MaxSize=start1(in);printf("关键字及运算符\n");fprintf(out,"关键字及运算符\n"); outputInfo(Table1,MaxSize); outInfoToFile(Table1,MaxSize,out); printf("标识符表:\n");fprintf(out,"标识符表:\n"); outputInfo(Variable,count1); outInfoToFile(Variable,count1,out); printf("常量表:\n");fprintf(out,"常量表:\n"); outputInfo(Const,count2); outInfoToFile(Const,count2,out); Flag=false;fclose(in);fclose(out);}}3.测试用例:int a=3;double b=4;int c;if(a>b)c=a;elsec=b;4.测试结果:第11页共12页5.心得体会:通过这次实验,我对编译原理这门专业必修课有了进一步的深层次了解,把理论知识应用于实验中,实验过程中对于转义字符,结束符、欠缺了考虑,在多次的调试和改进中最终完善了程序,而在调试过程中学习的知识得到了完善和补充,对词法分析器的理解更进一步。
编译原理词法分析实验

编译原理词法分析实验一、实验目的本实验旨在通过编写一个简单的词法分析器,了解编译原理中词法分析的基本原理和实现方法。
二、实验材料1. 计算机编程环境2. 编程语言三、实验步骤1. 了解词法分析的概念和作用。
词法分析是编译器中的第一个阶段,它的主要任务是将源代码中的字符序列转化为有意义的标识符,如关键字、操作符、常量和标识符等。
2. 设计词法分析器的流程和算法。
词法分析器的主要原理是通过有限状态自动机来识别和提取标识符。
在设计过程中,需考虑各种可能出现的字符序列,并定义相应的状态转移规则。
3. 根据设计的流程和算法,使用编程语言编写词法分析器的代码。
4. 编译并运行词法分析器程序,输入待分析的源代码文件,观察程序的输出结果。
5. 分析输出结果,检查程序是否正确地提取了源代码中的标识符。
四、实验结果经过词法分析器的处理,源代码将被成功地转化为有意义的标识符。
结果可以通过以下几个方面来验证:1. 关键字和操作符是否被正确识别和提取。
2. 常量和标识符是否被正确识别和提取。
3. 检查程序的错误处理能力,如能否发现非法字符或非法标识符。
4. 输出结果是否符合预期,可与自己编写的语法规则进行对比。
5. 对于特殊情况,如转义字符等是否正确处理。
五、实验总结通过本次实验,我深入了解了编译原理中词法分析的重要性和基本原理。
编写词法分析器的过程中,我学会了使用有限状态自动机来识别和提取标识符,并通过实践巩固了相关知识。
此外,我还对源代码的结构有了更深入的了解,并且掌握了如何运用编程语言来实现词法分析器。
通过本次实验,我不仅提升了自己的编程技术,也对编译原理有了更深入的认识和理解。
六、实验心得通过实验,我深刻体会到了词法分析在编译过程中的重要性。
合理设计和实现词法分析器,可以大大提高编译器的效率和准确性。
同时,通过编写词法分析器的代码,我不仅锻炼了自己的编程能力,还提升了对编译原理的理解和掌握。
这次实验让我更加深入地了解了编译原理中的词法分析,也为我今后在编程领域的发展打下了坚实的基础。
编译原理实验报告

编译原理实验报告一、实验目的编译原理是计算机科学中的重要课程,旨在让学生了解编译器的基本工作原理以及相关技术。
本次实验旨在通过设计和实现一个简单的编译器,来进一步加深对编译原理的理解,并掌握实际应用的能力。
二、实验环境本次实验使用了Java编程语言及相关工具。
在开始实验前,我们需要安装Java JDK并配置好运行环境。
三、实验内容及步骤1. 词法分析词法分析是编译器的第一步,它将源代码分割成一系列词法单元。
我们首先实现一个词法分析器,它能够将输入的源代码按照语法规则进行切割,并识别出关键字、标识符、数字、运算符等。
2. 语法分析语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。
我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。
3. 语义分析语义分析是编译器的第三步,它对语法树进行检查和转换。
我们主要进行类型检查、语法错误检查等。
如果源代码存在语义错误,编译器应该能够提供相应的错误提示。
4. 代码生成代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。
在本次实验中,我们将目标代码生成为Java字节码。
5. 测试与优化完成以上步骤后,我们需要对编译器进行测试,并进行优化。
通过多个测试用例的执行,我们可以验证编译器的正确性和性能。
四、实验心得通过完成这个编译器的实验,我收获了很多。
首先,我对编译原理的知识有了更深入的理解。
在实验过程中,我深入学习了词法分析、语法分析、语义分析和代码生成等关键技术,对编译器的工作原理有了更系统的了解。
其次,我提高了编程能力。
实现一个完整的编译器需要处理复杂的数据结构和算法,这对我的编程能力是一个很好的挑战。
通过实验,我学会了合理地组织代码,优化算法,并注意到细节对程序性能的影响。
最后,我锻炼了解决问题的能力。
在实验过程中,我遇到了很多困难和挑战,但我不断地调试和改进代码,最终成功地实现了编译器。
编译原理实验报告(词法分析器语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。
三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k (int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。
字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。
2 实验词法分析器源程序:#include <stdio.h>#include <math.h>#include <string.h>int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20);switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)",6,token);else printf("(%d,-)",k);break;case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token);break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break; case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break;default:printf("!\n");}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。
编译原理实验报告--词法分析器

编译原理实验—词法分析器一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
二、实验内容及要求对某特定语言A ,构造其词法规则。
该语言的单词符号包括:保留字(见左下表)、标识符(字母大小写不敏感)、整型常数、界符及运算符(见右下表) 。
功能要求如下所示:·按单词符号出现的顺序,返回二元组序列,并输出。
·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。
·如果出现词法错误,报出:错误类型,位置(行,列)。
·处理段注释(/* */),行注释(//)。
·有段注释时仍可以正确指出词法错误位置(行,列)。
三、实验过程1、词法形式化描述使用正则文法进行描述,则可以得到如下的正规式:其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。
A→(ID | NUM | RES | DEL | OPR) *ID→letter(letter | didit)*NUM→digit digit*letter→a | … | z | A | … | Zdigit→ 0 | … | 9RES→ program | begin | end | var | int | and | or | not | if | then | else | while | doDEL→( | ) | . | ; | ,OPR→+ | * | := | > | < | = | >= | <= | <>如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。
空格由空白、制表符和换行符组成。
2、单词种别定义;A语言中的单词符号及其对应的种别编码如下表所示:单词符号种别编码单词符号种别编码3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、java旗舰版5、关键算法的流程图及文字解释;程序中用到的函数列表:A类定义各种类函数以及包含主函数public static void main()变量ch储存当前最新读进的字符的地址strToken存放当前字符串main() //主函数Analysis()//分析函数,每次读入一行文件,进行识别处理;char GetChar(); //取得当前位置的字符的内容放入ch,并提前指向下一个字符;char GetNextChar();//取得当前位置的下一位置的字符,String ConCat(); //将ch指向的字符连接到strToken后面isLetter(); //判断ch指向的字符是否字母isDigit(); //判断ch指向的字符是否数字add(p,str); //向p表中插入当前strToken的字符串Boolean findKeyWord(str); //检测当前strToken中的字符串是否保留字,若是,则执行getKeyWordKey(str),返回保留字的id,否则,判别其是否是已存在的标示符,若是,返回标示符的id以及该标示符在表中的位置;findPunctuation()//判断是否是一个保留的符号;getindex() //返回已经识别的标示符或者是数字的位置下标;Boolean exist(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回true,否则返回falsevoid callError(); //出错处理过程,将错误的位置报告出来(1)main()函数的流程图如下:)具体分析流程图:开始类初始化,变量的初始化,准备执行main()函数调用Analyse()函数分析输出结果表结束Analyse(str)函数读取第一个字符赋给变量Ch继续判读IndexoutofBound6、测试报告(测试用例,测试结果);首先输入一个不含错误的程序(两种注释)进行检测:运行后在控制台上得到的结果如下所示:得到的二元组序列如下:经检验,输出的是正确的二元组序列。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理实验一
程序设计语言认知实验
1120141882
靳逸
目录
实验目的和内容 (2)
实验环境 (2)
实现的具体过程和步骤 (2)
运行效果截图 (2)
语言易用性和程序模型对比分析 (4)
程序运行性能对比分析 (4)
实验心得体会 (4)
实验目的和内容
实验环境
Windows10家庭中文版64位14393.953
处理器intelCorei5-6300UCPU@2.4GHz2.4GHz
Cache L1-数据2*32KB L1-指令2*32KB
L2 2*256KB
L3 3MB
已安装内存4.00GB
实现的具体过程和步骤
本次实验使用矩阵相乘的题目,在运用一般的算法计算100阶整数型方阵的相乘运行效果截图
C++
Java
Python
Haskell
语言易用性和程序模型对比分析
由于从一开始就接受的结构式的编程,除了haskell,其他语言都使用的十分顺利,只需要明白一定的语法规则即可,而函数式编程的思想与之完全不同,需要更多的思考如何构成结果而不是如何得到结果。
如果算法对结果的构成有十分明确的描述,那么使用函数式语言是更合适的,比如快速排序一类的递归算法。
程序运行性能对比分析
单位:毫秒
由以上数据可知,java速度约为C++的两倍,C++每次的运行时间十分的相近,python和haskell 的运行效率相近,相比c++和Java慢了很多。
实验心得体会
这次实验让我深刻体会到了函数式编程于结构式编程的不同,以及不同语言间的运算效率的不同。