编译原理实验报告《词法分析器的构造》

合集下载

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

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

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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、定义单词符号的类别和编码首先,确定实验中要识别的单词符号种类,如关键字(if、else、while 等)、标识符、整数常量、浮点数常量、运算符(+、、、/等)和界符(括号、逗号等)。

为每个单词符号类别分配一个唯一的编码,以便后续处理。

2、设计状态转换图根据单词符号的词法规则,绘制状态转换图。

例如,对于标识符的识别,起始状态为“起始状态”,当输入为字母时进入“标识符中间状态”,在“标识符中间状态”中,若输入为字母或数字则继续保持该状态,直到遇到非字母数字字符时结束识别,确定为一个标识符。

3、编写词法分析程序根据状态转换图,使用所选编程语言实现词法分析器。

在程序中,通过不断读取输入字符,根据当前状态进行转移,并在适当的时候输出识别到的单词符号。

4、测试词法分析程序准备一组包含各种单词符号的测试用例。

将测试用例输入到词法分析程序中,检查输出的单词符号是否正确。

五、实验代码以下是本次实验中实现词法分析器的核心代码部分:```include <stdioh>include <ctypeh>//单词符号类别定义typedef enum {KEYWORD,IDENTIFIER,INTEGER_CONSTANT,FLOAT_CONSTANT,OPERATOR,DELIMITER} TokenType;//关键字列表char keywords ={"if","else","while","for","int","float","void"};//状态定义typedef enum {START,IN_IDENTIFIER,IN_INTEGER,IN_FLOAT,IN_OPERATOR} State;//词法分析函数TokenType getToken(char token, int tokenLength) {State state = START;int i = 0;while (1) {char c = getchar();switch (state) {case START:if (isalpha(c)){state = IN_IDENTIFIER;tokeni++= c;} else if (isdigit(c)){state = IN_INTEGER;tokeni++= c;} else if (c =='+'|| c ==''|| c ==''|| c =='/'|| c =='('|| c ==')'|| c ==';'|| c ==','){state = IN_OPERATOR;tokeni++= c;} else if (c ==''){state = IN_FLOAT;tokeni++= c;} else if (c == EOF) {tokeni ='\0';tokenLength = i;return -1;} else {tokeni ='\0';tokenLength = i;return -2;}break;case IN_IDENTIFIER:if (isalpha(c) || isdigit(c)){tokeni++= c;} else {ungetc(c, stdin);tokeni ='\0';tokenLength = i;//检查是否为关键字for (int j = 0; j < sizeof(keywords) / sizeof(keywords0); j++){if (strcmp(token, keywordsj) == 0) {return KEYWORD;}}return IDENTIFIER;}break;case IN_INTEGER:if (isdigit(c)){tokeni++= c;} else if (c ==''){state = IN_FLOAT;tokeni++= c;} else {ungetc(c, stdin);tokeni ='\0';tokenLength = i;return INTEGER_CONSTANT;}break;case IN_FLOAT:if (isdigit(c)){tokeni++= c;} else {ungetc(c, stdin);tokeni ='\0';tokenLength = i;return FLOAT_CONSTANT;}break;case IN_OPERATOR: tokeni ='\0';tokenLength = i;return OPERATOR; break;}}}int main(){char token100;int tokenLength;TokenType tokenType;while ((tokenType = getToken(token, &tokenLength))!=-1) {switch (tokenType) {case KEYWORD:printf("Keyword: %s\n", token);break;case IDENTIFIER:printf("Identifier: %s\n", token);break;case INTEGER_CONSTANT:printf("Integer Constant: %s\n", token);break;case FLOAT_CONSTANT:printf("Float Constant: %s\n", token);break;case OPERATOR:printf("Operator: %s\n", token);break;case DELIMITER:printf("Delimiter: %s\n", token);break;}}return 0;}```六、实验结果对准备的测试用例进行输入,得到的词法分析结果如下:测试用例 1:```int main(){int num = 10;float pi = 314;if (num > 5) {printf("Hello, World!\n");}}```词法分析结果:```Keyword: int Identifier: main Delimiter: (Delimiter: ){Identifier: num Operator: =Integer Constant: 10;Identifier: float Identifier: pi Operator: =Float Constant: 314;Keyword: ifDelimiter: (Identifier: numOperator: >Integer Constant: 5){Identifier: printfDelimiter: (String: "Hello, World!\n" Delimiter: );}```测试用例 2:```for (int i = 0; i < 10; i++){double result = i 25;```词法分析结果:```Keyword: for Delimiter: (Keyword: int Identifier: i Operator: =Integer Constant: 0;Identifier: i Operator: <Integer Constant: 10;Identifier: i Operator: ++)Identifier: doubleIdentifier: resultOperator: =Identifier: iOperator:Float Constant: 25;}```通过对多个测试用例的分析,词法分析器能够正确识别出各种单词符号,实验结果符合预期。

词法分析器的实验报告

词法分析器的实验报告

词法分析器的实验报告词法分析器的实验报告引言:词法分析器是编译原理中的重要组成部分,它负责将源代码中的字符序列转换为有意义的词法单元,为后续的语法分析提供基础。

本实验旨在设计和实现一个简单的词法分析器,并对其进行测试和评估。

实验设计:1. 词法规则设计:在开始实验之前,我们首先需要设计词法规则,即定义源代码中的合法词法单元。

例如,对于一门类C的语言,我们可以定义关键字(如if、while、int等)、标识符、运算符(如+、-、*等)、分隔符(如()、{}等)等。

2. 有限自动机(DFA)的设计:基于词法规则,我们可以设计一个有限自动机,用于识别和分析源代码中的词法单元。

有限自动机是一个状态转换图,其中每个状态代表一种词法单元,而边表示输入字符的转换关系。

3. 实现代码:根据有限自动机的设计,我们可以使用编程语言(如Python、C++等)实现词法分析器的代码。

代码的主要功能包括读取源代码文件、逐个字符进行词法分析、识别和输出词法单元。

实验过程:1. 词法规则设计:我们以一门简单的算术表达式语言为例,设计了以下词法规则:- 数字:由0-9组成的整数或浮点数。

- 运算符:包括+、-、*、/等。

- 分隔符:包括括号()和逗号,。

- 标识符:以字母开头,由字母和数字组成的字符串。

2. 有限自动机(DFA)的设计:我们基于词法规则,设计了一个简单的有限自动机。

该自动机包含以下状态:- 初始状态:用于读取和识别源代码中的字符。

- 数字状态:用于识别和输出数字。

- 运算符状态:用于识别和输出运算符。

- 分隔符状态:用于识别和输出分隔符。

- 标识符状态:用于识别和输出标识符。

3. 实现代码:我们使用Python编程语言实现了词法分析器的代码。

代码主要包括以下功能:- 读取源代码文件。

- 逐个字符进行词法分析,根据有限自动机的设计进行状态转换。

- 识别和输出词法单元。

实验结果:我们对几个测试样例进行了词法分析,并对结果进行了评估。

编译原理实验报告——词法分析器(内含源代码)

编译原理实验报告——词法分析器(内含源代码)

编译原理实验(一)——词法分析器一.实验描述运行环境: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置为空白字符。

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

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

词法分析器实验报告实验目的:设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。

功能描述:该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。

并依次输出各个单词的内部编码及单词符号自身值。

(遇到错误时可显示“Error!”,然后跳过错误部分继续进行)设计思想:设计该词法分析器的过程中虽然没有实际将所有的状态转移表建立出来,但是所用的思想是根据状态转移表实现对单词的识别。

首先构造一个保留字表,然后,每输入一个字符就检测应该进入什么状态,并将该字符连接到d串后继续输入,如此循环,最后根据所在的接受状态以及保留字表识别单词。

符号表:记号类别属性值ws - -const 保留字 1var 保留字 1call 保留字 1begin 保留字 1if 保留字 1while 保留字 1do 保留字 1odd 保留字 1end 保留字 1then 保留字 1procedure 保留字 1= 运算符 2< 运算符 2<= 运算符 2<> 运算符 2> 运算符 2>= 运算符 2* 运算符 2+ 运算符 2- 运算符 2/ 运算符 2:= 运算符 2ident 标识符 3number 常数 4 ( 分隔符 5) 分隔符 5; 分隔符 5, 分隔符 5. 分隔符 5状态转换图:①标识符及保留字:letter or digittStart letter②number:③关系操作符:0 21 435startdigit.digit E+ | -digitdigitdigitdigitEdigit otherother④分隔符:start< other =(<=, 2) >= other>=* * (<>, 2)(<,2)(=, 2)(>=, 2)(>, 2):=(:=,2)⑤算术运算符:使用环境:Windows xp 下的visual c++6.0程序测试: input1 : int a,b;start;( ),.( ; ,5)( (,5)( ),5) ( , ,5)( . ,5)start+- * /( + ,2) ( -,2)( *,2) ( / ,2). a=b+2;input2:while(a>=0)do7x=x+6.7E+23;end;input3:begin:x:=9if x>0 then x:=x+1;while a:=0 dob:=2*x/3,c:=a;end;output1: 3,int 3,a 5,,3,b 5,;3,a2,=3,b2,+4,2 5,; output2:output2:1,while5,(3,a2,>=4,05,)1,doerror line 32,=3,x2,+4,6.7E+235,;1,end5,;output3:output3:1,beginerror line 13,x2,:=4,91,if3,x2,>4,01,then3,x2,:=3,x2,+4,15,;1,while3,a2,:=4,01,do 3,b 2,:= 4,2 2,* 3,x 2,/4,35,,3,c2,:=3,a5,;1,end5,;测试结果与预期结果一致源程序代码:#include<stdio.h>#include<string.h>void main(){int i=0,j,k=0,state=1,f=0,linenum=1;chara[11][10]={"const","var","call","begin","if","while","do","odd","end","then","proc edure"};char b,d[40]={"\0"};freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);b=getchar();while(b!=EOF)/*判断所输入字符是否为结束符*/{if(b==' '||b=='\n'||b=='\t')/*滤过空格、换行等分隔符号*/{ if(b='\n') linenum++;b=getchar();}else if((b>='a'&&b<='z')||(b>='A'&&b<='Z'))/*识别标识符以及保留字*/{d[i++]=b;b=getchar();while((b>='a'&&b<='z')||(b>='A'&&b<='Z')||(b>='0'&&b<='9')){d[i++]=b;b=getchar();}for(j=0;j<11;j++)/*查询保留字表确定该单词是否是保留字*/{ if(strcmp(d,a[j])==0){ printf("1,%s\n",d);k=1;break;}}if(k==0)/*在保留字表中没有查到该单词,是标识符*/printf("3,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;k=0;}else if(b>='0'&&b<='9')/*识别常数*/{ d[i++]=b;b=getchar();while(f!=1){switch (state) {case 1:if(b>='0'&&b<='9') {state=1;d[i++]=b;b=getchar();}else if(b=='.') { state=2;d[i++]=b;b=getchar();}else if(b=='E') { state=4;d[i++]=b;b=getchar();}else state=7;break;case 2:if(b>='0'&&b<='9') {state=3;d[i++]=b;b=getchar();}else state=8;break;case 3:if(b>='0'&&b<='9') {state=3;d[i++]=b;b=getchar();}else if(b=='E') { state=4;d[i++]=b;b=getchar();}else state=7;break;case 4:if(b=='+'||b=='-') { state=5;d[i++]=b;b=getchar();}else if(b>='0'&&b<='9'){ state=6;d[i++]=b;b=getchar();} else state=8;break;case 5:if(b>='0'&&b<='9'){ state=6;d[i++]=b;b=getchar();}else state=8;break;case 6:if(b>='0'&&b<='9'){ state=6;d[i++]=b;b=getchar();}else state=7;break;case 7: f=1;break;case 8: f=1;break;}}if(state==7&&(b<'a'||b>'z')&&(b<'A'||b>'Z'))printf("4,%s\n",d);else if(state==7&&(b>='a'&&b<='z')||(b>='A'&&b<='Z'))/*数字后接字母的出错控制*/{while((b>='a'&&b<='z')||(b>='A'&&b<='Z')){ d[i++]=b;b=getchar();}printf("error line %d\n",linenum);}else printf("error line %d\n",linenum);for(j=0;j<=i;j++)d[j]='\0';i=0;f=0;state=1;}else if(b=='<')/*识别'<'、'<='和'<>'*/{ d[i++]=b;b=getchar();if(b=='='||b=='>'){ d[i++]=b;b=getchar();printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}else{ printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}}else if(b=='>')/*识别'>'和'>='*/{ d[i++]=b;b=getchar();if(b=='='){ d[i++]=b;b=getchar();printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}else{ printf("2,%s\n",d);for(j=0;j<=i;j++)d[j]='\0';i=0;}}else if(b==':')/*识别':='*/{ d[i++]=b;b=getchar();if(b=='='){ d[i++]=b;b=getchar();printf("2,%s\n",d);}else printf("error line %d\n",linenum);for(j=0;j<=i;j++)d[j]='\0';i=0;}else if(b=='*'||b=='+'||b=='-'||b=='/'||b=='=')/*识别运算符*/{ printf("2,%c\n",b);b=getchar();}else if(b=='('||b==')'||b==','||b==';'||b=='.')/*识别分隔符*/{ printf("5,%c\n",b);b=getchar();}else{ printf("error line %d\n",linenum);b=getchar();}}}实验心得:此次实验让我了解了如何设计、编制并调试词法分析程序,并加深了我对词法分析器原理的理解;熟悉了直接构造词法分析器的方法和相关原理,并学会使用c语言直接编写词法分析器;同时更熟练的掌握用c语言编写程序,实现一定的实际功能。

词法分析器实验报告

词法分析器实验报告

词法分析器实验报告一、实验目的本实验旨在通过构建一个简单的词法分析器来加深对编译原理中词法分析的理解,并掌握基本的词法分析算法和程序设计技巧。

二、实验环境操作系统:Windows 10编程语言:C/C++开发环境:Visual Studio 2019三、实验内容1. 设计并实现一个词法分析器,要求具备以下功能:(1)能够识别并区分关键字、标识符、字符常量、字符串常量、整型常量和浮点型常量等基本单词;(2)能够跳过注释、空格、制表符和换行符等无用字符;(3)能够给出错误提示并指明错误所在位置。

2. 对设计的词法分析器进行测试,并记录测试结果,分析测试结果的正确性和效率。

四、实验方法1. 分析待处理的源程序,并确定需要识别的词法单元;2. 设计状态转换图或状态转换表,并将其转化为程序代码;3. 开发测试程序,对所设计的词法分析器进行测试。

五、实验结果1. 实现的词法分析器程序可以正确识别出源程序中的各个单词,并能够跳过无用字符;2. 在测试过程中发现了一些错误,比如未能正确识别一些特殊情况下的单词,或者给出了错误的错误提示等。

经过修改后,程序可以正确识别这些情况,并给出正确的错误提示信息;3. 程序的效率较高,能够在短时间内对源程序进行词法分析。

六、实验体会通过本次实验,我对编译原理中词法分析的概念、算法和程序设计技巧有了更加深入的了解和掌握。

在实践中,我遇到了许多问题,比如如何设计状态转换图,如何正确识别一些特殊的单词等。

这些问题一一解决后,我对词法分析有了更加深刻的理解。

通过本次实验,我还深刻体会到了编译器设计过程中的思维方式和技术要求。

编译器是计算机科学中的一项重要技术,对于提高程序运行效率、保证程序安全性、增强程序可读性和扩展程序功能等都有重要作用。

因此,编译原理作为计算机科学的重要组成部分,对于我以后的学习和研究具有重要意义。

构造词法分析器实习报告

构造词法分析器实习报告

班级:06级计算机1班学号:姓名:成绩:教学实习题目:构造词法分析器一、教学实习目的《编译原理》课程设计是计算机应用专业的主要实践性教学环节,在学习了《编译原理》及专业基础课的基础上,设计一个实际的程序语言编译系统,可以加深对程序语言结构和机器处理方式的理解,初步掌握高级语言到机器指令的基本转换方法,提高进行工程设计的基本技能及分析解决实际问题的能力,为毕业设计和以后的工程实践打下良好的基础。

二、教学实习要求根据课本p43页的图3.3构造词法分析器。

要求输入源数据文件,能够得出词法分析的结果,并显示出来,包括显示分离出来的单词符号、它们的助记符和内码值以及种类(如常数、字母、保留字及运算符、界符等)。

三、教学实习步骤3.1程序设计说明3.1.1需求分析词法分析是编译过程的第一个阶段,他的任务是输入源程序,对构成源程序的字符串进行扫描和分解,识别出一个个的单词符号,如基本字(begin、end、if、for、while等),标识符、常数、算符和界符(标点符号、左右括号等等)。

单词符号是语言的基本组成成分,是人们理解和编写程序的基本要素。

对于词法分析器,它的功能是输入源程序,输出单词符号。

程序语言的单词符号一般有以下几种:(1)保留字,是程序语言定义的具有固定意义的标识符。

(2)标识符,是用来表示各种名字,如变量名,数组名,过程名等等。

(3)常数,一般有整型,实型,布尔型,文字型等等。

(4)运算符,如+、—、*、/等等。

(5)界符,如逗号,分号,括号等等。

在词法分析器中要求输出的单词符号以二元式的形式给出:(单词种别,单词符号的属性值),单词种别常常用助记符来表示,单词符号的属性值则用内码来表示。

3.1.2详细设计首先给出词法分析器的结构图。

从图中可以看出:词法分析器工作的第一步是输入源程序文本。

输入串一般是放在一个缓冲区中,在很多情况下,把输入串处理一下,对单词符号的识别工作是比较方便的。

预处理可以剔除一些无意义的符号,如注释、多个空白符等等。

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

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

编译原理词法分析器实验报告竭诚为您提供优质文档/双击可除编译原理词法分析器实验报告篇一:编译原理词法分析器实验报告曲阜师范大学实验报告计算机系20XX年级软件工程一班组日期20XX年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。

七、实验结论:实验过程还算顺利,遇到的一系列问题都得到比较好的解决,当然分析器还有很大的改进空间,这里只是简单的实现了词素的识别及简单的判断。

词法分析器报告

词法分析器报告

编译原理实验报告实验题目:词法分析器构造
指导教师:杨建
XX:杨先宇
班级:计13-4
学号:
实验成绩:
fclose(fp);
}
system("pause");
exit(0);
}
问题及处理1、源文件在输入时如果发生错误,系统会直接退出黑屏。

不能处理,加入预处理
后错误报警,这样就可以正确识别输入源程序文件。

2goto语句要特别注意加以分析。

3预处理文件可以直接调用节约时间,或者解决方法是建立一个菜单选项,可以跳过预处理直接进行词法分析
4程序执行时输出界面要保持准确性输入,以免手误导致程序出错。

实验结果运行程序,显示初始功能菜单:
选择功能1,输入源文件路径,对其进行词法分析:
按任意键继续是调用了系统功能函数system("pause");
按任意键之后:
实验心得词法分析在编译原理课上老师强调了许多,但是编译原理相对较难理解我在课上认真听了老师讲课,但是课下也看了书,觉得理解太难,通过实验认真查资料以及了。

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

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

编译原理实验—词法分析器一、实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。

同时增强编写和调试程序的能力。

二、实验内容及要求对某特定语言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、单词种别定义;A语言中的单词符号及其对应的种别编码如下表所示:单词符号种别编码单词符号种别编码3、状态转换图;语言A的词法分析的状态转换图如下所示:空格符,制表符或回车符字母或数字4、java旗舰版5、关键算法的流程图及文字解释;程序中用到的函数列表:A类定义各种类函数以及包含主函数public static void main()变量ch储存当前最新读进的字符的地址strToken存放当前字符串main() //主函数Analysis()//分析函数,每次读入一行文件,进行识别处理;char GetChar(); //取得当前位置的字符的内容放入ch,并提前指向下一个字符;char GetNextChar();//取得当前位置的下一位置的字符,String ConCat(); //将ch指向的字符连接到strToken后面isLetter(); //判断ch指向的字符是否字母isDigit(); //判断ch指向的字符是否数字add(p,str); //向p表中插入当前strToken的字符串Boolean findKeyWord(str); //检测当前strToken中的字符串是否保留字,若是,则执行getKeyWordKey(str),返回保留字的id,否则,判别其是否是已存在的标示符,若是,返回标示符的id以及该标示符在表中的位置;findPunctuation()//判断是否是一个保留的符号;getindex() //返回已经识别的标示符或者是数字的位置下标;Boolean exist(); //检测当前strToken中的字符串是否在标识符表中已存在,若是,则返回true,否则返回falsevoid callError(); //出错处理过程,将错误的位置报告出来(1)main()函数的流程图如下:)具体分析流程图:开始类初始化,变量的初始化,准备执行main()函数调用Analyse()函数分析输出结果表结束Analyse(str)函数读取第一个字符赋给变量Ch继续判读IndexoutofBound6、测试报告(测试用例,测试结果);首先输入一个不含错误的程序(两种注释)进行检测:运行后在控制台上得到的结果如下所示:得到的二元组序列如下:经检验,输出的是正确的二元组序列。

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

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

实验LEX词法分析器自动生成器一、实验内容:用词法分析自动生成器LEX构造一个简单词法分析器,它能识别文件新行并为其添加行号,并将分析结果发送到屏幕上。

二、实验目的:1.掌握LEX源程序的编写方法。

2.掌握自动生成词法分析器LEX的使用方法和工作原理。

LEX源程序*.L通过LEX编译程序,产生一个C语言版本的词法分析程序*.C。

然后通过C语言编译器,将词法分析程序*.C转换成一个可执行文件*.EXE。

再编制一个测试文本文件*.TXT。

用生成的词法分析程序的可执行文件,对测试程序进行词法分析.三、实验要求1.写好实验预习报告;2.编写上机源程序和测试程序;3.写出实验结果;4.实验完后要上交实验报告;四、相关说明LEX上机过程部分:1)利用编辑器如EDIT编写LEX源程序和测试程序,如SHIYAN11.L和TEST.TXT;2)用LEX编译器编译LEX源程序SHIYAN11.L,格式为:LEX SHIYAN11.L↙如果LEX源程序没有语法错误,将得到一个用C语言描述的没有语法错误词法分析器SHIYAN11.C;3)在TC环境下,对SHIYAN11.C进行编译、连接,从而得到可执行的词法分析器SHIYAN11.EXE;4)利用SHIYAN11.EXE对TEST.TXT进行词法分析,格式为:SHIYAN0.EXE<TEST.TXT↙如果没有写测试程序TEST.TXT,则可测试其他某个程序如SHIYAN11.L。

LEX上机过程如下图所示(alt+c):五、实验器材硬件:PC机一台软件:Turbo C、LEX.EXE六、参考程序1.LEX源程序:shiyan11.L%{#include "stdio.h"int lineno=1;()%}line .*\n%%{line} {printf("%2d %s",lineno++,yytext);}%%main(){yylex();return 0;}2.shiyan11.EXE分析shiyan11.L的实验效果如下图所示:。

词法分析器实验报告

词法分析器实验报告

词法分析器实验报告词法分析器是编译器的一个重要组成部分,用于将输入的字符流转换成一个个词法单元(token)。

本次实验使用Python语言实现了一个简单的词法分析器。

主要包括以下几个步骤:1. 预处理:去除源代码中的空格、换行符等无意义字符,并进行必要的错误检查。

2. 正则表达式定义词法单元:利用正则表达式定义源代码可以被识别为词法单元的模式。

例如,整数可以定义为由数字组成的串,标识符可以定义为以字母或下划线开头,后面跟着任意个字母、数字或下划线的串。

3. 正则表达式匹配:利用Python的re模块,使用定义好的正则表达式对预处理后的源代码进行匹配。

如果匹配成功,则生成对应的词法单元,并存储起来。

4. 输出词法单元:将生成的词法单元按照一定的格式输出。

实验结果:通过对不同的源代码进行测试,可以得到正确的词法单元输出。

例如,对于以下的源代码:```pythonx = 123 + 456 * (789 - 100)```经过词法分析器处理后,可以得到以下的词法单元输出:```Token(ID, 'x')Token(ASSIGN, '=')Token(INT, '123')Token(PLUS, '+')Token(INT, '456')Token(LPAREN, '(')Token(INT, '789')Token(MINUS, '-')Token(INT, '100')Token(RPAREN, ')')```总结与收获:通过本次实验,我对词法分析器的基本原理和实现方法有了更深入的了解。

同时,我学会了如何使用正则表达式进行模式匹配,以及如何使用Python的re模块进行正则表达式匹配。

这对于我进一步学习和理解编译原理以及编译器的工作原理有很大帮助。

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

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

编译原理词法分析器实验报告1. 引言编译原理是计算机科学中的重要概念,它涉及将高级语言程序转换为计算机可执行的低级指令。

词法分析是编译过程中的第一个阶段,它负责将源代码分解为词法单元,为后续的语法分析做准备。

本实验旨在设计和实现一个基本的词法分析器,以了解词法分析的原理和实际应用。

2. 实验目标本实验的主要目标是实现一个基本的词法分析器,能够识别并提取源代码中的各种词法单元。

具体而言,我们将设计一个针对某种编程语言的词法分析器,能够识别关键字、标识符、算术运算符、括号、常量等。

3. 实验环境为了完成本实验,我们需要使用以下工具和环境:•一种编程语言,例如Python、Java或C++•一个文本编辑器,例如Visual Studio Code或Sublime Text•一个命令行终端4. 实验步骤4.1 定义词法规则首先,我们需要定义词法分析器的词法规则。

这些规则描述了编程语言中各种词法单元的模式。

例如,关键字可以被定义为由特定字符组成的字符串,标识符可以被定义为以字母开头并由字母和数字组成的字符串。

4.2 实现词法分析器接下来,我们将根据定义的词法规则,使用编程语言实现一个词法分析器。

在实现过程中,我们可以使用正则表达式来匹配和提取各种词法单元。

4.3 编写测试用例完成词法分析器的实现后,我们需要编写一些测试用例来验证其正确性。

测试用例应该包含各种可能的输入情况,以确保词法分析器能够正确地识别和提取词法单元。

4.4 运行测试用例最后,我们将使用编写的测试用例来运行词法分析器,并检查输出是否符合预期。

如果测试通过,说明词法分析器能够正常工作;否则,我们需要检查代码并进行调试。

5. 实验结果经过实验,我们成功地设计并实现了一个基本的词法分析器。

该词法分析器能够按照预定义的词法规则,正确地识别和提取源代码中的各种词法单元。

在运行测试用例时,词法分析器能够产生符合预期的输出,表明其具有良好的准确性和可靠性。

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

编译原理词法分析器实验报告
}
entity[count-1].idname=yytext;
fprintf(fpout,"%d [line:%d]: \"%s\" %s \n",count,linenum,entity[count-1].idname,entity[count-1].idproperty);
}
fclose(fpout);
char*idproperty; //token属性值;
char*idname; //识别的token名字;
}entity[maxnum]; //定义1000个这样的token,大小可改变;
char filename[maxname]; //源程序文件名;
int errnum=0; //错误token的数目;
case 2:entity[count-1].idproperty="number";break;
case 3:entity[count-1].idproperty="arithmetic-op";break;
case 4:entity[count-1].idproperty="relation-op";break;
3.识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表;
4.对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析
3.规则
•语句类型:
–赋值语句,if...then..., while...do..., read, write, call,复合语句begin... end,说明语句:const..., var..., procedure…

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

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

编译原理实验词法分析实验报告一、实验目的词法分析是编译过程中的第一个阶段,其主要任务是从输入的源程序中识别出具有独立意义的单词符号,并将其转换为内部编码形式。

本次实验的目的是通过设计和实现一个简单的词法分析程序,深入理解词法分析的基本原理和方法,提高对编程语言语法结构的认识和编程能力。

二、实验原理词法分析的基本原理是根据编程语言的词法规则,使用有限自动机或正则表达式等技术来识别单词符号。

在本次实验中,我们采用了状态转换图的方法来设计词法分析器。

状态转换图是一种用于描述有限自动机的图形表示方法,它由状态节点和有向边组成。

每个状态节点表示自动机的一个状态,有向边表示状态之间的转换条件。

当输入字符与当前状态的转换条件匹配时,自动机将从当前状态转换到下一个状态。

当到达一个终态时,表示识别出了一个单词符号。

三、实验环境本次实验使用了 Python 编程语言,并在 PyCharm 集成开发环境中进行开发和调试。

四、实验内容1、定义单词符号的种类和编码关键字:如`if`、`else`、`while` 等标识符:由字母、数字和下划线组成,且以字母或下划线开头常数:包括整数和浮点数运算符:如`+`、``、``、`/`等分隔符:如`(){},;`等2、设计状态转换图根据单词符号的定义,设计了相应的状态转换图,用于识别不同类型的单词符号。

例如,对于标识符的识别,从起始状态开始,当输入字符为字母或下划线时,进入标识符状态,继续输入字母、数字或下划线,直到遇到非标识符字符为止,此时到达终态,识别出一个标识符。

3、实现词法分析程序使用 Python 语言实现了基于状态转换图的词法分析程序。

程序首先读取输入的源程序文本,然后逐个字符进行处理,根据当前状态和输入字符进行状态转换,当到达终态时,输出识别出的单词符号及其编码。

4、进行测试编写了一些测试用例,包括包含各种单词符号的源程序代码。

运行词法分析程序对测试用例进行分析,检查输出结果是否正确。

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

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

编译原理_词法分析器实验报告一.实验题目和要求。

题目:设计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置为空白字符。

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

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

编译原理实验报告姓名:关海超学号: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).这些代码应该再标记"%{"和"%}"之间;规则部分&gt;可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送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、该个词法分析器要求至少能够识别以下几类单词:(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)专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */;2、分析器的输入为由上述几类单词构成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变为其对应的机内符,常数使用二进制形式,标识符使用相应的标识符表指针表示。

3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。

三、实验环境实验环境为win7系统、vs2005。

四、实验内容1、词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token)或(sum或fsum,对应二进制)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数;fsum为浮点型常数。

2、各种单词符号种别码如下表:单词符号种别码单词符号种别码1 > 19if 2 >= 20int 3 = 21return 4 == 22void 5 != 23while 6 ;24lettet(letter|digit)* 10 ,25 整型常量11 ( 26浮点常量12 ) 27 + 13 [ 28—14 ] 29* 15 { 30/ 16 } 31< 17 /* 32<= 18 */ 33五、主要函数说明1、程序全局变量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"};//关键字数组2、语法分析函数void scaner()该函数完成所有的语法分析,对于输入的程序片段,首先去掉空格和换行,然后逐字符分析,找出各个单词(存入token[8]),判别它们的类型(确定syn 值,如果是整数则是sum值,如果是浮点数则是fsum)。

编译原理实验报告(词法分析器-语法分析器)

编译原理实验报告(词法分析器-语法分析器)
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);
}
j=0;
get();
}}
六:实验结果:
实验二
一、实验名称:语法分析器的设计
二、实验目的:
用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。
三、 实验原理:
1、算术表达式语法分析程序的算法思想
首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。在分析的过程中,通过左右优先函数比较当前读入终结符和前一个读入终结符间的优先关系,分析后适时的以四元式形式输出相关的符号。








实验一
一、实验名称:词法分析器的设计
二、实验目的:1,词法分析器能够识别简单语言的单词符号
2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。
三、实验要求:给出一个简单语言单词符号的种别编码词法分析器
四、实验原理:
1、词法分析程序的算法思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
i=1;
j=0;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《词法分析器的构造》实验报告一、实验名称词法分析器的构造二、实验目的设计、编制、调试一个词法分析程序,对单词进行识别和编码,加深对词法分析原理的理解。

三、实验内容和要求编写一个C语言词法分析器,要求:1、允许用户自己输入源程序并保存为文件2、系统能够输出经过预处理后的源程序(去掉注释、换行、空格等)3、能够将该源程序中所有的单词根据其所属类型(整数、保留字、运算符、标识符等。

定义的类C语言中的标识符只能以字母或下划线开头)进行归类显示,例如:识别保留字:if、int、for、while、do、return、break、continue等,其他的都识别为标识符;常数为无符号整形数;运算符包括:+、-、*、/、=、>、<、>=、<=、!=等;分隔符包括:,、;、{、}、(、)等。

4、实现文件的读取操作,而不是将文本以字符串形式预存于程序中。

文本内容为待分析的类C语言程序。

例如下面为一段C语言源程序:main(){int a,b;a = 10;b = a + 20;}要求输出如下(2,’main’)(5,’(’)(5,’)’)(5,’{ ’)(1,’int’)(2,’a’)(5,’,’)(2,’b’)(5,’;’)(2,’a’)(4,’=’)(3,’10’)(5,’;’)(2,’b’)(4,’=’)(2,’a’)(4,’+’)(3,’20’)(5,’;’)(5,’}’)四、主要仪器设备硬件:微型计算机。

软件: Visual C++ 6.0(也可以是其它集成开发环境)。

五、实验过程描述1、状态转换图2、程序主要框架程序中编写了以下函数,各个函数实现的作用如下:int alpha(int st)://识别保留字和标识符int number(int st) //识别常数int anotation(int st) //处理除号/和注释//int other(int st) //识别运算符、分隔符、特殊字符int choice1(int st)//读入的字符是字母返回1int choice2(int st)//读入的字符是数字返回1int choice(int st) //根据读入的单词的第一个字符确定调用不同函数识别单词3、编写的源程序#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>using namespace std;stringkeywords[21]={"include","void","main","int","char","float","double","if","else","then","break","continue","for","d o","while","printf","scanf","begin","end","return","define"};char rz[99999]=" ";//源程序char pz[9999] ="";//预处理后的源程序string id[10000];//存储标识符int pp=0;//标识符序号string nu[10000];//存储常数int qq=0;//常数序号int choice1(char a) //判断是否是字母{if((a>='a'&&a<='z')||(a>='A'&&a<='Z'))return 1;else return 0;}int choice2(char a) //判断是否是数字{if(a>='0'&&a<='9')return 1;else return 0;}int alpha(int st) //识别保留字(1)和标识符(2){char wordbuf[20]=" ";for( ; ; ){wordbuf[n]=rz[st];st++;n++;if((choice2(rz[st])==1)||(choice1(rz[st])==1)||(rz[st]=='_'))//语法标识符=<标识符><字母>|<标识符><数字>|<标识符><特殊符号>wordbuf[n]=rz[st];else break;}int flag=0;for(int k=0;k<21;k++){if(strcmp(keywords[k].c_str(),wordbuf)==0) flag=1;//是保留字}if(flag==1) printf(" (%s,1) ",wordbuf);else{int flagg=-1;for(int t=0;t<pp;t++){if(strcmp(id[t].c_str(),wordbuf)==0)//已经出现过的标识符{flagg=t;}}if(flagg==-1) {//新的标识符记录到id[]中id[pp]=wordbuf;pp++;}printf(" (%s,2) ",wordbuf);}return st;}int number(int st) //识别常数{char numbuf[20]=" ";int n=0;int k=0;int flag=0;for( ; ; ){numbuf[n]=rz[st];n++;if(choice2(rz[st])==1){numbuf[n]=rz[st];}else if((k==0)&&(rz[st]=='.')){numbuf[n]=rz[st];k++;}else if(choice1(rz[st])==1){numbuf[n]=rz[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) //新的的常数{nu[qq]=numbuf;qq++;}printf(" (%s,3) ",numbuf);}else{printf(" (");for(int i=0;i<n;i++) printf("%s",numbuf[i]);printf(",error digital!) ");}return st;}int anotation(int st) //处理除号/和注释{char tabuf[9999]=" ";int n=0;st++;if(rz[st]=='/'){printf(" (//,-) ");st++;while(rz[st]!=10){tabuf[n]=rz[st];st++;n++;}printf(" 注释");for(int i=0;i<n;i++)printf("%c",tabuf[i]);}else if(rz[st]=='*'){printf(" (/*,-) ");st++;int stt=st+1;while(1){if(rz[st]=='*'&&rz[st+1]=='/') break;tabuf[n]=rz[st];st++;n++;if(rz[st+1]=='\0'){printf("(/* error!!\n)");return st+1;}} printf(" 注释");for(int i=0;i<n;i++)printf("%c",tabuf[i]);printf(" (*/,-) ");st=st+2;}else if(rz[st]=='='){st++;printf(" (/=,4) ");}else printf(" (/,4) ");return st;}int other(int st) //识别运算符(4)、分隔符(5)、特殊字符(-){switch(rz[st]){//运算符:=,+,+=,-,-=,*,*=,/,/=,>,>=,<,<=,%,%=,!,!=,&,&&,||case '=': st++;if(rz[st]=='='){st++;printf(" (==,4) ");}else printf(" (=,4) ");break;case '+': st++;if(rz[st]=='='){st++;printf(" (+=,4) ");}else if(rz[st]=='+'){st++;printf(" (++,4) ");}else printf(" (+,4) ");break;case '-': st++;if(rz[st]=='='){st++;printf(" (-=,4) ");}else if(rz[st]=='-'){st++;printf(" (--,4) ");}else printf(" (-,4) ");break;case '*': st++;if(rz[st]=='='){st++;printf(" (*=,4) ");}else printf(" (*,4) ");break;case '>': st++;if(rz[st]=='='){st++;printf(" (>=,4) ");}else printf(" (>,4) ");break;case '<': st++;if(rz[st]=='='){st++;printf(" (<=,4) ");}else printf(" (<,4) ");break;case '%': st++;if(rz[st]=='='){st++;printf(" (\%=,4) ");}else printf(" (\%,4) ");break;case '!': st++;if(rz[st]=='='){st++;printf(" (!=,4) ");}else printf(" (!,wrong thing!) ");break;case '&': st++;if(rz[st]=='&'){st++;printf(" (&&,4) ");}else printf(" (&,4) ");break;case '|': st++;if(rz[st]=='|'){st++;printf(" (||,4) ");}else printf(" (|,worng word!) ");break;//分隔符:{},(),[],,,;,:,",',空格,回车,TAB case '{': st++;printf(" ({,5) ");break;case '}': st++;printf(" (},5) ");break;case '(': st++;printf(" ((,5) ");break;case ')': st++;printf(" (),5) ");break;case '[': st++;printf(" ([,5) ");break;case ']': st++;printf(" (],5) ");break;case ':': st++;printf(" (:,5) ");break;case ';': st++;printf(" (;,5) ");break;case ',': st++;printf(" (,,5) ");break;case 34: st++;printf(" (\",5) ");break;case 39: st++;printf(" (',5) ");break;case ' ': st++;break;case ' ': st++;break;case 10: st++;printf("\n");//特殊字符:#,@,$等break;case '#': st++;printf(" (#,-) ");break;case '@': st++;printf(" (@,-) ");break;default: printf(" (%c,worng word!) ",rz[st]);st++;}return st;}int choice(int st) //根据读入的单词的第一个字符确定调用不同的单词识别函数{if(choice1(rz[st])==1)//字母开头,判断是保留字或标识符?st=alpha(st);else if(choice2(rz[st])==1)//数字开头,判断是否为常数st=number(st);else if(rz[st]=='/')//判断是/或//st=anotation(st);else st=other(st);//判断运算符、分隔符、特殊字符return st;}//主菜单void menu(){cout<<endl;cout<<" - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - "<<endl;cout<<" | ***************** 0.源程序输入****************** |\n";cout<<" | ***************** 1.预处理输出****************** |\n";cout<<" | ***************** 2.词法分析****************** |\n";cout<<" | ***************** 3.查看标识符****************** |\n";cout<<" | ***************** 4.查看常数****************** |\n";cout<<" | ***************** 5.退出****************** |\n";cout<<" - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - "<<endl;cout<<" 请选择要进行的操作: ";}int main(){cout<<" - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - "<<endl;cout<<" | "<<" 欢迎使用C语言词法分析器|"<<endl;cout<<" | "<<"程序媛:Q12010102 刘倩君。

相关文档
最新文档