词法分析实验报告
编译原理词法分析实验报告
编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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)程序结构描述:函数调用格式:参数含义: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语句的条件,解决了此问题。
词法分析实验报告
词法分析实验报告词法分析实验报告引言词法分析是自然语言处理中的一个重要环节,它负责将输入的文本分割成一个个的词语,并确定每个词语的词性。
本次实验旨在通过实现一个简单的词法分析器,来探索词法分析的原理和实践。
实验内容本次实验中,我们使用Python编程语言来实现词法分析器。
我们选取了一段简单的英文文本作为输入,以便更好地理解和演示词法分析的过程。
1. 文本预处理在进行词法分析之前,我们首先需要对输入文本进行预处理。
预处理的目的是去除文本中的标点符号、空格和其他无关的字符,以便更好地进行后续的分词操作。
2. 分词分词是词法分析的核心步骤之一。
在这个步骤中,我们将文本分割成一个个的词语。
常见的分词方法包括基于规则的分词和基于统计的分词。
在本次实验中,我们选择了基于规则的分词方法。
基于规则的分词方法通过事先定义一系列的分词规则来进行分词。
这些规则可以是基于语法的,也可以是基于词典的。
在实验中,我们使用了一个简单的基于词典的分词规则,即根据英文单词的常见前缀和后缀来进行分词。
3. 词性标注词性标注是词法分析的另一个重要步骤。
在这个步骤中,我们为每个词语确定其词性。
词性标注可以通过事先定义的规则和模型来进行。
在本次实验中,我们使用了一个简单的基于规则的词性标注方法。
基于规则的词性标注方法通过定义一系列的词性标注规则来进行词性标注。
这些规则可以是基于词法的,也可以是基于语法的。
在实验中,我们使用了一个简单的基于词法的词性标注规则,即根据英文单词的后缀来确定其词性。
实验结果经过实验,我们得到了输入文本的分词结果和词性标注结果。
分词结果如下:- I- love- natural- language- processing词性标注结果如下:- I (代词)- love (动词)- natural (形容词)- language (名词)- processing (名词)讨论与总结通过本次实验,我们深入了解了词法分析的原理和实践。
【编译原理】词法分析(CC++源代码+实验报告)
【编译原理】词法分析(CC++源代码+实验报告)⽂章⽬录1 实验⽬的和内容1.1实验⽬的(1)根据 PL/0 语⾔的⽂法规范,编写PL/0语⾔的词法分析程序;或者调研词法分析程序的⾃动⽣成⼯具LEX或FLEX,设计并实现⼀个能够输出单词序列的词法分析器。
(2)通过设计调试词法分析程序,实现从源程序中分离出各种类型的单词;加深对课堂教学的理解;提⾼词法分析⽅法的实践能⼒。
(3)掌握从源程序⽂件中读取有效字符的⽅法和产⽣源程序的内部表⽰⽂件的⽅法。
(4)掌握词法分析的实现⽅法。
(5)上机调试编出的词法分析程序。
1.2实验内容根据PL/0语⾔的⽂法规范,编写PL/0语⾔的词法分析程序。
要求:(1)把词法分析器设计成⼀个独⽴⼀遍的过程。
(2)词法分析器的输出形式采⽤⼆元式序列,即:(单词种类, 单词的值)2 设计思想2.1单词种类及其正规式(1)基本字单词的值单词类型正规式rbegin beginsym begincall callsym callconst constsym constdo dosym doend endsym endif ifsym ifodd oddsym oddprocedure proceduresym procedureread readsym readthen thensym thenvar varsym varwhile whilesym whilewrite writesym write(2)标识符单词的值单词类型正规式r标识符ident(字母)(字母|数字)*(3)常数单词的值单词类型正规式r常数number(数字)(数字)*(4)运算符单词的值单词类型正规式r+plus+-minus-*times*/slash/=eql=<>neq<><lss<<=leq<=>gtr>>=geq>=:=becomes:=(5)界符单词的值单词类型正规式r(lparen()rparen),comma,;semicolon;.period.2.2 根据正规式构造NFA下⾯我们根据上述的正规式来构造该⽂法的NFA,如下图所⽰,其中状态0为初态,凡带双圈的状态均为终态,状态24是识别不出单词符号的出错情形,其他状态的识别情况如下图中右边的注释所⽰。
实验一词法分析实验报告1
实验一词法分析一、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码与单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)二、实验要求使用一符一种的分法关键字、运算符和分界符可以每一个均为一种标识符和常数仍然一类一种三、实验内容功能描述:1、待分析的简单语言的词法(1)关键字:begin if then while do end(2)运算符和界符:(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码图 1程序结构描述:符号界符等符号四、实验结果输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图3所示:图3输入private x:=9;if x>0 then x:=2*x+1/3; end#后经词法分析输出如下序列:(private 10)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图4所示:图4显然,private是关键字,却被识别成了标示符,这是因为图1中没有定义private关键字的种别码,所以把private当成了标示符。
输入private x:=9;if x>0 then x:=2*x+1/3; @ end#后经词法分析输出如下序列:(private 10)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图5所示图5显然,@没有在图一中定义种别,所以输出了“Error in row 1!”的报错信息。
词法分析实验报告
词法分析实验报告一、实验目的和背景词法分析是编译原理中的重要部分之一,其主要作用是将源程序中的字符序列转化为有意义的单词序列,以便于后续的处理和分析。
为了更好地理解词法分析的实现原理以及掌握相关算法和工具,本次词法分析实验旨在通过手动编写正则表达式、确定有限自动机的状态转移函数和实现词法分析程序来实现词法分析。
二、实验内容在本次实验中,我们需要完成以下任务:1.手动编写正则表达式;2.确定有限自动机的状态转移函数;3.实现词法分析程序。
三、实验过程1.手动编写正则表达式对于给定的源程序,我们首先需要根据其语法规则手动编写正则表达式。
例如,对于一个简单的算术表达式,其正则表达式可以如下所示:i. 数字(0-9):[0-9]+ii. 加号(+):\+iii. 减号(-):-iv. 乘号(*):\*v. 除号(/):/vi. 左括号(():\(vii. 右括号()):\)2.确定有限自动机的状态转移函数根据正则表达式,我们可以确定有限自动机的状态转移函数。
例如,对于上述算术表达式的正则表达式,其有限自动机的状态转移函数如下所示:i. 初始状态(S):判断下一个字符,如果是数字则进入数字状态,如果是左括号则进入左括号状态;ii. 数字状态(D):继续判断下一个字符,如果是数字则保持在数字状态,如果是运算符则输出数字记号,返回初始状态,如果是右括号则输出数字记号,返回初始状态;iii. 左括号状态(L):输出左括号记号,返回初始状态;iv. 右括号状态(R):输出右括号记号,返回初始状态。
3.实现词法分析程序根据以上的正则表达式和有限自动机的状态转移函数,我们可以编写一个简单的词法分析程序。
该程序的主要流程如下所示:i. 读取源程序的字符序列;ii. 根据有限自动机的状态转移函数,逐个字符进行状态转移;iii. 如果当前状态为接受状态,则输出相应的记号;iv. 继续进行状态转移,直至读取完整个源程序。
四、实验结果通过以上步骤,我们成功完成了对给定源程序的词法分析。
词法分析实验报告(实验一)
编译原理词法分析实验报告软工082班兰洁200831104044一、实验内容二、实验目的三、实验预期四、程序规定五、实验原理●程序流程图●判别浮点功能扩展流程图●状态转换图六、程序代码与浮点判别功能扩展七、测试用例●扩展功能测试用例;●普通功能测试用例八、输出结果九、实验心得一、实验内容:词法分析:1、识别简单语言的单词符号;2、识别关键字、标识符、数字、运算符等。
并扩展浮点识别功能。
二、实验目的调试词法分析程序,加深对词法分析原理的理解,掌握编写简单词法分析程序的一般步骤。
三、实验预期结果:经过调试源代码程序,程序能够成功运行编译,对输入的简单字符串,能够别关键字、标识符、数字、运算符等,并且给出单词符号的对应编码。
四、程序规定:1、关键字:"function","if","then","while","do","endfunc";2、算术运算符:”+”,”-”,”*”,”/”,”=”;3、关系运算符:"<" ">" "<=" ">=" "==" "!=";4、界符:"(" ")" ";" "#";5、标识符规定以字母开头,字母均为小写;6、空格和换行符跳过;7、单词对应编码:十、实验原理:输入串--------------------〉词法分析程序————————〉单词符号串输入:字符串以#结束。
输出:单词的二元组(syn,token/sum)程序流程图分析浮点数功能扩展部分流程图:shuzi()函数状态转换图六、程序代码:备注:红色字体部分为程序功能的功能扩展,使程序能够分析浮点数!我把浮点数的syn设置为80!/*词法分析源代码*/#include<stdio.h>#include<string.h>scaner();char prog[80],token[8];char ch;int syn,p,m,n,sum;char * rwtab[6]={"function","if","then","while","do","endfunc"}; int i=0,k,c,sumint,f;char fenshu[80],sum1[80];double sumf=0,fudian;int shuzi(){if(ch>='0' && ch<='9')syn=80;elsesyn=-2;return syn;}main(){p=0;printf("\n please input string :\n");do{scanf("%c",&ch);prog[++p]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){ case 11:printf("\n(%d,%d)",syn,sum);break;case -1:printf("\n error");break;case 80:printf("\n(%d,%f)",syn,fudian);break; default:printf("\n(%d,%s)",syn,token);}}while(syn!=0);}scaner(){for(n=0;n<8;n++)token[n]=NULL;//if(1+2!=3)ch=prog[++p];while(ch==' ' || ch=='\n')ch=prog[++p];//跳过空格if(ch>='a' && ch<='z'){m=0;while(ch>='a' && ch<='z' || ch>='0' && ch<='9') {token[m++]=ch;//token[0]=f,m=1ch=prog[++p];}token[m]='\0';ch=prog[--p];syn=10;for(n=0;n<6;n++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}}elseif(ch>='0' && ch<='9'){c=p;k=0;do{ sum1[k]=ch;ch=prog[++c]; //ch取后一个数字k++;shuzi();//这个函数用来分析浮点数的整数部分是否已经输入到数组里f=syn;} while(f==80)if(ch=='.'){for(n=0;n<k;n++){sumint=sumint*10+sum1[n]-'0';} //计算整数部分i=0;do{ch=prog[++c];fenshu[i]=ch;i++;shuzi();//这个函数用来分析浮点数的小数部分是否已经输入到数组里} while(syn==80);sumf=0;for(k=i-2;k>=0;k--){sumf=sumf*0.1+(fenshu[k]-'0')*0.1;} //计算浮点数的小数部分fudian=sumint+sumf; //浮点数计算syn=80;p=--c;}else{ch=prog[p];//若是整数,ch等于原来的值 sum=0;while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=prog[++p];}ch=prog[--p];syn=11;}}elseswitch(ch){case'<':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m++]=ch;}elseif(ch=='>'){syn=21;token[m++]=ch;}else{syn=20;ch=prog[--p];}break;case'>':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=24;token[m++]=ch;}else{syn=23;ch=prog[--p];}break;case'=':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=25;token[m++]=ch;}else{syn=18;ch=prog[--p];}break;case'!':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m++]=ch;}else{syn=-1;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=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;default:syn=-1;}}七、测试用例:补充:功能扩展测试用例:八、程序输出结果:功能扩展测试用例输出结果用例一:用例二:用例三:普通功能测试用例显示结果九、实验心得通过编译原理实验一词法分析实验,使得自己对词法分析的流程有了更深刻的了解,虽然源代码并非由自己设计,但是在调试程序的过程中,尤其是进行测序功能扩展的过程中,想了很多种办法,终于找到了最合适的方法,而且还进行了代码的优化,这个过程虽然有时有些枯燥,但是更多时候是欣喜的,不仅复习了c语言的许多内容,并且有了更深的理解。
编译原理词法分析报告
实验一:词法分析一、实验目的:1、通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
2、编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本关键字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)二、实验预习提示1、词法分析器的功能和输出格式词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是一类符号一种别码的方式。
2、单词的BNF表示<标识符>-> <字母><字母数字串><字母数字串>-><字母><字母数字串>|<数字><字母数字串>|<下划线><字母数字串>|ε<无符号整数>-> <数字><数字串><数字串>-> <数字><数字串> |ε<加法运算符>-> +<减法运算符>->-<大于关系运算符>->><大于等于关系运算符>-> >=3、“超前搜索”方法词法分析时,常常会用到超前搜索方法。
如当前待分析字符串为“a>+”,当前字符为’>’,此时,分析器到底是将其分析为大于关系运算符还是大于等于关系运算符呢?显然,只有知道下一个字符是什么才能下结论。
于是分析器读入下一个字符’+’,这时可知应将’>’解释为大于运算符。
但此时,超前读了一个字符’+’,所以要回退一个字符,词法分析器才能正常运行。
在分析标识符,无符号整数等时也有类似情况。
词法分析实验报告文献
一、实验目的1. 深入理解词法分析的基本原理和过程。
2. 掌握词法分析器的设计与实现方法。
3. 熟悉C语言编程,并能够将其应用于词法分析程序的开发。
4. 培养问题分析和解决能力,提高编程技能。
二、实验原理词法分析是编译过程中的第一步,其主要任务是将源程序中的字符序列转换为一系列具有独立意义的单词符号(Token)。
词法分析器通过识别单词的构词规则,将源程序分解为一个个单词符号,为后续的语法分析和语义分析提供基础。
三、实验内容1. 词法分析器的设计本实验采用C语言实现一个简单的词法分析器,主要功能如下:- 识别并分类单词符号,包括关键字、标识符、常量、运算符和界符等。
- 对输入的源程序进行词法分析,输出每个单词符号及其对应的种别码。
- 处理词法错误,并给出错误提示。
2. 词法分析器的实现(1)数据结构- 关键字表:存储C语言中的关键字。
- 标识符表:存储用户自定义的标识符。
- 常量表:存储整型常量。
- 运算符表:存储C语言中的运算符。
- 界符表:存储C语言中的界符。
(2)主要函数- `isLetter(char c)`:判断字符是否为字母。
- `isDigit(char c)`:判断字符是否为数字。
- `alpha(char c)`:识别字母。
- `number(char c)`:识别整数。
- `anotation(char c)`:处理除号、注释以及其他特殊字符。
- `other(char c)`:处理其他字符。
(3)词法分析过程- 读取源程序中的字符。
- 根据字符类型调用相应的函数进行识别。
- 将识别出的单词符号及其种别码存储在相应的表中。
四、实验步骤1. 编写源程序,实现词法分析器。
2. 编写测试用例,对词法分析器进行测试。
3. 分析测试结果,验证词法分析器的正确性。
五、实验结果与分析1. 测试用例- 测试用例1:包含关键字、标识符、常量、运算符和界符的简单C程序。
- 测试用例2:包含错误标识符和运算符的C程序。
实验报告词法分析,模块图
模块设计实验报告:实验名称:词法分析实验目的和要求编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
实验内容和步骤:一、实验内容对于这个实验,我总共用了四个函数,即主函数、扫描函数、建立缓冲区、取单词。
主要完成的功能是从缓冲区中识别出一个个单词,并能够区分所取的单词是什么类型。
二、实验步骤1、基于实验的内容,构造程序所需的模块2、根据已建构的模块,写出各个模块的相应程序代码3、在主函数中调用模块来完成所要得到的效果在此,我想先介绍一下我的三个子模块,第一个是扫描函数。
扫描函数scanner(),其实大家都比较熟悉了,就是我们上次实验内容,可以原封不动的拿来用。
它的功能是调用一次就从缓冲区中取一个字符出来。
这为我们的取字符提供了基础,因此如果这个程序不会设计的话,那么这个实验就没法设计了。
至于建立第二个模块,就是从文件中把一个个字符读到缓冲区,比较简单,我在这里就不想说了。
接下来,我想比较地说一下第三个模块,也就是本实验的主要要求。
这个模块的函数程序代码如下:char getsym()//从缓冲区中取一个单词{bool flag=false;//用来表示取出的单词是否为关键词,如果是则flag的值为true,否则为falseint k=-1; //表示取出的字符放在单词数组的指针CType='0'; //预先定义的取出的单词的类型Lasttype='0'; //初始化先前的类型,此变量为判断正负数用while (ch<=32 && ch>0)//去掉不能显示的字符Fbuffer=scanner();if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z')//取出标识符或者是关键词{k=-1;while(true)//取出的单词长度不超过WMaxlen,如果超过,则其后的字符无效{if((++k)<WMaxlen)//(++k)为了使取出的单词最长为WMaxlen{Word[k]=ch;}Fbuffer=scanner();//如果取出的当前的字符不是字母或是数字,则此次取单词结束if (!(ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9'))break;}Word[++k]='\0';//以'\0'标识取出单词的结束,以方便后面的判断此单词是标识符还是关键词for (int i=0;i<KEY_No;i++)//用来判断取出的当前单词是不是关键词if (strcmp(Word,KEY[i])==0){flag=true;break;}if (flag) CType='1';//如果是关键词,则把此单词的类型定义为1型else CType='2'; //否则是标识符,其类型为2}else if (ch>='0' && ch<='9')//判断是不是为整数{Word[++k]=ch;Fbuffer=scanner();while(true)//如果是数字,则一直接受,且定义它的类型为3if(ch>='0' && ch<='9'){Word[++k]=ch;Fbuffer=scanner();}else {CType='3';break;}//不是数字则跳出循环//如果以字母开头,且长度不超过WMaxlen,且下面跟有字母,则此整数非法,输出类型为8,在主程序中输出出错信息if (k<WMaxlen)if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'){Word[++k]=ch;Fbuffer=scanner();//取这个非法整数的单词,其中可包含英文字母和数字while (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'|| ch>='0' &&ch<='9'||Fbuffer==-1)if (k<WMaxlen){Word[++k]=ch;Fbuffer=scanner();}else{Fbuffer=scanner();k++;}if (k>WMaxlen)//如果长度大于取出单词定义的最大长度,则返回类型为8,在主程序中打出出错信息CType=Longtype;else CType=Errtype;//否则返回类型7,在主程序出错,并明确写出此单词的具体内容}Word[++k]='\0';}else if (ch=='+'||ch=='-'||ch=='*'||ch=='/')//取出是运算符号的单词{Word[++k]=ch;if (ch=='+' || ch=='-')//如果是+号或者是-号,则还要判断是不是正负数if (Lasttype=='6')//判断其取出的当前字母的前一个单词是6号类型的,即是<、>、<=、>=、==、=时则可判断现在取出的是整数{Fbuffer=scanner();while(ch>='0' && ch<='9')//取出整数{Word[++k]=ch;Fbuffer=scanner();}CType='3';//如果正负整数,则直接返回类型为3,则表示此单词为整数return(CType);}else Fbuffer=scanner();//如果不是整数,则定义当前取出的单词是运算符,定义此类型为4Word[++k]='\0';CType='4';}else if (ch=='>'||ch=='<'||ch=='='||ch=='!')//取出运算符的另几类,即<、<=、>、>=、==、=、!={Word[++k]=ch;Fbuffer=scanner();if( ch=='=')//判断是不是<=、>=、==、!={Word[++k]=ch;Fbuffer=scanner();}Word[++k]='\0';for (int i=0;i<Sign_No;i++)//判断取出的单词是不是运算符if (strcmp(Sign[i],Word)==0){flag=true;break;}if (flag) CType='4';Lasttype='6';}else if (ch==','||ch==';'||ch=='{'||ch=='}'||ch=='('||ch==')')//判断当前取出的单词是不是界符,如果是界符,则定义其类型为5{CType='5';Word[++k]=ch;Word[++k]='\0';Fbuffer=scanner();}return(CType);}此函数返回一个识别出来的单词的类型,其实还返回一个值,那就是识别出来的单词。
词法分析程序实验报告
词法分析程序实验报告词法分析程序实验报告一、实验目的1. 理解词法分析器的基本功能2. 理解词法规则的描述方法3. 理解状态转换图及其实现4. 能够编写简单的词法分析器二、实验要求给出单词序列对应的状态识别。
单词符号State 对应的值单词符号State 对应的值function 1 = 18if 2 < 20else 3 <= 21for 4 != 22then 5 > 23while 6 >= 24do 7 == 25 endfunction 8 ; 26letter(letter|digit)* 10 ( 27digit digit* 11 ) 28+ 13 { 29- 14 } 30* 15 # 0/ 162、主程序流程图N程序开始初始化输入源程序调用scanner()函数,识别单词序列输出单词序列Y结束输入串结束?三、识别单词的状态转换图Scanner()函数流程图变量初始化忽略空格和换行num 读取常数state=11Token[]读入关键字、标识符关键字?判断关键字 statestate=10判断运算符和分界符 state 其余符号 state=-1 ReturnNY{)(;其他其他===其他!其他</* - + 非数字数字数字开始空格或换行字母0 1返回’10’或关键字234 返回’11’567 8返回’13’ 返回’14’ 返回’15’ 返回’16’ 910111213 14 1516171819 20 >=222425返回’20’返回’21’返回’-1’返回’22’ 返回’23’ 返回’24’返回’18’返回’25’ 返回’26’ 返回’27’ 返回’28’ 返回’29’} #2. 分析直接转向法和表驱动法的优缺点状态转换图的实现通常有两种方法:状态转换表和直接转向法(1) :状态转换表法又称数据中心,是把状态转换图看作一种数据结构,由控制程序控制字符在其上运行,从而完成词法分析。
词法分析器实验报告
词法分析器实验报告一、实验目的本实验旨在通过构建一个简单的词法分析器来加深对编译原理中词法分析的理解,并掌握基本的词法分析算法和程序设计技巧。
二、实验环境操作系统:Windows 10编程语言:C/C++开发环境:Visual Studio 2019三、实验内容1. 设计并实现一个词法分析器,要求具备以下功能:(1)能够识别并区分关键字、标识符、字符常量、字符串常量、整型常量和浮点型常量等基本单词;(2)能够跳过注释、空格、制表符和换行符等无用字符;(3)能够给出错误提示并指明错误所在位置。
2. 对设计的词法分析器进行测试,并记录测试结果,分析测试结果的正确性和效率。
四、实验方法1. 分析待处理的源程序,并确定需要识别的词法单元;2. 设计状态转换图或状态转换表,并将其转化为程序代码;3. 开发测试程序,对所设计的词法分析器进行测试。
五、实验结果1. 实现的词法分析器程序可以正确识别出源程序中的各个单词,并能够跳过无用字符;2. 在测试过程中发现了一些错误,比如未能正确识别一些特殊情况下的单词,或者给出了错误的错误提示等。
经过修改后,程序可以正确识别这些情况,并给出正确的错误提示信息;3. 程序的效率较高,能够在短时间内对源程序进行词法分析。
六、实验体会通过本次实验,我对编译原理中词法分析的概念、算法和程序设计技巧有了更加深入的了解和掌握。
在实践中,我遇到了许多问题,比如如何设计状态转换图,如何正确识别一些特殊的单词等。
这些问题一一解决后,我对词法分析有了更加深刻的理解。
通过本次实验,我还深刻体会到了编译器设计过程中的思维方式和技术要求。
编译器是计算机科学中的一项重要技术,对于提高程序运行效率、保证程序安全性、增强程序可读性和扩展程序功能等都有重要作用。
因此,编译原理作为计算机科学的重要组成部分,对于我以后的学习和研究具有重要意义。
实现词法分析实验报告
实现词法分析实验报告一、实验目的本次实验的目的是通过编写代码实现一个简单的词法分析器,可以对一段输入的代码进行词法分析,识别出其中的各种标识符、关键字、常数和运算符等。
二、实验原理词法分析是编译过程中的第一个阶段,它负责将源代码按照规定的规则划分为一个个的单词(Token),每个单词代表一个最基本的语法单元。
在词法分析中,我们通过预先定义好的正则表达式规则来描述各个单词类型,并自动从源代码中提取出这些单词。
本次实验采用基于正则表达式的文法描述方式,针对不同的单词类型,使用不同的正则表达式来匹配。
通过遍历源代码字符串,逐一尝试匹配各个正则表达式,从而实现对单词的划分。
在匹配过程中,我们使用一个状态机来记录当前的匹配状态,以便处理不同的情况。
三、实验过程1. 定义Token的数据结构,包括单词类型和单词值两个字段。
使用枚举类型来表示所有的单词类型,如关键字、标识符、常数等。
2. 编写正则表达式的匹配函数,用于判断给定的字符串是否符合某个模式。
在这个函数中,使用系统提供的正则表达式库或者手动实现正则表达式匹配算法。
3. 设计一个状态机,用于记录当前匹配的状态。
状态机的状态包括开始、正在匹配、匹配成功和匹配失败等。
在状态机中,根据当前字符和当前状态进行不同的处理。
4. 在状态机中,当一个完整的Token被匹配出时,根据其类型和值创建一个Token对象,并将其添加到Token列表中。
5. 将源代码字符串按照换行符划分成多行,逐行进行处理。
对于每一行,调用状态机进行匹配,将得到的Token添加到Token列表中。
6. 输出Token列表,观察结果。
四、实验结果经过实验,我们成功实现了一个简单的词法分析器。
通过对输入的代码进行词法分析,我们可以得到每个单词的类型和值。
在本次实验中,我们测试了一段C语言代码,并成功提取出其中的关键字、标识符、常数和运算符等。
五、实验总结本次实验让我初步了解了词法分析的原理和过程。
词法分析设计实验报告(附代码)
实验一词法分析设计实验学时:4实验类型:综合实验要求:必修一、实验目的通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。
二、实验内容用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。
通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。
以下是实现词法分析设计的主要工作:(1)从源程序文件中读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)按拼写单词,并用(内码,属性)二元式表示。
(属性值——token的机内表示)(5)如果发现错误则报告出错(6)根据需要是否填写标识符表供以后各阶段使用。
单词的基本分类:◆关键字:由程序语言定义的具有固定意义的标识符。
也称为保留字例如if、 for、while、printf ;单词种别码为1。
◆标识符:用以表示各种名字,如变量名、数组名、函数名;◆常数:任何数值常数。
如 125, 1,0.5,3.1416;◆运算符:+、-、*、/;◆关系运算符: <、<=、= 、>、>=、<>;◆分界符:;、,、(、)、[、];三、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。
2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。
3、根据测试数据进行测试。
测试实例应包括以下三个部分:◆全部合法的输入。
◆各种组合的非法输入。
◆由记号组成的句子。
4、词法分析程序设计要求输出形式:例:输入VC++语言的实例程序:If i=0 then n++;a﹤= 3b %);输出形式为:单词二元序列类型位置(行,列)(单词种别,单词属性)for (1,for ) 关键字(1,1)i ( 6,i ) 标识符(1,2)= ( 4,= ) 关系运算符(1,3)0 ( 5,0 ) 常数(1,4)then ( 1,then) 关键字(1,5)n (6,n ) 标识符(1,6)++ Error Error (1,7); ( 2, ; ) 分界符(1,8)a (6,a ) 标识符(2,1)﹤= (4,<= ) 关系运算符(2,2)3b Error Error (2,4)% Error Error (2,4)) ( 2, ) ) 分界符(2,5); ( 2, ; ) 分界符(2,6)实验报告正文:◆功能描述:该程序具有词法分析功能,即面对一段程序源代码,通过该程序,能检查出源代码是否由词法错误。
编译词法分析实验报告
一、实验目的1. 理解词法分析的基本概念和原理。
2. 掌握词法分析器的实现方法。
3. 熟悉C语言在词法分析中的应用。
4. 提高编程能力和问题解决能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C3. 开发环境:Visual Studio 2019三、实验内容1. 设计词法分析器,实现对源代码的词法分析。
2. 将源代码分解为单词序列。
3. 输出单词序列及对应的词法类型。
四、实验步骤1. 分析源代码中的词法单位,确定词法类型。
2. 设计词法分析器的状态转换表。
3. 编写词法分析器代码。
4. 测试词法分析器,验证其正确性。
五、实验过程1. 分析源代码中的词法单位在C语言中,词法单位包括标识符、关键字、运算符、分隔符、常量等。
本实验以C语言为例,分析源代码中的词法单位,确定词法类型。
2. 设计词法分析器的状态转换表根据词法单位,设计词法分析器的状态转换表。
状态转换表包括当前状态、输入字符、下一状态、输出词法类型和对应动作。
3. 编写词法分析器代码根据状态转换表,编写词法分析器代码。
以下为词法分析器的主要功能模块:(1)初始化:设置初始状态、词法类型和单词长度。
(2)读取字符:从源代码中读取字符,并判断字符类型。
(3)状态转换:根据状态转换表,更新当前状态、输出词法类型和单词长度。
(4)输出结果:将单词序列及对应的词法类型输出到屏幕。
4. 测试词法分析器编写测试用例,验证词法分析器的正确性。
测试用例包括以下几种情况:(1)包含各种词法单位的源代码。
(2)包含注释的源代码。
(3)包含错误标识符的源代码。
六、实验结果与分析1. 实验结果通过测试,词法分析器能够正确识别源代码中的各种词法单位,并将单词序列及对应的词法类型输出到屏幕。
以下为部分测试结果:```int a = 10; // 输出:int, 标识符if (a > 0) // 输出:if, 关键字{// 输出:{, 分隔符// ...// 输出:}, 分隔符}// 输出://, 注释开始注释内容// 输出://, 注释结束```2. 实验分析(1)实验过程中,通过对词法分析原理的学习,加深了对编译原理的理解。
词法分析实验报告(实验一)
词法分析实验报告(鲍小伟20032320)一.实验目的:通过设计、编程、调试出一个具体词法分析程序,加深对词法分析原理的理解,掌握其设计方法。
二.实验内容:用C/C++实现对PASCAL的子集程序设计语言的词法识别程序。
三.实验要求与原理:(1)实验要求:将该语言的源程序,即相应字符流转换成内部表示,并对标识符填写相应的符号表供编译程序以后各阶段使用,输出的单词符号格式为二元组(单词种别,单词在标识符表中的地址),标识符表格式有“序号”和“标识符本身的值”两项。
写出设计报告,内容为:状态转换图、单词符号及内部表示、符号表、出错处理、编程方法等。
(2)实验原理:状态转换图:空白8923单词符号及内部表示:标志符表和常数表:void getchar();//将下一输入字符读到ch中,指针后移一字符位置void getbc();//保证ch是一个非空白字符void concat();//将ch连接到字符串stroken的末尾void retract();//置ch为空白字符,指针前移一字符位置int isdigit();//判断是否整数int isletter();//首字母的判断int reserve();//对stroken进行关键字表的查找,返回其编码值int insertid();//将stroken中的标识符插入符号表,返回在符号表中的位置int insertconst();//将stroken中的常数插入常数表,返回在常数表中的位置四.主要源代码:Scanner::Scanner(char str[], int n) //构造函数{strcpy(buffer, str);length = n;i = j = 0;}int Scanner::isdigit()//判断是否整数{if(ch>='0' && ch<='9')return 1;elsereturn 0;}int Scanner::isletter()//首字母的判断{if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z'))return 1;elsereturn 0;}void Scanner::getchar() //将下一输入字符读到ch中,指针后移一字符位置{ch = buffer[i];i++;}void Scanner::getbc() //保证ch是一个非空白字符{while(ch == ' ')getchar();}void Scanner::concat() //将ch连接到字符串stroken的末尾{strtoken[j] = ch;j++;}void Scanner::retract() //置ch为空白字符,指针前移一字符位置{ch = ' ';i--;}int Scanner::reserve() //对stroken进行关键字表的查找,返回其编码值{int i, flag = 0;for(i=0; i<15; i++){if( strncmp(reservechar[i],strupr(strtoken), j) == 0 ){flag = 1;break;}}if(flag == 1) return i+1;else return 0;}int Scanner::insertid() //将stroken中的标识符插入符号表,返回在符号表中的位置{for(int a = 0; a < m; a++)for(int b = 0; b < x[a]; b++)if( strncmp(&id[a][0], strtoken, j) == 0 ){return m+1;break;}for(a = 0; a < j; a++)id[m][a] = strtoken[a];x[m] = j;m++;return m;}int Scanner::insertconst() //将stroken中的常数插入常数表,返回在常数表中的位置{for(int i = 0; i < j; i++)cst[n][i] = strtoken[i];y[n] = j;n++;return n;}void Scanner::scan(){while(i < length){j = 0;int code, value;strcpy(strtoken, " "); //置strtoken为空串getchar();getbc();if(isletter()) //如果打头的是字母{while(isletter() || isdigit()){concat();getchar();}retract();code = reserve();if(code == 0) //如果扫描到的是标识符{value = insertid();cout<<"<34,"<<value<<">"<<'\n';}else cout<<"<"<<code<<",*>"<<'\n'; //如果扫描到的是关键字}else if(isdigit()) //如果打头的是数字{while(isdigit()){concat();getchar();}retract();value = insertconst();cout<<"<33,"<<value<<">"<<'\n';}else if(ch == '+')cout<<"<16,*>"<<'\n';else if(ch == '-')cout<<"<17,*>"<<'\n';else if(ch == '*')cout<<"<18,*>"<<'\n';else if(ch == '/')cout<<"<19,*>"<<'\n';else if(ch == '=')cout<<"<20,*>"<<'\n';else if(ch == '<'){getchar();if(ch == '>')cout<<"<21,*>"<<'\n';else if(ch == '=')cout<<"<23,*>"<<'\n';else{retract();cout<<"<22,*>"<<'\n';}}else if(ch == '>'){getchar();if(ch == '=')cout<<"<25,*>"<<'\n';else{retract();cout<<"<24,*>"<<'\n';}}else if(ch == '.')cout<<"<26,*>"<<'\n';else if(ch == ',')cout<<"<27,*>"<<'\n';else if(ch == ';')cout<<"<28,*>"<<'\n';else if(ch == ':'){getchar();if(ch == '=')cout<<"<30,*>"<<'\n';else{retract();cout<<"<29,*>"<<'\n';}}else if(ch == '(')cout<<"<31,*>"<<'\n';else if(ch == ')')cout<<"<32,*>"<<'\n';else if(ch == '{'){while(ch != '}')getchar();}else cout<<"出错!"<<'\n';}}void main(void){fstream file;file.open("F:/20032320/20032320.txt", ios::in||ios::nocreate); //以只读方式打开file.unsetf(ios::skipws); //不跳过文本中的空格char buffer[100]; //缓冲区定义cout<<"扫描结果如下所示"<<'\n';while(file.getline(buffer, 100)){Scanner SS(buffer, strlen(buffer));SS.scan();}cout<<"标识符表如下:\n"<<"编号\t"<<"值\n";for(int i=0; i<m; i++){cout<<i+1<<'\t';for(int j=0; j<x[i]; j++)cout<<id[i][j];cout<<'\n';}cout<<"常数表如下:\n"<<"编号\t"<<"值\n";for(i=0; i<n; i++){cout<<i+1<<'\t';for(int j=0; j<y[i]; j++)cout<<cst[i][j];cout<<'\n';}}五.运行结果:程序的运行结果如下图所示:。
词法分析~实验报告
词法分析~实验报告实验⼀、词法分析实验专业商业软件3班姓名陈笑璞学号 201506110218⼀、实验⽬的(1)编制⼀个词法分析程序(2)词法分析是编译的第⼀个阶段,主要任务是从左⾄右逐个字符地对源程序进⾏扫描,产⽣⼀个个单词序列,⽤于语法分析。
(3)通过词法分析的练习,能够进⼀步了解编译原理。
(4)通过了解词法分析程序的设计原则、单词的描述技术、识别机制及词法分析程序的⾃动构造原理。
⼆、实验内容和要求(1)输⼊:源程序字符串(2)输出:⼆元组(种别,单词符号本⾝)。
三、实验⽅法、步骤及结果测试实验⽅法、步骤:(1)对字符串表⽰的源程序(2)从左到右进⾏扫描和分解(3)根据词法规则(4)识别出⼀个⼀个具有独⽴意义的单词符号(5)以供语法分析之⽤(6)发现词法错误,则返回出错信息2、原理分析: 我的设计思路是利⽤链队列(好处:先进先出且不浪费存储空间)进⾏存储⽤户输⼊字符串,以回车键结束(其中必须以⾮数字结尾,否则程序出错)(这是我在后来的编程⾥遇到的问题,我知道问题出在哪⾥,但我现在还解决不了,因为我是通过申请⼦针域来存储,所以我是利⽤p->next来作为判断结束条件,如果以数字结束,那p->next指向未知领域,程序出错,同时这也是很危险的),然后我是利⽤出队列来判断,如果是字母存进数组⾥,直到下⼀个字符不是字母,调⽤函数判断数组的字符串,利⽤strcmp来判断,输出数组,再清空数组;void Print(char str[])//调⽤函数来判断关键字与标识符并输出{int i=0;if(strcmp(str,"begin")==0)printf("(1,'%s')\n",str);else if(strcmp(str,"if")==0)printf("(2,'%s')\n",str);else if(strcmp(str,"then")==0)printf("(3,'%s')\n",str);else if(strcmp(str,"while")==0)printf("(4,'%s')\n",str);else if(strcmp(str,"do")==0)printf("(5,'%s')\n",str);else if(strcmp(str,"end")==0)printf("(6,'%s')\n",str);else{if(str[0]=='\0')return;printf("(10,'%s')\n",str);}memset(str,0,N);//清空数组str⾥的所有元素}结果测试:四、实验总结说实话,通过这次的编译原理词法分析的实验,我遇到了不少问题,也学到了不少的东西,因为这次实验我是想⽤我⾃⼰的想法来编写程序,我是⽤链队列来存储字符串的,也许⽤数组来存储字符串会简单点,但我不想,我还是想利⽤链队列来存储字符串,这样可以节约存储空间,还可以利⽤队列先进先出的特点,不好就是利⽤队列不够灵活,每次都要出栈判断、存储,释放p的⼦针域;虽然在编写过程中,遇到不少问题,遇到⼀个,就想办法解决⼀个,通过问朋友⽼师等,也通过发朋友圈问,还通过发博客来问⼤神们,这种途径是最有效的,也是最好的;所以每次就差⼀点就做好了,⼜会遇到⼀个新的问题,就要想办法去解决它,如今除了字符串是以数字结尾会出现问题外(暂时没找到好的⽅法),其他问题已解决。
编译原理词法分析器实验报告
编译原理词法分析器实验报告篇一:编译原理词法分析器实验报告曲阜师范大学实验报告计算机系2008年级软件工程一班组日期2010年10月17日星期日姓名陈金金同组者姓名课程编译原理成绩实验名称:教师签章词法分析器一、实验目的:1·掌握词法分析的原理。
2·熟悉保留字表等相关的数据结构与单词的分类方法。
3·掌握词法分析器的设计与调试。
二、实验内容:根据编译中的分词原理,编写一个词法分析程序:1. 输入:任意一个C 语言程序的源代码。
2. 处理:对输入进行分析,分离出保留字、标识符、常量、算符和界符。
3. 输出:对应的二元式(种别编码自定,可暂编为一类对应一个编码)。
三、实验要求:1. 任选C/C++/Java 中的一种高级程序语言编程完成词法分析器。
2. 词法分析器应以教材所述分词原理为依据,使用恰当的数据结构和方法,结构清晰、高效。
四、实验环境:WindowsXp操作系统,J2SE,Eclipse 集成开发环境五、实验分析:将源代码作为长字符串进行读入,之后通过switch语句,及状态转换图进行词素识别,并对识别的词素进行分类整理以二元式的形式输出。
六、实验过程:1、建立词法分析器界面,很简单:输入框,输出框,执行分析按钮,清空按钮,退出程序按钮。
主要的地方是,考虑mvc开发模式,为model及controller 提供接口。
实现界面如下所示:2、核心代码的编写,考虑到需要进行词素的匹配,创建符号表类SymTable。
提供两个变量,分别存放如下内容:并提供方法insert,lookUp,分别负责标志符的插入和查找。
3.、根据语法规则书写状态转换图,并用switch语句实现:需要注意的地方是,begin和forward 两个指针的移动:通过swith语句识别词素,并在符号表中进行匹配,匹配成功,则返回相应的记号,否则返回id。
七、实验结论:实验过程还算顺利,遇到的一系列问题都得到比较好的解决,当然分析器还有很大的改进空间,这里只是简单的实现了词素的识别及简单的判断。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
词法分析器一、实验目的:通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
二、实验要求如源程序为C语言。
输入如下一段:Array main(){int a,b;a = 10;b = a + 20;}#要求输出如右图。
要求:1、将单词分为五种识别关键字:main、if、int、for、while、do、return、break、continue;单词种别码为1。
标识符;单词种别码为2。
常数为无符号整形数;单词种别码为3。
运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
分隔符包括:,、;、{、}、(、);单词种别码为5。
2、使用一符一种的分法关键字、运算符和分界符可以每一个均为一种标识符和常数仍然一类一种三、实验内容1、功能描述改程序是一个实现词法分析的功能,能识别5种单词,其他单词报错。
2、程序结构描述int IsKey(char *Word)关键字匹配函数,查询是否为关键字,若是,返回值为1,否则为0。
int IsAlpha(char c) 查看是否为字母,若是,返回值为1,否则为0。
int IsNum(char c) 查看是否为数字,若是,返回值为1,否则为0。
void scanner(FILE *fp) 扫描函数,扫描程序中的字符串并调用上述三种函数检查是否是字母、数字,是否是关键字,并输出。
fseek(fp,-1,1)回退一个字符。
fgetc(fp)从数据流中区下一个字符。
fopen 文件打开函数,返回指向文件第一个字符的指针四、实验结果测试内容为main(){int a,b;a = 10;b = a + 20; }#结果测试代码为void main() {int a,b;if(a = 10;)b += 20; c=%;}#结果为测试代码main(){int a,b;if(a <= "10")b += 20; c=%@; return 0;}#结果五、实验过程记录1、因为用到回退函数fseek(),而以前没有用过这个函数,所以开始时很苦恼,不知道如何回退一个字符,后来问了同学,才明白原来有这么一个函数,顿时豁然开朗。
2、本次试验中word[20]保存字符串时,不能正确保存,总是出错,原因是while(IsNum(ch)||IsAlpha(ch)){Word[i]=ch;i++;ch=fgetc(fp);}中,i++与Word[i]=ch;次序不对,后来多次思索,发现问题。
六、实验总结本次实验花了将近一个下午才完成。
在纸上设计的时间大约40分钟,剩下的时间是录入和调试。
本次实验使我认识到,一段时间搁置,不编程序,水平会下降,好多有关c语言的知识会忘掉,所以以后我会经常写写程序。
另外,通过本次实验,我又进一步加深对词法分析原理的理解。
总的来说,获益匪浅!附录#include<>#include<>#include<>#include<>#include<>Char*Key[9]={"void","main","int","if","then","else","return","break","continue"}; char 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<8;i++){if((m=strcmp(Word,Key[i]))==0)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) cout<<"(2,"<<Word<<')'<<endl;//不是关键字else cout<<"(1,"<<Word<<')'<<endl; //输出关键字}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); //回退cout<<"(3,"<<Word<<')'<<endl;}else //开始判断的字符不是字母也不是数字{Word[0]=ch;switch(ch){case'[':case']':case'(':case')':case'{':case'}':case',':case'"':case';':cout<<"(5,"<<Word<<')'<<endl; break;case'+':ch=fgetc(fp);if(ch=='='||ch=='+'){Word[1]=ch;cout<<"(4,"<<Word<<')'<<endl;//运算符"+="或判断结果为"++"}else {fseek(fp,-1,1);cout<<"(4,"<<Word<<')'<<endl;//判断结果为"+"}break;case'-':ch=fgetc(fp);if(ch=='='||ch=='-'){Word[1]=ch;cout<<"(4,"<<Word<<')'<<endl; }else {fseek(fp,-1,1);cout<<"(4,"<<Word<<')'<<endl; //判断结果为"-"}break;case'*':case'/':case'!':case'=':ch=fgetc(fp);if(ch=='='){Word[1]=ch;cout<<"(4,"<<Word<<')'<<endl;}else {fseek(fp,-1,1);cout<<"(4,"<<Word<<')'<<endl;}break;case'<':ch=fgetc(fp);if(ch=='='||ch=='<'){Word[1]=ch;cout<<"(4,"<<Word<<')'<<endl;}else {fseek(fp,-1,1);cout<<"4\t"<<Word<<endl; //判断结果为"<"}break;case'>':ch=fgetc(fp);if(ch=='='||ch=='>'){Word[1]=ch;cout<<"(4,"<<Word<<')'<<endl;}else {fseek(fp,-1,1);cout<<"(4,"<<Word<<')'<<endl;}break;default:cout<<"(无法识别字符,"<<Word<<')'<<endl; break;}}}void main(){FILE *fp;fp=fopen("c:\\","r");if(fp==NULL) //读取文件内容,并返回文件指针,该指针指向文件的第一个字符{cout<<"读入文件错误!"<<endl;exit(0);}cout<<"******************* 词法分析结果如下*******************\n";while(ch!='#'){ch=fgetc(fp);if(ch=='#') break; //文件以#结尾,作为扫描结束条件else if(ch==' '||ch=='\t'||ch=='\n'){} //忽略空格,空白,和换行else{fseek(fp,-1,1); //回退一个字节开始识别单词流scanner(fp);}}}。