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

合集下载

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

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

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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对象。

五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。

我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。

这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。

编译原理实验报告

编译原理实验报告

编译原理实验报告班级姓名:学号:自我评定:实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。

二、实验内容根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。

例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。

输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。

输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。

例如,所输出的每一单词均按形如(CLASS,VALUE)的二元式编码。

对于变量和常数,CLASS字段为相应的类别码;VALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。

对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。

另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。

三、实现方法与环境词法分析是编译程序的第一个处理阶段,可以通过两种途径来构造词法分析程序。

其一是根据对语言中各类单词的某种描述或定义(如BNF),用手工的方式(例如可用C语言)构造词法分析程序。

一般地,可以根据文法或状态转换图构造相应的状态矩阵,该状态矩阵同控制程序便组成了编译器的词法分析程序;也可以根据文法或状态转换图直接编写词法分析程序。

构造词法分析程序的另外一种途径是所谓的词法分析程序的自动生成,即首先用正规式对语言中的各类单词符号进行词型描述,并分别指出在识别单词时,词法分析程序所应进行的语义处理工作,然后由一个所谓词法分析程序的构造程序对上述信息进行加工。

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

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

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

二、实验内容:自定义一种程序设计语言,或者选择已有的一种高级语言(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) 从某行接连出现的//到该行的结尾的任何文字都是注释(单行)。

实验1 词法分析实验报告

实验1  词法分析实验报告
{
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;
实验二时发现怎么出结果都会出现一个缺:=错误,便回头检查代码才发现实验一时的scaner()函数最后的:和:=的种别码互相写错了,所以回过头来重新修正了代码和实验结果图。
case -1: cout<<"Error in row"<<row<<"!"<<endl; break;
case -2: row=row++;break;
default: cout<<"("<<syn<<","<<token<<")"<<endl;break;
}
}
while (syn!=0);
}
四、结果验证
{
syn=21;
token[m++]=ch;
}
else if(ch=='=')

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

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

词法分析程序的设计与实现方法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,进入错误处理状态。

(完整word版)编译原理词法分析程序实现实验报告

(完整word版)编译原理词法分析程序实现实验报告

(完整word版)编译原理词法分析程序实现实验报告实验一词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。

输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。

输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。

二、设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:GOTO 1:(完整word版)编译原理词法分析程序实现实验报告GOTO 2:三、源程序代码部分#include <stdio.h>#include<stdlib.h>#include <math.h>#define MAX 100#define UNSIGNEDNUMBER 1#define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6#define RIGHTBRACKET 7#define INEFFICACIOUSLABEL 8#define FINISH 111int count=0;int Class;void StoreType();int Type[100];char Store[20]={'\0'};void ShowStrFile();//已经将要识别的字符串存在文件a中void Output(int a,char *p1,char *p2);//字符的输出过程int Sign(char *p);//'+''-''*''/'整体识别过程int UnsignedNum(char *p);//是否适合合法的正整数0~9int LegalCharacter(char *p);//是否是合法的字符:Sign(p)||UnsignedNum(p)||'E'||'.' void DistinguishSign(char *p);//'+''-''*''/'具体识别过程void TypyDistinguish();//字符的识别过程void ShowType();//将类别码存储在Type[100]中,为语法分析做准备void ShowStrFile()//已经将要识别的字符串存在文件a中{FILE *fp_s;char ch;if((fp_s=fopen("a.txt","r"))==NULL){printf("The FILE cannot open!");exit(0);}elsech=fgetc(fp_s);while(ch!=EOF){putchar(ch);ch=fgetc(fp_s);}printf("\n");}void StoreStr()//将文件中的字符串存储到数组Store[i] {FILE *fp=fopen("a.txt","r");char str;int i=0;while(!feof(fp)){fscanf(fp,"%c",&str);if(str=='?'){Store[i]='\0';break;}Store[i]=str;i++;}Store[i]='\0';}void ShowStore(){int i;for (i=0;Store[i]!='\0';i++)printf("%c",Store[i]);printf("\n");}void Output(int a,char *p1,char *p2){printf("%3s\t%d\t%s\t","CLASS",a,"VALUE");while(p1<=p2){printf("%c",*p1);p1++;}printf("\n");}int Sign(char *p){char ch=*p;if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')') return 1;elsereturn 0;}int UnsignedNum(char *p){char ch=*p;if('0'<=ch&&ch<='9')return 1;elsereturn 0;}int LegalCharacter(char *p){char ch=*p;if(Sign(p)||UnsignedNum(p)||ch=='E'||ch=='.')。

词法分析报告

词法分析报告

编译原理实验报告实验一词法分析程序的设计与实现指导教师:姓名:学号:班级:一、实验目的基本掌握计算机语言的词法分析程序的开发方法。

二、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。

三、实验要求1.根据以下的正规式,编制正规文法,画出状态图;标识符<字母>(<字母>|<数字字符>)*十进制整数0 | (1|2|3|4|5|6|7|8|9) (0|1|2|3|4|5|6|7|8|9)*八进制整数0 (0|1|2|3|4|5|6|7) (0|1|2|3|4|5|6|7)*十六进制整数0 (x|X) (0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f) (0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和分隔符+ - * / > < = ( ) ;关键字if then else while do2.根据状态图,设计词法分析函数int scan( ),完成以下功能:(1)从输入流(键盘或文件)读入数据,分析出一个单词。

(2)返回单词种别(用整数表示),(3)返回单词属性(不同的属性可以放在不同的全局变量中)。

3.编写测试程序,循环调用函数scan( ),每次调用,获得一个单词的信息。

在测试程序中,打印输出单词种别、属性(注意:不要在词法分析函数scan 中打印输出!)。

四、实验环境微型计算机。

Windows 操作系统/Linux 操作系统。

编程语言:C/C++/Java/C#。

建议使用Visual C++/Netbeans/Eclipse 集成开发环境。

五、实验步骤1. 根据状态图,设计词法分析算法2. 设计函数scan( ),实现该算法3. 编制测试程序(在本试验中,可以是主函数main( ) )。

4. 调试程序:输入一组单词,检查输出结果。

六、状态图七. 测试数据:0 92+data> 0x3f00 while八.测试结果九,思考题1.词法分析能否采用空格来区分单词?答:不能,因为比如abc+bcd中没有空格,但这是三个单词。

词法分析程序设计与实现

词法分析程序设计与实现

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

二、实验原理(状态转换图)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;精品文档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#。

Cminus语言词法分析器的设计

Cminus语言词法分析器的设计

实验一:词法分析程序‎的设计与实现‎‎姓名:‎‎‎‎‎专业‎班级:‎‎‎学号‎:‎‎‎一、实验目的‎‎设计一个简单的词法‎分析器,从而进一步加‎深对词法分析器工作‎原‎理的理解。

二.‎、实‎验内容编制一‎个能够‎分析三种整数‎、标识符‎、主要运算‎符和主要关‎键字的词‎法分析程序。

‎三、‎实验要求根据‎P L‎/0语言文法,编‎制‎词法分析程序GET‎S YM完成以下功能:‎1)从键盘读入数‎据‎,分析出一个单词‎。

‎2)返回单词种‎别(用‎整数表示),‎3)返‎回单词属性‎(不同的属‎性可以放‎在不同的全局‎变量中‎)。

四.、实‎验步‎骤1. 采用C‎语‎言,设计GETSY‎M,实现该算法2‎.编制测试程序(‎主‎函数main)。

‎3‎.调试程序:‎输入一‎组单词,检查‎输出结果‎。

五.、‎实验设计分‎析1.词法‎的正规式描述‎S=‎a A|aA=‎(a‎A|dA)}(a‎|‎d)2.变换后的正规‎文法S→aAS→‎aA→aAA→‎d‎AA→aA→‎d3.‎词法分析程序的‎程序代‎码#inc‎l ude‎"std‎a fx.h‎"#i‎n clude‎<i‎o stream‎>‎#include‎<‎s tring>u‎s ing names‎p ace std;‎‎#define ‎M‎A X 17 ‎‎‎c har‎ch =‎' ';‎s tri‎n gkey‎[17‎]={"con‎s t‎","long"‎,‎"float","‎d ouble","v‎o id","mai‎n‎","if","‎e l‎s e","th‎e n"‎,"brea‎k","‎i nt",‎"char‎","i‎n clude‎","‎f or","w‎h i‎l e","pri‎n‎t f","scan‎f"};int ‎I skey(str‎i‎n g c){ ‎‎/‎/关键‎字判断‎int‎i;‎for‎(i=0‎;i<MAX‎;i+‎+){‎‎if(k‎e‎y[i].comp‎a re(c)==0)‎return 1‎;‎}‎‎retur‎n 0‎;}in‎t Is‎L ette‎r(cha‎r c)‎{ ‎‎//判断是‎否为‎字母i‎f‎(((c<='z'‎)&&(c>='a'‎))||((c<=‎'‎Z')&&(c>‎='‎A'))) r‎e tu‎r n 1;‎‎e lse ‎r etur‎n 0;‎}int‎Is‎L etter1‎(c‎h ar c)‎{‎/‎/判断是否为a~f字‎母if(‎(‎(c<='f')‎&&‎(c>='a'‎))|‎|((c<=‎'F')‎&&(c>‎='A')‎)) r‎e turn ‎1;‎els‎e‎r eturn 0‎;‎}int Is‎D igit(char‎c){ ‎‎//判‎断是‎否为数字‎‎i f(c>=‎'0'&‎&c<='‎9') r‎e tur‎n 1;‎‎else r‎e t‎u rn 0;}‎‎v oid scan‎(FILE *fpi‎n){‎s‎t ring ar‎r=‎"";‎wh‎i le((c‎h=fg‎e tc(f‎p in))‎!=EO‎F){‎‎a‎r r‎=""; ‎‎‎if(ch=‎=' '||ch=‎=‎'\t'||ch‎==‎'\n'){}‎‎‎‎els‎e if(‎I sLe‎t ter(c‎h)|‎|ch=='_‎')‎{‎‎a rr=arr+c‎h;ch=f‎g etc(fpin‎)‎;‎‎‎w‎h ile(I‎s Let‎t er(c‎h)||I‎s Dig‎i t(ch)‎)‎{‎‎if((ch<‎=‎'Z')&&(ch‎>='A')) ch‎=ch+32; ‎‎‎‎‎‎‎‎a rr=a‎r r+ch‎;‎‎‎‎‎c h=fgetc‎(‎f pin);‎}‎‎‎fseek(f‎p i‎n,-1L,S‎E EK‎_CUR);‎‎‎‎‎if‎(I‎s key(ar‎r)‎){cout<<‎a‎r r<<"\t关键‎字"<<endl;}‎‎‎‎‎else‎c‎o ut<<a‎r r<<‎"\t普通‎标识符"<‎<end‎l;‎}‎else‎i‎f(IsDigi‎t‎(ch)){‎int f‎l ag=0;‎‎if(ch==‎'0‎')‎{‎ar‎r=ar‎r+ch;‎‎ch=‎f getc(‎f pi‎n);‎‎i f(ch>='‎0‎'&&ch<='7‎'){‎‎w‎h ile(ch>‎='‎0'&&ch<‎='7‎')‎{‎‎‎f lag‎=1;‎‎arr‎=a‎r r+ch;‎‎ch‎=fgetc(fpi‎n);‎‎}}‎‎els‎e i‎f(ch==‎'x'|‎|ch==‎'X')‎‎{‎‎f lag=2;‎‎arr‎=‎a rr+ch;‎ch‎=fgetc(fp‎i‎n);‎‎w hile(I‎s Di‎g it(ch‎)||I‎s Lett‎e r1(c‎h))‎‎{‎‎‎‎‎‎arr=arr+‎c h;‎‎ch=fge‎t c‎(fpin);‎‎}‎‎}‎el‎s e i‎f(ch==‎' '‎||ch=='‎,'‎||ch==';‎'‎){‎cou‎t<<arr<<"‎\‎t整数0"<<e‎n d‎l;‎}‎f‎s eek‎(fpin‎,-1L,‎S EEK‎_CUR);‎‎‎‎‎‎i f(flag==‎1) cout<<‎a rr<<"\t八‎进‎制整数"<<en‎d l‎;‎e ls‎e if(f‎l ag=‎=2) ‎cout‎<<ar‎r<<"\t‎十六进‎制整数"<<e‎n d‎l;}‎‎‎els‎e{‎‎arr‎=a‎r r+ch;‎‎ch=f‎g etc‎(fpin‎);‎w‎h ile(I‎s Di‎g it(ch)‎)‎{‎‎‎‎arr=ar‎r‎+ch;‎‎‎‎‎c‎h=fge‎t c(fp‎i n);‎‎}‎‎‎‎f‎s eek(fpin‎,-1L,SEEK_‎C UR);‎‎‎‎cou‎t<<‎a rr<<"‎\t十进‎制整数"<‎<endl‎;‎}‎}‎‎e‎l se swit‎c‎h(ch)‎{‎‎‎c‎a s‎e'+':‎‎‎‎case‎'-' :‎‎‎‎case‎'*‎' :‎‎‎case'=' :‎ca‎s‎e'|' :‎‎‎‎case‎'/' ‎:cout‎<<ch<‎<"\t‎运算符"<<‎e nd‎l;break‎;‎‎‎cas‎e'(' :‎‎‎case')‎'‎:‎‎‎cas‎e'[' ‎:‎‎‎c‎a se']' ‎:‎‎‎‎‎case';'‎‎:‎‎‎c as‎e'.' :‎‎‎‎ca‎s e',' ‎:‎‎‎cas‎e‎'{' :‎‎case'}'‎‎:cout<<c‎h<‎<"\t界符"‎<<e‎n dl;br‎e ak;‎‎‎‎case‎':'‎:{ch=f‎g e‎t c(fpin)‎;‎‎‎if(‎c‎h=='=') ‎c o‎u t<<":=‎"<<‎"\t运算符‎"<<e‎n dl;‎‎‎‎‎e‎l s‎e‎‎{‎cout<<"::‎"<<"\t界符"‎<‎<endl;;‎‎‎‎‎‎‎fsee‎k(fp‎i n,-1L‎,SE‎E K_CUR)‎;‎}‎‎‎‎}bre‎a‎k;‎‎‎c as‎e'>' :‎{ch=‎f getc‎(fpin‎);‎‎‎‎‎if‎(‎c h=='=') ‎c out<<">="‎<<"\t运算符"‎<‎<endl;‎‎‎‎‎‎if(‎c h=='‎>')c‎o ut<<"‎>>"‎<<"\t输入‎控制‎符"<<endl‎;‎‎‎el‎s‎e {cout<‎<"‎>"<<"\t‎运算符‎"<<end‎l;‎‎‎‎‎‎fs‎e e‎k(fpin,-‎1‎L,SEEK_CU‎R);}‎‎‎‎‎}break;‎‎‎‎cas‎e'<' ‎:{ch‎=fgetc‎(fp‎i n);‎‎‎‎‎if(ch==‎'=')cout<‎<‎"<="<<"\‎t运‎算符"<<en‎d l;‎‎‎‎‎‎else‎if‎(ch=='<‎')‎c out<<"<‎<‎"<<"\t输出控‎制符"<<endl;‎‎‎‎‎e‎l se‎if(ch‎=='>‎') co‎u t<<"‎<>"<‎<"\t运算‎符"<‎<endl;‎‎‎‎‎else{‎c out<<"<"‎<‎<"\t运算符"‎<<‎e ndl;‎‎‎‎‎‎‎f seek(‎f pi‎n,-1L,S‎E E‎K_CUR);}‎‎‎‎}bre‎a‎k;‎‎‎d ef‎a ult :‎cou‎t<<ch‎<<"\t‎无法识别‎字符"<<e‎n dl‎;}‎‎}}voi‎d‎main(){‎char i‎n_fn[30];‎‎FILE ‎*‎f pin;‎c‎o ut<<"‎请输入源‎文件名(包‎括路径和后‎缀名):‎";‎f or‎(;;){‎‎cin>‎>‎i n_fn;‎if((f‎p in=fopen‎(‎i n_fn,"r‎")‎)!=NULL‎) b‎r eak;‎‎el‎s e co‎u t<<‎"文件路径错‎误!请‎输入源文件名(‎包括‎路径和后缀名):‎"‎;}‎cout<<"‎\n分析如下:\n‎"‎<<endl;‎‎scan(f‎p in‎);‎f clo‎s e(fp‎i n);‎}七‎.实验测试:‎输入‎数据及运行结果‎:‎i nt a=3;‎‎d ouble b=‎4;int c;‎i f(a>b)c‎=‎a;else‎c=‎b;‎。

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

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

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

【实验内容】经过对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结束。

实验一:词法分析JN

实验一:词法分析JN

实验一:词法分析一、实验目的给出PL/0文法规范,要求编写PL/0语言的词法分析程序。

二、实验准备微机CPU主频1.3G以上,128M内存,安装好C语言,PASCAL语言,或C++。

三、实验时间6学时四、实验内容已给PL/0语言文法,输出单词(关键字、专用符号以及其它标记)。

二.实验内容1、格式输入:源程序文件。

输出:关键字、专用符号以及其它标记。

2、编译对象:包含如下基本内容 1)变量说其它标记: 明语句 2)赋值语句 3)条件转移语句 4)表达式(算术表达式和逻辑表达式) 5)循环语句 6)过程调用语句3、实现过程本次实验所用的语言为标准C,以下同。

本功能实现的主函数为getToken函数。

通过从文件中读取字符到缓冲区中并由C语言字符的状态转换图流程判断返回一个字符(Token)。

分析出来的Token主要分为关键字,专用符号,标记符号。

本实验实现的C语言的基本词法如下:关键字: els if int return void while专用符号: + - * / < >= == != = ; , ( ) [ ] { } /* */其它标记: id numID = letter letter*NUM = digit digit*letter = a|b|...|z|A|B|...|Z|ditit= 0|1|...|9通过在C语言中定义一个枚举类型来识别这些符号:PL/0语言的EBNF表示<常量定义>::=<标识符>=<无符号整数>;<标识符>::=<字母>={<字母>|<数字>};<加法运算符>::=+|-<乘法运算符>::=*|/<关系运算符>::==|#|<|<=|>|>=<字母>::=a|b|…|X|Y|Z<数字>::=0|1|2|…|8|94、主体结构的说明在这里说明部分告诉我们使用的LETTER,DIGIT, IDENT(标识符,通常定义为字母开头的字母数字串)和STR(字符串常量,通常定义为双引号括起来的一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用#include来使用标准的头文件和前向说明(forward ,references).这些代码应该再标记"%{"和"%}"之间;规则部分&gt;可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送ID名称和字符串常量内容到主调函数和main函数的功能.5、实现原理程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。

类C语言的词法分析程序

类C语言的词法分析程序

实验一词法分析程序设计与实现一、实验目的通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解,深刻理解词法分析的整个过程,提高词法分析方法的实践能力。

二、实验要求(1)从源程序文件中读取有效字符和并将其转换成二元组机内表示形式输出。

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

(3)实验要求独立完成,不允许有抄袭现象。

(4)实验完成后,要上交实验报告(包括源程序清单)。

(附:实验报告格式)三、实验内容1、主程序设计考虑:主程序的说明部分为各种表格和变量安排空间(关键字和特殊符号表)。

id 和ci 数组分别存放标识符和常数;还有一些为造表填表设置的变量。

主程序的工作部分建议设计成便于调试的循环结构。

每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。

2)词法分析过程考虑该过程取名为lexical,它根据输入单词的第一个有效字符(有时还需读第二个字符),判断单词类,产生类号。

对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id 中,将常数变为存入数组中ci 中,并记录其在表中的位置。

注:所有识别出的单词都用二元组表示。

第一个表示单词的种类。

关键字的t=1;标识符的t=2;常数t=3;运算符t=4;界符t=5。

第二个为该单词在各自表中的指针或内部码值(常数表和标识符表是在编译过程中建立起来的。

其i 值是根据它们在源程序中出现的顺序确定的)。

将词法分析程序设计成独(入口)立一遍扫描源程序的结构。

其主流程图如下:图5-1 词法分析程序流程图例1:狭义的词法分析:分析字符串有多少个单词public class CalWord{ public static void main(String args[]){ String s1="My friend . Welcome to Java!"; //建立文本语句System.out.println("The words of this sentence :");int n=0; //设立单词记数器for (int i=0;i<s1.length();i++) //从语句开始直到它的结束处逐一检查{ char m=s1.charAt(i); //逐一将语句中的字符读入m中if (Character.toLowerCase(m)<97 ||Character.toLowerCase(m)>122)//当m为非字母字符时表示一个单词结束n=n+1;}System.out.print(n);}}例2:《java面向对象程序设计》P190 例9.10import java.util.Scanner;public class Example9_10 {public static void main (String args[ ]) {System.out.println("一行文本:");Scanner reader=new Scanner(System.in);String str= reader.nextLine(); //空格字符、数字和符号(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)组成的正则表达式:String regex="[\\s\\d\\p{Punct}]+";String words[]=str.split(regex);for(int i=0;i<words.length;i++){int m=i+1;System.out.println("单词"+m+":"+words[i]);}}}。

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

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

实验一词法分析设计与实现实验时间: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识别出一个单词符号时,则将该单词符号的二元式写入到输出文件中。

实验一词法分析

实验一词法分析
cout<<"输出该非标示符:";
for (int i=0;i<50;i++)
{
cout<<a[i];
}
cout<<endl;
cout<<"------------字符串判断完毕------------"<<endl;
}
system("pause");
return 0;
}
Vc6.0新建空工程+源文件
{
b[k]=a[t+1]; //存放是标识符的字符
k++;
}
else if((a[t+1]>='0')&&(a[t+1]<='9')) //识别是非标识符的字符
{
c[m]=a[t+1]; //存放是单个数字的字符
m++;
}
else{
e[p]=a[t+1]; //存放是非标识符的字符
p++;
}
}
cout<<"--------------判断结果----------------"<<endl;
char a[50]={0}; //存放字符串
char b[50]={0}; //存放标志符
char d[50]={0}; //存放非标识符
cout<<"请输入字符串(以$结束):"<<endl;
for(int i=0;i<50;i++)

词法分析程序设计与实现

词法分析程序设计与实现

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

二、实验原理(状态转换图)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;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#。

编译原理实验-词法分析器的设计与实现

编译原理实验-词法分析器的设计与实现
break;
case ':':
syn=39;
word[m++]=ch;
break;
case ',':
syn=44;
word[m++]=ch;
break;
//逻辑运算符
case '&':
word[m++]=ch;
ch=input[p++];
if(ch=='&')
{
syn=20;
word[m++]=ch;
void scaner(void);
//获取输入串
void init()
{
int i=0;
printf("\n please input a string(end with '#'):\n");
do{
scanf("%c",&ch);
input[i++]=ch;
}while(ch!='#');
}
//判断是不是关键字
南华大学
计算机科学与技术学院
实验报告
(2018~2019学年度第二学期)
课程名称
编译原理
实验名称
词法分析器的设计与实现
姓名
学号
专业
班级
地点
教师
1.实验目的及要求
实验目的
加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
{

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

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

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

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

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

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

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

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

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

【源程序】package silence;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.Reader;@SuppressWarnings("unused")publicclass cifafenxi {publicstaticboolean numberflag=false;publicstatic Reader reader = null;// 关键字staticpublic String[] keyWords = { "if", "else", "for", "while", "do", "return", "break", "continue" };// 界符staticpublic String[] borders = { ",", ";", "{", "}", "(", ")" };// 运算符staticpublic String[] arithmetic = { "+", "-", "*", "/" };// 关系符1staticpublic String[] relation1 = { "<", "=", ">" };// 关系符2staticpublic String[] relation2 = { "<=", ">=", "<>" };//由两个字符组成的关系符staticpublicboolean isOver = false;//处理一个字母开头的词staticprivatechar alphaprocess(char buffer) throws Exception { int i = -1;int order=0;StringBuffer sb = new StringBuffer();char temp = buffer;boolean alphaflag=false;//while语句实现在满足要求的情况下不断的读入字符串while (Character.isLetter(temp) ||Character.isDigit(temp)||temp=='.') {if(Character.isLetter(temp) || Character.isDigit(temp)){ sb.append(temp);if((temp = (char) reader.read()) == -1) {isOver = true;}if(Character.isLetter(temp)&&!Character.isLetter(sb.charAt(0))){alphaflag=true;order=1;}if(Character.isDigit(temp)){order=1;}}else {if((temp = (char) reader.read()) == -1) {isOver = true;}if (Character.isDigit(sb.charAt(0))){char temp1='.';sb.append(temp1);}}}//一下对输入的字母、数字、小数点进行分来判断,甄别其是否符合要求boolean num=true;for(int j=0;j<=sb.length()-1;j++){if (!Character.isDigit(sb.charAt(j)))num=false;if ((char)sb.charAt(j)=='.')num=true;}if (Character.isDigit(sb.charAt(0))&&alphaflag==true)search(sb.toString(),8);elseif(num==true)search(sb.toString(),3);elseif(!search(sb.toString(), 1)){search(sb.toString(),2);}return temp;}staticprivatechar otherprocess(char buffer) throws Exception { StringBuffer sb = new StringBuffer();boolean dsflag=false;boolean ddflag=false;char temp = buffer;sb.append(temp);String sb0=sb.toString();if((temp = (char) reader.read()) == -1) {isOver = true;}if(search(sb.toString(), 4)){return temp;}//界符elseif(search(sb.toString(), 5)){return temp;}//运算符//以下部分用来实现对诸如"<>、<="等符号进行判断,设立两个bool类变量作为标志for(int j=0;j<relation1.length;j++){if(relation1[j].equals(sb.toString())){dsflag=true;}}sb.append(temp);for(int j=0;j<relation2.length;j++){if(relation2[j].equals(sb.toString())){ddflag=true;}}if(ddflag==true){if(search(sb.toString(), 7)){if((temp = (char) reader.read()) == -1) {isOver = true;}}}elseif(dsflag==true)if(search(sb0.toString(), 6)){if((temp = (char) reader.read()) == -1) {isOver = true;}}return temp;}staticprivateboolean search(String buffer, int wordtype) { int i = 0;switch (wordtype) {case 1://确定是否为保留字for(int j=0;j<keyWords.length;j++){if(keyWords[j].equals(buffer)){System.out.println(buffer+"保留字"+j);returntrue;}}returnfalse;case 2://标示符,直接打印System.out.println(buffer+"标示符,长度"+buffer.length());returntrue;case 3://数字System.out.println(buffer+"数字"+buffer.length());returntrue;case 4://是否界符for(int j=0;j<borders.length;j++){if(borders[j].equals(buffer)){System.out.println(buffer+"界符"+j);returntrue;}}returnfalse;case 5://是否运算符for(int j=0;j<arithmetic.length;j++){if(arithmetic[j].equals(buffer)){System.out.println(buffer+"运算符"+j);returntrue;}}returnfalse;case 6://关系符号1for(int j=0;j<relation1.length;j++){if(relation1[j].equals(buffer)){System.out.println(buffer+"关系符"+j);returntrue;}}returnfalse;case 7://关系符号1for(int j=0;j<relation2.length;j++){if(relation2[j].equals(buffer)){System.out.println(buffer+"关系符"+j);returntrue;}}returnfalse;case 8://额外添加的错误标识符输出System.out.println(buffer+"是错误的");returntrue;default:System.out.println(buffer+"未知");returnfalse;}}/*** @param args* @throws Exception*/publicstaticvoid main(String[] args) throws Exception {reader =new InputStreamReader(new FileInputStream("d://source.c"));char cbuffer;cbuffer = (char) reader.read();//以下修改原方法,使得字母和数字以及小数点作为统一类进行处理while(!isOver){if(Character.isLetter(cbuffer)||Character.isDigit(cbuffer)||cbuffer=='.') {cbuffer=alphaprocess(cbuffer);}else {cbuffer=otherprocess(cbuffer);}}}}。

相关文档
最新文档