编译原理实验一

合集下载

编译原理实验报告:实验一编写词法分析程序.

编译原理实验报告:实验一编写词法分析程序.

编译原理实验报告实验名称:实验一编写词法分析程序实验类型:验证型实验指导教师:何中胜专业班级:13软件四姓名:丁越学号:13030504电子邮箱:862245792@实验地点:秋白楼B720实验成绩:日期:2016年3 月18 日一、实验目的通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。

掌握文法转换成自动机的技术及有穷自动机实现的方法。

确定词法分析器的输出形式及标识符与关键字的区分方法。

加深对课堂教学的理解;提高词法分析方法的实践能力。

通过本实验,应达到以下目标:1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。

2、掌握词法分析的实现方法。

3、上机调试编出的词法分析程序。

二、实验过程以编写PASCAL子集的词法分析程序为例1.理论部分(1)主程序设计考虑主程序的说明部分为各种表格和变量安排空间。

数组 k为关键字表,每个数组元素存放一个关键字。

采用定长的方式,较短的关键字后面补空格。

P数组存放分界符。

为了简单起见,分界符、算术运算符和关系运算符都放在 p表中(编程时,还应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。

id和ci数组分别存放标识符和常数。

instring数组为输入源程序的单词缓存。

outtoken记录为输出内部表示缓存。

还有一些为造表填表设置的变量。

主程序开始后,先以人工方式输入关键字,造 k表;再输入分界符等造p表。

主程序的工作部分设计成便于调试的循环结构。

每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。

⑵词法分析过程考虑将词法分析程序设计成独立一遍扫描源程序的结构。

其流程图见图1-1。

图1-1该过程取名为 lexical,它根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,产生类号:以字符 k表示关键字;i表示标识符;c表示常数;p表示分界符;s表示运算符(编程时类号分别为 1,2,3,4,5)。

编译原理实验一

编译原理实验一

实验内容:实现标准C语言词法分析器实验目的:1.掌握程序设计语言词法分析的设计方法;2.掌握DFA的设计与使用方法;3.掌握正规式到有限自动机的构造方法;实验要求:1.单词种别编码要求基本字(关键字)、运算符、界符:一符一种;标识符(变量名):统一为一种;常量():按类型编码;2.词法分析工作过程中建立符号表、常量表,并以文本文件形式输出;3.词法分析的最后结果以文本文件形式输出;4.完成对所设计词法分析器的功能测试,并给出测试数据和实验结果;5.为增加程序可读性,请在程序中进行适当注释说明;6.整理上机步骤,总结经验和体会;7.认真完成并按时提交实验报告。

二、设计方案:这个词法分析器分析的主要关键字有:main, int, float, char, if, else, for, while, do, switch, case, break; default……。

选择要分析的c文件,首先对其去掉注释和与空格处理,再根据字符的不同类型分析。

1、全局数据结构:*key[ ]:关键字表全局文件指针*fr,*fw, *temp1,*temp2用于文件的读写。

2、以层次图模块的组成及调用关系3、主要函数的设计要求(功能、参数、返回值):isKey:判断ch中的字符是否为关键字;isLer 和isNum:布尔函数过程,分别判断ch中的字符是否为字母和数字;isBoudany():布尔函数过程,分别判断ch组成的字符否为边界符号;check:词法分析;clock:时间函数,计算程序运行所需的时间main:主函数。

4、状态转换图:字符a包括:= , & , | , + , --字符b包括:-- , < , > , | , *字符c包括:, , : , ( , ) , { , } , [ , ] , ! ,# , % , ” , / , * , + , -- , > , <, .# include<stdio.h># include <string.h># include <stdlib.h># include <time.h># include <ctype.h>FILE *fr,*fw,*temp1,*temp2;char *key0[]={"main","printf","scanf","else","if","auto","double", "int","struct","break","long","switch","case","enum","register","typedef", "char","extern","return","union","const","float","short","unsigned","continue","for", "signed","void","default","goto","sizeof","volatile","do","while","static"};/*关键字表*/char *key1[]={"\"","\\","(",")","[","]","{","}",",",";","'"};/*边界符表*/int isLet(char c)//判断是否是字母{if(c>='a'&& c<='z'||c>='A'&&c<='Z')return 1;elsereturn 0;}int isNum(char c)//判断是否是数字{if (c>='0'&&c<='9')return 1;elsereturn 0;}int isKey(char *word){int m,i;for(i=0;i<36;i++){if((m=strcmp(word,key0[i]))==0){if(i==0)return 2;elsereturn 1;}}return 0;}int isBoudany(char c){if(c=='\\')return 2;elseif(c=='('||c==')'||c=='{'||c=='}'||c=='['||c==']'||c==','||c==';'||c=='\''||c=='\"'||c=='\"') return 1;elsereturn 0;}void check(FILE *fr){char word[30];while(!feof(fr)){memset(word,0,sizeof(word));char ch,temp;ch=fgetc(fr); //获取字符,指针fr并自动指向下一个字符int i,c;if(ch=='#')//预处理{//temp=fgetc(fr);while(ch!='>')ch=fgetc(fr);ch=fgetc(fr);fprintf(fw,"*****************************************跳过头文件和文件宏定义\n");}elseif (ch=='/')//跳过注释/**/类型{ch=fgetc(fr);if (ch=='/')//跳过注释//类型{while(ch!='\n')ch=fgetc(fr);fprintf(fw,"*********************************************************跳过注释\n");}elseif (ch=='*'){ch=fgetc(fr);temp=fgetc(fr);do{ch=fgetc(fr);temp=fgetc(fr);}while (ch!='*'||temp!='/');fprintf(fw,"******************************************************跳过注释\n");ch=fgetc(fr);}}elseif(isLet(ch)){word[0]=ch;ch=fgetc(fr);i=1;while(isNum(ch)||isLet(ch))//判断该字符是否是字母或数字{word[i]=ch;i++;ch=fgetc(fr);}word[i]='\0'; //'\0' 代表字符结束(空格)fseek(fr,-1,1);c=isKey(word); //判断是否是关键字if(c==0) //不是关键字{fprintf(temp1,"%s ",word);fprintf(fw,"字符%s是:标识符,种别编码为:%d\n",word,2);}else{if(ch!='"')//判断是否是定义的字符{if(c==2)fprintf(fw,"字符%s是:***************************************************主函数,种别编码为:%d\n",word,0);//主函数elsefprintf(fw,"字符%s是:关键字,种别编码为:%d\n",word,1);//关键字}else{fprintf(fw,"字符%s是:定义的字符常量,种别编码为:%d\n\n",word,32);}}}else//开始判断的字符不是字母if(isNum(ch)){ //判断是否是数字word[0]=ch;ch=fgetc(fr);i=1;while(isNum(ch)){word[i]=ch;i++;ch=fgetc(fr);}word[i]='\0';fseek(fr,-1,1); //回退fprintf(fw,"字符%s是:常量,种别编码为:%d\n",word,3);}else{c=isBoudany(ch);//开始判断的字符不是字母也不是数字//边界符if(c){if(c==2)//判断是否是转义字符{word[0]=ch;ch=fgetc(fr);word[1]=ch;word[2]='\0';fprintf(fw,"字符%s是:转义字符,种别编码为:%d\n",word,4);}elseif(c==1){fprintf(fw,"字符%c是:界符,种别编码为:%d\n",ch,5);fprintf(temp2,"%c ",ch);}}elseswitch(ch){case'+':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch=='='){word[2]='\0';fprintf(fw,"字符%s是:运算符,种别编码为:%d\n",word,6);//运算符"+="}elseif(ch=='+'){word[2]='\0';fprintf(fw,"字符%s是运算符,种别编码为:%d\n",word,7); //判断结果为"++"}else {fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c是运算符,种别编码为:%d\n",ch,8); //判断结果为"+"}break;case'-':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch=='='){word[2]='\0';fprintf(fw,"字符%s是:运算符,种别编码为:%d\n",word,9); }elseif(ch=='-'){word[2]='\0';fprintf(fw,"字符%s是运算符,种别编码为:%d\n",word,10); //判断结果为"--"}else {fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c是运算符,种别编码为:%d\n",ch,11); //判断结果为"-"}break;case'*':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch!='='){if(isNum(ch)){fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c:是运算符,种别编码为:%d\n",ch,12);//判断结果为"*"}else{ //判断是否是指针i=2;ch=fgetc(fr);while(isLet(ch)){word[i]=ch;ch=fgetc(fr);i++;}fprintf(fw,"字符%s:是指针定义运算符,种别编码为:%d\n",word,13);}}else{word[2]='\0';fprintf(fw,"字符%s:是运算符,种别编码为:%d\n",word,14);//判断结果为"*="}break;case'/':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch!='='){if(isNum(ch)){fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c:是运算符,种别编码为:%d\n",ch,15);//判断结果为"/"}}else {word[2]='\0';fprintf(fw,"字符%s:是运算符,,种别编码为:%d\n",word,16);//判断结果为"/="}break;case'!':case'?':case':':case'.':case'=':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch!='='){fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c:是运算符,种别编码为:%d\n",ch,17);}else {word[2]='\0';fprintf(fw,"字符%s:是运算符,种别编码为:%d\n",word,18);break;case'|':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch=='|'){word[2]='\0';fprintf(fw,"字符%c是运算符,种别编码为:%d\n",ch,19); //判断结果为运算符"||"}else {fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c是运算符,种别编码为:%d\n",ch,20); //判断结果为"|"}break;case'%':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch=='='){word[2]='\0';fprintf(fw,"字符%s是运算符,种别编码为:%d\n",word,21);}elseif(isLet(ch)){word[2]='\0';fprintf(fw,"字符%s是输出类型标识符,种别编码为:%d\n",word,22);}else{fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c是取余运算符,种别编码为:%d\n",ch,23);}break;case'&':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch=='&'){word[2]='\0';fprintf(fw,"字符%s是:运算符,种别编码为:%d\n",word,24); //判断结果为运算符"&&"}else {fseek(fr,-2,1);ch=getc(fr);fprintf(fw,"字符%c是:运算符,种别编码为:%d\n",ch,25); //判断结果为"&"}break;case'<':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch=='='){word[2]='\0';fprintf(fw,"字符%s是:运算符,种别编码为:%d\n",word,26); //判断结果为运算符"<="}elseif(ch=='<'){word[2]='\0';fprintf(fw,"字符%s是:运算符,种别编码为:%d\n",word,27); //判断结果为运算符"<<"}else{fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c是:运算符,种别编码为:%d\n",ch,28); //判断结果为"<"}break;case'>':word[0]=ch;ch=fgetc(fr);word[1]=ch;if(ch=='=') {word[2]='\0';fprintf(fw,"字符%s是运算符,种别编码为:%d\n",word,29);}elseif(ch=='>'){word[2]='\0';fprintf(fw,"字符%s是运算符,种别编码为:%d\n",word,30);}else {fseek(fr,-2,1);ch=fgetc(fr);fprintf(fw,"字符%c是运算符,种别编码为:%d\n",ch,31);}break;default: break;}}fprintf(fw,"\n");}}int main(){clock_t start,end;char cr;char str_in[25],str_out[25],str_out1[25],str_out2[25];double duration;start=clock();printf("请输入文件的读取路径(包含文件的后缀名):\n");scanf("%s",str_in);fr=fopen(str_in,"r");while(fr==NULL){printf("文件路径输入错误!请重新输入:\n");scanf("%s",str_in);fr=fopen(str_in,"r");}printf("文件读入成功!内容显示如下:\n");printf("**************************************************\n");cr=fgetc(fr);while (cr!=EOF) {putchar(cr);cr=fgetc(fr);}printf("\n");printf("**************************************************\n");printf("请输入文件的最终结果的写入路径(包含文件的后缀名):\n");scanf("%s",str_out);printf("请输入文件的常量表的写入路径(包含文件的后缀名):\n");scanf("%s",str_out1);printf("请输入文件的符号表的写入路径(包含文件的后缀名):\n");scanf("%s",str_out2);while(str_in==str_out||str_in==str_out1||str_in==str_out2){if(str_out==str_in){printf("请输入文件的最终结果的写入路径(包含文件的后缀名):\n");scanf("%s",str_out);}elseif(str_in==str_out1){printf("请输入文件的常量表的写入路径(包含文件的后缀名):\n");scanf("%s",str_out1);}elseif(str_in==str_out2){printf("请输入文件的符号表的写入路径(包含文件的后缀名):\n");scanf("%s",str_out2);}}fw=fopen(str_out,"w");temp1=fopen(str_out1,"w");temp2=fopen(str_out2,"w");while(fw==NULL||temp1==NULL||temp2==NULL){printf("文件写入路径错误,请重新输入:\n");if(fw==NULL){scanf("%s",str_out);fw=fopen(str_out,"w");}elseif(temp1=NULL){scanf("%s",str_out1);temp1=fopen(str_out1,"w");}elseif (temp2=NULL) {scanf("%s",str_out2);temp2=fopen(str_out2,"w");}}fprintf(temp1,"文件中依次出现的标识符\n");fprintf(temp2,"文件中依次出现的符号\n");fr=fopen(str_in,"r");check(fr);printf("文件写入成功!编译结果已写入指定文件区域!请注意查看...........\n\n");fclose(fw);fclose(temp1);fclose(temp2);fclose(fr);printf("\n");end=clock();duration=(double)(end-start)/CLOCKS_PER_SEC * 1000;printf("该词法分析程序共运行约%lf ms\n", duration);return 0;}测试结果:这个程序主要参考书上关于词法分析器的假设,完成了关于c语言词法分析的所有的功能。

编译原理实验报告(C语言)

编译原理实验报告(C语言)

编译原理实验报告实验项目1:词法分析程序实验一、实验的目的与任务:编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。

设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现方法,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。

编译原理是一门理论性和实践性都比较强的课程。

进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。

同时培养学生实际动手能力。

编译实验由三个独立实验组成,按照由浅入深进行排列,希望通过本实验使学生更深学习并理解编译的主要过程和相关方法。

词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等分隔符号。

基本符号是与输入的语言定义的词法所规定的终结符。

本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。

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

(遇到错误时可显示“Error”,然后跳过错误部分继续进行)二、题目分析1.这里采用C语言编写的源程序作为词法分析程序的输入数据,输入数据保存在“in.txt”记事本中,将分析结果存在“out.txt”记事本中。

词法分析器的源代码使用C语言编写。

2.下面就词法分析程序中的主要变量进行说明:主函数main():打开要分析的C语言源程序,若不能正确打开,则报错。

先从源程序中读入一个字符ch,然后进行如下处理:1、cp消耗掉空格,制表符,换行符后,cp数组复位,开始检测cp;2、数字检测,对照符号表输出,若匹配成功,则返回序号;3、字符串检测, 对照符号表输出,若匹配成功,则返回序号;4、基本保留字检测,对照符号表输出,若匹配成功,则返回序号;5、运算符检测,对照符号表输出,若匹配成功,则返回序号;注意这里碰到‘/’时,要判断后面是否跟着是注释语句。

编译原理-实验1

编译原理-实验1

实验1《词法分析程序设计与实现》实验学时: 2 实验地点:实验日期:一、实验目的加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。

二、实验内容自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法分析程序。

词法分析程序的实现可以采用任何一种编程语言和编程工具。

从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算符、界符。

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

(遇到错误时可显示“Error”,然后跳过错误部分继续显示)三、实验方法算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

主程序初始包括以下两个方面:⑴关键字表的初值。

关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。

如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};图3-1(2)程序中需要用到的主要变量为syn,token和sum扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。

四、实验步骤1.定义目标语言的可用符号表和构词规则;2.依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束;3.对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中;4.对不正确的单词,做出错误处理。

五、实验结果输入begin x:=9: if x>9 then x:=2*x+1/3; end #显示结果如下:六、实验结论该词法分析器可以进行输入、预处理;关键字的识别;标识符的识别、常数的识别、算符和界符的识别等。

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

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

实验一词法分析器设计【实验目的】1.熟悉词法分析的基本原理,词法分析的过程以及词法分析中要注意的问题。

2.复习高级语言,进一步加强用高级语言来解决实际问题的能力。

3.通过完成词法分析程序,了解词法分析的过程。

【实验内容】用C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字,运算符,标识符,常数以及界符)输出。

【实验流程图】【实验步骤】1.提取pl/0文件中基本字的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE];int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {printf("%s\t",wsym[m]);m=14;n=k+1;} }2.提取pl/0文件中标识符的源代码while((ch=fgetc(stream))!='.'){int k=-1;char a[SIZE]=" ";int s=0;while(ch>='a' && ch<='z'||ch>='A' && ch<='Z'){if(ch>='A' && ch<='Z') ch+=32;a[++k]=(char)ch;ch=fgetc(stream);}for(int m=0;m<=12&&k!=-1;m++)for(int n=0;n<=k;n++){if(a[n]==wsym[m][n]) ++s;else s=0;if(s==(strlen(wsym[m]))) {m=14;n=k+1;}}if(m==13) for(m=0;a[m]!=NULL;m++) printf("%c ",a[m]);3.提取pl/0文件中常数的源代码while((ch=fgetc(stream))!='.'){while(ch>='0' && ch<='9'){num=10*num+ch-'0';ch=fgetc(stream);}if(num!=0) printf("%d ",num);num=0;}4.提取pl/0文件中运算符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case'+': printf("+ ");break;case'-': printf("- ");break;case'*': printf("* ");break;case'/': printf("/ ");break;case'>': if(fgetc(stream)=='=')printf(">= "); else printf("> ");break;case'<': if(fgetc(stream)=='=')printf("<= "); else printf("< ");break;case':': printf(":= ");break;case'#': printf("# ");break;case'=': printf("= ");break;default: break;}ch=fgetc(stream);5.提取pl/0文件中界符的源代码int ch=fgetc(stream);while(ch!='.'){switch(ch){case',': printf(", ");break;case';': printf("; ");break;case'(': printf("( ");break;case')': printf(") ");break;default: break;}ch=fgetc(stream);}【实验结果】1.pl/0文件(222.txt)内容const a=10;var b,c;procedure p;beginc:=b+a;end;beginread(b);while b#0 dobegincall p;write(2*c);read(b)endend .2.实验运行结果【实验小结】1.了解程序在运行过程中对词法分析,识别一个个字符并组合成相应的单词,是机器能过明白程序,定义各种关键字,界符。

编译原理实验报告(手打)

编译原理实验报告(手打)

《编译原理》实验报告班级:计C104姓名:李云霄学号:108490实验一词法分析程序实现一、实验目的与要求通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。

二、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。

输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。

输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。

三、实现方法与环境1、首先设计识别各类单词的状态转换图。

描述无符号常数的确定、最小化状态转换图如图1所示。

其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。

图1 文法G[<无符号数>]的状态转换图其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。

在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。

四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢根据描述语言中各类单词的文法状态转换图或状态矩阵,利用某种语言(C语言或JAVA语言)直接编写词法分析程序。

编译原理—实验指导书-1

编译原理—实验指导书-1
(13)end.#
4.词法分析器的功能和输出格式
词法分析器的功能是输入以字符串表示的源程序,从左向右扫描每行源程序的符号,拼成单词,换成统一的二元式(单词种别码,单词符号的属性值)表示。对给定的程序通过词法分析器识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示,本程序是通过对给定路径的文件的分析后以单词符号和文字提示显示),本实验中,采用单词种别码是一符一种种别码的方式。
(4)var
(5)a,b,c:integer;
(6)x:char;
(7)begin
(8)if(a+c*3>b)and(b>3)thenc:=3;
(9)x:=2+(3*a)-b*c*8;
(10)forx:=1+2to3dob:=100;
(11)whilea>bdoc:=5;
(12)repeata:=10;untila>b;
(124){
(125)printf("%s\t$运算符\n\n",Word);
(126)}
(127)else if(ch=='-')
(128){
(129)printf("%s\t$运算符\n\n",Word); //判断结果为“--”
(2)设计描述Sample语言各类单词结构的状态转换图(即有限自动机FA);
如标识符的状态转换图可以用下图表示
其相应代码科为
(1)recog_id(char ch)
(2){
(3)char state='0';
(4)while(state!='2')
(5){
(6)switch(state)

《编译原理(实验部分)》实验1_程序预处理

《编译原理(实验部分)》实验1_程序预处理

《编译原理》(实验部分)实验1_程序预处理一、实验目的明确预处理子程序的任务,构造一个简单的预处理子程序,对源程序进行相应的预处理。

二、实验设备1、PC 兼容机一台;操作系统为WindowsWindowsXP。

2、Visual C++ 6.0 或以上版本, Windows 2000 或以上版本,汇编工具(在Software 子目录下)。

三、实验原理定义模拟的简单语言的词法构成,编制读入源程序和进行预处理的程序,要求将源程序读入到文件或存入数组中,再从文件或数组中逐个读取字符进行预处理,包括去掉注释、Tab、Enter和续行符等操作,并显示预处理后的程序。

四、实验步骤1、从键盘读入源程序存放到输入缓冲区中。

2、对源程序进行预处理,预处理后的程序存放到扫描缓冲区中。

3、显示预处理后的程序。

参考源程序(C++语言编写)//源程序的输入及预处理#include <fstream.h>#include <iostream.h>void pro_process(char *);void main( ) //测试驱动程序{//定义扫描缓冲区char buf[4048]={'\0'}; //缓冲区清0//调用预处理程序pro_process(buf); //在屏幕上显示扫描缓冲区的内容cout<<buf<<endl;}void pro_process(char *buf) //预处理程序{ifstream cinf("source.txt",ios::in);int i=0; //计数器char old_c='\0',cur_c; //前一个字符,当前字符。

bool in_comment=false; //false表示当前字符未处于注释中。

while(cinf.read(&cur_c,sizeof(char))){ //从文件读一个字符switch(in_comment){case false:if(old_c=='/' && cur_c=='*'){ //进入注释i--; //去除已存入扫描缓冲区的字符'/'in_comment=true;}else {if(old_c=='\\' && cur_c=='\n') //发现续行i--; //去除已存入扫描缓冲区的字符'\'else {if(cur_c>='A' && cur_c<='Z') //大写变小写cur_c+=32;if(cur_c =='\t' || cur_c =='\n')//空格取代TAB换行cur_c=' ';buf[i++]=cur_c ;}}break;case true:if(old_c=='*' && cur_c=='/') //离开注释in_comment=false;}//end of switchold_c= cur_c; //保留前一个字符}//end of whilebuf[i++]='#'; //在源程序尾部添加字符'#' }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一文本编辑器中正规式的应用
一.实验目的
1.掌握正规式的一般概念与表示。

2.掌握unix语法规则的正规式表示规则。

3.掌握在UltraEdit中使用正规式查找和替换功能处理文档排版的方法。

二.实验原理
1.UltraEdit中的正规式
仅用于查找和替换功能。

遵循两种语法格式:UltraEdit语
法和unix语法。

2.Unix语法
三、实验内容
1.英文文档单词查找与替换处理
查找文件中每行第二个单词;
查找文件中以指定字母结束的单词
将所有双字母单词改为大写字母
2.中文文档排版处理
要求通过正规式查找替换,处理好分段、首行缩进、空行
消除、章节标题分行处理等问题。

相关文档
最新文档