




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验教案班级:计科0501/0502教师:刘小豫
实验一源程序的输入及预处理一、实验目的明确预处理子程序的任务,构造一个简单的预处理子程序,对源程序进行相应的预处理。二、实验要求选择一种熟悉的高级语言,编制读入源程序和进行预处理的程序。三、实验内容定义模拟的简单语言的词法构成,编制读入源程序和进行预处理的程序,要求将源程序读入到文件或存入数组中,再从文件或数组中逐个读取字符进行预处理,包括去掉注释、Tab、Enter和续行符等操作,并显示预处理后的程序。四、实验学时2学时五、实验步骤1.从键盘读入源程序存放到输入缓冲区中。2.对源程序进行预处理,预处理后的程序存放到扫描缓冲区中。3.显示预处理后的程序。六、参考源程序(C++语言编写)//源程序的输入及预处理#include<fstream.h>#include<iostream.h>voidpro_process(char*);voidmain() //测试驱动程序{//定义扫描缓冲区 charbuf[4048]={'\0'}; //缓冲区清0//调用预处理程序 pro_process(buf);//在屏幕上显示扫描缓冲区的内容 cout<<buf<<endl;}voidpro_process(char*buf) //预处理程序{ ifstreamcinf("source.txt",ios::in); inti=0; //计数器 charold_c='\0',cur_c; //前一个字符,当前字符。 boolin_comment=false; //false表示当前字符未处于注释中。 while(cinf.read(&cur_c,sizeof(char))){ //从文件读一个字符 switch(in_comment){ casefalse: 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; casetrue: if(old_c=='*'&&cur_c=='/') //离开注释 in_comment=false; }//endofswitch old_c=cur_c; //保留前一个字符 }//endofwhile buf[i++]='#'; //在源程序尾部添加字符'#'}实验二词法分析程序实现一、实验目的加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。二、实验要求1.对单词的构词规则有明确的定义;2.编写的分析程序能够正确识别源程序中的单词符号;3.识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表;4.*对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;5.实验报告要求用自动机或者文法的形式对词法定义做出详细说明,说明词法分析程序的工作过程。三、实验内容自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法分析程序。词法分析程序的实现可以采用任何一种编程工具。四、实验学时6学时五、实验步骤1.定义目标语言的可用符号表和构词规则(参考教材17页例2.6正规定义);(自己定义)2.调用预处理程序,对源程序进行单词切分和识别,直到源程序结束;3.对正确的单词,按照它的种别以<种别码,值>的形式输出到显示器,*并保存在符号表中;4.*对不正确的单词,做出错误处理。六、选作实验带星号的内容为选作内容。学生可以根据自身的情况完善词法分析程序的错误处理功能,如对错误的单词给出准确的位置和错误类型提示。七、参考源程序(C++语言编写)词法分析器流程图//词法分析器手工构造实例#include<iostream.h>#include<fstream.h>#include<string.h>#include<stdlib.h>#include<conio.h>constshortWORDLEN=20;structcode_val{ charcode; charval[WORDLEN];};//预处理函数原型voidpro_process(char*);//扫描函数原型code_valscanner(char*);//拼接函数原型voidconcat(char[],char);//查保留字表函数charreserve(char[]);//主函数voidmain(){ charbuf[4048]={'\0'};//扫描缓冲区//预处理 pro_process(buf);//显示buf cout<<buf<<endl;//单词识别 ofstreamcoutf("Lex_r.txt",ios::out); code_valt;//临时变量 do{ t=scanner(buf);//调用一次扫描器获得一个单词二元式 cout<<t.code<<'\t'<<t.val<<endl;//屏幕显示单词二元式 coutf<<t.code<<'\t'<<t.val<<endl;//单词二元式输出至文件 }while(t.code!='#'); cout<<"Endoflexicalanalysis!"<<endl; getch();}//扫描函数,每调用一次,返回一个单词的二元式。structcode_valscanner(char*buf){ staticinti=0;//buf指针 structcode_valt={'\0',"NUL"};//临时变量 chartoken[WORDLEN]="";//用于拼接单词//去除前导空格 while(buf[i]=='')i++;//开始识别单词 //标识符或基本字 if(buf[i]>='a'&&buf[i]<='z'){ while(buf[i]>='a'&&buf[i]<='z'||buf[i]>='0'&&buf[i]<='9') concat(token,buf[i++]); t.code=reserve(token);//查保留字表 if(t.code=='i')strcpy(t.val,token);//是标识符 returnt;//返回标识符或基本字的二元式 } //整常数或实常数 if(buf[i]>='0'&&buf[i]<='9'){ while(buf[i]>='0'&&buf[i]<='9') concat(token,buf[i++]); if(buf[i]=='.'){//实常数123. concat(token,buf[i++]); while(buf[i]>='0'&&buf[i]<='9')//123.4 concat(token,buf[i++]); t.code='y'; } else//整常数 t.code='x'; strcpy(t.val,token); returnt;//返回当前单词整常数(123)或实常数(123.或123.4)的二元式 } //无整数部分实常数 if(buf[i]=='.'){ concat(token,buf[i++]); if(buf[i]>='0'&&buf[i]<='9'){ while(buf[i]>='0'&&buf[i]<='9') concat(token,buf[i++]); t.code='y'; strcpy(t.val,token); returnt;//返回当前单词实常数(.123)的二元式 } else{//单个.错误词形 cout<<"<Errorword>"<<token<<endl; exit(0); } } //其余单词 switch(buf[i]){ case',': t.code=','; break; case';': t.code=';'; break; case'(': t.code='('; break; case')': t.code=')'; break; case'=': t.code='='; break; case'+': if(buf[++i]=='+') t.code='$'; else{ t.code='+'; i--; } break; case'*': t.code='*'; break; case'#': t.code='#'; break; default://错误字符 cout<<"Errorchar>"<<buf[i]<<endl; exit(0); }//endofswitch i++;//指向下个单词 returnt;//返回当前单词的二元式}//拼接函数,原token="BEG",buf[i++]='I',调用后token="BEGI"。voidconcat(chartoken[],charc){ for(inti=0;token[i];i++); token[i]=c; token[++i]='\0';}charreserve(chartoken[]){ constchar*table[]={"begin","end","integer","real"}; constcharcode[]={"{}ac"}; for(inti=0;i<(int)strlen(code);i++) if(strcmp(token,table[i])==0)returncode[i]; return'i'; //标识符的单词种别为'i'}//预处理函数voidpro_process(char*buf){ ifstreamcinf("source.txt",ios::in); inti=0;charold_c='\0',cur_c;//计数器,前一个字符,当前字符。 boolin_comment=false;//状态标志,false表示当前字符未处于注释中。 while(cinf.read(&cur_c,sizeof(char))){//从文件读一个字符 switch(in_comment){ casefalse: 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')cur_c='';//空格 buf[i++]=cur_c; } } break; casetrue: if(old_c=='*'&&cur_c=='/')//离开注释 in_comment=false; }//endofswitch old_c=cur_c;//保留前一个字符 }//endofwhile buf[i]='#';}实验三LL(1)分析法一、实验目的根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对预测分析LL(1)分析法的理解。程序比较复杂,通过这个练习可提高软件开发能力。二、实验要求1.明确LL(1)分析法的功能LL(1)分析法的功能是利用LL(1)控制程序根据符号栈栈顶内容、输入串当前输入符号,以及LL(1)预测分析表,对输入符号串自上而下的分析过程。2.LL(1)分析法的前提改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法。3.程序要求:程序输入/输出示例:对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|-TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i(1)用户自行输入一个以#结束的符号串(包括+-*/()i#)(2)输出过程如下:(参考教材78页例4.6分析步骤)步骤符号栈剩余输入串所用产生式1Ei+i*i#E->TG备注:在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。三、实验内容利用LL(1)分析算法进行表达式处理,根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。四、实验学时4学时五、实验步骤1.定义部分:定义常量、变量、数据结构。2.初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);3.控制部分:从键盘输入一个表达式符号串;4.利用LL(1)分析算法(教材77页)进行表达式处理,结合符号栈栈顶符号及表达式符号串当前符号,根据LL(1)分析表进行分析,输出分析结果,如果遇到错误则显示错误信息。六、参考源代码/*LL(1)分析法源程序,只能在VC++中运行*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<dos.h>charA[20];/*分析栈*/charB[20];/*剩余串*/charv1[20]={'i','+','*','(',')','#'};/*终结符*/charv2[20]={'E','G','T','S','F'};/*非终结符*/intj=0,b=0,top=0,l;/*L为输入串长度*/typedefstructtype/*产生式类型定义*/{charorigin;/*大写字符*/chararray[5];/*产生式右边字符*/intlength;/*字符个数*/}type;typee,t,g,g1,s,s1,f,f1;/*结构体变量*/typeC[10][10];/*预测分析表*/voidprint()/*输出分析栈*/{inta;/*指针*/for(a=0;a<=top+1;a++)printf("%c",A[a]);printf("\t\t");}/*print*/voidprint1()/*输出剩余串*/{intj;for(j=0;j<b;j++)/*输出对齐符*/printf("");for(j=b;j<=l;j++)printf("%c",B[j]);printf("\t\t\t");}/*print1*/voidmain(){intm,n,k=0,flag=0,finish=0;charch,x;typecha;/*用来接受C[m][n]*//*把文法产生式赋值结构体*/e.origin='E';strcpy(e.array,"TG");e.length=2;t.origin='T';strcpy(t.array,"FS");t.length=2;g.origin='G';strcpy(g.array,"+TG");g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,"*FS");s.length=3;s1.origin='S';s1.array[0]='^';s1.length=1;f.origin='F';strcpy(f.array,"(E)");f.length=3;f1.origin='F';f1.array[0]='i';f1.length=1;for(m=0;m<=4;m++)/*初始化分析表*/for(n=0;n<=5;n++)C[m][n].origin='N';/*全部赋为空*//*填充分析表*/C[0][0]=e;C[0][3]=e;C[1][1]=g;C[1][4]=g1;C[1][5]=g1;C[2][0]=t;C[2][3]=t;C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;C[4][0]=f1;C[4][3]=f;printf("提示:本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析,\n");printf("请输入要分析的字符串:");do/*读入分析串*/{scanf("%c",&ch);if((ch!='i')&&(ch!='+')&&(ch!='*')&&(ch!='(')&&(ch!=')')&&(ch!='#')){printf("输入串中有非法字符\n");exit(1);}B[j]=ch;j++;}while(ch!='#');l=j;/*分析串长度*/ch=B[0];/*当前分析字符*/A[top]='#';A[++top]='E';/*'#','E'进
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 西方政治制度对移民公民化的影响试题及答案
- 叉车全部考试题库及答案
- 2025年环境政策与地方实施考试题及答案
- 软件设计师考试团队项目展示与试题及答案
- 兔玩网java面试题及答案
- java程序员进bat面试题及答案
- 动画驾驶考试题及答案
- 人大哲学面试题及答案
- 华泰证券java面试题及答案
- 自我反思的抒情作文5篇
- 世界环境日主题课件
- 职业道德与法治 第13课《学会依法维权》第一框课件《依法理性维权》
- 邻近铁路营业线施工安全监测技术规程 (TB 10314-2021)
- 妇科常见病科普知识讲座
- 城市土壤主要类型及特点
- 宾馆财务安全管理制度
- 《康复护理学基础》期末考试复习题库(含答案)
- 宝钢武钢并购重组案例研究
- 胰岛素的种类及应用(共26张PPT)
- 眩晕诊疗方案总结优化
- 转让鱼塘股份合同范本
评论
0/150
提交评论