S语言词法分析器设计
编译原理词法分析实验报告

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的:1.熟悉编译原理中词法分析的基本概念和原理;2.掌握正则表达式的使用方法;3.实现一个简单的词法分析器。
二、实验内容:1.设计一个简单的编程语言,包含如下几种类型的词法单元:关键字、标识符、常量、运算符和界符。
2.使用正则表达式定义每种词法单元的模式。
3.设计一个词法分析器,将源代码中的每个词法单元识别出来并输出。
三、实验步骤:1. 确定编程语言的词法单元类型和正则表达式模式,定义相应的单词类型(如 TokenType)和模式(如 regex)。
2. 实现一个词法分析器的类 Lexer,包含以下方法:(1)一个构造方法,用于初始化词法分析器的输入源代码。
(2) 一个getNextToken方法,用于获取源代码中的下一个词法单元。
3. 在getNextToken方法中,使用正则表达式逐个识别源代码中的词法单元,并返回相应的Token对象。
4. 设计一个Token类,包含以下属性:词法单元类型、词法单元的值和位置信息等。
5.在主程序中使用词法分析器,将源代码中的每个词法单元识别出来并输出。
四、实验结果:1.设计一个简单的编程语言,包含如下词法单元类型(示例):(1) 关键字:if、else、while、for等;(2)标识符:变量名等;(3)常量:整数、浮点数、字符串等;(4)运算符:+、-、*、/、=等;(5)界符:(、)、{、}、;等。
2. 实现一个词法分析器,识别出源代码中的每个词法单元,并输出相应的Token对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
编译原理课程设计—词法分析器

编译原理课程设计(一)——词法分析器1、题目编写程序实现一个简易的词法分析器。
2、实验目的对一段程序代码进行词法分析,将程序段中的关键字、标识符、常数、运算符、界符按照一定的种别编码分析出来。
3、环境及工具操作系统:windows XP ;使用工具:Microsoft Visual C++ 6.0; 编程语言:C 语言;4、分析程序输入:从文件中读入程序段;程序输出:由单词种别和单词符号的属性值组成的二元式;单词种别通常使用整数编码,编码方式可以有多种,在设计词法分析器之前应确定一种程序处理起来较方便的编码方式。
当一个种别中含有多个单词符号时,在分析出其属于哪个种别的时候应同时给出其单词符号属性,本程序为方便起见,采用单词符号本身来作为其属性,以标识同种别种的不同单词符号。
标识符及关键字的识别:字母开头的字母和数字组成的串是多数编程语言的标识符,所以我们的简易词法分析器中,将标识符定义为这种字母数字串。
当第一个字母为字母且紧接着的字符为数字或字母时,应将其串接在一起为一个单词,直到紧跟着的不在是字母数字时。
由于关键字通常为一个单词,则这样得到的串可能是标识符也可能是关键字,又因为一种语言的关键字通常是有限个,则我们可以构造一个存放所有关键字的表,查询关键字表,可以判断得到的串是否为关键字。
界符和运算符的识别:它们多为当个字符,建立两个分别存放界符合运算符的表,读取字符后,进行查表便可以得出它们的类型。
为方便词法分析器的设计,可以使用状态转换图,根据一种特定的编程语言先设计出其状态转换图才能更好将其用代码实现。
典型状态转换图结构如下:(a)有不含回路含分支的状态节点:对应if …else if …else …语句;(b)有含回路的状态节点:对应while …if …语句。
(b )5、状态转换图6、程序框架描述程序中编写了以下函数,各个函数实现的作用如下:1. GetChar():将下一输入的字符读入到全局变量ch中,搜素指示器前移一个字符的位置。
词法分析器实验报告

词法分析器实验报告词法分析器实验报告实验目的:设计、编制、调试一个词法分析子程序,识别单词,加深对词法分析原理的理解。
实验要求:该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分界符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(一)实验内容(1)功能描述:对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。
而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。
(2)程序结构描述:函数调用格式:函数调用格式函数名(实在参数表 )Switch(m)、 isKey(String string)、isLetter(char c)、实参isDigit(char c)、isOperator(char c)isKey(String string)、isLetter(char c)、调作为表达式isDigit(char c)、isOperator(char c) 用方作为语句 getChar()、judgement()、法函数的递归调用 isOperator(char c) 、isLetter(char c)、isDigit(char c)参数含义:1String string;存放读入的字符串 String str; 存放暂时读入的字符串 char ch; 存放读入的字符 int rs 判断读入的文件是否为空 char []data 存放文件中的数据 int m;通过switch用来判断字符类型,函数之间的调用关系图:mainComplier..judgementisOperate()M=0 getChar( )isDigit()M=4 For(ch )isLetter() M=2Switch(m)isKey() M=3 函数功能:Judgement()判断输入的字符并输出单词符号,返回值为空; getChar() 读取文件的,返回值为空;isLetter(char c) 判断读入的字符是否为字母的,返回值为Boolean类型; switch (m) 判断跳转输出返回值为空;isOperator(char c)判断是否为运算符的,返回值为Boolean类型;isKey(String string)判断是否为关键字的,返回值为Boolean类型;isDigit(char c) 判断读入的字符是否为数字的,返回值为Boolean类型。
计算机网络课程设计:词法分析器

计算机网络课程设计报告班级:计1102姓名:杨勇学号: 41155047词法分析器:一、实验目的调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验要求1、待分析的简单语言的词法(1)关键字:begin if then while do end所有关键字都是小写。
(2)运算符和界符::= + –* / <<= <>>>= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码3、词法分析程序的功能输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
三、C语言程序源代码:#include <stdio.h>#include <string.h>char prog[80],token[8],ch;int syn,p,m,n,sum;char *rwtab[6]={"begin","if","then","while","do","end"}; scaner();main(){p=0;printf("\n please input a string(end with '#'):/n");do{scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11:printf("( %-10d%5d )\n",sum,syn);break;case -1:printf("you have input a wrong string\n");getch();exit(0);default: printf("( %-10s%5d )\n",token,syn);break;}}while(syn!=0);getch();}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;ch=prog[p++];m=0;while((ch==' ')||(ch=='\n'))ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;ch=prog[p++];}p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0) { syn=n+1;break;}}else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':token[m++]=ch;ch=prog[p++];if(ch=='=')token[m++]=ch;}else{ syn=20;p--;}break;case '>':token[m++]=ch; ch=prog[p++];if(ch=='='){ syn=24;token[m++]=ch;}else{ syn=23;p--;}break;case '+': token[m++]=ch; ch=prog[p++];if(ch=='+')token[m++]=ch;}else{ syn=13;p--;} break;case '-':token[m++]=ch; ch=prog[p++];if(ch=='-'){ syn=29;token[m++]=ch;}else{ syn=14;p--;} break;case '!':ch=prog[p++];{ syn=21;token[m++]=ch;}else{ syn=31;p--;}break;case '=':token[m++]=ch; ch=prog[p++];if(ch=='='){ syn=25;token[m++]=ch;}else{ syn=18;p--;}break;case '*': syn=15;token[m++]=ch; break;case '/': syn=16; token[m++]=ch; break;case '(': syn=27; token[m++]=ch; break;case ')': syn=28; token[m++]=ch; break;case '{': syn=5; token[m++]=ch; break;case '}': syn=6; token[m++]=ch; break;case ';': syn=26; token[m++]=ch; break;case '\"': syn=30; token[m++]=ch;break;case '#': syn=0;token[m++]=ch;break;case ':':syn=17;token[m++]=ch;break;default: syn=-1;break;}token[m++]='\0';}三、实验结果:1、给定源程序begin x:=9; if x>0 then x:=2*x+1/3; end#输出结果2、源程序(包括上式未有的while、do以及判断错误语句):beginx<=$;whilea<0dob<>9-x;end#输出结果四、总结分析:通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种高级语言(例如C++语言)直接编写此法分析程序。
词法分析器实验报告

词法分析器实验报告词法分析器实验报告一、引言词法分析器是编译器中的重要组成部分,它负责将源代码分解成一个个的词法单元,为之后的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,以深入理解其工作原理和实现过程。
二、实验目标本实验的目标是设计和实现一个能够对C语言代码进行词法分析的程序。
该程序能够将源代码分解成关键字、标识符、常量、运算符等各种词法单元,并输出其对应的词法类别。
三、实验方法1. 设计词法规则:根据C语言的词法规则,设计相应的正则表达式来描述各种词法单元的模式。
2. 实现词法分析器:利用编程语言(如Python)实现词法分析器,将源代码作为输入,根据词法规则将其分解成各种词法单元,并输出其类别。
3. 测试和调试:编写测试用例,对词法分析器进行测试和调试,确保其能够正确地识别和输出各种词法单元。
四、实验过程1. 设计词法规则:根据C语言的词法规则,我们需要设计正则表达式来描述各种词法单元的模式。
例如,关键字可以使用'|'操作符将所有关键字列举出来,标识符可以使用[a-zA-Z_][a-zA-Z0-9_]*的模式来匹配,常量可以使用[0-9]+的模式来匹配等等。
2. 实现词法分析器:我们选择使用Python来实现词法分析器。
首先,我们需要读取源代码文件,并将其按行分解。
然后,针对每一行的代码,我们使用正则表达式进行匹配,以识别各种词法单元。
最后,我们将识别出的词法单元输出到一个结果文件中。
3. 测试和调试:我们编写了一系列的测试用例,包括各种不同的C语言代码片段,以测试词法分析器的正确性和鲁棒性。
通过逐个测试用例的运行结果,我们可以发现和解决词法分析器中的问题,并进行相应的调试。
五、实验结果经过多次测试和调试,我们的词法分析器能够正确地将C语言代码分解成各种词法单元,并输出其对应的类别。
例如,对于输入的代码片段:```cint main() {int a = 10;printf("Hello, world!\n");return 0;}```我们的词法分析器将输出以下结果:```关键字:int标识符:main运算符:(运算符:)运算符:{关键字:int标识符:a运算符:=常量:10运算符:;标识符:printf运算符:(常量:"Hello, world!\n"运算符:)运算符:;关键字:return常量:0运算符:;```可以看到,词法分析器能够正确地将代码分解成各种词法单元,并输出其对应的类别。
实验一、词法分析器(含源代码)

词法分析器实验报告一、实验目的及要求本次实验通过用C语言设计、编制、调试一个词法分析子程序,识别单词,实现一个C语言词法分析器,经过此过程可以加深对编译器解析单词流的过程的了解。
运行环境:硬件:windows xp软件:visual c++6.0二、实验步骤1.查询资料,了解词法分析器的工作过程与原理。
2.分析题目,整理出基本设计思路。
3.实践编码,将设计思想转换用c语言编码实现,编译运行。
4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。
通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。
三、实验内容本实验中将c语言单词符号分成了四类:关键字key(特别的将main说明为主函数)、普通标示符、常数和界符。
将关键字初始化在一个字符型指针数组*key[]中,将界符分别由程序中的case列出。
在词法分析过程中,关键字表和case列出的界符的内容是固定不变的(由程序中的初始化确定),因此,从源文件字符串中识别出现的关键字,界符只能从其中选取。
标识符、常数是在分析过程中不断形成的。
对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是关键字、普通标示符、常数或界符中之一,那么就将此单词以文字说明的形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串。
输出形式例如:void $关键字流程图、程序流程图:程序:#include<string.h>#include<stdio.h>#include<stdlib.h>#include<ctype.h>//定义关键字char*Key[10]={"main","void","int","char","printf","scanf","else","if","return"}; char Word[20],ch; // 存储识别出的单词流int IsAlpha(char c) { //判断是否为字母if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;else return 0;}int IsNum(char c){ //判断是否为数字if(c>='0'&&c<='9') return 1;else return 0;}int IsKey(char *Word){ //识别关键字函数int m,i;for(i=0;i<9;i++){if((m=strcmp(Word,Key[i]))==0){if(i==0)return 2;return 1;}}return 0;}void scanner(FILE *fp){ //扫描函数char Word[20]={'\0'};char ch;int i,c;ch=fgetc(fp); //获取字符,指针fp并自动指向下一个字符if(IsAlpha(ch)){ //判断该字符是否是字母Word[0]=ch;ch=fgetc(fp);i=1;while(IsNum(ch)||IsAlpha(ch)){ //判断该字符是否是字母或数字Word[i]=ch;i++;ch=fgetc(fp);}Word[i]='\0'; //'\0' 代表字符结束(空格)fseek(fp,-1,1); //回退一个字符c=IsKey(Word); //判断是否是关键字if(c==0) printf("%s\t$普通标识符\n\n",Word);//不是关键字else if(c==2) printf("%s\t$主函数\n\n",Word);else printf("%s\t$关键字\n\n",Word); //输出关键字 }else //开始判断的字符不是字母if(IsNum(ch)){ //判断是否是数字Word[0]=ch;ch=fgetc(fp);i=1;while(IsNum(ch)){Word[i]=ch;i++;ch=fgetc(fp);}Word[i]='\0';fseek(fp,-1,1); //回退printf("%s\t$无符号实数\n\n",Word);}else //开始判断的字符不是字母也不是数字{Word[0]=ch;switch(ch){case'[':case']':case'(':case')':case'{':case'}':case',':case'"':case';':printf("%s\t$界符\n\n",Word); break;case'+':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word);//运算符“+=”}else if(ch=='+'){printf("%s\t$运算符\n\n",Word); //判断结果为“++”}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word); //判断结果为“+”}break;case'-':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word); }else if(ch=='-'){printf("%s\t$运算符\n\n",Word); //判断结果为“--”}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word); //判断结果为“-”}break;case'*':case'/':case'!':case'=':ch=fgetc(fp);if(ch=='='){printf("%s\t$运算符\n\n",Word);}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word);}break;case'<':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word); //判断结果为运算符“<=”}else if(ch=='<'){printf("%s\t$运算符\n\n",Word); //判断结果为“<<”}else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word); //判断结果为“<”}break;case'>':ch=fgetc(fp);Word[1]=ch;if(ch=='=') printf("%s\t$运算符\n\n",Word);else {fseek(fp,-1,1);printf("%s\t$运算符\n\n",Word);}break;case'%':ch=fgetc(fp);Word[1]=ch;if(ch=='='){printf("%s\t$运算符\n\n",Word);}if(IsAlpha(ch)) printf("%s\t$类型标识符\n\n",Word);else {fseek(fp,-1,1);printf("%s\t$取余运算符\n\n",Word);}break;default:printf("无法识别字符!\n\n"); break;}}}main(){char in_fn[30]; //文件路径FILE *fp;printf("\n请输入源文件名(包括路径和后缀名):");while(1){gets(in_fn);//scanf("%s",in_fn);if((fp=fopen(in_fn,"r"))!=NULL) break; //读取文件内容,并返回文件指针,该指针指向文件的第一个字符else printf("文件路径错误!请重新输入:");}printf("\n******************* 词法分析结果如下 *******************\n");do{ch=fgetc(fp);if(ch=='#') break; //文件以#结尾,作为扫描结束条件else if(ch==' '||ch=='\t'||ch=='\n'){} //忽略空格,空白,和换行else{fseek(fp,-1,1); //回退一个字节开始识别单词流scanner(fp);}}while(ch!='#');return(0);}4.实验结果解析源文件:void main(){int a=3;a+=b;printf("%d",a);return;}#解析结果:5.实验总结分析通过本次实验,让再次浏览了有关c语言的一些基本知识,特别是对文件,字符串进行基本操作的方法。
编译-词法分析器-语法分析器实验报告

一、目的编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:单词符号种别编码助记符内码值DIMIFDO STOP END标识符常数(整)=+***,()1234567891011121314$DIM$IF$DO$STOP$END$ID$INT$ASSIGN$PLUS$STAR$POWER$COMMA$LPAR$RPAR------内部字符串标准二进形式------对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。
例如,下面的写法是绝对禁止的:IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
例如,一个条件语句应写为IF i>0 i= 1;而绝对不要写成IFi>0 i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。
这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+ 减- 乘* 除/ 乘方^ 括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。
编译原理词法分析器实验报告

一、实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的明白得。
二、实验要求一、该个词法分析器要求至少能够识别以下几类单词:(1)关键字:else if int return void while共6个,所有的关键字都是保留字,而且必需是小写;(2)标识符:识别与C语言词法规定相一致的标识符,通过以下正那么表达式概念:ID = letter (letter | digit)*;(3)常数:NUM = digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123等;小数,如123.45等;科学计数法表示的常数,如1.23e3,2.3e-9等;(4)专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */;二、分析器的输入为由上述几类单词组成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变成其对应的机内符,常数利用二进制形式,标识符利用相应的标识符表指针表示。
3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。
三、实验环境实验环境为win7系统、vs2005。
四、实验内容1、词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token)或(sum或fsum,对应二进制)组成的序列。
其中:syn为单词类别码;token为寄存的单词自身字符串;sum为整型常数;fsum为浮点型常数。
二、各类单词符号类别码如下表:五、要紧函数说明一、程序全局变量char inputstr[300],token[8];//别离寄存程序段、组成单词符号的字符串char ch;//输入字符int syn;//单词字符的类别码int p;//缓冲区inputstr的指针int sum;//整型常量float fsum;//浮点型常量char *rwtab[6]={"else","if","int","return","void","while"};//关键字数组二、语法分析函数void scaner()该函数完成所有的语法分析,关于输入的程序片段,第一去掉空格和换行,然后逐字符分析,找出各个单词(存入token[8]),判别它们的类型(确信syn 值,若是是整数那么是sum值,若是是浮点数那么是fsum)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验1-3 S语言词法分析器设计一、实验名称:S语言词法分析器设计二、实验目的:通过手工编写简化C语言词法分析器,熟悉并深入理解编译程序词法分析器的工作原理。
三、实验容:1.根据保留字和特殊符号表能区分出源文件中的保留字、普通标识符和特殊符号,并能进行简单的错误处理。
2.设计词法分析器模块调用结构图和各模块流程图。
3.程序源代码。
4.程序的执行结果:输入文件,输出结果文件及屏幕信息。
四、实验中出现的问题及解决方法。
遇到问题及解决:1、关于注释//和除号/。
需要区分,在isanotation函数中。
2、关于遇到空格时回退,一开始没有懂,后来经过同学讲解,明白了如何回退的。
3、关于词法分析器的思想过程,经过老师再三讲解,已经大致明白,具体步骤,在最后体会部分中。
五、程序结构和代码程序结构:代码:#include<stdio.h>#include<stdlib.h>#include<string>#include<iostream>using namespace std;//关键字表stringkeywords[20]={"include","void","main","int","c har","float","double","if","else","then","break"," continue","for","do","while","printf","scanf","be gin","end","return"};char aa[99999]=" ";//关键字表初始为空string id[10000];int pp=0;//常数表string nu[10000];int qq=0;//初始化函数void initscanner(){int i=0;FILE *fp;if((fp=fopen("源程序.txt","r"))==NULL)//打开源程序文件{printf("没有找到此文件!");exit(0);}char ch=fgetc(fp);while(ch!=EOF){aa[i]=ch;i++;ch=fgetc(fp);}fclose(fp);}int decide1(char a) //判断是否是字母{if((a>='a'&&a<='z')||(a>='A'&&a<='Z')) return 1;else return 0;}int decide2(char a) //判断是否是数字{if(a>='0'&&a<='9')return 1;else return 0;}int isalpha(int st) //识别保留字和标识符{char wordbuf[20]=" ";int n=0;for( ; ; ){wordbuf[n]=aa[st];st++;n++; if((decide2(aa[st])==1)||(decide1(aa[st])==1)||( aa[st]=='_'))wordbuf[n]=aa[st];else break;}int flag=0;for(int k=0;k<20;k++){if(strcmp(keywords[k].c_str(),wordbuf)==0) flag=1;}if(flag==0){int flagg=-1;for(int t=0;t<pp;t++){if(strcmp(id[t].c_str(),wordbuf)==0){flagg=t;}}if(flagg!=-1) printf(" (id,%d) ",flagg);else{id[pp]=wordbuf;printf(" (id,%d) ",pp);pp++;}}else{printf(" (");for(int i=0;i<n;i++){printf("%c",wordbuf[i]);}printf(",-) ");}return st;}int isnumber(int st) //识别数字{char numbuf[20]=" ";int n=0;int k=0;int flag=0;for( ; ; ){numbuf[n]=aa[st];st++;n++;if(decide2(aa[st])==1){numbuf[n]=aa[st];}else if((k==0)&&(aa[st]=='.')){numbuf[n]=aa[st];k++;}else if(decide1(aa[st])==1){numbuf[n]=aa[st];flag=1;continue;}else break;}if(flag==0){int flagg=-1;for(int t=0;t<qq;t++)if(strcmp(nu[t].c_str(),numbuf)==0)flagg=t;if(flagg!=-1) printf(" (nu,%d) ",flagg); else{nu[qq]=numbuf;printf(" (nu,%d) ",qq);qq++;}}else{printf(" (");for(int i=0;i<n;i++) printf("%c",numbuf[i]); printf(",错误) ");} return st;}int isanotation(int st) //处理除号/和注释{char tabuf[9999]=" ";int n=0;st++;if(aa[st]=='/'){printf(" (//,-) ");st++;while(aa[st]!=10){tabuf[n]=aa[st];st++;n++;}printf(" (");for(int i=0;i<n;i++)printf("%c",tabuf[i]);printf(",注释容) ");}else if(aa[st]=='*'){printf(" (/*,-) ");st++;int stt=st+1;while(1){if(aa[st]=='*'&&aa[st+1]=='/') break; tabuf[n]=aa[st];st++;n++;if(aa[st+1]==NULL){printf("(/* 错误\n)");return st+1;}} printf(" (");for(int i=0;i<n;i++)printf("%c",tabuf[i]);printf(",注释容) ");printf(" (*/,-) ");st=st+2;}else if(aa[st]=='='){st++;printf(" (/*,-) ");}else printf(" (/,-) ");return st;}int isother(int st) //函数识别其他特殊字符{switch(aa[st]){case '=': st++;if(aa[st]=='='){st++;printf(" (rlop,==) ");}else printf(" (rlop,=) ");break;case '+': st++;if(aa[st]=='='){st++;printf(" (+=,-) ");}else if(aa[st]=='+'){st++;printf(" (++,-) ");}else printf(" (+,-) ");break;case '-': st++;if(aa[st]=='='){st++;printf(" (-=,-) ");}else if(aa[st]=='-'){st++;printf(" (--,-) "); }else printf(" (-,-) "); break;case '*': st++;if(aa[st]=='='){st++;printf(" (*=,-) ");}else printf(" (*,-) "); break;case '>': st++;if(aa[st]=='='){st++;printf(" (rlop,>=) ");}else printf(" (rlop,>) "); break;case '<': st++;if(aa[st]=='='){st++;printf(" (rlop,<=) ");}else printf(" (rlop,<) "); break;case '%': st++;if(aa[st]=='='){st++;printf(" (\%=,-) ");}else printf(" (\%,-) "); break;case '!': st++;if(aa[st]=='='){st++;printf(" (!=,-) ");}else printf(" (!,错误!) "); break;case '&': st++;if(aa[st]=='&'){st++;printf(" (&&,-) ");}else printf(" (&,错误) "); break;case '|': st++;if(aa[st]=='|'){st++;printf(" (||,-) ");}else printf(" (|,错误) "); break;case '{': st++;printf(" ({,-) "); break;case '}': st++;printf(" (},-) "); break;case '(': st++;printf(" ((,-) "); break;case ')': st++;printf(" (),-) "); break;case '[': st++;printf(" ([,-) "); break;case ']': st++;printf(" (],-) "); break;case ':': st++;printf(" (:,-) "); break;case '#': st++;printf(" (#,-) "); break;case ';': st++;printf(" (;,-) "); break;case '.': st++;printf(" (.,-) "); break;case ',': st++;printf(" (,,-) ");break;case ' ': st++;break;case ' ': st++;break;case 10: st++;printf("\n");break;case 34: st++;printf(" (\",-) ");break;case 39: st++;printf(" (',-) ");break;default: printf(" (%c,错误) ",aa[st]);st++;}return st;}int lexscan(int st) //根据读入的单词的第一个字符确定调用不同的单词识别函数{if(decide1(aa[st])==1)//如果是字母st=isalpha(st);else if(decide2(aa[st])==1)//如果是数字st=isnumber(st);else if(aa[st]=='/')//如果是标识符或关键字st=isanotation(st);else st=isother(st);//其他特殊字符return st;}void scanner() //若文件未结束,反复调用lexscan函数识别单词{int i=0;while(aa[i]!=NULL)i=lexscan(i);}void print(){cout<<endl;cout<<endl<<"关键字、标示符表如下:"<<endl;cout<<"======================== ====================="<<endl;for(int i=0;i<pp;i++)cout<<i<<" "<<id[i]<<endl;cout<<"======================== ====================="<<endl; cout<<endl;cout<<"常数表如下:"<<endl;cout<<"======================== ====================="<<endl; for(int j=0;j<qq;j++)cout<<j<<" "<<nu[j]<<endl;cout<<"======================== ====================="<<endl;}void main(){ cout<<"二元式流如下:"<<endl;cout<<"======================== ====================="<<endl; initscanner();scanner();print();}程序执行结果截图:源程序截图:。