编译原理词法分析程序的设计实验报告
编译原理词法分析程序实现实验报告
编译原理词法分析程序实现实验报告实验一词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,,,*,/, ( , ) 构成的算术表达式,如1.5E+2,100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
二、设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:输入字符p指向第一个字符符号识别*p=+||-||*||/YYNN*p=0~9*p=E*p=0~9||"."N无效符号Y*p=“.”GOTO 2GOTO 1GOTO 1:NY无符号数GOTO 1*p=0~9*p='/0'YNP++NNP++*p=E*p='+'||'-'YYP++P++continueYY*p=0~9*p=0~9NN无符号数无符号数P++P++continuecontinueGOTO 2:GOTO 2*p=EcontinueY无符号数P++continue三、源程序代码部分#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~9 int 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=='.') return 1;else return 0;}void DistinguishSign(char *p) { int Class;char ch=*p;switch(ch){case '+':Output(PLUS,p,p);Type[count++]=PLUS;break;case '-':Output(SUBTRACT,p,p);Type[count++]=SUBTRACT;break; case '*':Output(MULTIPLY,p,p);Type[count++]=MULTIPLY;break; case '/':Output(DIVIDE,p,p);Type[count++]=DIVIDE;break; case '(':Output(LEFTBRACKET,p,p);Type[count++]=LEFTBRACKET;break; case ')':Output(RIGHTBRACKET,p,p);Type[count++]=RIGHTBRACKET;break; default:break;}}void TypyDistinguish(){printf("词法开始,分析结果如下:\n");char *p;p=&Store[0];while(*p!='\0'){if(Sign(p)){DistinguishSign(p++);continue;}else if(UnsignedNum(p)||*p=='.'){char *p1=p;if(UnsignedNum(p)){while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~"); break; Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else if(*p=='.'){p++;while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~ /n");break;Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~因为他的后面既不是0~9也不是“+”或者“-…");break;//1.5E*2这样的字符串不是无符号数Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}}if(*p=='.'){p++;if(UnsignedNum(p)){p++;while(UnsignedNum(p))p++;if(*p=='\0'){Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='E'){p++;if(UnsignedNum(p)){while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p); Type[count++]=UNSIGNEDNUMBER; p++;continue;}else if(*p=='+'||*p=='-'){p++;while(UnsignedNum(p))p++;Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}}else{Output(UNSIGNEDNUMBER,p1,--p);Type[count++]=UNSIGNEDNUMBER;p++;continue;}}else{Output(INEFFICACIOUSLABEL,p1,--p);printf("输入的这个符号是不合法的~"); break; Type[count++]=INEFFICACIOUSLABEL;p++;continue;}}}else if(*p=='E'){Output(INEFFICACIOUSLABEL,p,p); break;Type[count++]=INEFFICACIOUSLABEL;printf("输入的这个符号是不合法的~");p++;continue;}}printf("\n\n词法分析完毕~");}void ShowType()//将类别码存储在Type[100]中,为语法分析做准备{printf("\n用类别码表示输入的字符如下:\n");int i;printf("\n");for(i=0;Type[i]!=FINISH;i++){printf("%d",Type[i]);}printf("\n\n");}void main(){//词法分析部分StoreStr();ShowStore();TypyDistinguish();Type[count]=FINISH;ShowType();}四、实验结果正确的结果:错误的结果:输入的字符串中有1.5E*2因为实验是以文件的形式进行读取的所以,在读取不合法的过程中只是将存在project 中的a.txt 中的内容改变改为1.5E*2+100*555实验结果如下:结果分析:对于正确的结果,我以二元式的形式输出,包括他的值和他的类别码,其中将类别码存放在另外的一个数组中,为了在实验二中的语法识别打下基础。
编译原理词法分析实验报告
编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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对象。
五、实验总结:通过本次实验,我熟悉了编译原理中词法分析的基本概念和原理,并掌握了正则表达式的使用方法。
我成功完成了一个简单的词法分析器的设计与实现,实现了源代码中每个词法单元的识别与输出。
这次实验对我深化了对编译原理中词法分析的理解,并提高了我的编程能力。
编译原理实验报告
编译原理实验报告一、实验目的本次编译原理实验的主要目的是通过实践加深对编译原理中词法分析、语法分析、语义分析和代码生成等关键环节的理解,并提高实际动手能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 C/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理词法分析实验报告
词法分析器实验报告一、实验目的选择一种编程语言实现简单的词法分析程序,设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码2.3 词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1 主程序示意图:主程序示意图如图3-1所示。
其中初始包括以下两个方面:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};图3-1(2)程序中需要用到的主要变量为syn,token和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn 用来存放单词符号的种别码。
编译原理实验报告
编译原理实验报告一、实验概述本次实验旨在设计并实现一个简单的词法分析器,即实现编译器的第一个阶段,词法分析。
词法分析器将一段源程序代码作为输入,将其划分为一个个的词法单元,并将其作为输出。
二、实验过程1.设计词法规则根据编程语言的规范和所需实现的功能,设计词法规则,以明确规定如何将源程序代码分解为一系列的词法单元。
2.实现词法分析器采用合适的编程语言,根据所设计的词法规则,实现词法分析器。
词法分析器的主要任务是读入源程序代码,并将其根据词法规则进行分解,生成对应的词法单元。
3.测试词法分析器设计测试用例,用于检验词法分析器的正确性和性能。
测试用例应包含各种情况下的源程序代码。
4.分析和修正错误根据测试过程中发现的问题,分析产生错误的原因,并进行修正。
重复测试和修正的过程,直到词法分析器能够正确处理所有测试用例。
三、实验结果我们设计了一个简单的词法分析器,并进行了测试。
测试用例涵盖了各种情况下的源程序代码,包括正确的代码和错误的代码。
经过测试,词法分析器能够正确处理所有的测试用例。
词法分析器将源程序代码分解为一系列的词法单元,每个词法单元包含了单词的种类和对应的值。
通过对词法单元的分析,可以进一步进行语法分析和语义分析,从而完成编译过程。
四、实验总结通过本次实验,我深入了解了编译原理的词法分析阶段。
词法分析是编译器的第一个重要阶段,它将源程序代码分解为一个个的词法单元,为后续的语法分析和语义分析提供基础。
在实现词法分析器的过程中,我学会了如何根据词法规则设计词法分析器的算法,并使用编程语言实现词法分析器。
通过测试和修正,我掌握了调试和错误修复的技巧。
本次实验的经验对我今后的编程工作有很大帮助。
编译原理是计算机科学与技术专业的核心课程之一,通过实践能够更好地理解和掌握其中的概念和技术。
我相信通过进一步的学习和实践,我能够在编译原理领域取得更大的成果。
编译原理词法分析实验报告
编译原理词法分析实验报告实验一词法分析一、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
二、实验内容(1)功能描述:该程序是实现一个词法分析器,词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是将单词分为五种的方法。
识别关键字:main、if、int、for、while、do、return、break、continue;单词种别码为1。
标识符:单词种别码为2。
常数:为无符号整形数;单词种别码为3。
运算符:包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
分隔符:包括:,、;、{、}、(、);单词种别码为5。
(2)程序结构描述:输入:从控制台输入一段源程序代码,对输入的代码进行词法分析,处理:分离出关键字、标识符、数值、运算符和界符。
输出:在词法分析结果表中输出每个单词所在行号、类型以及它所对应的编码。
其中,编码是自定义的,一种类型对应一个编码。
词法分析结果显示在控制台上。
(3)程序设计思路1、定义编码表,用ArrayList集合存放单词,如:关键字、运算符、分界符。
这三种单词是固定的,标示符和数字这两种单词不存放在集合中。
编码表是固定的,只需要初始化一次就够了,所以将集合定义为static类型,使其在类加载时,进行一次初始化。
2、static char allstr[] = new char[100000];该数组用于存储用户从控制台输入的所有字符。
3、//从键盘获取一个一个的字符public char Getchar() {try {ch = (char) System.in.read();} catch (Exception e) {e.printStackTrace();}return ch;}4、用while循环遍历allstr数组中存放的字符,判断分离出关键字、标示符、数字、运算符、标示符。
编译原理词法分析程序设计实验报告
编译原理词法分析程序设计实验报【实验目的】1.了解词法分析的主要任务。
2.熟悉编译程序的编制。
【实验内容】根据某文法,构造一基本词法分析程序。
找出该语言的关键字、标识符、整数以及其他一些特殊符号,给出单词的种类和值。
【实验要求】1. 构造一个小语言的文法类 C 小语言文法(以EBNF 表示)<程序>::=<分程序>{<分程序>} .<分程序>::=<标识符>' (变'<量说明部分>{,<变量说明部分>} ' )函'数<体><变量说明部分>::=int<标识符>{,<标识符>}<函数体>::=' { '变[量<说明部分>;]<语句序列>'}'<语句序列>: : =<语句序列>;<语句>|<语句><语句>::=<赋值语句>|<条件语句>|<循环语句>|<函数调用语句><赋值语句>::=<标识符>=<表达式><表达式>: : =[+|-]<项>{<加法运算符><项>}<项>::=<因子>{<乘法运算符><因子>}<因子>:=<标识符>|<无符号整数><加法运算符>::= +|-<乘法运算符>::= *|/<条件语句>::=if<条件>'{语句序列>'}' [else语句序列〉’}']<条件>::=<表达式><关系运算符><表达式><关系运算符>::= ==|!=|>|<|>=|<=<循环语句>::=for '表达式>;<条件>;<表达式>')” {语句序列>'}'<函数调用语句>::=<标识符>' (标'识<符>{,<标识符>}|<空>' ) '<标识符>::=<字母>{<字母>|<数字>}<无符号整数>::=<数字>{<数字>}<字母>::=a|b|c| …|X|Y|Z<数字>::=0|1|2| …|8|9单词分类情况关键字: int if else for标识符:以字母开头的字母和数字的组合关系运算符: ==|!=|>|<|>=|<=加法运算符: +|-乘法运算符: *|/界符:,;{ } ( )2. 设计单词的输出形式,单词的种类和值的表示方法种别码单词值如: 1 int3. 编写词法分析程序cffx.c实现基本的词法分析器,能够分析关键字、标识符、数字、运算符(需要有“ ==”或之类需要超前搜索的运算符)以及其他一些符号。
编译原理词法分析报告
实验一:词法分析一、实验目的:1、通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
2、编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本关键字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)二、实验预习提示1、词法分析器的功能和输出格式词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
本实验中,采用的是一类符号一种别码的方式。
2、单词的BNF表示<标识符>-> <字母><字母数字串><字母数字串>-><字母><字母数字串>|<数字><字母数字串>|<下划线><字母数字串>|ε<无符号整数>-> <数字><数字串><数字串>-> <数字><数字串> |ε<加法运算符>-> +<减法运算符>->-<大于关系运算符>->><大于等于关系运算符>-> >=3、“超前搜索”方法词法分析时,常常会用到超前搜索方法。
如当前待分析字符串为“a>+”,当前字符为’>’,此时,分析器到底是将其分析为大于关系运算符还是大于等于关系运算符呢?显然,只有知道下一个字符是什么才能下结论。
于是分析器读入下一个字符’+’,这时可知应将’>’解释为大于运算符。
但此时,超前读了一个字符’+’,所以要回退一个字符,词法分析器才能正常运行。
在分析标识符,无符号整数等时也有类似情况。
编译原理实验报告
编译原理实验报告一、实验目的编译原理是计算机科学中的重要课程,旨在让学生了解编译器的基本工作原理以及相关技术。
本次实验旨在通过设计和实现一个简单的编译器,来进一步加深对编译原理的理解,并掌握实际应用的能力。
二、实验环境本次实验使用了Java编程语言及相关工具。
在开始实验前,我们需要安装Java JDK并配置好运行环境。
三、实验内容及步骤1. 词法分析词法分析是编译器的第一步,它将源代码分割成一系列词法单元。
我们首先实现一个词法分析器,它能够将输入的源代码按照语法规则进行切割,并识别出关键字、标识符、数字、运算符等。
2. 语法分析语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。
我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。
3. 语义分析语义分析是编译器的第三步,它对语法树进行检查和转换。
我们主要进行类型检查、语法错误检查等。
如果源代码存在语义错误,编译器应该能够提供相应的错误提示。
4. 代码生成代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。
在本次实验中,我们将目标代码生成为Java字节码。
5. 测试与优化完成以上步骤后,我们需要对编译器进行测试,并进行优化。
通过多个测试用例的执行,我们可以验证编译器的正确性和性能。
四、实验心得通过完成这个编译器的实验,我收获了很多。
首先,我对编译原理的知识有了更深入的理解。
在实验过程中,我深入学习了词法分析、语法分析、语义分析和代码生成等关键技术,对编译器的工作原理有了更系统的了解。
其次,我提高了编程能力。
实现一个完整的编译器需要处理复杂的数据结构和算法,这对我的编程能力是一个很好的挑战。
通过实验,我学会了合理地组织代码,优化算法,并注意到细节对程序性能的影响。
最后,我锻炼了解决问题的能力。
在实验过程中,我遇到了很多困难和挑战,但我不断地调试和改进代码,最终成功地实现了编译器。
编译原理实验报告(一)----词法分析程序
结束
是 转关键字和标识符处理
是 转数字处理
是 转运算符处理
)[p--8]
{[p--23] char[k--0] ch[i--5] ;[p--13]
关闭所有文件
下面简要分析一下词法分析程序的运行流程:
能否打开所要编译的 C 语言文 件
能
判断当前字符是否是文件结束符
否
报错 是
否
是
从源判程断序当中前读字入符一是行否到是数’组\n缓’ 冲区
否
判断当前字符是否是字母
否 判断当前字符是否是数字
否 判断当前字符是否是运算符
否
【程序调试】 现有源程序 a.c 清单如下: #include <stdio.h> int main(int argc, char *argv[]) {char ch; int i; ch='a'; ch=ch+32 ; i=ch; printf("%d id %c\n",i,ch);/*打印*/ return 0; } 运行词法分析程序后,显示如下结果: after_com.txt 文件: #[p--2] include[i--0] <[p--14] stdio.h[i--1] >[p--16]
"fclose","exit","r","read","close","w","fprintf"};
编译原理上机实验报告
编译原理上机实验报告一、实验目的本次实验旨在通过实践的方式理解和掌握编译原理中的一些重要概念和技术,包括词法分析、语法分析和语义分析等。
通过实验的操作,了解和体验编译器的工作过程,深入理解编译原理的相关理论知识。
二、实验环境本次实验使用了Java语言作为编程语言,使用Eclipse作为开发环境,实验所需的相关工具和库已经提前配置完成。
三、实验内容本次实验主要分为三个部分,分别是词法分析、语法分析和语义分析。
1.词法分析词法分析是编译器的第一个阶段,也是最基础的阶段。
在本次实验中,我们首先需要实现一个词法分析器,该分析器可以将源代码分割成一个个的词法单元,将其存储到一个词法单元表中。
我们首先需要定义一些词法单元的模式,比如关键字、标识符、常量等。
然后,我们使用正则表达式和有限自动机的思想来实现一个可以识别各种模式的词法分析器。
2.语法分析语法分析是编译器的第二个阶段,其目的是将词法单元表中的内容按照语法规则进行分析,生成一个语法树。
在本次实验中,我们需要实现一个递归下降的语法分析器。
我们首先需要定义一些语法规则,然后根据这些规则逐条实现相应的语法分析函数。
最终,我们可以通过递归调用这些函数,将源代码转换成语法树的形式。
3.语义分析语义分析是编译器的第三个阶段,其目的是对语法树进行进一步的检查和处理。
在本次实验中,我们需要实现一个简单的语义分析器。
我们可以在语法分析的基础上,增加一些语义规则,然后对生成的语法树进行检查。
比如,我们可以检查变量的定义和使用是否一致,是否存在未定义的变量等。
最终,我们可以通过语义分析器发现和纠正一些潜在的错误。
四、实验总结通过本次实验,我深入学习了编译原理的相关知识,并通过实践中加深了对这些知识的理解和掌握。
实验中,我了解到了词法分析、语法分析和语义分析在编译器设计中的重要性,也学会了如何使用相关工具和技术来实现这些功能。
通过实验,我发现编译原理是一门非常有趣且实用的课程,它既涉及到理论知识,又需要实践操作。
词法分析器实验报告_5
一、实验目的1.1总体目的1.1.1 掌握词法分析的基本原理;1.1.2.理解词法分析在编译程序过程中的作用;1.1.3.熟悉关键字表等相关的数据结构与单词的分类方法.1.1.4.加深对编译原理的理解,掌握词法分析器的实现方法和技术,同时,将JA V A 的理论知识结合实际,锻炼编程技术,强调良好的程序设计风格。
1.2程序目的利用JAVA语言针对C语言编制一个一遍扫描的编译程序。
从文件中识别出各个单词, 识别出所取的单词的类型, 并且对代码中的词法错误进行提示。
二、实验内容根据编译原理中的词法分析原理, 利用Java语言针对C语言编写一个词法分析程序: 输入: 打开一个C语言程序的源代码文件, 将其读入程序输入框。
处理: 对输入框中的代码进行词法分析,分离出关键字、标识符、数值、运算符和界符。
输出:在词法分析结果表中输出每个单词所在行号、类型以及它所对应的编码。
其中, 编码是自定义的,一种类型对应一组编码。
词法分析结果显示在词法分析错误信息栏, 提示错误个数、错误所在行号, 并对某些词法错误原因进行说明。
三、实验需求针对C语言程序代码进行词法分析器, 从指定文件中读入预分析的源程序, 从左至右扫描源程序的字符串, 按照词法规则(正则文法规则)识别出一个个正确的单词, 并转换成该单词相应的二元式(种别码、属性值)以便之后进行语法分析使用。
同时, 按照给定的规则, 识别出单词符号作为输出, 发现其中的语法错误, 不同类别的字符通过相应的函数模块来分析识别, 使程序能够正确识别文法所规定的任何组织形式的字符组合, 将所有的分析状态显示在词法分析器中。
最后在错误分析栏中显示该文件中C语言代码的词法错误个数、错误所在行, 并对错误原因进行说明。
四、主要数据结构介绍4.1关键字编码4.2标识符统一编码1004.3数值统一编码2004.4界符编码4.5运算符编码4.6全局变量含义int row: 语法错误出现的所在列数int line: 语法错误出现的所在行数int err: 语法错误的个数int begin: 当前程序扫描在字符串中的开始位置int end: 当前程序扫描在字符串中的结束位置4.7局部变量定义int i: 选择第i 个字符进行检测 int state: 单词类型判断标志 int N: 文件长度char c: 当前遍历的字符 string str: 输入字符串 int flag: 退出标志五、主要模块算法介绍5.1总体流程介绍说明: state 为输入字符状态标志, 根据输入字符不同类型选择不同处理。
编译原理词法分析器实验报告
编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。
词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。
本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。
2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。
具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。
3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。
这些规则描述了编程语言中各种词法单元的模式。
例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。
4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。
在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。
4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。
测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。
4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。
如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。
5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。
该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。
在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。
编译原理教程实验报告
一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。
二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。
2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。
3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。
4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。
5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。
6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。
四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。
2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。
3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。
4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。
5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。
6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。
五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。
编译原理_词法分析器实验报告
编译原理_词法分析器实验报告一.实验题目和要求。
题目:设计PL / 0语言的词法分析器。
要求:单词(关键字);begin end if then else while write read docall const var procedure repeat until运算符:+ - * / := = <>(#) < <= > >=界符:, . ; ( )标识符:字母打头的字母数字串,长度不超过10.常数:整数,所含数字的个数不超过14.返回单词形式:二元式(种别,属性值)二.实验平台。
PC机: Windows XP操作系统编程环境: Turbo C 2.0编程语言: C语言三.实验算法说明。
定义2个全局变量char ch和char strtoken分别用来存放最新读入的源程序字符和构成单词符号的字符串。
然后用各个子函数的功能和读文件内容的操作,实现对源程序的词法分析,分别进行关键字,标识符,常数,运算符和界符的分析确认,然后将对应的二元式结果输出。
首先用户输入要读文件的名称,然后程序会把文件的内容读到定义的够大的字符数组str(相当于词法分析的一个缓冲区)里,然后开始从str里一个一个的读出字符并放在专门用来暂时存放单词数组strtoken里进行词法分析,若符合语言的规则,则打印出相关的说明信息,即该字符或字符串的二元式信息,可以清楚的明白该字符的种别和属性值。
如果读入的字符或字符串是非法的,即不是语法规定或是没有意义的字符或字符串,程序会提示相关的错误信息并进行一定四.程序子函数功能说明。
1.void getChar( ) 将下一个输入字符读到ch中,搜索指示器前移一个字符的位置。
2. void getBc( ) 检查ch中的字符是否为空白,若是,则调用getChar( ),直到ch中进入一个非空的字符。
3.void retract( ) 将搜索指示器回调一个字符位置,将ch置为空白字符。
编译原理熟悉实验报告
一、实验目的1. 理解编译原理的基本概念和流程;2. 掌握编译器的各个阶段及其实现方法;3. 熟悉编译器各个阶段中使用的算法和数据结构;4. 培养编程能力和问题解决能力。
二、实验内容1. 词法分析;2. 语法分析;3. 语义分析;4. 代码生成;5. 符号表;6. 中间代码生成。
三、实验步骤1. 词法分析(1)设计词法分析器:首先需要确定源程序中的词法单元,如标识符、关键字、运算符等。
然后,编写代码实现词法分析器,对源程序进行扫描,将词法单元转换成词法符号。
(2)实现词法分析器:使用C语言或Java等编程语言实现词法分析器,完成词法单元的识别和转换。
2. 语法分析(1)设计语法分析器:根据源程序的语言规范,设计语法分析器,实现语法规则的定义和匹配。
(2)实现语法分析器:使用递归下降分析法、LL(1)分析法、LR(1)分析法等实现语法分析器,对词法分析器输出的词法符号序列进行语法分析。
3. 语义分析(1)设计语义分析器:根据源程序的语言规范,设计语义分析器,实现语义规则的检查和类型检查。
(2)实现语义分析器:使用C语言或Java等编程语言实现语义分析器,完成语义规则的检查和类型检查。
4. 代码生成(1)设计代码生成器:根据源程序的语言规范,设计代码生成器,将抽象语法树转换成目标代码。
(2)实现代码生成器:使用C语言或Java等编程语言实现代码生成器,完成抽象语法树到目标代码的转换。
5. 符号表(1)设计符号表:在编译过程中,需要记录变量、函数等信息,设计符号表实现这些信息的存储和管理。
(2)实现符号表:使用C语言或Java等编程语言实现符号表,完成变量、函数等信息的存储和管理。
6. 中间代码生成(1)设计中间代码生成器:根据源程序的语言规范,设计中间代码生成器,将抽象语法树转换成中间代码。
(2)实现中间代码生成器:使用C语言或Java等编程语言实现中间代码生成器,完成抽象语法树到中间代码的转换。
四、实验结果与分析1. 词法分析器能够正确识别源程序中的词法单元,并将它们转换成词法符号。
编译原理实验报告 词法分析
编译原理实验一·词法分析一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
二、实验内容及要求对某特定语言A ,构造其词法规则。
该语言的单词符号包括:保留字(见左下表)、标识符(字母大小写不敏感)、整型常数、界符及运算符(见右下表) 。
功能要求如下所示:·按单词符号出现的顺序,返回二元组序列,并输出。
·出现的标识符存放在标识符表,整型常数存放在常数表,并输出这两个表格。
·如果出现词法错误,报出:错误类型,位置(行,列)。
·处理段注释(/* */),行注释(//)。
·有段注释时仍可以正确指出词法错误位置(行,列)。
三、实验过程1、词法形式化描述使用正则文法进行描述,则可以得到如下的正规式:其中ID表示标识符,NUM表示整型常量,RES表示保留字,DEL表示界符,OPR表示运算符。
A→(ID | NUM | RES | DEL | OPR) *ID→letter(letter | didit)*NUM→digit digit*letter→a | …| z | A | …| Zdigit→0 | …| 9RES→program | begin | end | var | int | and | or | not | if | then | else | while | doDEL→( | ) | . | ; | ,OPR→+ | * | := | > | < | = | >= | <= | <>如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。
空格由空白、制表符和换行符组成。
2、单词种别定义;3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、运行环境介绍;本次实验采用win-tc进行代码的编写和编译及运行程序的运行环境为windows5、关键算法的流程图及文字解释;程序中用到的函数列表:变量ch储存当前最新读进的字符的地址strToken存放当前字符串voidmain() //主函数struct binary *lexicalAnalyze(); //词法分析的主函数,返回一个二元组的指针void GetBC(); //检查ch指向的字符是否为空格、制表或回车符,如果是则调用GetChar()直至不是上述字符void GetChar(); //ch前移一个地址单元int ConCat(); //将ch指向的字符连接到strToken之后int isLetter(); //判断ch指向的字符是否字母int isDigit(); //判断ch指向的字符是否数字int insertId(); //向标识符表中插入当前strToken的字符串int insertConst(); //将strToken的常数插入常数表中int Reserved(); //检测当前strToken中的字符串是否保留字,若是,则返回编码,否则返回0int isId(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回其编号,否则返回0int isConst(); //检测当前strToken中的字符串是否在常数表中已存在,若是,则返回其编号,否则返回0void errProc(int errType); //出错处理过程,errType是错误类型,将错误信息加入错误表中main()函数的流程图如下:lexicalAnalyze()函数的流程图如下所示:Reserved()、isId()和isConst()函数均采用了对链表的遍历算法,errProc()函数通过识别不同的错误编号,向错误链表中添加相应的错误信息。
编译原理词法分析器实验报告
编译原理词法分析器实验报告篇一:编译原理词法分析器实验报告曲阜师范大学实验报告计算机系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,识别出并输出简单语言的基本字。
标示符。
无符号整数.运算符.和界符。
三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符.字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。
2 实验词法分析器源程序:#include 〈stdio.h〉#include <math.h>#include <string。
h>int i,j,k;char c,s,a[20],token[20]={’0’};int letter(char s){if((s〉=97)&&(s〈=122)) return(1);else return(0);}int digit(char s){if((s〉=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else”)==0) return(3);else if(strcmp(token,"switch”)==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf(”please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!=’#’);i=1;j=0;get();while(s!=’#'){ memset(token,0,20);switch(s){case 'a':case ’b':case ’c':case ’d':case ’e’:case ’f’:case 'g’:case ’h':case 'i':case ’j':case 'k’:case ’l':case 'm’:case 'n':case ’o':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)printf("(%d,%s)”,6,token);else printf("(%d,—)",k);break;case ’0':case ’1’:case ’2':case ’3':case '4’:case '5’:case ’6':case ’7’:case ’8’:case '9’:while(digit(s)){token[j]=s;j=j+1;get();}retract();printf(”%d,%s",7,token);break;case '+':printf(”(’+',NULL)”);break;case ’-':printf("(’-',null)");break;case ’*':printf(”('*’,null)");break;case '<':get();if(s=='=’) printf(”(relop,LE)”);else{retract();printf("(relop,LT)");}break;case ’=':get();if(s=='=’)printf("(relop,EQ)");else{retract();printf(”('=',null)”);}break;case ’;':printf(”(;,null)");break;case ' ’:break;default:printf("!\n”);}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术.三、实验原理:1、算术表达式语法分析程序的算法思想首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理词法分析程序设计实验报告【实验目的】1.了解词法分析的主要任务。
2.熟悉编译程序的编制。
【实验容】根据某文法,构造一基本词法分析程序。
找出该语言的关键字、标识符、整数以及其他一些特殊符号,给出单词的种类和值。
【实验要求】1.构造一个小语言的文法类C小语言文法(以EBNF表示)<程序>::=<分程序>{<分程序>} .<分程序>::=<标识符>’(’<变量说明部分>{,<变量说明部分>}’)’<函数体><变量说明部分>::=int<标识符>{,<标识符>}<函数体>::=’{’[<变量说明部分>;]<语句序列>’}’<语句序列>::=<语句序列>;<语句>|<语句><语句>::=<赋值语句>|<条件语句>|<循环语句>|<函数调用语句><赋值语句>::=<标识符>=<表达式><表达式>::=[+|-]<项>{<加法运算符><项>}<项>::=<因子>{<乘法运算符><因子>}<因子>:=<标识符>|<无符号整数><加法运算符>::= +|-<乘法运算符>::= *|/<条件语句>::=if<条件>’{’<语句序列>’}’[else’{’<语句序列>’}’]<条件>::=<表达式><关系运算符><表达式><关系运算符>::= ==|!=|>|<|>=|<=<循环语句>::=for’(’<表达式>;<条件>;<表达式>’)’ ’{’<语句序列>’}’<函数调用语句>::=<标识符>’(’<标识符>{,<标识符>}|<空>’)’<标识符>::=<字母>{<字母>|<数字>}<无符号整数>::=<数字>{<数字>}<字母>::=a|b|c|…|X|Y|Z<数字>::=0|1|2|…|8|9单词分类情况关键字:int if else for标识符:以字母开头的字母和数字的组合关系运算符: ==|!=|>|<|>=|<=加法运算符:+|-乘法运算符: *|/界符:,;{ } ( )2.设计单词的输出形式,单词的种类和值的表示方法种别码单词值如:1 int3. 编写词法分析程序cffx.c实现基本的词法分析器,能够分析关键字、标识符、数字、运算符(需要有“==”或“:=”之类需要超前搜索的运算符)以及其他一些符号。
// 编译原理词法分析程序.cpp#include<stdio.h>#include<stdlib.h>#include<string.h>typedef struct words{int id;char name[20];char value[20];}word;char integer[20]={'i','n','t'};char iff[20]={'i','f'};char elsee[20]={'e','l','s','e'};char forr[20]={'f','o','r'};int main(){char code[10000];char words[20],ch;int i,j,p,count,n,m;int k=0;word symbol[500];printf("种别码:1 类别:关键字int\n");printf("种别码:2 类别:关键字if\n");printf("种别码:3 类别:关键字else\n");printf("种别码:4 类别:关键字for\n");printf("种别码:5 类别:标识符\n");printf("种别码:6 类别:计算运算符\n");printf("种别码:7 类别:关系运算符\n");printf("种别码:8 类别:界符\n");while(1){gets(code);n=strlen(code);for(m=0,j=0;m<n;m++){if((code[m]>='a'&&code[m]<='z')||(code[m]>='0'&&code[m]<='9')){words[j]=code[m];j++;}else{if(words[0]=='i'&&words[1]=='n'&&words[2]=='t'&&words[3]=='\0'){symbol[k].id=1;for(i=0;i<20;i++){symbol[k].value[i]=words[i];}k++;}else if(words[0]=='i'&&words[1]=='f'&&words[2]=='\0'){symbol[k].id=2;for(i=0;i<20;i++){symbol[k].value[i]=iff[i];}k++;}elseif(words[0]=='e'&&words[1]=='l'&&words[2]=='s'&&words[3]=='e'&&words[4]=='\0') {symbol[k].id=3;for(i=0;i<20;i++){symbol[k].value[i]=elsee[i];}k++;}elseif(words[0]=='f'&&words[1]=='o'&&words[2]=='r'&&words[3]=='\0'){symbol[k].id=4;for(i=0;i<20;i++){symbol[k].value[i]=forr[i];}k++;}else{symbol[k].id=5;for(i=0;i<20;i++){symbol[k].value[i]=words[i];}k++;}for(p=0;p<20;p++){words[p]=0;}j=0;if(code[m]=='+'){symbol[k].id=6;symbol[k].value[0]='+';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='-'){symbol[k].id=6;symbol[k].value[0]='-';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='*'){symbol[k].id=6;symbol[k].value[0]='*';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='/'){symbol[k].id=6;symbol[k].value[0]='/';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='='&&code[m+1]!='=') {symbol[k].id=6;symbol[k].value[0]='=';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='='&&code[m+1]=='=') {symbol[k].id=7;symbol[k].value[0]='=';symbol[k].value[1]='=';for(i=2;i<20;i++){symbol[k].value[i]=0;}k++;m++;}if(code[m]=='!'&&code[m+1]=='=') {symbol[k].id=7;symbol[k].value[0]='!';symbol[k].value[1]='=';for(i=2;i<20;i++){symbol[k].value[i]=0;}k++;m++;}if(code[m]=='>'&&code[m+1]=='=') {symbol[k].id=7;symbol[k].value[0]='>';symbol[k].value[1]='=';for(i=2;i<20;i++){symbol[k].value[i]=0;}k++;m++;}if(code[m]=='<'&&code[m+1]=='=') {symbol[k].id=7;symbol[k].value[0]='<';symbol[k].value[1]='=';for(i=2;i<20;i++){symbol[k].value[i]=0;}k++;m++;}if(code[m]=='>'){symbol[k].id=7;symbol[k].value[0]='>';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='<'){symbol[k].id=7;symbol[k].value[0]='<';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]==','){symbol[k].id=8;symbol[k].value[0]=',';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]==';'){symbol[k].id=8;symbol[k].value[0]=';';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='('){symbol[k].id=8;symbol[k].value[0]='(';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]==')'){symbol[k].id=8;symbol[k].value[0]=')';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='{'){symbol[k].id=8;symbol[k].value[0]='{';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}if(code[m]=='}'){symbol[k].id=8;symbol[k].value[0]='}';for(i=1;i<20;i++){symbol[k].value[i]=0;}k++;}}count=k;}system("cls");for(i=0;i<count;i++){printf("%d ",symbol[i].id);printf("%s\n",symbol[i].value);}}return 0;}4.生成并输出单词符号表识别单词的状态转换图:5.流程图6.源程序清单int a,b,c;a=b+c;7.测试结果8.实验心得:此次实验让我了解了如何设计、编制并调试词法分析程序,并加深了我对词法分析器原理的理解;熟悉了直接构造词法分析器的方法和相关原理,并学会使用c语言直接编写词法分析器;同时更熟练的掌握用c语言编写程序,实现一定的实际功能。