实验1 词法分析程序的设计与开发

合集下载

简单词法分析程序设计

简单词法分析程序设计

实验一简单词法分析程序设计一、实验目的了解词法分析程序的基本构造原理,掌握词法分析程序的手工构造方法。

二、实验内容1、了解编译程序的词法分析过程。

2、根据PASCAL S言的说明语句形式,用手工方法构造一个对说明语句进行词法分析的程序。

该程序能对从键盘输入或从文件读入的形如:“ const count=10,sum=81.5,char1= ' f ' ,string1= ” hj ” , max=169 ;”的常量说明串进行处理,分析常量说明串中各常量名、常量类型及常量值,并统计各种类型常量个数。

三、实验要求1、输入的常量说明串,要求最后以分号作结束标志;2、根据输入串或读入的文本文件中第一个单词是否为“const ”判断输入串或文本文件是否为常量说明内容;3、识别输入串或打开的文本文件中的常量名。

常量名必须是标识符,定义为字母开头,后跟若干个字母,数字或下划线;4、根据各常量名紧跟等号“ =”后面的内容判断常量的类型。

其中:字符型常量定义为放在单引号内的一个字符;字符串常量定义为放在双引号内所有内容;整型常量定义为带或不带+、- 号,不以0 开头的若干数字的组合;实型常量定义为带或不带+、- 号,不以0 开头的若干数字加上小数点再后跟若干数字的组合;5、统计并输出串或文件中包含的各种类型的常量个数;6、以二元组( 类型,值)的形式输出各常量的类型和值;7、根据常量说明串置于高级语言源程序中时可能出现的错误情况,模仿高级语言编译器对不同错误情况做出相应处理。

四、运行结果1、输入如下正确的常量说明串:const count=10,sum=81.5,char1= ‘f ' ,max=169,str1= “ h*54 2..4S!AAsj ” char2=‘@' ,str2= “ aa!+h ”;输出:count(integer,10)sum(float,81.5)char1(char, ‘ f ' )max(integer,169)str1(string, “ h*54 2..4S!AAsj ” )char2(char, ‘ @' )str2(string, “ aa!+h ” )int_num=2; char_num=2; string_num=2; float_num=1.2、输入类似如下的保留字const 错误的常量说明串:Aconstt count=10,sum=81.5,char1= ‘f ' ;输出类似下面的错误提示信息:It is not a constant declaration statement!Please input a string again!3、输入类似如下含常量名或常量值错误的常量说明串:const count=10,12sum=81.5,char1= ‘ff ' ,max=0016;输出类似下面的错误提示信息:count(integer,10)12sum(Wrong! It is not a identifier!) char1(Wrong! There are more than one char in‘' .)max(Wrong! The integer can ' t be started with ‘0'.)int_num=1; char_num=0; string_num=0; float_num=0.4、其他类型的错误处理情况(略) 。

词法分析程序设计与实现

词法分析程序设计与实现

实验一词法分析程序设计与实现一、实验目的及内容调试并完成一个词法分析程序,加深对词法分析原理的理解。

二、实验原理(状态转换图)1、C语言子集(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为整型常数。

二、软件平台及工具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;。

词法分析程序实验报告

词法分析程序实验报告

词法分析程序实验报告篇一:词法分析器_实验报告词法分析器实验报告实验目的:设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。

实验要求:该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分界符五大类。

并依次输出各个单词的内部编码及单词符号自身值。

(一)实验内容(1)功能描述:对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。

而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。

(2)程序结构描述:函数调用格式:参数含义:String string;存放读入的字符串 String str; 存放暂时读入的字符串 char ch; 存放读入的字符 int rs 判断读入的文件是否为空 char []data 存放文件中的数据 int m;通过switch用来判断字符类型,函数之间的调用关系图:函数功能:Judgement()判断输入的字符并输出单词符号,返回值为空; getChar() 读取文件的,返回值为空;isLetter(char c) 判断读入的字符是否为字母的,返回值为Boolean类型; switch (m) 判断跳转输出返回值为空;isOperator(char c)判断是否为运算符的,返回值为Boolean类型; isKey(String string)判断是否为关键字的,返回值为Boolean类型; isDigit(char c) 判断读入的字符是否为数字的,返回值为Boolean类型。

(二)实验过程记录:本次实验出错3次,第一次无法输出双运算符,于是采用双重if条件句进行判断,此方法失败,出现了重复输出,继续修改if语句,仍没有成功。

然后就采用了直接方法调用解决此问题。

对于变量的判断,开始忘了考虑字母和数字组成的变量,结果让字母和数字分家了,不过改变if语句的条件,解决了此问题。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。

二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。

三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。

在本次实验中,我们使用有限自动机的理论来设计词法分析器。

首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。

然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。

在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。

(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。

在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。

首先,我们根据给定的语法规则,编写了相应的递归函数。

每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。

在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。

(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。

在本次实验中,我们使用了四元式作为中间代码的表示形式。

在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。

同时,根据语法树的结构,生成相应的四元式中间代码。

(四)代码优化代码优化的目的是提高生成代码的质量和效率。

在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。

通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。

编译原理综合性实验:词法分析的设计

编译原理综合性实验:词法分析的设计
编译过程中编译程序需要不断汇集和反复查证出现在源程序中各种名字的属性和特征 等有关信息。这些信息通常记录在符号表中。符号表中的每一项一般包含两部分:名字,与 此名字有关的信息,如类型,种属,值等。符号表主要在词法或语法分析阶段生成,可能用 于语义检查、产生中间代码以及最终生成目标代码等不同阶段。
对数字常数的处理如下:先查符号表 VAL 栏,若发现相同的常数则直接输出其二元式。 若表内无相同的常数,则将数字常数填入符号表内,在 TYPE 栏内填入整型或实型,然后输 出其二元式。二元式中包含该常数在符号表中的入口。
1.3 词法分析程序的详细设计
图 1-3 的数据流图属于输入-变换-输出形式的变换型数据流图,但加工 1.3—1.9 构成了典型的事务处理型数据流图。根据数据流图,可以得到词法分析 程序的总体框架,如图 1-4。
图 1-3 词法分析程序的详细数据流图 在上面的数据流图中,各个加工处理完成的功能如下: 加工 1.1(读一行并打印):收到读下一行命令后,从源程序读入一行,装入缓冲区,行计 数,并打印。在这里需要注意的是,回车换行在源程序(文本文件)中用两个字符 0D0AH 来表示,而用高级语言(C 语言)读入内存后,就用一个字符 0AH 来表示,这是在用高级
查找函数可以使用顺序查找,也可以使用折半查找。 例如:使用顺序查找方法查找给定单词 key 是否是关键字的函数原型和算法描述如下:
int iskeyword (char * str)/*设 keyword 为所有关键字列表*/ /*该函数返回 0 表示 str 不是关键字,不为 0 表示 str 是关键字*/
词不能跨行书写; (4) 关键字都是保留字。
1.2 词法分析程序的总体设计
图 1-2 词法分析程序的顶层数据流图 图 1-2 是词法分析程序的顶层数据流图,即是词法分析程序的输入输出界面图,由此可 以看出词法分析程序的功能就是从源程序中读入一个个字符,依据一定的构词规则,识别出 各类有用的单词。其中源程序清单和错误信息从屏幕、打印机或文件输出,其余文件均以顺 序文件的形式输出到外存储器上,以供下一阶段使用。由此可以得到更详细的数据流图,如 图 1-3。

实验一 词法分析程序的设计与实现

实验一  词法分析程序的设计与实现

实验一词法分析程序的设计与实现一、实验内容【实验目的和要求】设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。

【实验内容】通过对PL/0词法分析程序(GETSYM)的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。

此程序应具有如下功能:输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。

有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。

【实验环境】Windows PC机,任何语言。

【提交内容】提交实验报告,报告内容如下:目的要求、算法描述、程序结构、主要变量名说明、程序清单、调试情况、设计技巧、心得体会。

提交源程序和可执行文件。

【学时】4课时。

二、实验说明词法分析程序的任务就是扫描源程序,依据词法规则识别单词并报告构词错误信息。

通常将单词分为5种类型。

1)基本字:也叫关键字、保留字,是程序设计语言用来表示特定语法含义的一种标识符,如if、begin等。

2)运算符:如+、-、*、/、:=、>、<等。

3)标识符:用户定义的变量名、常数名、函数名等。

不同的高级程序设计语言对关键字是否可以作为普通标识符有不同的要求,有的语言允许程序员使用关键字作为普通标识符,有的程序设计语言则不允许程序员将关键字用着普通标识符(如C/C++、Pascal等都不允许)。

在允许程序员将关键字用作普通标识符的程序设计语言的编译器中,编译器必须具备能够区分一个标识符到底是关键字还是普通标识符的功能。

4)常数:如23、6等。

5)界符:如“,”、“;”、“(”、“)”、“.”等。

注意事项●空格的作用仅仅是将一个个单词分割开来,源程序中的空格不具备别的语法意义,在语法分析及其后续阶段都没有任何作用,因此,词法分析的另一个工作是过滤空格。

●注释对整个源程序的编译也没有任何语法意义,只是为了便于阅读和交流,因此,有的编译程序的词法分析程序也负责过滤注释。

编译实验1 编写词法分析程序

编译实验1 编写词法分析程序

实验1:编写词法分析程序
本实验进行词法分析程序的编程与调试。

1 实验类型
验证型实验。

2 实验目的和要求
通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。

掌握文法转换成自动机的技术及有穷自动机实现的方法。

确定词法分析器的输出形式及标识符与关键字的区分方法。

加深对课堂教学的理解;提高词法分析方法的实践能力。

通过本实验,应达到以下目标:
1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。

2、掌握词法分析的实现方法。

3、上机调试编出的词法分析程序。

3 背景知识
词法分析是作为相对独立的阶段来完成的(对源程序或中间结果从头到尾扫描一次,并作相应的加工处理,生成新的中间结果或目标程序)。

在词法分析过程中,编译程序是通过操作系统从外部介质中读取源程序文件中的各个字符的。

同时,为正确地识别单词,有时还需进行超前搜索和回退字符等操作。

因此,为了提高读盘效率和便于扫描器进行工作,通常可采用缓冲输入的方案,即在内存中设置一个适当大小的输入缓冲区,让操作系统直接将磁盘上的源程序字符串分批送入此缓冲区中,供扫描器进行处理。

词法分析程序的一般设计方案是:
1、词法规则⇒正规表达式⇒FA;
2、NFA 确定化⇒DFA;
3、最小化DFA;
4、确定单词符号输出形式;
5、构造词法分析程序。

4 实验
设计一个程序,可以实现任意正则式的最小化DFA二维表输出,并能进行单词的识别和输出。

实验1:词法分析程序

实验1:词法分析程序

实验1 词法分析程序一、实验目的与要求1.复习正规文法、正规式、有限自动机之间的相互转换的原理及技术;2.学会使用Visual C++等高级语言编程实现上述转换,并能合理显示结果;3.以C++的一个真子集为案例,具体分析词法分析程序的设计步骤、基本架构及代码编制,并通过一定实例验证其可行性,以加深对词法分析原理的理解;4.通过本次实验,使学生理解模块化程序设计的思想,从而从全局角度领会一个完整软件的设计精髓,为后续试验的顺利完成奠定坚实的基础。

二、实验仪器及设备1.微型电子计算机80台2.配置Windows 2000及以上版本操作系统3.安装Visual C++6.0/Visual C#2000/Delphi6.0等以上版本的开发环境三、实验内容及步骤(一)正规文法与有限自动机的相互转换1.正规文法⇒有限自动机已知某正规文法G[S]如下:S→aAS→bBS→εA→aBA→bAB→aSB→bAB→ε请编程实现:(1)将G[S]转换为NFA;(2)将上述得到的NFA确定化为DFA;(3)再将DFA最简化为MFA。

2.有限自动机⇒正规文法已知某有限自动机NFA M=(Q,∑,f,q0,Z)如下:状态集:Q={1,2,3,4,5,6,7,8,9}字母表:∑={a,b}转移函数:f(1,a)=5f(1,ε)=2f(1,a)=4f(5,ε)=6f(2,b)=3f(4,ε)=7f(6,ε)=2f(6,b)=9f(3,ε)=8f(8,a)=9f(7,b)=9初态:q0=1终态集:Z={6,7,9}请编程实现:(1)首先将此NFA确定化为DFA;(2)再将得到的DFA最简化为MFA;(3)最后,将MFA转化为正规文法(左线性或右线性均可)。

(二)编程实现MiniC++的词法分析这里的MiniC++为C++语言的一个真子集,其语法结构与C++类似。

基本组成如下:(1)关键字有18个,分别为:void、int、char、bool、float、double、if、else、switch、case、default、break、continue、do、while、for、return以及struct等。

实验安排+词法分析程序设计与实现

实验安排+词法分析程序设计与实现

实验一词法分析程序设计与实现一、实验目的:加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。

二、实验内容:自定义一种程序设计语言,或者选择已有的一种高级语言(C语言),编制它的词法分析程序。

词法分析程序的实现可以采用任何一种编程工具。

三、实验要求:1. 对单词的构词规则有明确的定义;2. 编写的分析程序能够正确识别源程序中的单词符号;3. 识别出的单词以<种别码,值>的形式保存在符号表中;4. 词法分析中源程序的输入以.c格式,分析后的符号表保存在.txt文件中。

5. *对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;6. 实验报告要求用自动机或者文法的形式对词法定义做出详细说明,说明词法分析程序的工作过程,说明错误处理的实现*。

四、实验学时:6学时五、实验步骤:1. 定义目标语言的可用符号表和构词规则;2. 依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束;3. 对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中;4. *对不正确的单词,做出错误处理*。

六、选作实验学生可以根据自身的情况完善词法分析程序的错误处理功能(实验要求5&6),如对错误的单词给出准确的位置和错误类型提示。

七、作业提交时间第8周实验课结束后提交词法分析程序(zzwyanqiu@)。

八、提示1. char Scanin[100],Scanout[100]; //用于接收输入输出文件名FILE *fin,*fout; //用于指向输入输出文件的指针2. //下面定义保留,为简化程序,使用字符指针数组保存所有保留字。

//如果想增加保留字,可继续添加,并修改保留字数目#define keywordSum 8char *keyword[keywordSum]={ "if","else","for","while","do","int","read","write"};3. //下面定义纯单分界符,如需要可添加char singleword[50]="+-*(){};,:";4. //下面定义双分界符的首字符char doubleword[10]="><=!";5. scanf("%s",Scanin);printf("请输入词法分析输出文件名(包括路径):");scanf("%s",Scanout);6. if ((fin=fopen(Scanin,"r"))==NULL) //判断输入文件名是否正确{printf("\n打开词法分析输入文件出错!\n");return(1);//输入文件出错返回错误代码1}if ((fout=fopen(Scanout,"w"))==NULL) //判断输出文件名是否正确{printf("\n创建词法分析输出文件出错!\n");return(2); //输出文件出错返回错误代码2}7. ch=getc(fin);//读取文件里的一个字符8. isalpha(ch) //字母判断函数isalnum(ch)) //数字判断函数strcmp(token,keyword[n]) //串比较fprintf(fout,"%s\t%s\n","ID",token); //输出标识符符号到fout指定的文件strchr(singleword,ch) //声明: char *strchr( const char *string, int c );//在字符串string中搜索字符c,若成功则返回一个指向该字符第一次出现的位置,否则返回NULL//这个例子中的变量x的值为5:char string[]="hello"; char *p; int x; p=strchr(string,'o'); x=p-string+1; /tenax/clib/clib.html //c库函数查找地址任务1:识别小型语言所有单词的词法分析程序设计源程序设计语言G[<程序>]<程序>→<变量说明><BEGIN> <语句表> <END>.<变量说明>→VAR<变量表>:<类型>;|<空><变量表>→<变量表>,<变量>|<变量><类型>→INTEGER<语句表>→<语句> | <语句>;<语句表><语句>→<赋值语句>|<条件语句>|<WHILE语句>|<复合语句><赋值语句>→<变量>:=<算术表达式><条件语句>→IF<关系表达式>THEN<语句>ELSE<语句><WHILE语句>→WHILE<关系表达式>DO<语句><复合语句>→BEGIN<语句表>END<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项><项>→<因式>|<项>*<因式>|<项>/<因式><因式>→<变量>|<整数>|(<算术表达式>)<关系表达式>→<算术表达式><关系符><算术表达式><变量>→<标识符><标识符>→<标识符><字母>|<标识符><数字>|<字母><整数>→0|<非零数字><泛整数><泛整数>→<数字>|<数字><泛整数>|ε<关系符>→<|<=|==|>|>=|<><字母>→A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z<非零数字>→1|2|3|4|5|6|7|8|9<数字>→<非零数字>|0<空>→要求和提示:词法分析阶段,可以打开任意位置和名称的源文件进行词法分析,可以进行非法字符和数字后边跟字母的错误判断,如果没有错误则提示“词法分析正确完成!”,并且可以选择输出token.txt(token文件)string.txt(符号表)两个文件;1.词法分析程序的主要任务如下:①组织源程序的输入,识别出源程序中的各个基本语法单位(也称为单词或语法符号),按规则转换成二元式的形式;②删除无用的空白字符、回车符、及其它非实质性符号;③删除注解行;④为后面的语法和语义分析提供二元式链表;单词编码单词编码标识符1 < 15正整数2 <= 16BEGIN 3 > 17END 4 >= 18IF 5 <> 19THEN 6 == 20ELSE 7 ;21WHILE 8 .22DO 9 := 23INTEGER 10 ,24+ 11 ( 25- 12 )26* 13/ 141) 对标识符的长度控制在8个字符(包括8个)以内,超过的做截断处理;2) 数字不大于65535,否则报错;3) 能跳过源程序中的空白格:两个单词之间的任何空格,制表符,回车,换行都是白空格,除了用来分隔单词以外,没有意义;4) 能跳过注释:a) 接连出现的/*到下一次接连出现的*/之间的任何文字都是注释(多行);b) 从某行接连出现的//到该行的结尾的任何文字都是注释(单行)。

实验一词法分析程序开发

实验一词法分析程序开发

实验一词法分析程序开发【实验目的】•深入理解有限自动机及其应用•掌握根据语言的词法规则构造识别其单词的有限自动机的方法•深入理解词法分析程序自动生成原理•掌握词法分析程序的开发。

【实验学时】4学时【实验要求】•掌握词法分析程序自动生成工具LEX的使用。

•掌握各类单词的形式描述•学会用数据中心法实现有限自动机•学会用直接转向法实现有限自动机•独立完成SNL语言的词法分析器【实验原理】词法分析是编译过程的第一阶段。

它的任务就是对输入的字符串形式的源程序按顺序进行扫描,根据源程序的词法规则识别具有独立意义的单词(符号),并输出与其等价的Token序列。

有限自动机是描述程序设计语言单词构成的工具,而状态转换图是有限自动机的比较直观的描述方法。

我们使用确定的有限状态自动机,简记为DFA。

下面给出能够识别SNL中各类单词的DFA:识别SNL单词的DFA表示根据语言的词法规则构造出识别其单词的确定有限自动机DFA, 仅仅是词法分析程序的一个形式模型,距离词法分析程序的真正实现还有一定的距离。

状态转换图的实现通常有两种方法,一种是用状态转换表T;另一种是直接转向法。

状态转换表法又称数据中心法,是把状态转换图看作一种数据结构(状态转换表),由控制程序控制字符在其上运行,从而完成词法分析。

用转换表的优点是程序短,但占存储空间多,直接转向法的优缺点正好与此相反。

直接转向法又称程序中心法,是把状态转换图看成一个流程图,从状态转换图的初态开始,对它的每一个状态结点都编一段相应的程序。

【实验步骤】一、构造识别单词的自动机1.根据构成规则对程序语言的单词按类构造出相应的状态转换图。

2. 对各类单词的状态转换图合并,构成一个能识别语言所有单词的状态转换图。

合并步骤为:(1) 将各类单词的状态转换图的初始状态合并为一个唯一的初态;(2) 化简调整状态冲突和对冲突状态重新编号;(3) 如有必要,增加出错状态。

二、(a)用数据中心法实现有限自动机,生成词法分析程序。

实验一 编写词法分析程序

实验一  编写词法分析程序

实验一编写词法分析程序1 实验类型设计型实验,4学时。

2 实验目的通过设计、调试词法分析程序,掌握词法分析程序的设计工具,即有穷自动机,进一步理解自动机理论;掌握文法转换成自动机的技术及有穷自动机实现的方法;会确定词法分析器的输出形式及标识符与关键字的区分方法;加深对课堂教学的理解,提高词法分析方法的实践能力。

3 背景知识词法分析作为相对独立的阶段来完成(对源程序或中间结果从头到尾扫描一次,并作相应的加工处理,生成新的中间结果或目标程序)。

在词法分析过程中,编译程序从外部介质中读取源程序文件中的各个字符,为正确地识别单词,有时还需进行超前搜索和回退字符等操作。

因此,为了提高读盘效率和便于扫描器进行工作,通常可采用缓冲输入的方案,即在内存中设置一个适当大小的输入缓冲区,将磁盘上的源程序字符串分批送入该缓冲区中,供扫描器进行处理。

词法分析程序的一般设计方案是:1、程序设计语言词法规则⇒正则文法⇒ FA;或:词法规则⇒正则表达式⇒ FA;2、NFA确定化⇒ DFA;3、DFA最小化;4、确定单词符号输出形式;5、化简后的DFA+单词符号输出形式⇒构造词法分析程序。

从设计方案可知,要构造词法分析程序,必须掌握以下三个知识点:文法、正则表达式和FA。

文法与语言的形式定义如下:一个形式文法G 是下述元素构成的一个元组(V N,V T,P,S )。

其中:1、V T—非空有限的终结符号集,即Σ;终结符:一个语言不可再分的基本符号。

2、V N—非空有限的非终结符号集;非终结符:也称语法变量,用来代表语法范畴。

一个非终结符代表一个一定的语法概念,是一个类(集合)记号,而不是一个体记号。

3、S —开始符号/识别符号,S∈V N;4、P —产生式规则集(或叫规则或生成式或重写规则);产生式:形如α → β或α ::= β的表达式,其中α为左部,β为右部。

α∈(V T∪V N)+且至少含一个V N;β∈(V T∪V N)*。

【实验报告】实验一 编写词法分析程序

【实验报告】实验一 编写词法分析程序

编译原理实验报告实验名称:编写词法分析程序_______实验类型:设计型实验指导教师:专业班级:姓名:学号:实验地点:实验成绩:日期:2017年4月15日实验一编写语法分析程序一、实验目的1)通过设计、调试词法分析程序,掌握词法分析程序的设计工具,即有穷自动机,进一步理解自动机理论;2)掌握正则文法和正则表达式转换成有穷自动机的方法及有穷自动机的实现方法;3)会确定词法分析程序的输出形式及标识符与关键字的区分方法;4)加深对课堂教学的理解,提高词法分析方法的实践能力,掌握使用实验环境的技能技巧以及程序的调试方法。

二、实验设计1、写出TEST语言每条词法规则对应的正则文法或者正则表达式1)标识符:字母打头,后接任意字母或数字。

正则表达式:( a|b|……|z|A|B……|Z )( 0|1|……|9| a|b|……|z|A|B……|Z )*2)保留字:标符的子集,包括:if, else, for, while, do, int, write, read。

正则表达式:if | else | for | while | do | int | write | read3)无符号整数:由数字组成,但最高位不能为0,允许一位的0。

正则表达式:( (1……|9 )( 0|1|……|9)* )|04)分界符:(、)、;、{、}正则表达式:( | ) | ; | { | }5)运算符:+、-、*、/、=、<、>、>=、<=、!=、==正则表达式:+ | - | * | / | = | < | > | >= | <= | != | ==6)注释符:/* */正则表达式:/*(没有连续的*/的任意字符串|ℇ)*/2、对每个文法或者正则表达式分别构造NFA1)标识符:( a|b|……|z|A|B……|Z )( 0|1|……|9| a|b|……|z|A|B……|Z )*2)无符号整数:( (1|2|……|9 )( 0|1|……|9)* )|03)分界符:( | ) | ; | { | }4)运算符:+ | - | * | / | = | < | > | >= | <= | != | ==5)注释符:/*(没有连续的*/的任意字符串|ℇ)*/非*非*|非/3、将NFA合并,确定化,化简得到最终的DFA。

实验一词法分析程序的设计与实现范文

实验一词法分析程序的设计与实现范文

实验一词法分析程序的设计与实现实验一词法分析程序的设计与实现一、实验内容【实验目的和要求】设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。

【实验内容】经过对PL/0词法分析程序(GETSYM)的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。

此程序应具有如下功能:输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。

有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。

【实验环境】Windows PC机,任何语言。

【提交内容】提交实验报告,报告内容如下:目的要求、算法描述、程序结构、主要变量名说明、程序清单、调试情况、设计技巧、心得体会。

提交源程序和可执行文件。

【学时】4课时。

二、实验说明词法分析程序的任务就是扫描源程序,依据词法规则识别单词并报告构词错误信息。

一般将单词分为5种类型。

1)基本字:也叫关键字、保留字,是程序设计语言用来表示特定语法含义的一种标识符,如if、begin等。

2)运算符:如+、-、*、/、:=、>、<等。

3)标识符:用户定义的变量名、常数名、函数名等。

不同的高级程序设计语言对关键字是否能够作为普通标识符有不同的要求,有的语言允许程序员使用关键字作为普通标识符,有的程序设计语言则不允许程序员将关键字用着普通标识符(如C/C++、Pascal等都不允许)。

在允许程序员将关键字用作普通标识符的程序设计语言的编译器中,编译器必须具备能够区分一个标识符到底是关键字还是普通标识符的功能。

4)常数:如23、6等。

5)界符:如“,”、“;”、“(”、“)”、“.”等。

注意事项●空格的作用仅仅是将一个个单词分割开来,源程序中的空格不具备别的语法意义,在语法分析及其后续阶段都没有任何作用,因此,词法分析的另一个工作是过滤空格。

●注释对整个源程序的编译也没有任何语法意义,只是为了便于阅读和交流,因此,有的编译程序的词法分析程序也负责过滤注释。

实验一 词法分析程序的设计与实现(C语言)

实验一 词法分析程序的设计与实现(C语言)

实验一 词法分析程序的设计与实现(C 语言)一、实验目的通过C 语言词法分析程序的实现理解编译程序过程中对单词的分析过程。

二、实验重难点DFA 自动机的数据结构表示,程序流程图,词法分析程序实现三、实验内容与要求实验内容:1. 设计存储DFA 自动机的数据结构2.绘制程序流程图3. 词法分析程序设计四、实验学时2课时五、实验设备与环境C 语言编译环境六、根据实验过程填写下列内容1.DFA 自动机的状态转换图和数据结构设计。

a /b2. 程序流程图(见附页)3. 代码#include<stdio.h>int f(int x,char e){ int df[4][2]={{2,3},{4,3},{2,4},{4,4}};U a a a S b Q bV bint i;if(e=='a')i=df[x][1];if(e=='b')i=df[x][2];return(i);}void main(){ int S=1,U=2,V=3,Q=4;int k=S;char c;printf("请输入字符,按#结束:\n");c=getchar();while(c!='#'){k=f(k,c);c=getchar();}if(k==Q) printf("你输入的字符串能被DFA所识别\n");else printf("你输入的字符串能被DFA所识别\n");}4.测试数据及结果分析(结果见附页)分析:从实验的结果可以看出上面程序代码基本上可以实现所给DFA的要求,但是有关实验的可读性和功能方面还有待进一步改进。

程序流程图教师评语:是否完成实验程序的预备设计? 是: 不是: 程序能否正常运行? 是: 不是: 有无测试数据及结果分析 是: 不是: 是否在本次规定时间完成所有项目? 是: 不是: 实验成绩等级: 教师签名:N0:时间:开始初始化输入句子判断是否退出标志判断是否被接受?接受不接受输出错误位置NY NY结束。

实验一 词法分析设计与实现

实验一 词法分析设计与实现

实验一词法分析设计与实现实验时间:2016.4.13,4.20实验目的对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。

实验要求利用该词法分析器完成对源程序字符串的词法分析。

输出形式是源程序的单词符号二元式的代码,并保存到文件中。

实验内容(1) 假设该语言中的单词符号及种别编码如下表所示。

单词符号及种别编码算符和界符=+-* / &<<=>>===!=&& || , : ; { } [ ] ( )ID和NUM的正规定义式为:ID→letter(letter | didit)*NUM→digit digit*letter→a| … | z | A | … | Zdigit→ 0 | … | 9如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。

空格由空白、制表符和换行符组成。

(3) 设计词法分析器的步骤:①首先根据上面单词符号表及ID和NUM的正规定义式,构造出状态转换图;②定义相关的变量和数据结构。

关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。

如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

关键字表为一个字符串数组,其描述如下:char *KEY_WORDS[7]={″main″,″int″,″char″,″if″,″else″,″for″,″while″};用以存放单词符号二元式的数据结构可如下定义:#define MAXLENGTH 255 /* 一行允许的字符个数 */union WORDCONTENT { /* 存放单词符号的内容 */char T1[MAXLENGTH];/* 存放标识符及由两个(以上)字符组成的符号 */int T2; /* 存放整型常数的拼数 */char T3; /* 存放其他符号 */};typedefstruct WORD { /* 单词符号二元式 */int code; /* 存放种别编码 */union WORDCONTENT value;} WORD;③按照编译程序一遍扫描的要求,把词法分析器Scaner作为一个独立的子程序来设计,通过对Scaner的反复调用识别出所有的单词符号;④当Scaner识别出一个单词符号时,则将该单词符号的二元式写入到输出文件中。

实验一手工编写简易词法分析程序

实验一手工编写简易词法分析程序

编译原理实验报告日期:班级:题目:组员:1实验目的及要求1.通过设计、编写、调试一个具体的词法分析程序,加深对词法分析原理的理解。

2.掌握在对程序设计语言源程序进行扫描的过程中, 将其分解为各类单词的词法分析方法。

2实验平台Windows + VC + Win32 Console3实验步骤1.查询资料,了解词法分析器的工作过程与原理。

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

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

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

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

4实验内容4.1 实现下述功能, 并将分析结果保存在文件中. (既可以参考范例程序, 也可以独立完成)程序输入/输出示例:输入一段C语言程序,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、界符。

(遇到错误时可显示“Error”,然后跳过错误部分继续显示)输入源程序示例:main ( ){int a , b =10;int c ;c = a + b * 20;}输出固定表格如下输出动态表格如下运算符表44.2 程序:#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;elsereturn 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("\t\t├───────┼───┼───────┤\n\t\t │%s\t\t│1\t│1\t\t│\n",Word);//不是关键字else if(c==2)printf("\t\t├───────┼───┼───────┤\n\t\t │%s\t\t│2\t│3\t\t│\n",Word);elseprintf("\t\t├───────┼───┼───────┤\n\t\t │%s\t\t│3\t│1\t\t│\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("\t\t├───────┼───┼───────┤\n\t\t │%s\t\t│3\t│1\t\t│\n",Word);}else //开始判断的字符不是字母也不是数字{Word[0]=ch;switch(ch){case'[':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│7\t\t│\n",Word); break;case']':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│9\t\t│\n",Word); break;case'(':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│3\t\t│\n",Word); break;case')':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│4\t\t│\n",Word); break;case'{':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│5\t\t│\n",Word); break;case'}':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│6\t\t│\n",Word); break;case',':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│1\t\t│\n",Word); break;case'"':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│8\t\t│\n",Word); break;case';':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│2\t\t│\n",Word); break;case'+':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//运算符"+="}else if(ch=='+'){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word); //判断结果为"++"}else {fseek(fp,-1,1);printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│1\t\t│\n",Word); //判断结果为"+"}break;case'-':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word); }else if(ch=='-'){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word); //判断结果为"--"}else {fseek(fp,-1,1);printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│2\t\t│\n",Word); //判断结果为"-"}break;case'*':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│3\t\t│\n",Word);break;case'/':printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│4\t\t│\n",Word);break;case'!':case'=':ch=fgetc(fp);if(ch=='='){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);}else {fseek(fp,-1,1);printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│5\t\t│\n",Word);}break;case'<':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word); //判断结果为运算符"<="}else if(ch=='<'){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//判断结果为"<<"}else {fseek(fp,-1,1);printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word); //判断结果为"<"}break;case'>':ch=fgetc(fp);Word[1]=ch;if(ch=='=') printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);else {fseek(fp,-1,1);printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);}break;case'%':ch=fgetc(fp);Word[1]=ch;if(ch=='='){ printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);}if(IsAlpha(ch)) printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t│类型标识符\t│ \t│\n",Word);else {fseek(fp,-1,1);printf("\t\t├───────┼───┼───────┤\n\t\t│%s \t│取余运算符\t│ \t\n",Word);}break;default:printf("\t\t├───────┼───┼───────┤\n\t\t│无法识别字符! \t\t\t\t │\n"); break;}}}main(){char in_fn[30]; //文件路径FILE *fp;printf("\n请输入源文件名(包括路径和后缀名):");while(true){gets(in_fn);//scanf("%s",in_fn);if((fp=fopen(in_fn,"r"))!=NULL) break; //读取文件内容,并返回文件指针,该指针指向文件的第一个字符else printf("文件路径错误!请重新输入:");}printf("\n**************************** 单词类别表****************************\n");printf("\t\t┌───────┬───────┐\n\t\t│单词类型\t│单词种别\t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│标识符 \t│1 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│保留字 \t│2 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│常量 \t│3 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│运算符 \t│4 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│分界符 \t│5 \t│\n",Word);printf("\t\t└───────┴───────┘\n",Word);printf("\n**************************** 保留字表******************************\n");printf("\t\t┌───────┬───────┐\n\t\t│保留字 \t│地址指针\t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│int \t│1 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│float \t│2 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│main \t│3 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│printf \t│4 \t│\n",Word);printf("\t\t└───────┴───────┘\n",Word);printf("\n**************************** 运算符表******************************\n");printf("\t\t┌───────┬───────┐\n\t\t│算符 \t│地址指针\t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│+ \t│1 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│- \t│2 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│* \t│3 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│/ \t│4 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│= \t│5 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│其他 \t│6 \t│\n",Word);printf("\t\t└───────┴───────┘\n",Word);printf("\n**************************** 分界符表******************************\n");printf("\t\t┌───────┬───────┐\n\t\t│界符 \t│地址指针\t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│, \t│1 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│; \t│2 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│( \t│3 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│) \t│4 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│{ \t│5 \t│\n",Word);printf("\t\t├───────┼───────┤\n\t\t│} \t│6 \t│\n",Word);printf("\t\t└───────┴───────┘\n",Word);printf("\n**************************** 词法分析结果如下******************************\n");printf("\t\t┌───────┬───┬───────┐\n\t\t│单词名称\t│类别\t│地址指针\t│\n",Word);do{ch=fgetc(fp);if(ch=='#') break; //文件以#结尾,作为扫描结束条件else if(ch==' '||ch=='\t'||ch=='\n'){} //忽略空格,空白,和换行else{fseek(fp,-1,1); //回退一个字节开始识别单词流scanner(fp);}}while(ch!='#');printf("\t\t└───────┴───┴───────┘\n",Word);return(0);}5实验结果5.1 解析源文件:main ( ){int a , b =10;int c ;c = a + b * 20;}#5.2 解析结果:6实验总结分析在本次实验,使我们再次浏览了有关C语言的一些基本知识,特别是对文件,字符串进行基本操作的方法。

实验一 词法分析程序的设计与实现

实验一  词法分析程序的设计与实现

实验项目一词法分析程序的设计与实现实验目的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); }。

实验一 源程序的预处理及词法分析程序设计

实验一 源程序的预处理及词法分析程序设计

实验一源程序的预处理及词法分析程序设计(6学时)一、实验目的设计并实现一个包含预处理功能的词法分析程序,加深对编译中词法分析过程的理解。

二、实验要求1、实现预处理功能源程序中可能包含有对程序执行无意义的符号,要求将其剔除。

首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;把多个空白符合并为一个;去掉注释。

2、实现词法分析功能输入:所给文法的源程序字符串。

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

其中,syn为单词种别码。

Token为存放的单词自身字符串。

Sum为整型常量。

具体实现时,可以将单词的二元组用结构进行处理。

3、待分析的C语言子集的词法1)关键字main if then while do static int double struct break else long switch case typedef char return const float shortcontinue for void default sizeof do所有的关键字都是小写。

2)运算符和界符+ - * / : := < <> <= > >= = ; ( ) #3)其他标记ID和NUM通过以下正规式定义其他标记:ID→letter(letter|digit)*NUM→digit digit*letter→a|…|z|A|…|Zdigit→0|…|9…4)空格由空白、制表符和换行符组成空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。

4、各种单词符号对应的种别码表1 各种单词符号的种别码单词符号种别码单词符号种别码main 1 ; 41if 2 ( 42then 3 ) 43while 4 int 7do 5 double 8static 6 struct 9ID 25 break 10NUM 26 else 11+ 27 long 12- 28 switch 13* 29 case 14/ 30 typedef 15: 31 char 16:= 32 return 17< 33 const 18<> 34 float 19<= 35 short 20> 36 continue 21>= 37 for 22= 38 void 23default 39 sizeof 24do 40 # 05、词法分析程序的主要算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到的单词符号的第一个字符的种类,拼出相应的单词符号。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理实验报告
一、实验目的
• 深入理解有限自动机及其应用 • 掌握词法分析程序的开发。

• 掌握根据语言的词法规则构造识别其单词的有限自动机的方法 • 深入理解词法分析程序自动生成原理
二、实验要求
• 掌握各类单词的形式描述
•用直接转向法实现有限自动机的代码编写。

• 独立完成PL0语言的词法分析器。

• 掌握词法分析程序自动生成工具LEX 的使用。

三、实验原理
词法分析是编译过程的第一阶段。

它的任务就是对输入的字符串形式的源程序按顺序进行扫描,根据源程序的词法规则识别具有独立意义的单词(符号),并输出与其等价的Token 序列。

有限自动机是描述程序设计语言单词构成的工具,而状态转换图是有限自动机的比较直观的描述方法。

我们使用确定的有限状态自动机,简记为DFA 。

PL/0的语言的词法分析器将要完成以下工作: (1) 跳过分隔符(如空格,回车,制表符); (2) 识别诸如begin ,end ,if ,while 等保留字;
(3) 识别非保留字的一般标识符,此标识符值(字符序列)赋给全局量id ,而全局量sym 赋值为SYM_IDENTIFIER 。

(4) 识别数字序列,当前值赋给全局量NUM ,sym 则置为SYM_NUMBER ; (5) 识别:=,<=,>=之类的特殊符号,全局量sym 则分别被赋值为SYM_BECOMES ,SYM_LEQ ,SYM_GEQ 等。

课程名称: 编译原理
班级: 计算1614
实验成绩:
指导教师: 付永钢 姓名: 施心萍
实验项目名称: 实验一 词法分析程序设计与开发
学号: 201621121097 上机实践日期:
识别PL0单词的DFA表示
相关过程(函数)有getsym(),getch(),其中getch()为获取单个字符的过程,除此之外,它还完成:
(1)识别且跳过行结束符;
(2)将输入源文件复写到输出文件;
(3)产生一份程序列表,输出相应行号或指令计数器的值。

下面给出能够识别PL0语言中各类单词的DFA:
根据语言的词法规则构造出识别其单词的确定有限自动机DFA, 仅仅是词法分析程序的一个形式模型,距离词法分析程序的真正实现还有一定的距离。

状态转换图的程序实现通常是采用直接转向法。

直接转向法又称为程序中心法,是把状态转换图看成一个流程图,从状态转换图的初态开始,对它的每一个状态结点都编写一段相应的程序。

四、实验步骤
一、构造识别单词的自动机
1.根据给定的词法构成规则对程序语言的单词按类构造出相应的状态转换图,并根据具体需求对该状态转换图进行完善。

2. 对各类单词的状态转换图合并,构成一个能识别语言所有单词的状态转换图。

合并步骤为:
(1) 将各类单词的状态转换图的初始状态合并为一个唯一的初态;
(2) 化简调整状态冲突和对冲突状态重新编号;
(3) 对上述形成的状态图进行修正,以满足识别合适单词的要求。

(4) 如有必要,在合适的位置增加出错状态。

二、用直接转向法实现有限自动机的代码,生成对应的词法分析程序。


严格按照给出的DFA,对每个状态编写对应的识别代码,然后对每个状
态的代码用合适的分支、循环等语句进行整合,完成整个代码的合成
工作,并上机进行调试。

对实现的代码进行测试,给出合适的测试用
例(要求至少有3个用例,二个正确识别所有的保留字、标识符、分
界符、数字等;另外一个识别错误的单词。

1.样例1
输入
输出生成的txt程序列表
2.样例2
输入(部分)
输出(部分)
生成的txt程序列表(部分)
3.样例3(小数)
三、用自动生成工具LEX生成上述给定DFA所对应的PL0语言的词法分析
程序。

并进行调试,用上述3个测试用例进行测试,给出测试结果。

编写LEX文件
运用flex生成lex.yy.c文件
运行结果
样例1
样例2(部分)
样例3(小数)
五、实验小结
FLEX通过对LEX源文件的扫描自动生成相应的语法分析函数,生成lex.yy.c 程序。

LEX具有“最长匹配原则”和“最先匹配原则”,能够使用简洁的正规表达式去实现语法分析程序,而且lex.yy.c中定义了很多用户可定义的全局变量以及在LEX源文件的动作中可调用的函数和宏,具有良好的可移植性。

但是LEX 对源文件的格式要求非常严格,而且LEX本身的查错能力很弱,所以书写时一定要特别注意。

C语言提供大量的函数,其中包括系统生成的函数和用户定义的函数,语法也很容易理解,使用C语言实现语法分析程序可以较好地掌握程序的分支和流程,但是代码量很多,容易出现错误,书写的时候需要特别细心。

实验的处理单词集(仅供参考)
(注:单词种类统一分类如下:)
单词符号单词种类
空0
标识符 1
整数 2
+ 3
- 4
* 5
/ 6
= 7
> 8
< 9
<> 10
<= 11
>= 12
( 13
) 14 { 15
} 16
; 17
, 18
“ 19
:= 20
var 21
if 22 then 23 else 24 while 25
for 26 begin 27 writeln 28 procedure 29 end 30
出错 100。

相关文档
最新文档