编译原理实验词法解析总结器的设计及实现.doc
编译原理实验-词法分析器的设计与实现
1.对单词的构词规则有明确的定义;
2.编写的分析程序能够正确识别源程序中的单词符号;
3.识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表;
4.对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;
2.实验步骤
1.词法分析规则
{
while(isDigit(ch))
{
word[m++]=ch;
ch=input[p++];
}
p--;
syn=42;
}
else
{
syn=16;
p--;
}
break;
case '*':
word[m++]=ch;
ch=input[p++];
if(ch=='=')
{
syn=23;
word[m++]=ch;
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;
3.源程序
编译原理词法分析实验报告
编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
编译原理实验报告(词法分析器语法分析器)
函数 int f(char c) 和 int g(char c) , 判断运算符之间的优先关系 , 根据不同情况作各种不同操作 。 流程
图如下 :
word 完美格式
专业资料
输入算数表达式,以 #结束 初始化 loptr[1]= ’#’ 用 get()取一个待分析字符 s
Optr[1] 和 s 是否同时为 #
。
2 、而且对词法分析和语法分析在实践中的应用有了深入的掌握
。
3 、 更加熟悉了构造词法分析程序和语法分析程序的手工方式的相关原理
, 能够实现对词
法分析程序所提供的单词符号序列进行相应的语法检查和结构分析
,达到了学以致用的目的 。
word 完美格式
word 完美格式
专业资料
case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
while(letter(s)||digit(s)) {token[j]=s; j=j+1; get(); } retract();k=lookup(token); if(k==0)
-
9
*
10
<=
11
<
11
==
11
=
12
;
13
word 完美格式
助记符 while
if else switch case
编译原理实验报告
编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理实验报告
编译原理实验报告一、实验概述本次实验旨在设计并实现一个简单的词法分析器,即实现编译器的第一个阶段,词法分析。
词法分析器将一段源程序代码作为输入,将其划分为一个个的词法单元,并将其作为输出。
二、实验过程1.设计词法规则根据编程语言的规范和所需实现的功能,设计词法规则,以明确规定如何将源程序代码分解为一系列的词法单元。
2.实现词法分析器采用合适的编程语言,根据所设计的词法规则,实现词法分析器。
词法分析器的主要任务是读入源程序代码,并将其根据词法规则进行分解,生成对应的词法单元。
3.测试词法分析器设计测试用例,用于检验词法分析器的正确性和性能。
测试用例应包含各种情况下的源程序代码。
4.分析和修正错误根据测试过程中发现的问题,分析产生错误的原因,并进行修正。
重复测试和修正的过程,直到词法分析器能够正确处理所有测试用例。
三、实验结果我们设计了一个简单的词法分析器,并进行了测试。
测试用例涵盖了各种情况下的源程序代码,包括正确的代码和错误的代码。
经过测试,词法分析器能够正确处理所有的测试用例。
词法分析器将源程序代码分解为一系列的词法单元,每个词法单元包含了单词的种类和对应的值。
通过对词法单元的分析,可以进一步进行语法分析和语义分析,从而完成编译过程。
四、实验总结通过本次实验,我深入了解了编译原理的词法分析阶段。
词法分析是编译器的第一个重要阶段,它将源程序代码分解为一个个的词法单元,为后续的语法分析和语义分析提供基础。
在实现词法分析器的过程中,我学会了如何根据词法规则设计词法分析器的算法,并使用编程语言实现词法分析器。
通过测试和修正,我掌握了调试和错误修复的技巧。
本次实验的经验对我今后的编程工作有很大帮助。
编译原理是计算机科学与技术专业的核心课程之一,通过实践能够更好地理解和掌握其中的概念和技术。
我相信通过进一步的学习和实践,我能够在编译原理领域取得更大的成果。
词法分析器的设计与实现
《编译原理》课程实验报告实验题目:某种简单程序语言的词法分析器的设计与实现专业:计算机科学与技术班级:11060341学号:11060341姓名:实验目的:设计一个词法分析程序,理解词法分析器实现的原理,掌握程序设计语言中的各类单词的词法分析方法,加深对词法分析原理的理解。
实验任务:词法分析是从左向右扫描每行源程序的符号,拼成单词,换成统一的二元式(单词种别,单词符号的属性值)表示。
对给定的程序通过词法分析器识别一个个单词符号,并以二元式(单词种别,单词符号的属性值)显示,本程序则是通过对给定程序段分析后以单词符号和文字提示显示)实验流程:程序清单:#include<iostream>#include<cstdio>#include<cstring>using namespace std;int k=0;struct word{char name[10];int kind;} word[1000];char key[35][10]= {"scanf","short","int","long","float","double","char","struct","union","printf","typedef","const","unsigned","signed","extern","register","static","volatile","void","if","else","switch","case","for","do","while","goto","continue","break","default","sizeof","return","include","bool"};bool cmp(char a[]){int i;for(int k=0; k<35; k++){if(strcmp(a,key[k])==0)return 1;}return 0;}int main(){#ifdef LOCALfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);#endifint p,q,flag;char a[1000],b[10],ch;while(gets(a)){p=0;int len=strlen(a);while(p<len){ch=a[p];memset(b,0,sizeof(b));while(ch==' '){p++;ch=a[p];}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||ch=='_'){flag=0;q=0;while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||ch=='_'||(ch>='0'&&ch<='9')) {if((ch>='0'&&ch<='9')||ch=='_')flag=1;b[q++]=ch;p++;ch=a[p];}if(flag==1){strcpy(word[k].name,b);word[k++].kind=1;}else if(flag==0){if(ch=='\''||ch=='"'){strcpy(word[k].name,b);word[k++].kind=2;}else if(cmp(b)==1){strcpy(word[k].name,b);word[k++].kind=3;}else{strcpy(word[k].name,b);word[k++].kind=1;}}}else if((ch>='0'&&ch<='9')||ch=='-'){if(a[t]>='0'&&a[t]<='9'||a[t]>='a'&&a[t]<='z'||a[t]>='A'&&a[t]<='Z'){p++;ch=a[p];if(ch=='-'||ch=='='){b[0]='-';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='-';strcpy(word[k].name,b);word[k++].kind=5;}}else{q=0;b[q++]=ch;p++;ch=a[p];while((ch>='0'&&ch<='9')||ch=='.'){b[q++]=ch;p++;ch=a[p];}strcpy(word[k].name,b);word[k++].kind=2;}}elseif(ch=='('||ch==')'||ch=='['||ch==']'||ch=='{'||ch=='}'||ch==','||ch==';'||ch==':'||ch=='\''||ch=='"')//ch=='('| |ch==')'||ch=='['||ch==']'||ch=='{'||ch=='}'||{b[0]=ch;strcpy(word[k].name,b);word[k++].kind=4;}else if(ch=='%'||ch=='^'){b[0]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else if(ch=='+'){p++;ch=a[p];if(ch=='+'||ch=='='){b[0]='+';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='+';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='*'){p++;ch=a[p];if(ch=='*'||ch=='='){b[0]='*';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='*';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='/'){p++;ch=a[p];if(ch=='/'||ch=='='){b[0]='/';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='/';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='='){p++;ch=a[p];if(ch=='='){b[0]=b[1]='=';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='=';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='>'){p++;ch=a[p];if(ch=='>'||ch=='='){b[0]='>';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='>';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='<'){p++;ch=a[p];if(ch=='<'||ch=='='){b[0]='<';b[1]=ch;strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='<';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='!'){p++;ch=a[p];if(ch=='='){b[0]='!';b[1]='=';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='!';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='&'){p++;ch=a[p];if(ch=='&'){b[0]=b[1]='&';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='&';strcpy(word[k].name,b);word[k++].kind=5;}}else if(ch=='|'){p++;ch=a[p];if(ch=='|'){b[0]=b[1]='|';strcpy(word[k].name,b);word[k++].kind=5;ch=a[++p];}else{b[0]='|';strcpy(word[k].name,b);word[k++].kind=5;}}}}for(int i=0; i<k; i++){switch(word[i].kind){case 1:{printf("(标识符,");break;}case 2:{printf("(常量,");break;}case 3:{printf("(关键字,");break;}case 4:{printf("(界符,");break;}case 5:{printf("(运算符,");break;}}printf("%s)\n",word[i].name); }int a1=0,a2=0,a3=0,a4=0,a5=0; for(int i=0;i<k;i++){if(word[i].kind==1)a1++;else if(word[i].kind==2)a2++;else if(word[i].kind==3)a3++;else if(word[i].kind==4)a4++;else if(word[i].kind==5)a5++;}printf("标识符:%d\n常量:%d\n关键字:%d\n界符:%d\n运算符:%d\n",a1,a2,a3,a4,a5);return 0;}运行结果:。
编译原理实验报告
编译原理实验报告一、实验目的编译原理是计算机科学中的重要学科,它涉及到将高级编程语言转换为计算机能够理解和执行的机器语言。
本次实验的目的是通过实际操作和编程实践,深入理解编译原理中的词法分析、语法分析、语义分析以及中间代码生成等关键环节,提高我们对编译过程的认识和编程能力。
二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。
此外,还使用了一些相关的编译工具和调试工具,如 GDB 等。
三、实验内容(一)词法分析器的实现词法分析是编译过程的第一步,其任务是将输入的源程序分解为一个个单词符号。
在本次实验中,我们使用有限自动机的理论来设计和实现词法分析器。
首先,定义了各种单词符号的类别,如标识符、关键字、常量、运算符等。
然后,根据这些类别设计了相应的状态转换图,并将其转换为代码实现。
在实现过程中,使用了正则表达式来匹配输入字符串中的单词符号。
对于标识符和常量等需要进一步处理的单词符号,使用了相应的规则进行解析和转换。
(二)语法分析器的实现语法分析是编译过程的核心环节之一,其任务是根据给定的语法规则,分析输入的单词符号序列是否符合语法结构。
在本次实验中,我们使用了递归下降的语法分析方法。
首先,根据实验要求定义了语法规则,并将其转换为相应的递归函数。
在递归函数中,通过对输入单词符号的判断和处理,逐步分析语法结构。
为了处理语法错误,在分析过程中添加了错误检测和处理机制。
当遇到不符合语法规则的输入时,能够输出相应的错误信息,并尝试进行恢复。
(三)语义分析及中间代码生成语义分析的目的是对语法分析得到的语法树进行语义检查和语义处理,生成中间代码。
在本次实验中,我们使用了三地址码作为中间代码的表示形式。
在语义分析过程中,对变量的定义和使用、表达式的计算、控制流语句等进行了语义检查和处理。
对于符合语义规则的语法结构,生成相应的三地址码指令。
四、实验步骤(一)词法分析器的实现步骤1、定义单词符号的类别和对应的正则表达式。
编译原理实验_词法分析器的设计与实现
41
-
16
数字
42
-=
17
标识符
43
--
18
,
44
&
19
//
45
&&
20
/**/
46
#
21
*
22
*=
23
/
24
/=
25
3.状态转换图
4.算法分析
①词法分析器工作的第一步是输入源程序文本。为了更好地对单词符号识别,把输入串预处理一下。预处理主要滤掉空格,跳过注释、换行符等。
②对预处理后的输入串依次扫描单个字符,使用if-while嵌套语句和switch case语句判断字符的类型,具体识别方法可看状态转换图。有时为了确定词性,需要超前扫描,若超前扫描的字符对识别当前单词无用处,则需要退还给输入串,以备识别下一单词字符时使用。
③若读入的字符与单词符号编码表的字符匹配不上,则报错,并输出出错行数。对识别处的单词符号以(单词符号,种别码)二元式的形式输出。
3.实验容
1.流程图
2.程序的变量与函数说明
(1)input
全局字符数组,用来存放输入串
(2)word
全局字符数组,用来存放获取到的单词符号,限定长度为8
(3)ch
全局字符变量,用来存放最新读入的字符
南华大学
计算机科学与技术学院
实 验 报 告
( 2018~2019学年度 第二学期 )
课程名称
编译原理
实验名称
词法分析器的设计与实现
学号
专业
班级
地点
教师
1.实验目的及要求
实验目的
加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
编译原理实验-词法分析器的设计
集美大学计算机工程学院实验报告课程名称:编译原理班级:指导教师:姓名:实验项目编号:实验一学号:实验项目名称:词法分析器的设计实验成绩:一、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
二、实验内容编写一个词法分析器,从输入的源程序(编写的语言为C语言的一个子集)中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)三、实验要求1、词法分析器的功能和输出格式词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
单词示例单词种别码要求保留字if、else、int、while、do 每个保留字的单词种别都单独为一种标识符以字母开头且包含字母和数字的字符串标识符作为一种常数(只识别无符号整数)123、343 无符号整数作为一种运算符+、-、*、/、=、= = 、!=、> 、<、>=、<= 每符一种,也可以每一类符号一种分隔符,、;、{、}、(、) 每符一种2、上述要求仅为基本要求,可以在此基础上扩充,例如删除注释,增加识别单词的类型,将标识符和常量分别插入到相应的符号表中,增加错误处理等。
3、编程语言不限。
四、实验设计方案1、数据字典本实验用到的数据字典如下表所示:单词示例标识ID1 保留字void、if、else、for、while、do、return、break、main、int、float、char、double、String标识符以字母开头且包含字母和数字的字符串 2无符号整数和小数 3 常数(只识别无符号整数)运算符+、-、*、/、=、> 、<、 4分隔符,、;、{、}、(、) 5 本实验所使用的开发语言是C语言,在Test2类中定义了以下几个函数:2.程序流程图:YNY NNY YN Y N Y YN NN Y YN N N Y Y开始读入文件,把内容存入string 中,m=0,check=ture ,error=false从string 中读出一个字符放入ch 中输出str ,标识为无法识别的串check=ture ,error=falsech 是运算符?error=ture ? check=false ? 输出str ,标识为标示符check=ture 输出str ,标识为运算符输出str ,标识为无法识别的串check=ture ,error=falseerror=ture ? check=false ? 输出str ,标识为标示符check=ture 输出str ,标识为分隔符ch 是分隔符?ch 是数字?check=ture ?清空str ,ch 加到str 中,check=false ch 加到str 中Ch 是字母?check=ture ?清空str ,ch 加到str 中,check=falsech 加到str 中打印出错ch 是最后一个字符? 结束YN Y N3、实验程序#include<stdio.h> #include<string.h> #include<ctype.h> #include<windows.h>//判断读入的字符是否为字母 bool isLetter(char c){if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')){ return true; } else return false; }//判断读入的字符是否为数字 bool isDigit(char c){if(c >='0' && c <= '9'){ return true; } else return false; }//判断是否为关键字 bool isKey(char *string) { if(!strcmp(string,"void")|| !strcmp(string,"if")|| !strcmp(string,"for")|| !strcmp(string,"while")|| !strcmp(string,"do")|| !strcmp(string,"return")|| !strcmp(string,"break")|| !strcmp(string,"main")|| !strcmp(string,"int")|| !strcmp(string,"float")|| !st rcmp(string,"char") || !strcmp(string,"double")|| !strcmp(string,"String")) { return true;ch 是数字?ch 加到str 中,error=true ch 是关键字? 输出str ,标识为关键字,check=true}else return false;}bool isError(char ch){if(ch == '@' || ch == '$' || ch == '&' || ch == '#' || ch == '~' || ch == '^'){return true;}elsereturn false;}void main(){char string[500]="";//存放文件中读出来的字符串char str[10]="";//存放需要对比的字符串char ch,c;//ch存放文件中的单个字符(翻译时用),c存放文件中的单个字符(从文件中提取信息时用)char filename[20];//文件名int j=0;printf("请输入文件名进行词法翻译:");scanf("%s",filename);FILE *cfPtr;if((cfPtr=fopen(filename,"r"))==NULL)printf("文件未找到!");else{while(!feof(cfPtr)){if(isspace(c=fgetc(cfPtr))){//判断是否是字符串;}else{string[j]=c;//从文件中一一提取字符j++;}}}int m = 0,k=0;//m翻译时用,k是str数组的下标string[j]=' ';j++;bool check=true,error=false;//用于判断标识for(int i = 0;i < j;i++){//实现语法翻译器switch (m){ch = string[i];if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '='|| ch == '>' || ch == '<'){if(error){printf("%s,此字符无法是识别!\n",str);error=false;check=true;}else if(!check){printf("(2,%s)标示符\n",str);check=true;}m = 4;}else if(ch == ',' || ch == ';' || ch == '{' || ch == '}' || ch == '(' || ch == ')'){if(error){printf("%s此字符无法识别\n",str);error=false;check=true;}else if(!check){printf("(2,%s)标示符\n",str);check=true;}m = 5;}else if ( isDigit((ch =string[i]) ) ){if(check){memset(str, 0, strlen(str));//清空k=0;str[k]=ch;k++;m = 3;check=false;} else{str[k]=ch;k++;}}else if ( isLetter(ch = string[i]) )if(check){check=false;memset(str, 0, strlen(str));k=0;str[k]=ch;k++;}else{str[k]=ch;k++;if(isKey(str)){printf("(1,%s)关键字\n",str);check=true;}}}else if(isError(ch = string[i])){if(check){memset(str, 0, strlen(str));//清空k=0;str[k]=ch;k++;check=false;error=true;}else{str[k]=ch;k++;error=true;}}else{}break;case 3:if(isLetter(ch =string[i])){printf("程序有错误!!!\n");str[k] = ch;k++;error=true;m = 0;break;}if(isError(ch = string[i])){printf("程序有错误!!!\n");str[k] = ch;k++;error=true;m = 0;break;}if (isDigit((ch =string[i] ) )){str[k] = ch;k++;}else if(ch=='.'){str[k]=ch;k++;}else{printf("( 3,%s) 数字\n",str);i --;m = 0;check=true;}break;case 4:i--;printf("( 4 ,%c) 运算符\n",ch);m = 0;break;case 5:i --;printf("( 5 ,%c) 分隔符\n",ch);m = 0;break;}}return;}五、实验结果六、实验小结本次实验中,运用C语言进行实验,实验刚开始的时候,能够对输入的字符进行判断,但是却不能排错以及只能识别全是字母的标识符,后来经过修改程序代码和编程的逻辑最终实现了,既能排错又能分析句子;通过实验掌握了词法分析,能实现对普通程序的语法分析翻译。
编译原理实验--词法分析器
实验一词法分析器设计【实验目的】1.熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。
2.复习高级语言,进一步加强用高级语言来解决实际问题的能力。
3.通过完成词法分析程序,了解词法分析的过程。
【实验内容】用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字,运算符,标识符,常数以及界符)输出。
【实验流程图】【实验步骤】1.提取pl/0文件中基本字的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE];int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {printf("%s\t",wsym[m]);m=14;n=k+1;} }2.提取pl/0文件中标识符的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE]=" ";int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {m=14;n=k+1;}}if(m==13) for(m=0;a[m]!=NULL;m++) printf("%c ",a[m]);3.提取pl/0文件中常数的源代码while((ch=fgetc(stream))!='.'){while(ch>='0' && ch<='9'){num=10*num+ch-'0';ch=fgetc(stream);}if(num!=0) printf("%d ",num);num=0;}4.提取pl/0文件中运算符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case'+': printf("+ ");break;case'-': printf("- ");break;case'*': printf("* ");break;case'/': printf("/ ");break;case'>': if(fgetc(stream)=='=')printf(">= "); else printf("> ");break;case'<': if(fgetc(stream)=='=')printf("<= "); else printf("< ");break;case':': printf(":= ");break;case'#': printf("# ");break;case'=': printf("= ");break;default: break;}ch=fgetc(stream);5.提取pl/0文件中界符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case',': printf(", ");break;case';': printf("; ");break;case'(': printf("( ");break;case')': printf(") ");break;default: break;}ch=fgetc(stream);}【实验结果】1.pl/0文件(222.txt)内容const a=10;var b,c;procedure p;beginc:=b+a;end;beginread(b);while b#0 dobegincall p;write(2*c);read(b)endend .2.实验运行结果【实验小结】1.了解程序在运行过程中对词法分析,识别一个个字符并组合成相应的单词,是机器能过明白程序,定义各种关键字,界符。
词法分析器的设计与实现编译原理实验报告
中北大学软件学院实验报告
专业软件工程
课程名称编译原理
学号
姓名
辅导教师张静成绩
//test.cpp 测试程序路径:D:\test.cpp
main()
{
int score;
char grade;
printf("please input a score\n");
scanf("%d",amp;score);
grade=score>=90?'A':(scoregt;=60?'B':'C'); printf("%d belongs to %c",score,grade);
}
$
7、测试及结果
1、登陆界面:
2、出错异常处理:
3、结果分析:
8、心得
在本次实验中,我纠正了一个一直以来的概念错误:main不是关键字,它定义为程序的入口,是主函数!在本实验中,虽然我把main初始化在关键字表
(字符指针类型数组)*Key[10]中,当与该数组中字符串进行比较时,若与main匹配成功,则返回2,若为其他关键字则返回1,以此来把main从关键字中区别出来。
在本实验中的关键字表只初始化了几个常用的关键字,还可继续扩充(只需扩大数组,向其中补充要添加的关键字)。
如果要对本程序中未识别的c语言中的一些其他的字符进行扩充(目前处理为不可识别字符),可在程序代码中继续添加case选项,分别对相应要识别的特殊字符加以描述。
编译原理实验词法分析器与语法分析器实现
编译原理实验词法分析器与语法分析器实现词法分析器与语法分析器是编译器的两个重要组成部分,它们在编译过程中扮演着至关重要的角色。
词法分析器负责将源代码转化为一个个标记(token)序列,而语法分析器则根据词法分析器生成的标记序列构建语法树,验证源代码的语法正确性。
本实验旨在实现一个简单的词法分析器和语法分析器。
实验一:词法分析器实现在实现词法分析器之前,需要定义所需词法项的规则。
以C语言为例,常见的词法项包括关键字(如int、if、for等)、标识符、运算符(如+、-、*、/等)、常量(如整数、浮点数等)和分隔符(如括号、逗号等)。
接下来,我们来实现一个简单的C语言词法分析器。
1. 定义词法项的规则在C语言中,关键字和标识符由字母、数字和下划线组成,且首字符不能为数字。
运算符包括各种数学运算符和逻辑运算符。
常量包括整数和浮点数。
分隔符包括括号、逗号等。
2. 实现词法分析器的代码下面是一个简单的C语言词法分析器的实现代码:```pythondef lexer(source_code):keywords = ['int', 'if', 'for'] # 关键字列表operators = ['+', '-', '*', '/'] # 运算符列表separators = ['(', ')', '{', '}', ',', ';'] # 分隔符列表tokens = [] # 标记序列列表current_token = '' # 当前标记for char in source_code:if char.isspace(): # 如果是空格,则忽略continueelif char.isalpha(): # 如果是字母,则可能是关键字或标识符的一部分current_token += charelif char.isdigit(): # 如果是数字,则可能是常量的一部分current_token += charelif char in operators or char in separators: # 如果是运算符或分隔符,则当前标记结束if current_token:tokens.append(current_token)current_token = ''tokens.append(char)else: # 如果是其他字符,则当前标记结束if current_token:tokens.append(current_token)current_token = ''return tokens```以上代码通过遍历源代码的字符,根据定义的规则生成一个个标记,存储在`tokens`列表中。
编译原理实验报告——词法分析器(内含源代码)
编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
编译原理实验报告
编译原理实验报告一、实验目的编译原理是计算机科学中的重要课程,旨在让学生了解编译器的基本工作原理以及相关技术。
本次实验旨在通过设计和实现一个简单的编译器,来进一步加深对编译原理的理解,并掌握实际应用的能力。
二、实验环境本次实验使用了Java编程语言及相关工具。
在开始实验前,我们需要安装Java JDK并配置好运行环境。
三、实验内容及步骤1. 词法分析词法分析是编译器的第一步,它将源代码分割成一系列词法单元。
我们首先实现一个词法分析器,它能够将输入的源代码按照语法规则进行切割,并识别出关键字、标识符、数字、运算符等。
2. 语法分析语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。
我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。
3. 语义分析语义分析是编译器的第三步,它对语法树进行检查和转换。
我们主要进行类型检查、语法错误检查等。
如果源代码存在语义错误,编译器应该能够提供相应的错误提示。
4. 代码生成代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。
在本次实验中,我们将目标代码生成为Java字节码。
5. 测试与优化完成以上步骤后,我们需要对编译器进行测试,并进行优化。
通过多个测试用例的执行,我们可以验证编译器的正确性和性能。
四、实验心得通过完成这个编译器的实验,我收获了很多。
首先,我对编译原理的知识有了更深入的理解。
在实验过程中,我深入学习了词法分析、语法分析、语义分析和代码生成等关键技术,对编译器的工作原理有了更系统的了解。
其次,我提高了编程能力。
实现一个完整的编译器需要处理复杂的数据结构和算法,这对我的编程能力是一个很好的挑战。
通过实验,我学会了合理地组织代码,优化算法,并注意到细节对程序性能的影响。
最后,我锻炼了解决问题的能力。
在实验过程中,我遇到了很多困难和挑战,但我不断地调试和改进代码,最终成功地实现了编译器。
编译原理实验报告
编译原理实验报告一、实验目的本次实验的目的是了解编译原理的基本知识,并运用所学知识实现一个简单的词法分析器。
二、实验内容1.设计一个词法分析器,能够识别并输出源程序中的关键字、标识符、常数和运算符等。
2.设计并实现一个词法分析器的算法。
3.对编写的词法分析器进行测试。
三、实验过程1.设计词法分析器的算法在设计词法分析器的时候,需要先了解源程序的基本构成,了解关键字、标识符、常数和运算符等的特点,以及它们在源程序中的表示形式。
然后,根据这些特点,设计一个适合的算法来进行词法分析。
2.实现词法分析器根据设计好的算法,在编程语言中实现词法分析器。
在实现过程中,需要根据不同的词法单元,设计相应的正则表达式来进行匹配和识别。
3.测试词法分析器编写几个简单的测试用例,对词法分析器进行测试。
检查输出结果是否正确,并根据实际情况对词法分析器进行调试和优化。
四、实验结果经过测试,词法分析器能够正确识别并输出源程序中的关键字、标识符、常数和运算符等。
测试用例的输出结果与预期结果一致。
五、实验总结通过本次实验,我学习了编译原理的基本知识,掌握了词法分析器的设计和实现方法。
在实验过程中,我遇到了一些困难和问题,但通过仔细思考和查阅文献资料,最终成功地完成了实验任务。
这次实验不仅帮助我巩固了所学知识,还提高了我的编程能力和解决问题的能力。
通过实践,我深刻体会到了编译原理在软件开发中的重要性和作用,并对将来的学习和工作有了更好的规划和方向。
通过本次实验,我对编译原理的相关知识有了更深入的理解和掌握,对词法分析器的设计和实现方法有了更加清晰的认识。
同时,我还学会了如何进行实验报告的撰写,提高了我的文档写作能力。
通过本次实验,我不仅实现了实验的目标,还提高了自己的综合素质和能力。
编译原理词法分析器实验报告
编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。
词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。
本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。
2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。
具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。
3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。
这些规则描述了编程语言中各种词法单元的模式。
例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。
4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。
在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。
4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。
测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。
4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。
如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。
5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。
该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。
在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。
编译原理课程设计-词法分析器(附含源代码).doc
编译原理 -词法分析器的设计一.设计说明及设计要求一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。
本课程设计即为词法分析阶段。
词法分析阶段是编译过程的第一个阶段。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。
如保留字(关键字或基本字)、标志符、常数、算符和界符等等。
二.设计中相关关键字说明1.基本字:也称关键字,如 C 语言中的 if , else , while , do ,for,case,break, return 等。
2.标志符:用来表示各种名字,如常量名、变量名和过程名等。
3.常数:各种类型的常数,如12,,和“ ABC”等。
4.运算符:如+ ,- , * , / ,%, < , > ,<= , >=等。
5.界符,如逗点,冒号,分号,括号,# ,〈〈,〉〉等。
三、程序分析词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源程序进行扫描,产生一个个单词序列,用以语法分析。
词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。
然而,更一般的情况,常将词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则调用该子程序。
词法分析程序每得到一次调用,便从源程序文件中读入一些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。
四、模块设计下面是程序的流程图五、程序介绍在程序当前目录里建立一个文本文档,取名为 ,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。
程序结果输出在同一个目录下,文件名为,此文件为自动生成。
本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果(57,"#")(33,"include")(52,"<")(33,"iostream") 等。
编译原理实验报告——词法分析器
编译原理实验报告姓名:关海超学号:200807010209专业:计算机科学与技术班级:08—02班一、实验目的通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。
二、词法分析器的实现1、词法分析过程的考虑词法分析器的任务是将程序源代码看做一个字符串,只需从中分离出一个个具有独立意义的单词(包括标识符,符号和常量)即可,而无需考虑其在上下文环境中的正确性。
基于此认识,词法分析的过程可如下描述:本程序中用户源程序存储在文件“E:\prog.txt”文件中,程序首先调用readFromFile()函数将源程序代码从文件中读出,放到数组中暂存,然后主函数调用scaner()函数对其进行逐个扫描,分离出的每个独立单词进行分类判断,构成二元组形式,再将其输出的文件“E:\result.txt”中进行保存。
2、各种单词符号对应的种别码0 标识符21 ret 42 ++ 63 ||1 整型常量22 sho 43 -- 64 ?:2 auto 23 sig 44 - 65 =3 brea 24 siz 45 * 66 +=4 case 25 sta 46 & 67 -=5 char 26 str 47 / 68 *=6 cons 27 swi 48 % 69 /=7 cont 28 typ 49 + 70 %=8 defa 29 uni 50 - 71 >>=9 do 30 uns 51 << 72 <<=10 dou 31 voi 52 >> 73 &=11 els 32 vol 53 < 74 ^=12 enu 33 whi 54 <= 75 |=13 ext 34 ( 55 > 76 ,14 flo 35 ) 56 >= 77 '15 for 36 [ 57 == 78 ;16 got 37 ] 58 != 79 :17 if 38 -> 59 & 80 \{18 int 39 . 60 ^ 81 }19 lon 40 ! 61 | 82 //20 reg 41 ~ 62 &&3、关键数据结构的描述计数器count:将二元组写入文件时通过count判断是否是首次写入,若是则清空文件,否则追加写入;字符串常量endStr:其值为“end”,在分析判断每一单词的种类时,该字符串作为rwtab表的结束标志;数组prog[200]:暂存从文件中读取的源程序代码,该词法分析器约定源代码长度不超过199;数组token[20]:暂存每次分离出的单个具有独立意义的单词,该词法分析器约定每个单词的长度不超过19;结构体result:存放一个单词的种别码和单词本身的值,在写入文件时以结构体中的元素为单位依次写入;4、程序结构的描述本程序采用结构化设计方法,共有两个文件,六个模块,分别介绍如下:rwtab.h文件包含一个模块,即各种单词符号对应的种别码,作为外部文件被main.cpp文件引用。
编译原理实验报告++词法分析器实验报告
编译原理实验报告词法分析器制作与应用设计思想(1)程序主体结构部分:说明部分%%规则部分%%辅助程序部分(2)主体结构的说明在这里说明部分告诉我们使用的LETTER,DIGIT, IDENT(标识符,通常定义为字母开头的字母数字串)和STR(字符串常量,通常定义为双引号括起来的一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用#include来使用标准的头文件和前向说明(forward ,references).这些代码应该再标记"%{"和"%}"之间;规则部分>可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送ID名称和字符串常量内容到主调函数和main函数的功能.(3)实现原理程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。
PL/0语言的EBNF表示<常量定义>::=<标识符>=<无符号整数>;<标识符>::=<字母>={<字母>|<数字>};<加法运算符>::=+|-<乘法运算符>::=*|/<关系运算符>::==|#|<|<=|>|>=<字母>::=a|b|…|X|Y|Z<数字>::=0|1|2|…|8|9三:设计过程1.关键字:void,main,if,then,break,int,Char,float,include,for,while,printfscanf 并为小写。
2."+”;”-”;”*”;”/”;”:=“;”:”;”<“;”<=“;”>“;”>=“;”<>“;”=“;”(“;”)”;”;”;”#”为运算符。
3.其他标记如字符串,表示以字母开头的标识符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
南华大学计算机科学与技术学院实验报告( 2018~2019学年度第二学期)课程名称编译原理实验名称词法分析器的设计与实现姓名学号专业班级地点教师1.实验目的及要求实验目的加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
实验要求1.对单词的构词规则有明确的定义;2.编写的分析程序能够正确识别源程序中的单词符号;3.识别出的单词以 <种别码,值 >的形式保存在符号表中,正确设计和维护符号表;4.对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;2.实验步骤1.词法分析规则<标识符 >::=< 字母 >|< 标识符 ><字母 >|< 标识符 ><数字 ><常数 >::=< 数字 >|< 数字序列 ><数字 ><数字序列 >:: =<数字序列 ><数字 >|< 数字 >|<.><字母 >::=a|b|c|⋯⋯|x|y|z<数字 >::=0|1|2|3|4|5|6|7|8|9<运算符 >::=< 关系运算符 >|< 算运算符 >|< 运算符 >|< 位运算符 >|< 运算符 ><算数运算符 >:: =+|-|*|/|...|--<关系运算符 >:: =<|>|!=|>=|<=|==<运算符 >::=&&| || |!<位运算符 >::=&| | |!<运算符 >::==|+=|-=|/=|*=<分界符 >:: = ,|;|(|)|{|}|:| // |/**/<保留字 >:: = main|if|else|while|do|for|...|void2.符号的符号种符号种main0>26if1>=27else2<28while3<=29do4!30for5!=31switch 6 = 32 case 7 == 33 int 8 ( 34 double 9 ) 35 float 10 { 36 long 11 } 37 void 12 ; 38 + 13 :39 += 14 | 40 ++ 15 || 41 - 16 数字42 -= 17 标识符43 -- 18 , 44 & 19 // 45 && 20 /**/ 46 # 21* 22*= 23/ 24/= 253.状态转换图空白字母数字/+!><,(&:{;其它字母与数字非字母与数字1 2数字非数字4 3其它6 5=7/ 8*9其它11 10= 12+ 13其它15 14=16其它17 18=19其它20 21 ..22 ..33344.算法分析①词法分析器工作的第一步是输入源程序文本。
为了更好地对单词符号识别,把输入串预处理一下。
预处理主要滤掉空格,跳过注释、换行符等。
②对预处理后的输入串依次扫描单个字符,使用 if-while嵌套语句和switch case 语句判断字符的类型,具体识别方法可看状态转换图。
有时为了确定词性,需要超前扫描,若超前扫描的字符对识别当前单词无用处,则需要退还给输入串,以备识别下一单词字符时使用。
③若读入的字符与单词符号编码表的字符匹配不上,则报错,并输出出错行数。
对识别处的单词符号以(单词符号,种别码)二元式的形式输出。
3.实验内容1. 流程图2.程序的变量与函数说明(1)input全局字符数组,用来存放输入串(2)word全局字符数组,用来存放获取到的单词符号,限定长度为 8(3)ch全局字符变量,用来存放最新读入的字符(4)syn全局整型变量,表示单词符号的编码(5)p全局整型变量,表示当前字符在input 数组的位置(6)m全局整型变量,表示最新读入的字符在word 数组的下标(7)line全局整型变量,当前行数(8)keyword全局字符数组,存放关键字(9)init()获取输入串(10)isKey()判断关键字的函数,若参数数组中是关键字,则把 syn 置为该关键字对应的编码并返回 1,否则返回 0(11)isLetter()判断字母的函数,若参数字符是字母,则返回1,否则返回 0(12)isDigit()判断数字的函数,若参数字符是数字,则返回1,否则返回 0(13)isSpace()判断空白符的函数,若参数字符是空格、 TAB或换行符,则返回 1,否则返回 0(14)scaner()扫描输入串的函数,对读出的字符进行判断,若是单词符号表中的符号,则将 syn 置为对应的编码3.源程序#include <stdio.h>#include <string.h>char input[1000];// 输入串char word[8];// 获取到的单词char ch;int syn;// 种别码int p;int m;int line;// 行数//关键字charkeyword[][8]={"main","if","else","while","do","for","switch","case","int","double ","float","long","void"};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!='#');}//判断是不是关键字int isKey(char *str){int n;for(n=0;n<13;n++){if(strcmp(str,keyword[n])==0){syn=n;return 1;}}return 0;}//判断是不是数字int isDigit(char c){if (c>='0'&&c<='9')return 1;else}//判断是不是字母int isLetter(char c){if ((c<='z'&&c>='a')||(c>='A'&&c<='Z')) return 1;elsereturn 0;}int isSpace(char c){if (c==' '||c=='\t'||c=='\n'){return 1;}return 0;}void main(){init();// 输入字符串line=0;p=0;do{scaner();{case -1:printf("you have input a wrong string in line %d\n",line);break;default:printf("( %s,%d )\n",word,syn);break;}}while(syn!=21);}void scaner(void){//清空 wordfor(m=0;m<8;m++){word[m] = ' ';}//读取字符ch=input[p++];m=0;//当 ch 为空格或换行符时,继续往下读while(isSpace(ch)){{line++;}ch=input[p++];}//如果以字母开头if(isLetter(ch)){// 如果往后是字母或数字,把字符存入word 中,然后往下继续读//串长超过 8 则截断while((isLetter(ch)||isDigit(ch))&&m<8){word[m++]=ch;ch=input[p++];}p--;syn=43;word[m++]='\0';isKey(word);//判断是不是关键字}//如果是以数字开头,并且往后是数字else if(isDigit(ch)){while((isDigit(ch)||ch=='.')&&m<8) {word[m++]=ch;ch=input[p++];}//如果数字之后是字母 ,则出错if (isLetter(ch)){while(!isSpace(ch)){ch=input[p++];}syn=-1;return ;}p--;syn=42;}else{switch(ch){//比较运算符case '<':word[m++]=ch;ch=input[p++];if(ch=='='){syn=29;word[m++]=ch;}else{syn=28;p--;}break;case '>':word[m++]=ch;ch=input[p++];if(ch=='='){syn=27;word[m++]=ch;}else{syn=26;p--;}break;case '!':ch=input[p++];if(ch=='='){syn=31;word[m++]=ch;}else{syn=30;p--;}break;case '=':word[m++]=ch;ch=input[p++];if(ch=='='){syn=33;word[m++]=ch;}else{syn=32;p--;}break;//算术运算符 +、-、* 、/ case '+':word[m++]=ch;ch=input[p++];if(ch=='+'){syn=15;word[m++]=ch;}else if(ch=='='){syn=14;word[m++]=ch;}else{syn=13;p--;}break;case '-':word[m++]=ch;ch=input[p++];if(ch=='-'){syn=18;word[m++]=ch;}else if(ch=='='){syn=17;word[m++]=ch;}else if (isDigit(ch)){while(isDigit(ch)){word[m++]=ch;ch=input[p++];}p--;syn=42;}else{syn=16;p--;}break;case '*':word[m++]=ch;ch=input[p++];if(ch=='='){syn=23;word[m++]=ch;}else{syn=22;p--;}break;case '/':word[m++]=ch;ch=input[p++];if(ch=='='){syn=25;word[m++]=ch;}//如果是单行注释,则读到换行符为止else if (ch=='/'){word[m++]=ch;syn=45;while (ch!='\n'){ch=input[p++];}line++;}//如果是多行注释,则读到匹配的 */ 为止else if(ch=='*'){word[m++]=ch;syn=46;int flag=1;while (flag){ch=input[p++];if (ch=='*'){if (input[p++]=='/'){word[m++]='*';word[m++]='/';flag=0;}else{p--;}}if (ch=='\n'){line++;}}}else{syn=24;p--;}break;//界符case '(':syn=34;word[m++]=ch;break;case ')':syn=35;word[m++]=ch;break;case '{':syn=36;word[m++]=ch;break;case '}':syn=37;word[m++]=ch;break;case ';':syn=38;word[m++]=ch;break;case '#':syn=21;word[m++]=ch;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;}else{syn=19;p--;}break;case '|':word[m++]=ch;ch=input[p++];if(ch=='|'){syn=41;word[m++]=ch;}else{syn=40;p--;}break;default:syn=-1;break;}}//字符串结束符word[m++]='\0';}4.实验结果因为 printf和""不是单词符号表中的符号,因而判定输入有错5.实验总结分析这个程序实现了对所选词法子集的单词识别,并对识别出的单词以二元式的形式输出,对于存在的一些词法错误,能够做出简单的错误处理,比如,若标识符以数字开头或单词符号在符号表中不存在,则输出错误信息,并给出行号;同时该程序也能清除掉源程序中的注释,识别出实型常数。