简单的词法分析器设计

合集下载

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

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

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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、环境及工具操作系统:windows XP ;使用工具:Microsoft Visual C++ 6.0; 编程语言:C 语言;4、分析程序输入:从文件中读入程序段;程序输出:由单词种别和单词符号的属性值组成的二元式;单词种别通常使用整数编码,编码方式可以有多种,在设计词法分析器之前应确定一种程序处理起来较方便的编码方式。

当一个种别中含有多个单词符号时,在分析出其属于哪个种别的时候应同时给出其单词符号属性,本程序为方便起见,采用单词符号本身来作为其属性,以标识同种别种的不同单词符号。

标识符及关键字的识别:字母开头的字母和数字组成的串是多数编程语言的标识符,所以我们的简易词法分析器中,将标识符定义为这种字母数字串。

当第一个字母为字母且紧接着的字符为数字或字母时,应将其串接在一起为一个单词,直到紧跟着的不在是字母数字时。

由于关键字通常为一个单词,则这样得到的串可能是标识符也可能是关键字,又因为一种语言的关键字通常是有限个,则我们可以构造一个存放所有关键字的表,查询关键字表,可以判断得到的串是否为关键字。

界符和运算符的识别:它们多为当个字符,建立两个分别存放界符合运算符的表,读取字符后,进行查表便可以得出它们的类型。

为方便词法分析器的设计,可以使用状态转换图,根据一种特定的编程语言先设计出其状态转换图才能更好将其用代码实现。

典型状态转换图结构如下:(a)有不含回路含分支的状态节点:对应if …else if …else …语句;(b)有含回路的状态节点:对应while …if …语句。

(b )5、状态转换图6、程序框架描述程序中编写了以下函数,各个函数实现的作用如下:1. GetChar():将下一输入的字符读入到全局变量ch中,搜素指示器前移一个字符的位置。

计算机网络课程设计:词法分析器

计算机网络课程设计:词法分析器

计算机网络课程设计报告班级:计1102姓名:杨勇学号: 41155047词法分析器:一、实验目的调试并完成一个词法分析程序,加深对词法分析原理的理解。

二、实验要求1、待分析的简单语言的词法(1)关键字:begin if then while do end所有关键字都是小写。

(2)运算符和界符::= + –* / <<= <>>>= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。

空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。

2、各种单词符号对应的种别码3、词法分析程序的功能输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

三、C语言程序源代码:#include <stdio.h>#include <string.h>char prog[80],token[8],ch;int syn,p,m,n,sum;char *rwtab[6]={"begin","if","then","while","do","end"}; scaner();main(){p=0;printf("\n please input a string(end with '#'):/n");do{scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11:printf("( %-10d%5d )\n",sum,syn);break;case -1:printf("you have input a wrong string\n");getch();exit(0);default: printf("( %-10s%5d )\n",token,syn);break;}}while(syn!=0);getch();}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;ch=prog[p++];m=0;while((ch==' ')||(ch=='\n'))ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;ch=prog[p++];}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')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':token[m++]=ch;ch=prog[p++];if(ch=='=')token[m++]=ch;}else{ syn=20;p--;}break;case '>':token[m++]=ch; ch=prog[p++];if(ch=='='){ syn=24;token[m++]=ch;}else{ syn=23;p--;}break;case '+': token[m++]=ch; ch=prog[p++];if(ch=='+')token[m++]=ch;}else{ syn=13;p--;} break;case '-':token[m++]=ch; ch=prog[p++];if(ch=='-'){ syn=29;token[m++]=ch;}else{ syn=14;p--;} break;case '!':ch=prog[p++];{ syn=21;token[m++]=ch;}else{ syn=31;p--;}break;case '=':token[m++]=ch; ch=prog[p++];if(ch=='='){ syn=25;token[m++]=ch;}else{ syn=18;p--;}break;case '*': syn=15;token[m++]=ch; break;case '/': syn=16; token[m++]=ch; break;case '(': syn=27; token[m++]=ch; break;case ')': syn=28; token[m++]=ch; break;case '{': syn=5; token[m++]=ch; break;case '}': syn=6; token[m++]=ch; break;case ';': syn=26; token[m++]=ch; break;case '\"': syn=30; token[m++]=ch;break;case '#': syn=0;token[m++]=ch;break;case ':':syn=17;token[m++]=ch;break;default: syn=-1;break;}token[m++]='\0';}三、实验结果:1、给定源程序begin x:=9; if x>0 then x:=2*x+1/3; end#输出结果2、源程序(包括上式未有的while、do以及判断错误语句):beginx<=$;whilea<0dob<>9-x;end#输出结果四、总结分析:通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种高级语言(例如C++语言)直接编写此法分析程序。

用C语言实现简单的词法分析器

用C语言实现简单的词法分析器

⽤C语⾔实现简单的词法分析器词法分析器⼜称扫描器。

词法分析是指将我们编写的⽂本代码流解析为⼀个⼀个的记号,分析得到的记号以供后续语法分析使⽤。

词法分析器的⼯作是低级别的分析:将字符或者字符序列转化成记号.。

要实现的词法分析器单词符号及种别码对照表:单词符号#begin if then while do End+-*/:: =种别码0123456131415161718单词符号<<><=>>==;()Letter(letter|digit)digit digit*种别码2021222324252627281011#include<stdio.h>#include<string.h>char input[200];//存放输⼊字符串char token[5];//存放构成单词符号的字符串char ch; //存放当前读⼊字符int p; //input[]下标int fg; //switch标记int num; //存放整形值//⼆维字符数组,存放关键字char index[6][6]={"begin","if","then","while","do","end"};main(){p=0;printf("please intput string(End with '#'):\n");do{ch=getchar();input[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(fg){case 11:printf("( %d,%d ) ",fg,num);break;case -1:printf("input error\n"); break;default:printf("( %d,%s ) ",fg,token);}}while(fg!=0);getch(); //⽤于让程序停留在显⽰页⾯}/*词法扫描程序:*/scaner(){int m=0;//token[]下标int n;//清空token[]for(n=0;n<5;n++)token[n]=NULL;//获取第⼀个不为0字符ch=input[p++];while(ch==' ')ch=input[p++];//关键字(标识符)处理流程if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')){while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0')){token[m++]=ch;ch=input[p++];}token[m++]='\0';ch=input[--p];fg=10;for(n=0;n<6;n++)if(strcmp(token,index[n])==0)//strcmp()⽐较两个字符串,相等返回0{fg=n+1;break;}}//数字处理流程else if((ch<='9'&&ch>='0')){num=0;while((ch<='9'&&ch>='0')){num=num*10+ch-'0';ch=input[p++];}ch=input[--p];fg=11;}//运算符界符处理流程elseswitch(ch){case '<':m=0;token[m++]=ch;ch=input[p++];if(ch=='>') //产⽣<>{fg=21;token[m++]=ch;}else if(ch=='=') //产⽣<={fg=22;token[m++]=ch;}else{fg=20;ch=input[--p];}break;case '>':token[m++]=ch;ch=input[p++];if(ch=='=') //产⽣>={fg=24;token[m++]=ch;}else //产⽣>{fg=23;ch=input[--p];}break;case ':':token[m++]=ch;ch=input[p++];if(ch=='=') //产⽣:={fg=18;token[m++]=ch;}else //产⽣:{fg=17;ch=input[--p];}break;case '+':fg=13;token[0]=ch;break; case '-':fg=14;token[0]=ch;break; case '*':fg=15;token[0]=ch;break; case '/':fg=16;token[0]=ch;break; case ':=':fg=18;token[0]=ch;break; case '<>':fg=21;token[0]=ch;break; case '<=':fg=22;token[0]=ch;break; case '>=':fg=24;token[0]=ch;break; case '=':fg=25;token[0]=ch;break; case ';':fg=26;token[0]=ch;break; case '(':fg=27;token[0]=ch;break; case ')':fg=28;token[0]=ch;break; case '#':fg=0;token[0]=ch;break; default:fg=-1;}}。

词法分析器实验报告

词法分析器实验报告

词法分析器实验报告词法分析器实验报告一、引言词法分析器是编译器中的重要组成部分,它负责将源代码分解成一个个的词法单元,为之后的语法分析提供基础。

本实验旨在设计和实现一个简单的词法分析器,以深入理解其工作原理和实现过程。

二、实验目标本实验的目标是设计和实现一个能够对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运算符:;```可以看到,词法分析器能够正确地将代码分解成各种词法单元,并输出其对应的类别。

实验一、词法分析器(含源代码)

实验一、词法分析器(含源代码)

词法分析器实验报告一、实验目的及要求本次实验通过用C语言设计、编制、调试一个词法分析子程序,识别单词,实现一个C语言词法分析器,经过此过程可以加深对编译器解析单词流的过程的了解。

运行环境:硬件:windows xp软件:visual c++6.0二、实验步骤1.查询资料,了解词法分析器的工作过程与原理。

2.分析题目,整理出基本设计思路。

3.实践编码,将设计思想转换用c语言编码实现,编译运行。

4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。

通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。

三、实验内容本实验中将c语言单词符号分成了四类:关键字key(特别的将main说明为主函数)、普通标示符、常数和界符。

将关键字初始化在一个字符型指针数组*key[]中,将界符分别由程序中的case列出。

在词法分析过程中,关键字表和case列出的界符的内容是固定不变的(由程序中的初始化确定),因此,从源文件字符串中识别出现的关键字,界符只能从其中选取。

标识符、常数是在分析过程中不断形成的。

对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是关键字、普通标示符、常数或界符中之一,那么就将此单词以文字说明的形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串。

输出形式例如:void $关键字流程图、程序流程图:程序:#include<string.h>#include<stdio.h>#include<stdlib.h>#include<ctype.h>//定义关键字char*Key[10]={"main","void","int","char","printf","scanf","else","if","return"}; char Word[20],ch; // 存储识别出的单词流int IsAlpha(char c) { //判断是否为字母if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;else return 0;}int IsNum(char c){ //判断是否为数字if(c>='0'&&c<='9') return 1;else return 0;}int IsKey(char *Word){ //识别关键字函数int m,i;for(i=0;i<9;i++){if((m=strcmp(Word,Key[i]))==0){if(i==0)return 2;return 1;}}return 0;}void scanner(FILE *fp){ //扫描函数char Word[20]={'\0'};char ch;int i,c;ch=fgetc(fp); //获取字符,指针fp并自动指向下一个字符if(IsAlpha(ch)){ //判断该字符是否是字母Word[0]=ch;ch=fgetc(fp);i=1;while(IsNum(ch)||IsAlpha(ch)){ //判断该字符是否是字母或数字Word[i]=ch;i++;ch=fgetc(fp);}Word[i]='\0'; //'\0' 代表字符结束(空格)fseek(fp,-1,1); //回退一个字符c=IsKey(Word); //判断是否是关键字if(c==0) printf("%s\t$普通标识符\n\n",Word);//不是关键字else if(c==2) printf("%s\t$主函数\n\n",Word);else printf("%s\t$关键字\n\n",Word); //输出关键字 }else //开始判断的字符不是字母if(IsNum(ch)){ //判断是否是数字Word[0]=ch;ch=fgetc(fp);i=1;while(IsNum(ch)){Word[i]=ch;i++;ch=fgetc(fp);}Word[i]='\0';fseek(fp,-1,1); //回退printf("%s\t$无符号实数\n\n",Word);}else //开始判断的字符不是字母也不是数字{Word[0]=ch;switch(ch){case'[':case']':case'(':case')':case'{':case'}':case',':case'"':case';':printf("%s\t$界符\n\n",Word); break;case'+':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word);//运算符“+=”}else if(ch=='+'){printf("%s\t$运算符\n\n",Word); //判断结果为“++”}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word); //判断结果为“+”}break;case'-':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word); }else if(ch=='-'){printf("%s\t$运算符\n\n",Word); //判断结果为“--”}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word); //判断结果为“-”}break;case'*':case'/':case'!':case'=':ch=fgetc(fp);if(ch=='='){printf("%s\t$运算符\n\n",Word);}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word);}break;case'<':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word); //判断结果为运算符“<=”}else if(ch=='<'){printf("%s\t$运算符\n\n",Word); //判断结果为“<<”}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word); //判断结果为“<”}break;case'>':ch=fgetc(fp);Word[1]=ch;if(ch=='=') printf("%s\t$运算符\n\n",Word);else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word);}break;case'%':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word);}if(IsAlpha(ch)) printf("%s\t$类型标识符\n\n",Word);else {fseek(fp,-1,1);printf("%s\t$取余运算符\n\n",Word);}break;default:printf("无法识别字符!\n\n"); break;}}}main(){char in_fn[30]; //文件路径FILE *fp;printf("\n请输入源文件名(包括路径和后缀名):");while(1){gets(in_fn);//scanf("%s",in_fn);if((fp=fopen(in_fn,"r"))!=NULL) break; //读取文件内容,并返回文件指针,该指针指向文件的第一个字符else printf("文件路径错误!请重新输入:");}printf("\n******************* 词法分析结果如下 *******************\n");do{ch=fgetc(fp);if(ch=='#') break; //文件以#结尾,作为扫描结束条件else if(ch==' '||ch=='\t'||ch=='\n'){} //忽略空格,空白,和换行else{fseek(fp,-1,1); //回退一个字节开始识别单词流scanner(fp);}}while(ch!='#');return(0);}4.实验结果解析源文件:void main(){int a=3;a+=b;printf("%d",a);return;}#解析结果:5.实验总结分析通过本次实验,让再次浏览了有关c语言的一些基本知识,特别是对文件,字符串进行基本操作的方法。

编译原理词法分析器语法分析课程设计范本

编译原理词法分析器语法分析课程设计范本

《编译原理词法分析器语法分析课程设计-《编译原理》课程设计院系信息科学与技术学院专业软件工程年级级学号 2723姓名林苾湲西南交通大学信息科学与技术学院12月目录课程设计1 词法分析器 (2)设计题目 (2)设计内容 (2)设计目的 (2)设计环境 (2)需求分析 (2)概要设计 (2)详细设计 (4)编程调试 (5)测试 (11)结束语 (13)课程设计2 赋值语句的解释程序设计 (14)设计题目 (14)设计内容 (14)设计目的 (14)设计环境 (14)需求分析 (15)概要设计 (16)详细设计 (16)编程调试 (24)测试 (24)结束语 (25)课程设计一词法分析器设计一、设计题目手工设计c语言的词法分析器(能够是c语言的子集)。

二、设计内容处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。

三、设计目的了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。

四、设计环境该课程设计包括的硬件和软件条件如下:.硬件(1)Intel Core Duo CPU P8700(2)内存4G.软件(1)Window 7 32位操作系统(2)Microsoft Visual Studio c#开发平台.编程语言C#语言五、需求分析.源程序的预处理:源程序中,存在许多编辑用的符号,她们对程序逻辑功能无任何影响。

例如:回车,换行,多余空白符,注释行等。

在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。

.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。

单词符号能够划分成5中。

(1)标识符:用户自己定义的名字,常量名,变量名和过程名。

(2)常数:各种类型的常数。

(3) 保留字(关键字):如if、else、while、int、float 等。

(4) 运算符:如+、-、*、<、>、=等。

词法分析器(含完整源码)

词法分析器(含完整源码)
}//error
void Scanner(char ch[],int chLen,Table table[Max],int nLine) {
int chIndex = 0;
while(chIndex < chLen) //对输入的字符扫描 { /**************************处理空格和 tab ************************/
六、总结:
词法分析是构造编译器的起始阶段,也是相应比较简单的一个环节。词法分析的主要任 务是:根据构造的状态转换图,从左到右逐个字符地対源程序进行扫描,识别开源程序中具 有独立含义的最小语法单位——符号或单词,如变量标识符,关键字,常量,运算符,界符 等。
然后将提取出的标识符以内码的形式表示,即用 int 类型的数字来表示其类型和在 display 表中的位置,而无须保留原来标识符本身的字符串,这不仅节省了内存空间,也有 利于下一阶段的分析工作。
typedef struct DisplayTable {
int Index; //标识符所在表的下标 int type; //标识符的类型 int line; //标识符所在表的行数 char symbol[20]; //标识符所在表的名称 }Table;
int TableNum = 0; //display 表的下标 char Word[WordMaxNum][20]; //标识符表 char Digit[WordMaxNum][20]; //数字表 int WordNum = 0; //变量表的下标 int DigNum = 0; //常量表的下标 bool errorFlag = 0; //错误标志
当然,在扫描源程序串的同时,进行一些简单的处理,如删除空格、tab、换行等无效 字符,也进行了一些基本的错误处理,如变量长度的判别,有些不合词法规则的标识符判别 等。总之,严格说来,词法分析程序只进行和词法分析相关的工作。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《编译原理》
课程设计院系
专业
年级 11级
学号
姓名
2014年 05月
实验一简单的词法分析器设计
一、设计内容
熟悉并实现一个简单的词法分析器
二、设计目的
了解高级语言单词的分类,了解如何识别单词规则,掌握状态图到识别程序的编程。

源程序中,存在许多编辑用的符号,她们对程序逻辑功能无任何影响。

例如:回车,换行,多余空白符,注释行等。

在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。

三、实验步骤
1、
将每个单词符号进行不同类别的划分。

单词符号可以划分成5中。

(1)标识符:用户自己定义的名字,常量名,变量名与过程名。

(2)常数:各种类型的常数。

(3) 保留字(关键字):如if、begin、then、while、do等。

(4) 运算符:如+、-、*、<、>、=等。

(5)界符:如逗号、分号、括号等。

2、
将所有合法的单词符号转化为便于计算机处理的二元组形式:(单词分类号,单词自身值);以图形化界面显示出来。

3、
可选择性地将结果保存到文件中。

四、概要设计
1.待分析的简单语言的词法
(1)关键字:while do relop letter id number所有关键字都就是小写。

(2)运算符与界符:
: = + –* / < <= <> > >= = ; ( ) #
(3)其她单词就是标识符(ID)与整型常数(NUM),通过以下正规式定义:
如课本P20例2、6
空格由空白、制表符与换行符组成。

空格一般用来分隔ID、NUM,运算符、界符与关键字,词法分析阶段通常被忽略。

2.词法分析器的结构
图6、1 词法分析器的结构
3.部分单词的正规式与状态转换图
图6、2部分单词的状态转换图
4.功能模块
表6、2 词法分析器的C#程序过程或函数功能表
过程或函数名简要功能说明
void scaner() 分析源程序得到单个单词并大致区分其
类型,并生成二元组
void main( )输入源程序
五、详细设计
1.流程图
图7、1程序总体流程图
六、编程调试
1、源代码
#include"stdio、h"
#include"string、h"
#include"iostream、h"
char prog[100],token[20];
char ch;
int syn,p,m=0,n,row,sum=0;
char *rwtab[6]={"while","do","relop","letter","id","number"};
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<<"请输入字符串(字符#就是字符串输入结束标志):"<<endl;
do
{
cin、get(ch);
prog[p++]=ch;
}
while(ch!='#');
cout<<"字符串输出结果为:"<<endl;
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、调试
七、收获(体会)与建议
通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种高级语言直接编写此法分析程序。

相关文档
最新文档