词法分析器设计与实现
- 格式:doc
- 大小:610.50 KB
- 文档页数:27
> C语言词法分析器设计与实现C语言词法分析器的设计与实现一.实验目的1.强化对系统软件综合工程实现能力、规划能力的训练;2.加强对词法分析原理、方法和基本实现技术的理解;二.实验内容用C语言(或 C++ )作为宿主语言完成:其中具体要求:1.使用DFA实现词法分析器的设计;2.实现对C源程序中注释的过滤;3.利用两对半缓冲区从文件中逐一读取单词;4.词法分析结果属性字流存放在独立文件中;5.统计源程序每行单词的个数和整个源文件单词个数;6.具有报告词法错误和出错位置(源程序行号和该行字符)的功能;7.屏幕输出属性字流,每次显示10行,按ESC可中途退出,每行有统计信息,最后有词法分析的全部信息,包括各种属性单词的个数。
三.实验验收与评分要求1.编写C语言词法分析器的源程序并调试通过;2.通过测试程序的验收 (测试程序名称:Test-Lexcial);3.提交简明扼要的书面实验报告。
内容包括:FA设计;源程序主要函数功能;主要数据结构设计。
四. 验收测试用例1. 测试用例一:统一验收测试用例;#include<stdio.h>#include<string.h>char buf[100],str[15];int countdef=0;FILE *fpmiddle;struct define{char with[30];char des[30];char filename[15];}def[30];char* getFileName(){int i=0,k=0;for(i=0;buf[i]!='<'&&i<30&&buf[i]!='\0';i++);i++;while(buf[i]!='>'&&i<30&&buf[i]!='\0')str[k++]=buf[i++];str[k]='\0';puts(str);return str;}long readline(FILE *fpt){if(fgets(buf,100,fpt)==NULL){puts(buf);printf("readline error or reach file end!\n");return 0;}puts(buf);return (long)(strlen(buf)+1);}void writeline(){fprintf(fpmiddle,"%s",buf);}void processDefine(char *filename){int i=8,j=0;while((def[countdef].des[i-8]=buf[i])!=' ') i++;def[countdef].des[i-8]='\0';while((def[countdef].with[j]=buf[i])!='\0'){i++;j++;}def[countdef].with[j-1]='\0';strcpy(def[countdef].filename,filename);countdef++;}long comment(FILE *fpt){char prechar=buf[0],ch='*';int i=0,j=0;for(i=0;buf[i]!='\0'&&!(buf[i]=='/'&&buf[i+1]=='*');i++) ;j=i;buf[i]='\0';if(i==strlen(buf)) return 0L;do{prechar=ch;if((ch=fgetc(fpt))==EOF){printf(" in comment, end");exit(0);}i++;}while(!(prechar=='*'&&ch=='/'));return (long)(i-j+1);}isin(char *p){int i=0,j=0,temp=0;while(temp!=strlen(buf)){while(buf[i]!='\0'&&buf[i]!=p[0])i++;temp=i;while(buf[i]==p[j]&&p[j]!='\0'&&buf[i]!='\0'){i++;j++;}if((i-temp)==strlen(p)) return temp;i=temp+1;j=0;}return -1;}void includeAndDefine(FILE *fpt){void add(char*);void replace(char*);while(readline(fpt)){if(isin("#include")>=0)add(getFileName());else if(isin("#define")>=0)processDefine(str);else{fseek(fpt,comment(fpt),1);replace(str);writeline();}}}void add(char *filename){void replace(char*);FILE *fpp;if((fpp=fopen(filename,"r"))==NULL){printf("file %s not found or open error!",filename);exit(0);}fseek(fpp,-readline(fpp),1);if(isin("#include")<0&&isin("#define")<0)while(readline(fpp)){fseek(fpp,comment(fpp),1);replace(filename);writeline();}elseincludeAndDefine(fpp);fclose(fpp);}void replace(char *filename){int i=0,start=0;for(i=0;i<countdef;i++)if(!strcmp(def[i].filename,filename))break;if(i>=countdef||(start=isin(def[i].des))==-1) return;else{int lenOfWith=strlen(def[i].with);int lenOfDes=strlen(def[i].des);if(lenOfDes>=lenOfWith){int k,j;for(k=start; k<start+lenOfWith; k++)buf[k]=def[i].with[k-start];for(j=(start+lenOfWith); j<start+lenOfDes; j++) buf[j]=' ';}else{int offset=lenOfWith-lenOfDes;int k,j;for(k=offset+strlen(buf);k>start;k--)buf[k]=buf[k-offset];for(j=start;j<start+lenOfWith;j++)buf[j]=def[i].with[j-start];}}}2. 自己编写的C语言词法分析器源码。
编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
《编译原理》课程实验报告实验题目:某种简单程序语言的词法分析器的设计与实现专业:计算机科学与技术班级:11060341学号:11060341姓名:实验目的:设计一个词法分析程序,理解词法分析器实现的原理,掌握程序设计语言中的各类单词的词法分析方法,加深对词法分析原理的理解。
实验任务:词法分析是从左向右扫描每行源程序的符号,拼成单词,换成统一的二元式(单词种别,单词符号的属性值)表示。
对给定的程序通过词法分析器识别一个个单词符号,并以二元式(单词种别,单词符号的属性值)显示,本程序则是通过对给定程序段分析后以单词符号和文字提示显示)实验流程:程序清单:#include<iostream>#include<cstdio>#include<cstring>using namespace std;int k=0;struct word{char name[10];int kind;} word[1000];char key[35][10]= {"scanf","short","int","long","float","double","char","struct","union","printf","typedef","const","unsigned","signed","extern","register","static","volatile","void","if","else","switch","case","for","do","while","goto","continue","break","default","sizeof","return","include","bool"};bool cmp(char a[]){int i;for(int k=0; k<35; k++){if(strcmp(a,key[k])==0)return 1;}return 0;}int main(){#ifdef LOCALfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);#endifint p,q,flag;char a[1000],b[10],ch;while(gets(a)){p=0;int len=strlen(a);while(p<len){ch=a[p];memset(b,0,sizeof(b));while(ch==' '){p++;ch=a[p];}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||ch=='_'){flag=0;q=0;while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||ch=='_'||(ch>='0'&&ch<='9')) {if((ch>='0'&&ch<='9')||ch=='_')flag=1;b[q++]=ch;p++;ch=a[p];}if(flag==1){strcpy(word[k].name,b);word[k++].kind=1;}else if(flag==0){if(ch=='\''||ch=='"'){strcpy(word[k].name,b);word[k++].kind=2;}else if(cmp(b)==1){strcpy(word[k].name,b);word[k++].kind=3;}else{strcpy(word[k].name,b);word[k++].kind=1;}}}else if((ch>='0'&&ch<='9')||ch=='-'){if(a[t]>='0'&&a[t]<='9'||a[t]>='a'&&a[t]<='z'||a[t]>='A'&&a[t]<='Z'){p++;ch=a[p];if(ch=='-'||ch=='='){b[0]='-';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='-';strcpy(word[k].name,b);word[k++].kind=5;}}else{q=0;b[q++]=ch;p++;ch=a[p];while((ch>='0'&&ch<='9')||ch=='.'){b[q++]=ch;p++;ch=a[p];}strcpy(word[k].name,b);word[k++].kind=2;}}elseif(ch=='('||ch==')'||ch=='['||ch==']'||ch=='{'||ch=='}'||ch==','||ch==';'||ch==':'||ch=='\''||ch=='"')//ch=='('| |ch==')'||ch=='['||ch==']'||ch=='{'||ch=='}'||{b[0]=ch;strcpy(word[k].name,b);word[k++].kind=4;}else if(ch=='%'||ch=='^'){b[0]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else if(ch=='+'){p++;ch=a[p];if(ch=='+'||ch=='='){b[0]='+';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='+';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='*'){p++;ch=a[p];if(ch=='*'||ch=='='){b[0]='*';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='*';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='/'){p++;ch=a[p];if(ch=='/'||ch=='='){b[0]='/';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='/';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='='){p++;ch=a[p];if(ch=='='){b[0]=b[1]='=';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='=';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='>'){p++;ch=a[p];if(ch=='>'||ch=='='){b[0]='>';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='>';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='<'){p++;ch=a[p];if(ch=='<'||ch=='='){b[0]='<';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='<';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='!'){p++;ch=a[p];if(ch=='='){b[0]='!';b[1]='=';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='!';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='&'){p++;ch=a[p];if(ch=='&'){b[0]=b[1]='&';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='&';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='|'){p++;ch=a[p];if(ch=='|'){b[0]=b[1]='|';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='|';strcpy(word[k].name,b);word[k++].kind=5;}}}}for(int i=0; i<k; i++){switch(word[i].kind){case 1:{printf("(标识符,");break;}case 2:{printf("(常量,");break;}case 3:{printf("(关键字,");break;}case 4:{printf("(界符,");break;}case 5:{printf("(运算符,");break;}}printf("%s)\n",word[i].name); }int a1=0,a2=0,a3=0,a4=0,a5=0; for(int i=0;i<k;i++){if(word[i].kind==1)a1++;else if(word[i].kind==2)a2++;else if(word[i].kind==3)a3++;else if(word[i].kind==4)a4++;else if(word[i].kind==5)a5++;}printf("标识符:%d\n常量:%d\n关键字:%d\n界符:%d\n运算符:%d\n",a1,a2,a3,a4,a5);return 0;}运行结果:。
课程设计(论文)任务书软件学院学院软件测试专业 2 班一、课程设计(论文)题目词法分析器的设计与实现二、课程设计(论文)工作自2014 年 6 月16 日起至2014 年6 月 21 日止。
三、课程设计(论文) 地点: 软件学院实训中心四、课程设计(论文)内容要求:1.本课程设计的目的进一步培养学生编译器设计的思想,加深对编译原理和应用程序的理解,针对编译过程的重点和难点内容进行编程,独立完成有一定工作量的程序设计任务,同时,强调好的程序设计风格,并综合使用程序设计语言、数据结构和编译原理的知识, 熟悉使用开发工具VC /JA V A/C#/.NET 。
2.课程设计的任务及要求1)课程设计任务:词法分析器的设计词法分析器的实现扫描器的设计与实现2)创新要求:在到达基本要求后,可进行创新要求。
3)课程设计论文编写要求(1)课程设计任务及要求(2)设计思路--工作原理、功能规划(3)详细设计---数据分析、算法思路、功能实现(含程序流程图、主要代码及注释)、界面等。
(4)运行调试与分析讨论---给出运行屏幕截图,分析运行结果,有何改进想法等。
(5)设计体会与小结---设计遇到的问题及解决办法,通过设计学到了哪些新知识,巩固了哪些知识,有哪些提高。
(6)报告按规定排版打印,要求装订平整,否则要求返工;(7)课设报告的装订顺序如下:封面---任务书---中文摘要---目录----正文---附录(代码及相关图片)(8)严禁抄袭,如有发现,按不及格处理。
4)课程设计评分标准:(1)学习态度:20分;(2)系统设计:20分;(3)编程调试:20分;(4)回答问题:20分;(5)论文撰写:20分。
5)参考文献:(1)张素琴,吕映芝. 编译原理[M]., 清华大学出版社(2)蒋立源、康慕宁等,编译原理(第2版)[M],西安:西北工业大学出版社6)课程设计进度安排1.准备阶段(4学时):选择设计题目、了解设计目的要求、查阅相关资料2.程序模块设计分析阶段(4学时):程序总体设计、详细设计3.代码编写调试阶段(8学时):程序模块代码编写、调试、测试4.撰写论文阶段(4学时):总结课程设计任务和设计内容,撰写课程设计论文学生签名:2014 年 6 月21 日课程设计(论文)评审意见(1)学习态度(20分):优()、良()、中()、一般()、差();(2)系统设计(20分):优()、良()、中()、一般()、差();(3)编程调试(20分):优()、良()、中()、一般()、差();(4)回答问题(20分):优()、良()、中()、一般()、差();(5)论文撰写(20分):优()、良()、中()、一般()、差();评阅人:职称:副教授2014 年 6 月26 日中文摘要词法分析器的工作是低级别的分析:将字符或者字符序列转化成记号.。
编译方法课程设计词法分析器设计学院:计算机与信息工程学院专业:软件工程学号:姓名:指导教师:职称:设计报告日期:二О一二年十二月目录1设计概述 (2)1.1设计题目 (2)1.2 设计目的 (3)1.3 设计任务内容: (3)1.4 设计时间 (3)2 设计环境与工具 (3)3设计要求 (3)4分析与概要设计 (4)5算法描述与框图 (4)6 源程序清单 (6)7 软件测试 (10)7.1 设计的测试题目 (10)7.2测试结果截图 (10)8 总结 (10)8 参考文献 (11)1设计概述1.1设计题目词法分析器的设计与实现。
1.2 设计目的词法分析是编译程序第一个阶段的工作,它的任务是对输入的字符串形式的源程序进行扫描,在扫描的同时,根据源语言的词法规则识别具有独立意义的单词。
本设计是C++高级程序语言,数据结构和变异原理中词法分析原理等知识的综合运用。
掌握生成词法分析器的方法,加深对词法分析原理的理解,掌握设计,编制并调试词法分析程序的思想和方法。
1.3 设计任务内容:1、格式输入:将C++语言的源代码从文本文档中读入。
处理:对输入框中的代码进行词法分析,分离出关键字、标示符、数值、运算符和界符。
输出:在文本文档中输出每个单词对应的编码和值。
2、编译对象声明和其他标记赋值语句分支结构语句循环语句1.4 设计时间2012年12月23日至2012年12月28日2 设计环境与工具Windows7环境下使用 C++语言。
3设计要求1、使用任何一种编程语言编制一个词法分析程序。
2、该程序能够识别的单词有5类:(1)关键字:"long", "float", "static", "char", "short", "switch", "int", "const", "if", "then", "else", "for", "while", "break"。
词法分析器的设计与实现词法分析器的设计与实现内蒙古财经学院计算机信息管理学院,内蒙古呼和浩特摘要介绍了词法分析器的概念,并指出词法分析器设计时,输入的源程序以文件的形式存储在外部。
主控程序通过打开文件调用待分析的源程度。
关键词词法分析器;正规式;自动机中图分类号TP391 文献标识码A 文章编号词法分析是编译程序进行翻译的第一个阶段,他对程序进行线性分析,从字符串中分出单词,并检查所分出的单词是否为合法的词类。
编译中的分词思想在“文本格式化”及“公式排版”中应用的比较广泛,是一种实用性很强的分析方法。
词法分析顾名思义就是分词。
它以程序设计语言编制的源程序作为输入,以单词序列作为输出。
分词过程可以通过编制程序自动完成,我们通常称这个分词程序为词法分析器。
词法分析器分析的源程序可以是现有的各类程序设计语言源程序也可以是人为给定的模型语言的源程序。
本文中的源程序为后者。
词法分析器的设计词法分析在教学上的主要应用是对源程序进行分词同时验证词的合法性,词法分析的输入是给定的模型语言,输出为单词序列。
输入的源程序可以看成是一个字符串序列,通过把源程序看作字符串序列就可以采用形式语言的一些现有理论处理相关的编译问题。
分词的输出为单词序列,单词是一个有共同含义的字符集。
由于程序设计语言中通常使用空格来分割不同的词,因此初学者在理解这一概念时可以简单的把空格分隔开的字符串认为是一个单词。
词法分析器设计时,输入的源程序以文件的形式存储在外部。
主控程序通过打开文件调用待分析的源程序。
我给定的模型语言如图4。
从词的角度来看,它涉及的内容较为简单,只包括几个较为常用的词类,词类的构成上也适当的作了一些简化。
对词进行分析时,我们是按类型进行分析的。
不同类型的词在后续的分析中所起的作用不同,相应的操作也各有不同,但同种类型中的词虽然单词的构成不同但从宏观上看它们的操作大体一致。
模型语言中的单词可以分为”关键字”、“标识符”、“常数”、“分隔符”、“运算符”几类。
词法分析器实验报告词法分析器实验报告一、引言词法分析器是编译器中的重要组成部分,它负责将源代码分解成一个个的词法单元,为之后的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,以深入理解其工作原理和实现过程。
二、实验目标本实验的目标是设计和实现一个能够对C语言代码进行词法分析的程序。
该程序能够将源代码分解成关键字、标识符、常量、运算符等各种词法单元,并输出其对应的词法类别。
三、实验方法1. 设计词法规则:根据C语言的词法规则,设计相应的正则表达式来描述各种词法单元的模式。
2. 实现词法分析器:利用编程语言(如Python)实现词法分析器,将源代码作为输入,根据词法规则将其分解成各种词法单元,并输出其类别。
3. 测试和调试:编写测试用例,对词法分析器进行测试和调试,确保其能够正确地识别和输出各种词法单元。
四、实验过程1. 设计词法规则:根据C语言的词法规则,我们需要设计正则表达式来描述各种词法单元的模式。
例如,关键字可以使用'|'操作符将所有关键字列举出来,标识符可以使用[a-zA-Z_][a-zA-Z0-9_]*的模式来匹配,常量可以使用[0-9]+的模式来匹配等等。
2. 实现词法分析器:我们选择使用Python来实现词法分析器。
首先,我们需要读取源代码文件,并将其按行分解。
然后,针对每一行的代码,我们使用正则表达式进行匹配,以识别各种词法单元。
最后,我们将识别出的词法单元输出到一个结果文件中。
3. 测试和调试:我们编写了一系列的测试用例,包括各种不同的C语言代码片段,以测试词法分析器的正确性和鲁棒性。
通过逐个测试用例的运行结果,我们可以发现和解决词法分析器中的问题,并进行相应的调试。
五、实验结果经过多次测试和调试,我们的词法分析器能够正确地将C语言代码分解成各种词法单元,并输出其对应的类别。
例如,对于输入的代码片段:```cint main() {int a = 10;printf("Hello, world!\n");return 0;}```我们的词法分析器将输出以下结果:```关键字:int标识符:main运算符:(运算符:)运算符:{关键字:int标识符:a运算符:=常量:10运算符:;标识符:printf运算符:(常量:"Hello, world!\n"运算符:)运算符:;关键字:return常量:0运算符:;```可以看到,词法分析器能够正确地将代码分解成各种词法单元,并输出其对应的类别。
词法分析程序的设计与实现方法1:采用C作为实现语言,手工编制一.文法及状态转换图1.语言说明:C语言有以下记号及单词:(1)标识符:以字母开头的、后跟字母或数字组成的符号串。
(2)关键字:标识符集合的子集,该语言定义的关键字有32个,即auto,break,case,char,const,continue,default,do,double,else,enum, extern,float,for,goto,if,int,long,register,return,short,signed,static, sizeof,struct,switch,typedef ,union,unsigned ,void, volatile和while。
(3)无符号数:即常数。
(4)关系运算符:<,<=,==,>,>=,!=。
(5)逻辑运算符:&&、||、!。
(6)赋值号:=。
(7)标点符号:+、++、-、--、*、:、;、(、)、?、/、%、#、&、|、“”、,、.、{}、[]、_、^等(8)注释标记:以“/*”开始,以“*/”结束。
(9)单词符号间的分隔符:空格。
2.记号的正规文法:仅给出各种单词符号的文法产生式(1)标识符的文法id->letter ridrid->ε|letter rid|digit rid(2)无符号整数的文法digits->digit remainderremainder->ε|digit remainder(3)无符号数的文法num->digit num1num1->digit num1|. num2|E num4|εnum2->digit num3num3->digit num3|E num4|εnum4->+digits|-digits|digit num5digits->digit num5num5->digit num5|ε(4)关系运算符的文法relop-> <|<=|==|>|>=|!=(5)赋值号的文法assign_op->=(6)标点符号的文法special_symbol->+|-|*|%|#|^|(|)|{|}|[|]|:|;|”|?|/|,|.& (7)逻辑运算符的文法logic->&&| || | !(8)注释头符号的文法note->/starstar->*3.状态转换图其中,状态0是初始状态,若此时读入的符号是字母,则转换到状态1,进入标识符识别过程;如果读入的是数字,则转换到状态2,进入无符号数识别过程;……;若读入的符号是/,转换到状态11,再读入下一个符号,如果读入的符号是*,则转换到状态12,进入注释处理状态;如果在状态0读入的符号不是语言所定义的单词符号的开始字符,则转换到状态13,进入错误处理状态。
词法分析器的实验报告词法分析器的实验报告引言:词法分析器是编译原理中的重要组成部分,它负责将源代码中的字符序列转换为有意义的词法单元,为后续的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,并对其进行测试和评估。
实验设计:1. 词法规则设计:在开始实验之前,我们首先需要设计词法规则,即定义源代码中的合法词法单元。
例如,对于一门类C的语言,我们可以定义关键字(如if、while、int等)、标识符、运算符(如+、-、*等)、分隔符(如()、{}等)等。
2. 有限自动机(DFA)的设计:基于词法规则,我们可以设计一个有限自动机,用于识别和分析源代码中的词法单元。
有限自动机是一个状态转换图,其中每个状态代表一种词法单元,而边表示输入字符的转换关系。
3. 实现代码:根据有限自动机的设计,我们可以使用编程语言(如Python、C++等)实现词法分析器的代码。
代码的主要功能包括读取源代码文件、逐个字符进行词法分析、识别和输出词法单元。
实验过程:1. 词法规则设计:我们以一门简单的算术表达式语言为例,设计了以下词法规则:- 数字:由0-9组成的整数或浮点数。
- 运算符:包括+、-、*、/等。
- 分隔符:包括括号()和逗号,。
- 标识符:以字母开头,由字母和数字组成的字符串。
2. 有限自动机(DFA)的设计:我们基于词法规则,设计了一个简单的有限自动机。
该自动机包含以下状态:- 初始状态:用于读取和识别源代码中的字符。
- 数字状态:用于识别和输出数字。
- 运算符状态:用于识别和输出运算符。
- 分隔符状态:用于识别和输出分隔符。
- 标识符状态:用于识别和输出标识符。
3. 实现代码:我们使用Python编程语言实现了词法分析器的代码。
代码主要包括以下功能:- 读取源代码文件。
- 逐个字符进行词法分析,根据有限自动机的设计进行状态转换。
- 识别和输出词法单元。
实验结果:我们对几个测试样例进行了词法分析,并对结果进行了评估。
词法分析器的设计一.设计说明及设计要求一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。
本课程设计即为词法分析阶段。
词法分析阶段是编译过程的第一个阶段。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。
如保留字(关键字或基本字)、标志符、常数、算符和界符等等。
二.设计中相关关键字说明1.基本字:也称关键字,如C语言中的if , else , while , do ,for,case,break, return 等。
2.标志符:用来表示各种名字,如常量名、变量名和过程名等。
3.常数:各种类型的常数,如12,6.88,和“ABC”等。
4.运算符:如+ ,- , * , / ,%, < , > ,<= , >= 等。
5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。
三、程序分析词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源程序进行扫描,产生一个个单词序列,用以语法分析。
词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。
然而,更一般的情况,常将词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则调用该子程序。
词法分析程序每得到一次调用,便从源程序文件中读入一些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。
四、模块设计下面是程序的流程图五、程序介绍在程序当前目录里建立一个文本文档,取名为infile.txt,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。
程序结果输出在同一个目录下,文件名为outfile.txt,此文件为自动生成。
本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。
词法分析器设计与实现一、问题描述:设计并实现一个小型程序语言(Micro)的词法分析器,实现源程序的输入,预处理词法分析,最后以编译程序需要的内部表示形式(二元组)将识别的单词符号输出。
利用状态转换图设计Micro语言的词法规则,用C语言实现该词法分析程序。
实验环境:C/C++开发平台。
二、Micro的单词分类:标识符:字母打头的字母/数字串常数:数字打头的数字串保留字:begin,end, var,read,write,integer,real符号:+,*,(,),:,=,;三、设计思想1)本程序的状态转换图如下:图1:标识符状态表示图图2:识别常数状态表示图图3:识别符号状态表示图2)状态转换图的实现a)ch 字符变量,读进最新的源程序字符b)strToken 字符数组,存放构成单词符号的字符串有了以上定义,对常数状态转换图可得:if(ch>='0'&&ch<='9'){strToken[i++]=ch;ch=fgetc(in);while(ch>='0'&&ch<='9'){strToken[i++]=ch;ch=fgetc(in);}if(ch!='.') {strToken[i++]='\0';fprintf(out,"%s%d,%c%s%c%s\n","(",3,'"',strToken,'"',")"); }else{strToken[i++]=ch;ch=fgetc(in);while(ch>='0'&&ch<='9'){strToken[i++]=ch;ch=fgetc(in);}strToken[i++]='\0';fprintf(out,"%s%d,%c%s%c%s\n","(",3,'"',strToken,'"',")"); }while(ch==' '){ch=fgetc(in);}}3)单词符号及内部种别码,对Micro种别码的设定:四、实验结果本次实验输入输出都采用文件形式。
词法分析器的设计与实现
1.定义词法规则:根据编程语言的语法规范,定义不同的词法规则,
如关键字、标识符、操作符、常量等。
每个词法规则由一个正则表达式或
有限自动机来描述。
2.构建有限自动机:根据词法规则,构建一个有限自动机(DFA)来
识别词法单元。
有限自动机是一种形式化模型,用于在输入字符序列上进
行状态转换。
3.实现状态转换函数:根据有限自动机的定义,实现状态转换函数。
状态转换函数接受一个输入字符,并返回当前状态和输出的词法单元。
4.实现输入缓冲区:为了方便词法分析器的实现,通常需要实现一个
输入缓冲区,用于存储源代码,并提供一些读取字符的函数。
5. 实现词法分析器:将前面实现的状态转换函数和输入缓冲区结合
起来,实现一个完整的词法分析器。
词法分析器可以使用迭代器模式,每
次调用next(函数来获取下一个词法单元。
6.处理错误情况:在词法分析过程中,可能会遇到一些错误情况,如
未定义的词法单元、不符合语法规范的词法单元等。
词法分析器需要能够
检测并处理这些错误情况。
7.构建测试用例:为了验证词法分析器的正确性,需要构建测试用例,包括各种不同的源代码片段,并验证分析结果是否符合预期。
8.进行性能优化:词法分析是编译器中的一个耗时操作,因此可以进
行一些性能优化,如使用缓存机制、减少状态转换次数等。
以上是词法分析器的设计与实现的一般步骤,具体实现过程可能因编程语言和编译器的不同而有所差异。
词法分析器的实现与设计
1. 确定待分析的源代码的字符集和词法规则:首先,确定源代码所
使用的字符集,例如ASCII或Unicode。
然后,根据编程语言的语法规则,确定各种词法单元(如关键字、标识符、操作符、常量等)的识别规则。
2.设计识别词法单元的算法:根据词法规则,设计算法来识别每个词
法单元。
通常,这涉及到使用正则表达式或有限自动机(DFA)来进行模
式匹配。
3. 实现词法分析器:使用选定的编程语言实现词法分析器。
词法分
析器可以使用手写的代码实现,也可以使用工具(如Lex、Flex等)来自
动生成。
4.构建词法分析器的输入和输出接口:词法分析器通常需要从输入流
中读取源代码,并将识别出的词法单元输出到输出流中。
因此,需要设计
适当的输入和输出接口。
5.测试和调试词法分析器:编写测试用例,用不同类型的代码对词法
分析器进行测试,以确保它能正确地识别各种词法单元。
在测试过程中,
需要检查词法分析器的输出是否符合预期的结果。
6.集成到编译器中:将词法分析器集成到编译器的其他部分中,例如
语法分析器、语义分析器等。
这需要定义合适的接口,并确保各个部分之
间的协调工作。
总结起来,词法分析器的设计和实现包括选择字符集和词法规则、设
计识别算法、实现词法分析器、构建输入和输出接口、测试和调试以及集
成到编译器中。
这些步骤需要综合考虑编程语言的特点、词法规则的复杂
性和性能需求等因素。
实验一词法分析程序设计与实现一、实验目的及内容调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验原理(状态转换图)1、C语言子集(1)关键字:begin if then while do end所有关键字都是小写。
(2)运算符和界符::= + –* / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
3、词法分析程序的功能输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
二、软件平台及工具PC机以及VISUAL C++6.0软件。
三、实验方法、步骤(或:程序代码或操作过程)(1)程序代码:#include<stdio.h>#include<string.h>#include<iostream.h>char prog[80],token[8];char ch;int syn,p,m=0,n,row,sum=0;char *rwtab[6]={"begin","if","then","while","do","end"};void scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}else if((ch>='0'&&ch<='9')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;p--;}break;case'*':syn=13;token[0]=ch;break; case'/':syn=14;token[0]=ch;break; case'+':syn=15;token[0]=ch;break; case'-':syn=16;token[0]=ch;break; case'=':syn=25;token[0]=ch;break; case';':syn=26;token[0]=ch;break; case'(':syn=27;token[0]=ch;break; case')':syn=28;token[0]=ch;break; case'#':syn=0;token[0]=ch;break; case'\n':syn=-2;break;default: syn=-1;break;}}void main(){p=0;row=1;cout<<"Please input string:"<<endl;do{cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11: cout<<"("<<syn<<","<<sum<<")"<<endl; break;case -1: cout<<"Error in row "<<row<<"!"<<endl; break;case -2: row=row++;break;default: cout<<"("<<syn<<","<<token<<")"<<endl;break;}}while (syn!=0);}(2)创建编辑程序(3)连接、编译和调试程序(4)运行程序五、实验过程原始记录( 测试数据、图表、计算等)(1)给定源程序begin x:=8; if x>0 then x:=2*x+1/5; end#输出结果(2)源程序(包括上式未有的while、do以及判断错误语句):beginx<=$; whilea<0dob<>9-x; end#。
实验一:词法分析器的设计与实现
实验目的:
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、算符、界符五大类。
并依次输出各个单词的内部编码及单词符号自身价值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
实验内容:
给定一个C语言的子集,如下:
关键字(小写)
main if else int return void while
算符或界符:
= + - * / < <= > >= = = != ;:,{ } [ ] ( )
标识符是字母开头,后面字母和数字组合
数值指无符号常数
空格一般用来分隔标识符、数值、专用符号和关键字
实验要求:
1.请给出自己单词符号的种别码表
2.给出标识符ID和数值NUM的正规式定义
3.给出该语言的子集对应的状态转换图
4.词法分析器的功能
输入:所给文法的源程序
输出:二元组(token 或sum ,syn)构成的序列。
其中
syn 为单词种别码
token 为存放单词自身字符串
sum 为整型常数
5.给出总体及各主要程序段的算法流程
把源程序放入一个数组中,用token数组取词;
进行匹配查找,和错误处理,最后输出。
6.给出程序使用说明、程序运行示例
给出完整可执行程序的程序代码(有关键变量及关键语句的注释)。
实验项目一词法分析程序的设计与实现实验目的1. 学会针对DFA转换图实现相应的高级语言源程序。
2. 深刻领会状态转换图的含义,逐步理解有限自动机。
3. 掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理。
实验内容计算机语言的编译程序的词法分析部分实现。
从左到右扫描每行该语言源程序的符号,拼成单词,换成统一的内部表示(token)送给语法分析程序。
为了简化程序的编写,有具体的要求如下:1)整数或浮点数。
2)空白符仅仅是空格、回车符\n、制表符\t。
3)代码是自由格式。
4)注释应放在花括号或者/* */或者// 之内,并且不允许嵌套要求实现编译器的以下功能:1)按规则拼单词,并转换成二元式形式2)删除注释行3)删除空白符(空格、回车符、制表符),即中间表示形式中不含空白符。
4)列表打印源程序,按照源程序的行打印,在每行的前面加上行号,并且打印出每行包含的记号的二元形式5)能发现并定位词法错误词法分析建议:1)记号的二元式形式中种类采用枚举方法定义;其中保留字和特殊字符是每个都一个种类,标示符自己是一类,数字是一类;单词的属性值就是表示的字符串值。
2)词法分析的具体功能实现是一个函数GetToken(),每次调用都对剩余的字符串分析得到一个单词或记号识别其种类,收集该记号的符号串属性,当识别一个单词完毕,采用返回值的形式返回符号的种类,同时采用程序变量的形式提供当前识别出记号的属性值。
3)标示符和保留字的词法构成相同,为了更好的实现,把语言的保留字建立一个表格存储,这样可以把保留字的识别放在标示符之后,用识别出的标示符对比该表格,如果在该表格中则是保留字,否则是一般标示符。
词法分析的过程可如下描述:测试测试该设计词法分析器,代码可自选,例如自己编写的某段程序。
输入与输出形式:例如输入main() {int i = 10;while(i) i = i - 1;}输出如下二元式代码序列:1, (1,main) (26,() (27,)) (30,{)2, (2,int) (10,i) (21,=) (20,10) (34,;)3, (7,while) (26,() (10,i) (27,)) (10,i) (21, =) (10,i) (23,-) (20,1) (34,;) 4, (31,})测试代码:/*PROGRAM 求max*/float max2(float x, float y){ float max;if(x>y) max=x;else max=y;return max;}main( ){ float a,b,max;printf("Input values of a and b: "); scanf("%f%f",&a,&b);max=max2(a,b);printf("max(%f,%f)=%f\n",a,b, max); }。
合肥学院
计算机科学与技术系
课程实验报告
2016~2017学年第二学期
课程软件编译技术
学生姓名罗萱(组长)
学号**********
学生姓名郑李
学号**********
学生姓名丁希林
学号**********
专业班级14软工2班
指导教师吴晓琴
2017 年 3 月
签字:年月日
实验序号及名称:实验一词法分析器的设计与实现
姓名:郑李实验时间:2017年3月25日
六、完整的实验结果(程序、电路或相关的数据等)记录(不够可在第四页续)
输入:
main()
{ int a,b;
a = 10;
b = a + 20;
}
实验结果:
main 2 ( 5 ) 5 { 5 int 0 a 2 , 5 b 2 , 5 c 2 ; 5 a 2 = 4 8 3 ; 5 b 2 = 4
实验序号及名称:实验一词法分析器的设计与实现
姓名:丁希林实验时间:2017年3月25日
六、完整的实验结果(程序、电路或相关的数据等)记录(不够可在第四页续)
输入:
main()
{ int a,b;
a = 10;
b = a + 20;
}
实验结果:
main 2 ( 5 ) 5 { 5 int 0 a 2 , 5 b 2 , 5 c 2 ; 5 a 2 = 4 8 3 ; 5 b 2 = 4
实验序号及名称:实验一词法分析器的设计与实现
姓名:罗萱实验时间:2017年3月25日
六、完整的实验结果(程序、电路或相关的数据等)记录(不够可在第四页续)
输入:
main()
{ int a,b;
a = 10;
b = a + 20;
}
实验结果:
main 2 ( 5 ) 5 { 5 int 0 a 2 , 5 b 2 , 5 c 2 ; 5 a 2 = 4 8 3 ; 5 b 2 = 4。