编译原理实验报告2词法分析程序的设计
编译原理词法分析实验报告

编译原理词法分析实验报告实验名称:词法分析器的设计与实现一、实验目的: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。
三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。
在本次实验中,我们使用有限自动机的理论来设计词法分析器。
首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。
然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。
在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。
(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。
在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。
首先,我们根据给定的语法规则,编写了相应的递归函数。
每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。
在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。
(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。
在本次实验中,我们使用了四元式作为中间代码的表示形式。
在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。
同时,根据语法树的结构,生成相应的四元式中间代码。
(四)代码优化代码优化的目的是提高生成代码的质量和效率。
在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。
通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。
编译原理词法分析实验报告

编译原理词法分析实验报告词法分析实习报告实习题目设计一个表达式的文法①表达式中的运算按运算符优先级由高到低依次有:+、-、*、/、↑其中+、-是左结合,*、/、↑右结合。
②表达式中的运算对象可以为标识符、无正负号常量。
设计的文法G[<表达式>]=(VN,VT,P,<表达式>)其中,VN={<表达式>,<无正负号常量>,<标志符>,<数字>,<字母>} VT={ a…z,A…Z,0…9}P={<表达式>→DE↑<表达式>∣DE;DE→ME/DE∣ME;ME→SE*ME∣SE;SE→SE-AE∣AE;AE→AE +<表达式>∣<表达式>∣<标识符>∣<无正负号常量>;〈标识符〉→〈字母〉|〈标识符〉〈字母〉|〈标识符〉〈数字〉;〈无正负号常量〉→〈数字〉|〈无正负号常量〉〈数字〉;〈字母〉→a|b|…|x|y|z|A|B|…|X|Y|Z;〈数字〉→1│2│3│4│5│6│7│8│9│0}词法分析程序设计思路词法分析就是逐个读入源程序字符并按照构词规则切分成一系列单词.单词是语言中具有独立意义的最小单位,根据设计的文法可以判断出表达式中的单词种类有标识符,运算符,常量。
字母或数字识别各类单词符号的状态转换图所用数据结构FILE *fp;//用于存放原表达式文件FILE *outp;//用于存放单词输出结果char ch;//用于存储当前读取的字符char *operatornum[5]={"+","-","*","/","|"};//用于存放运算符源码#include#include#include#include#include#include#includeFILE *fp;//用于存放原表达式文件FILE *outp;//用于存放单词输出结果char ch;//用于存储当前读取的字符char *operatornum[5]={"+","-","*","/","|"};//用于存放运算符/////////////////////////////////////////////////////////////////// /////////////////////// bool search(char searchstr[])//匹配运算符{int i;for(i=0;i<=4;i++)if(strcmp(operatornum[i],searchstr)==0)return(true);return(false);}/////////////////////////////////////////////////////////////////// //////////////////////// char letterprocess (char ch)//字母处理函数{int i=-1;char letter[20];while (isalnum(ch)!=0){letter[++i]=ch;ch=fgetc(fp);}letter[i+1]='\0';printf("<标示符,%s>\n",letter);fputs("<标示符,",outp);fputs(">\n",outp);return(ch);}/////////////////////////////////////////////////////////////////// //////////////////////// char numberprocess(char ch)//数字处理程序{int i=-1;char num[20];while (isdigit(ch)!=0)//如果为数字{num[++i]=ch;ch=fgetc(fp);}if(isalpha(ch)!=0)//如果为字母{while(isspace(ch)==0)//如果为空格{num[++i]=ch;ch=fgetc(fp);}num[i+1]='\0';printf("错误!非法标识符:%s\n",num);return(ch);}num[i+1]='\0';printf("<常数,%s>\n",num);fputs("<常数,",outp);fputs(num,outp);return(ch);}/////////////////////////////////////////////////////////////////// /////////////////////////// char otherprocess(char ch)//其它符号(运算符和非法字符)的处理{int i=-1;char other[20];if (isspace(ch)!=0){ch=fgetc(fp);return(ch);}while ((isspace(ch)==0)&&(isalnum(ch)==0)){other[++i]=ch;ch=fgetc(fp);}other[i+1]='\0';if (search(other)){ printf("<运算符,%s>\n",other);fputs("<运算符,",outp);fputs(other,outp);fputs(">\n",outp);}elseprintf("错误!非法字符:%s\n",other);return (ch);}/////////////////////////////////////////////////////////////////////////////////////////////int main (){char str,c;printf("**********************************词法分析器************************************\n");outp=fopen("二元式表.txt","w");if ((fp=fopen("源程序.txt","r"))==NULL)printf("源程序无法打开!\n");else{str =fgetc(fp);while (str!=EOF){if (isalpha(str)!=0)str=letterprocess(str);else{if (isdigit(str)!=0)str=numberprocess(str);elsestr=otherprocess(str);}};printf("词法分析结束,谢谢使用!\n");printf("点任意键退出!\n");}c=getch();}输入从存放源文件的目录下的源程序.txt 中读取表达式输出从将结果存放到源文件的目录下的二元式表.txt 中问题分析词法分析相对而言较为简单,词法分析的目的就是识别出一个个的单词符号,为进一步进行语法分析打下坚实的基础。
编译原理词法分析实验报告

编译原理词法分析实验报告一,题目编制C语言子集的词法分析程序二,实验目的通过设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
三,实验要求1.根据具体情况,由同学们自己选取C语言的一个适当大小的子集(可取一类典型单词,也可以尽可能使各种类型的单词都兼顾到),如课本表2.1;在上机前一定要制出相应的表。
2.程序功能输入:字符串。
输出:二元式(种别编码,单词自身)构成的序列。
举例:输入:a=$;#输出:(6,a)(12,=)FOUND ERROR(13,;)四,步骤1.定义单词表2.完善词法分析器程序(1)定义变量、函数(2)增加程序的输入、输出3.程序验证词法分析程序的功能输入:所给文法的源程序字符串。
输出:二元组(syn,token)构成的序列。
其中:typenum为单词种别码;token为单词缓冲区;五,源程序代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#define _KEY_WORD_END "waiting fou your expanding"/*定义关键字的结束标志*/ typedef struct{int typenum; /*种别码*/char *word;}WORD;char input[255]; /*源程序缓字符冲区*/char token[255]=""; /*单词缓冲区*/int p_input; /*源程序字符指针*/int p_token; /*单词缓冲区指针*/char ch;char *rwtab[]={"begin","if","then","while","do","end",_KEY_WORD_END}; WORD *scaner(); /*词法扫描函数,获得一个单词*/void main(){int over=1;int count=0;WORD *oneword = new WORD;printf("Enter Your words(end with #):");scanf("%[^#]s",input); /*输入源程序字符串到缓冲区,以#结束*/p_input=0;printf("词法分析结果是:\n\n");while (over<1000 && over!= -1){oneword=scaner();if(oneword->word=="OVER")break;else if(oneword->typenum==-3)printf(oneword->word);else if(oneword->typenum <1000)printf("(%d,%s) ",oneword->typenum ,oneword->word );over=oneword->typenum ;count++;if(count%6==0) printf("\n");//每六行输出}}char m_getch() /*从输入源读一个字符到CH中*/{ch=input[p_input];p_input=p_input+1;return ch;}void getbc() /*去掉空白字符*/{while (ch == ' '|| ch== 10){ch = input[p_input];p_input=p_input+1;}}void concat() /*拼接单词*/{token[p_token]=ch;p_token=p_token+1;token[p_token]='\0';}int letter()/*判断是否是字母*/{if(ch>='a' && ch<='z'|| ch >='A'&& ch <='Z') return 1;else return 0;}int digit()/*判断是否是数字*/{if(ch>='0'&& ch<='9')return 1;else return 0;}int reserve()/*检索关键字表格*/{int i=0;while(strcmp(rwtab[i],_KEY_WORD_END)){if(!strcmp(rwtab[i],token)){return i+1;}i=i+1;}return 6;}void retract()/*回退一个字符*/{p_input=p_input-1;}char *dtb(){return NULL;}WORD *scaner()/*词法扫描程序*/{WORD *myword =new WORD;myword->typenum=10;myword->word=" ";p_token=0;m_getch();getbc();if(letter()){while(letter()||digit()){concat();m_getch();}retract();myword->typenum=reserve();myword->word=token;return myword;}else if(digit()){while(digit()){concat();m_getch();}retract();myword->typenum =11;myword->word =token;return myword;}else switch(ch){case'=' : m_getch();if(ch=='='){myword->typenum =11;myword->word ="==";return myword;}retract();myword->typenum =12;myword->word ="=";return myword;break;case'+':myword->typenum =8;myword->word ="+";return myword;break;case'-':myword->typenum =9;myword->word ="-";return myword;break;case'*':myword->typenum =10;myword->word ="*";return myword;break;case'/':myword->typenum =16;myword->word ="/";return myword;break;case'(':myword->typenum =27;myword->word ="(";return myword;break;case')':myword->typenum =28;myword->word =")";return myword;break;case'[':myword->typenum =30;myword->word ="[";return myword;break;case']':myword->typenum =31;myword->word ="]";return myword;break;case'{':myword->typenum =32;myword->word ="{";return myword;break;case'}':myword->typenum =33;myword->word ="}";return myword;break;case',':myword->typenum =34;myword->word =",";return myword;break;case':':if(input[p_input]=='='){myword->typenum =18;myword->word =":=";return myword;}elsemyword->typenum =17;myword->word =":";return myword;break;case';':myword->typenum =13;myword->word =";";return myword;break;case'>':m_getch();if(ch=='='){myword->typenum =24;myword->word =">=";return myword;}retract();myword->typenum =23;myword->word =">";return myword;break;case'<':m_getch();if(ch=='='){myword->typenum =11;myword->word ="<=";return myword;}retract();myword->typenum =20;myword->word ="<";return myword;break;case'!':m_getch();if(ch=='='){myword->typenum =40;myword->word ="!=";return myword;}retract();myword->typenum =-1;myword->word ="ERROR";return myword;break;case'\0':myword->typenum=100;myword->word="OVER";return myword;break;case'#':myword->typenum=-1;myword->word="FOUND ERROR";return myword;break;default:myword->typenum=-3 ;myword->word="FOUND ERROR";return myword;}}六,结果验证a)给定源程序a=s;#输出结果b)给定源程序x<=s;#输出结果。
编译原理实验报告-词法分析

词法分析实验报告一、实验目的1.编制一个词法分析程序。
2.加深对词法分析原理的理解。
二、实验要求1.待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符: = + - * / < <= <> > >= = ; ( ) .(3)其他单词是标识符(IDENT)和整型常数(NUMBER),通过以下正规式定义:IDENT = letter (letter | digit)*NUMBER = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔IDENT、NUMBER、运算符、界符和关键字,词法分析阶段通常被忽略。
2.各种单词符号对应的类别值:表各种单词符号对应的类别码3.词法分析程序的功能:输入:所给文法的源程序字符串,以“.”结束。
输出:二元组(sym,token或number)构成的序列。
其中:sym为单词种别码;token为存放的单词自身字符串;number为整型常数。
例如:对源程序begin x:=9;if x<10 then x:=(x+10)*2 end.的源文件,经过词法分析后输出如下序列:(17,begin)(1,x)(16,:=)(2,9)(15,;)……4.词法分析程序的设计词法分析采用状态转换图方法:三、实验设计方法从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
主程序示意图:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:图3-11.主要技术难点a)设计各种单词符号对应的符号表b)实现输入字符数字和单词符号及其对应单词种别码的正确输出。
《编译原理(实验部分)》实验2_PL0词法分析

《编译原理》(实验部分)实验2_PL0 词法分析一、实验目的加深和巩固对于词法分析的了解和掌握;初步认识PL/0 语言的基础和简单的程序编写;通过本实验能够初步的了解和掌握程序词法分析的整个过程;提高自己上机和编程过程中处理具体问题的能力。
二、实验设备1、P C兼容机一台;操作系统为WindowsWindowsX P2、Visual C++ 6.0 或以上版本,Windows 2000 或以上版本,汇编工具 (在Software 子目录下)。
三、实验原理PL/O语言的编译程序,是用高级语言PASCAL语言书写的。
整个编译过程是由一些嵌套及并列的过程或函数完成。
词法分析程序是独立的过程GETSY完成,供语法分析读单词时使用。
四、实验步骤阅读所给出的词法分析程序( pl0_lexical.c ),搞懂程序中每一个变量的含义,以及每一个过程的作用,并在该过程中进行中文注释;阅读完程序后,画出各过程的流程图;给出的程序包含两处输入错误,利用所给的pl/0 源程序(test.pl0) 对程序进行调试,使其能正确对所给文件进行分析并能够解释运行;在阅读懂所给出的词法分析程序后,将你对词法分析的理解写在实验报告上。
实验代码#include<stdio.h>main(){ printf ("my name is 08061118 yuchaofeng ");}主程序:#include <stdio.h>#include <ctype.h>#include <alloc.h>#include <stdlib.h>#include <string.h>#define NULL 0FILE *fp;char cbuffer;char *key[8]={"DO","BEGIN","ELSE","END","IF","THEN","VAR","WHILE"}; char *border[6]={",",";",":=",".","(",")"};char *arithmetic[4]={"+","-","*","/"};char *relation[6]={"<","<=","=",">",">=","<>"};char *consts[20];char *label[20];int constnum=0,labelnum=0;int search(char searchchar[],int wordtype){int i=0;switch (wordtype) {case 1:for (i=0;i<=7;i++){if (strcmp(key[i],searchchar)==0)return(i+1);};case 2:{for (i=0;i<=5;i++){if (strcmp(border[i],searchchar)==0)return(i+1);};return(0);}case 3:{for (i=0;i<=3;i++){ if (strcmp(arithmetic[i],searchchar)==0){};};return(0);};case 4:{for (i=0;i<=5;i++){ if (strcmp(relation[i],searchchar)==0){return(i+1);};};return(0);};case 5:{for (i=0;i<=constnum;i++){ if (strcmp(consts[i],searchchar)==0){return(i+1);};}consts[i-1]=(char *)malloc(sizeof(searchchar));strcpy(consts[i-1],searchchar);constnum++;return(i);};case 6:{for (i=0;i<=labelnum;i++){ if (strcmp(label[i],searchchar)==0){ return(i+1);};}label[i-1]=(char *)malloc(sizeof(searchchar)); strcpy(label[i-1],searchchar);return(i);};}}char alphaprocess(char buffer){int atype;int i=-1;char alphatp[20];while ((isalpha(buffer))||(isdigit(buffer))){ alphatp[++i]=buffer; buffer=fgetc(fp);}; alphatp[i+1]='\0';if (atype=search(alphatp,1)) printf("%s (1,%d)\n",alphatp,atype-1); else { atype=search(alphatp,6);printf("%s (6,%d)\n",alphatp,atype-1); };return(buffer);char digitprocess(char buffer){int i=-1;char digittp[20];int dtype;while ((isdigit(buffer))){ digittp[++i]=buffer;buffer=fgetc(fp);}digittp[i+1]='\0';dtype=search(digittp,5);printf("%s (5,%d)\n",digittp,dtype-1); return(buffer);}char otherprocess(char buffer){int i=-1;char othertp[20];int otype,otypetp;othertp[0]=buffer;othertp[1]='\0';if (otype=search(othertp,3)){printf("%s (3,%d)\n",othertp,otype-1);buffer=fgetc(fp);goto out;};if (otype=search(othertp,4)){buffer=fgetc(fp);othertp[1]=buffer;othertp[2]='\0';if (otypetp=search(othertp,4)){printf("%s (4,%d)\n",othertp,otypetp-1); goto out;}elseothertp[1]='\0';printf("%s (4,%d)\n",othertp,otype-1);goto out;};if (buffer==':'){ buffer=fgetc(fp);if (buffer=='=')printf(":= (2,2)\n");buffer=fgetc(fp);goto out;}else{if (otype=search(othertp,2)){ printf("%s (2,%d)\n",othertp,otype-1); buffer=fgetc(fp); goto out;}};if ((buffer!='\n')&&(buffer!=' '))printf("%c error,not a word\n",buffer); buffer=fgetc(fp);out: return(buffer);} void main(){ int i;for (i=0;i<=20;i++){label[i]=NULL; consts[i]=NULL;};if ((fp=fopen("skh.c","r"))==NULL) printf("error");else{ cbuffer = fgetc(fp);while (cbuffer!=EOF){if (isalpha(cbuffer)) cbuffer=alphaprocess(cbuffer);else if (isdigit(cbuffer))cbuffer=digitprocess(cbuffer); else cbuffer=otherprocess(cbuffer); };printf("over\n");};}。
编译原理实验词法分析实验报告

编译原理实验词法分析实验报告一、实验目的词法分析是编译过程的第一个阶段,其主要任务是从左到右逐个字符地对源程序进行扫描,产生一个个单词符号。
本次实验的目的在于通过实践,深入理解词法分析的原理和方法,掌握如何使用程序设计语言实现词法分析器,提高对编译原理的综合应用能力。
二、实验环境本次实验使用的编程语言为_____,开发工具为_____。
三、实验原理词法分析的基本原理是根据编程语言的词法规则,将输入的字符流转换为单词符号序列。
单词符号通常包括关键字、标识符、常量、运算符和界符等。
词法分析器的实现方法有多种,常见的有状态转换图法和正则表达式法。
在本次实验中,我们采用了状态转换图法。
状态转换图是一种有向图,其中节点表示状态,有向边表示在当前状态下输入字符的可能转移。
通过定义不同的状态和转移规则,可以实现对各种单词符号的识别。
四、实验步骤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.设计词法规则根据编程语言的规范和所需实现的功能,设计词法规则,以明确规定如何将源程序代码分解为一系列的词法单元。
2.实现词法分析器采用合适的编程语言,根据所设计的词法规则,实现词法分析器。
词法分析器的主要任务是读入源程序代码,并将其根据词法规则进行分解,生成对应的词法单元。
3.测试词法分析器设计测试用例,用于检验词法分析器的正确性和性能。
测试用例应包含各种情况下的源程序代码。
4.分析和修正错误根据测试过程中发现的问题,分析产生错误的原因,并进行修正。
重复测试和修正的过程,直到词法分析器能够正确处理所有测试用例。
三、实验结果我们设计了一个简单的词法分析器,并进行了测试。
测试用例涵盖了各种情况下的源程序代码,包括正确的代码和错误的代码。
经过测试,词法分析器能够正确处理所有的测试用例。
词法分析器将源程序代码分解为一系列的词法单元,每个词法单元包含了单词的种类和对应的值。
通过对词法单元的分析,可以进一步进行语法分析和语义分析,从而完成编译过程。
四、实验总结通过本次实验,我深入了解了编译原理的词法分析阶段。
词法分析是编译器的第一个重要阶段,它将源程序代码分解为一个个的词法单元,为后续的语法分析和语义分析提供基础。
在实现词法分析器的过程中,我学会了如何根据词法规则设计词法分析器的算法,并使用编程语言实现词法分析器。
通过测试和修正,我掌握了调试和错误修复的技巧。
本次实验的经验对我今后的编程工作有很大帮助。
编译原理是计算机科学与技术专业的核心课程之一,通过实践能够更好地理解和掌握其中的概念和技术。
我相信通过进一步的学习和实践,我能够在编译原理领域取得更大的成果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*
运算符和界符+ - * / > < = ( );
关键字if then else while do
SearchOp():整型函数,对ch查找运算符和界符,若它是一个运算符或界符,则返回它的编码,否则返回0。
Retract():子函数,将搜索指示器回调一个字符位置,将ch置为空白字符。
ProError():错误处理函数。
关键字保存在字符数组中,定义编码为相对数组首地址的位置+ 1。保留子表顺序如下:{if,then,else,while,do} ,则相应编码为:1,2,3,4,5。
2、根据状态图,设计词法分析函数int scan( ),完成以下功能:
1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,
2)以二元式形式输出单词<单词种类,单词属性>
其中单词种类用整数表示:
0:标识符
1:十进制整数
2:八进制整数
3:十六进制整数
运算符和界符,关键字采用一字一符,不编码
其中单词属性表示如下:
}while(ch ==' '|| ch =='\t'|| ch =='\n');
returnch;
}
voidConcat(charch,charstrToken[]) {//将ch中的字符连接到strToken之后
charstr[2];
str[0] =ch;
str[1] ='\0';
strcat(strToken,str);
intflag = 0;
if(ch>='0'&&ch<='9')
GetBC():子函数,检查ch中的字符是否为空白。若是,则调用GetChar()直至ch中进入一个非空白字符。
Concat():子函数,将ch中的字符连接到strToken之后。
IsLetter():布尔函数,判断ch中的字符是否为字母。
IsDigit():布尔函数,判断ch中的字符是否为数字。
Reserve():整型函数,对strToken中的字符串查找保留字表,若它是一个保留字则返回它的编码,否则返回0。
3、采用C或C++语言,设计函数scan( ),实现该算法;
charGetChar(FILE*fp) {//读取文件中的一个字符
charch;
ch = fgetc(fp);
returnch;
}
charGetBC(FILE*fp) {//读取文件的字符直至ch不是空白
charch;
do{
ch = GetChar(fp);
while(ch >=‘0’&& ch <=‘7’)
{ Concat();GetChar(); }
Retract();
printf("<,2,%s >", strToken) ;
}
else if(ch==’x’) {
GetChar();
while(IsDigit() || ch>=‘a’&& ch<=’f’)
2、根据状态图,设计词法分析算法;
观察状态图,其中状态2、4、7、10(右上角打了星号)需要回调一个字符。
声明一些变量和函数:
ch:字符变量,存放最新读进的源程序字符。
strToken:字符串变量,存放构成单词符号的字符串。
GetChar():子函数,将下一输入字符读到ch中,搜索指示器前移一字符位置。
实验2词法分析程序的设计
一、实验目的
掌握计算机语言的词法分析程序的开发方法。
二、实验内容
编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求
1、根据以下的正规式,编制正规文法,画出状态图;
标识符<字母>(<字母>|<数字字符>)*
十进制整数0 |((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)
GetBC();
if(IsLetter()) {
while(IsLetter() || IsDigit())
{ Concat();GetChar(); }
Retract();
If(Reserve())printf("<%s , ->", strToken);
elseprintf("<,0,%s >", strToken);
标识符,整数由于采用一类一符,属性用单词表示
运算符和界符,关键字采用一字一符,属性为空
3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。
四、实验环境
PC微机
DOS操作系统或Windows操作系统
Turbo C程序集成环境或Visual C++程序集成环境
五、实验步骤
1、根据正规式,画出状态转换图;
{ Concat();GetChar(); }
Retract();
printf("<,3,%s >", strToken);
}
else {
Retract();
printf(“<1,0>“) ;
}
}
else if(SearchOp()) printf("<%c,->",ch);
else ProError();
}
else if(‘1’< =ch && ch <=’9’) {
while(IsDigit())
{ Concat();GetChar(); }
Retract();
printf("<,1,%s >", strToken) ;
}
else if(ch==’0’) {
GetChar();
if(ch >=‘1’&& ch <=‘7’) {
}
intIsLetter(charch) {//布尔函数,判断ch中的字符是否为字母,是返回1,否则返回0
intflag = 0;
if(ch>='a'&&ch<='z')
flag = 1;
returnflag;
}
intIsDigit(charch) {//布尔函数,判断ch中的字符是否为数字,是返回1,否则返回0
运算符和界符保存在字符数组中,编码定义与关键字相同,顺序如下:{+,-,*,/,>,<,=,(,),;},编码为:1~10。
二元表
单词
单词种类
属性
标识符
0
单词自身
十进制整数
1
单词自身
八进制整数
2
单词自身
十六进制整数
3
单词自身
运算符和界符
单词自身
-
关键字
单词自身
-
算法如下:
ch=’‘;strToken=””;