




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
實驗教案班級:計科0501/0502教師:劉小豫
實驗一源程序的輸入及預(yù)處理一、實驗?zāi)康拿鞔_預(yù)處理子程序的任務(wù),構(gòu)造一個簡單的預(yù)處理子程序,對源程序進行相應(yīng)的預(yù)處理。二、實驗要求選擇一種熟悉的高級語言,編制讀入源程序和進行預(yù)處理的程序。三、實驗內(nèi)容定義模擬的簡單語言的詞法構(gòu)成,編制讀入源程序和進行預(yù)處理的程序,要求將源程序讀入到文件或存入數(shù)組中,再從文件或數(shù)組中逐個讀取字符進行預(yù)處理,包括去掉注釋、Tab、Enter和續(xù)行符等操作,并顯示預(yù)處理后的程序。四、實驗學(xué)時2學(xué)時五、實驗步驟1.從鍵盤讀入源程序存放到輸入緩沖區(qū)中。2.對源程序進行預(yù)處理,預(yù)處理后的程序存放到掃描緩沖區(qū)中。3.顯示預(yù)處理后的程序。六、參考源程序(C++語言編寫)//源程序的輸入及預(yù)處理#include<fstream.h>#include<iostream.h>voidpro_process(char*);voidmain() //測試驅(qū)動程序{//定義掃描緩沖區(qū) charbuf[4048]={'\0'}; //緩沖區(qū)清0//調(diào)用預(yù)處理程序 pro_process(buf);//在屏幕上顯示掃描緩沖區(qū)的內(nèi)容 cout<<buf<<endl;}voidpro_process(char*buf) //預(yù)處理程序{ ifstreamcinf("source.txt",ios::in); inti=0; //計數(shù)器 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--; //去除已存入掃描緩沖區(qū)的字符'/' in_comment=true; } else{ if(old_c=='\\'&&cur_c=='\n') //發(fā)現(xiàn)續(xù)行 i--; //去除已存入掃描緩沖區(qū)的字符'\' 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++]='#'; //在源程序尾部添加字符'#'}實驗二詞法分析程序?qū)崿F(xiàn)一、實驗?zāi)康募由顚υ~法分析器的工作過程的理解;加強對詞法分析方法的掌握;能夠采用一種編程語言實現(xiàn)簡單的詞法分析程序;能夠使用自己編寫的分析程序?qū)唵蔚某绦蚨芜M行詞法分析。二、實驗要求1.對單詞的構(gòu)詞規(guī)則有明確的定義;2.編寫的分析程序能夠正確識別源程序中的單詞符號;3.識別出的單詞以<種別碼,值>的形式保存在符號表中,正確設(shè)計和維護符號表;4.*對于源程序中的詞法錯誤,能夠做出簡單的錯誤處理,給出簡單的錯誤提示,保證順利完成整個源程序的詞法分析;5.實驗報告要求用自動機或者文法的形式對詞法定義做出詳細說明,說明詞法分析程序的工作過程。三、實驗內(nèi)容自定義一種程序設(shè)計語言,或者選擇已有的一種高級語言,編制它的詞法分析程序。詞法分析程序的實現(xiàn)可以采用任何一種編程工具。四、實驗學(xué)時6學(xué)時五、實驗步驟1.定義目標語言的可用符號表和構(gòu)詞規(guī)則(參考教材17頁例2.6正規(guī)定義);(自己定義)2.調(diào)用預(yù)處理程序,對源程序進行單詞切分和識別,直到源程序結(jié)束;3.對正確的單詞,按照它的種別以<種別碼,值>的形式輸出到顯示器,*并保存在符號表中;4.*對不正確的單詞,做出錯誤處理。六、選作實驗帶星號的內(nèi)容為選作內(nèi)容。學(xué)生可以根據(jù)自身的情況完善詞法分析程序的錯誤處理功能,如對錯誤的單詞給出準確的位置和錯誤類型提示。七、參考源程序(C++語言編寫)詞法分析器流程圖//詞法分析器手工構(gòu)造實例#include<iostream.h>#include<fstream.h>#include<string.h>#include<stdlib.h>#include<conio.h>constshortWORDLEN=20;structcode_val{ charcode; charval[WORDLEN];};//預(yù)處理函數(shù)原型voidpro_process(char*);//掃描函數(shù)原型code_valscanner(char*);//拼接函數(shù)原型voidconcat(char[],char);//查保留字表函數(shù)charreserve(char[]);//主函數(shù)voidmain(){ charbuf[4048]={'\0'};//掃描緩沖區(qū)//預(yù)處理 pro_process(buf);//顯示buf cout<<buf<<endl;//單詞識別 ofstreamcoutf("Lex_r.txt",ios::out); code_valt;//臨時變量 do{ t=scanner(buf);//調(diào)用一次掃描器獲得一個單詞二元式 cout<<t.code<<'\t'<<t.val<<endl;//屏幕顯示單詞二元式 coutf<<t.code<<'\t'<<t.val<<endl;//單詞二元式輸出至文件 }while(t.code!='#'); cout<<"Endoflexicalanalysis!"<<endl; getch();}//掃描函數(shù),每調(diào)用一次,返回一個單詞的二元式。structcode_valscanner(char*buf){ staticinti=0;//buf指針 structcode_valt={'\0',"NUL"};//臨時變量 chartoken[WORDLEN]="";//用于拼接單詞//去除前導(dǎo)空格 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;//返回標識符或基本字的二元式 } //整常數(shù)或?qū)嵆?shù) if(buf[i]>='0'&&buf[i]<='9'){ while(buf[i]>='0'&&buf[i]<='9') concat(token,buf[i++]); if(buf[i]=='.'){//實常數(shù)123. concat(token,buf[i++]); while(buf[i]>='0'&&buf[i]<='9')//123.4 concat(token,buf[i++]); t.code='y'; } else//整常數(shù) t.code='x'; strcpy(t.val,token); returnt;//返回當前單詞整常數(shù)(123)或?qū)嵆?shù)(123.或123.4)的二元式 } //無整數(shù)部分實常數(shù) 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;//返回當前單詞實常數(shù)(.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;//返回當前單詞的二元式}//拼接函數(shù),原token="BEG",buf[i++]='I',調(diào)用后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'}//預(yù)處理函數(shù)voidpro_process(char*buf){ ifstreamcinf("source.txt",ios::in); inti=0;charold_c='\0',cur_c;//計數(shù)器,前一個字符,當前字符。 boolin_comment=false;//狀態(tài)標志,false表示當前字符未處于注釋中。 while(cinf.read(&cur_c,sizeof(char))){//從文件讀一個字符 switch(in_comment){ casefalse: if(old_c=='/'&&cur_c=='*'){//進入注釋 i--;//去除已存入掃描緩沖區(qū)的字符'/' in_comment=true; } else{ if(old_c=='\\'&&cur_c=='\n')//去除續(xù)行符'\',包括后續(xù)換行符。 i--;//去除已存入掃描緩沖區(qū)的字符'\' 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)分析法一、實驗?zāi)康母鶕?jù)某一文法編制調(diào)試LL(1)分析程序,以便對任意輸入的符號串進行分析。本次實驗的目的主要是加深對預(yù)測分析LL(1)分析法的理解。程序比較復(fù)雜,通過這個練習可提高軟件開發(fā)能力。二、實驗要求1.明確LL(1)分析法的功能LL(1)分析法的功能是利用LL(1)控制程序根據(jù)符號棧棧頂內(nèi)容、輸入串當前輸入符號,以及LL(1)預(yù)測分析表,對輸入符號串自上而下的分析過程。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)用戶自行輸入一個以#結(jié)束的符號串(包括+-*/()i#)(2)輸出過程如下:(參考教材78頁例4.6分析步驟)步驟符號棧剩余輸入串所用產(chǎn)生式1Ei+i*i#E->TG備注:在“所用產(chǎn)生式”一列中如果對應(yīng)有推導(dǎo)則寫出所用產(chǎn)生式;如果為匹配終結(jié)符則寫明匹配的終結(jié)符;如分析異常出錯則寫為“分析出錯”;若成功結(jié)束則寫為“分析成功”。三、實驗內(nèi)容利用LL(1)分析算法進行表達式處理,根據(jù)LL(1)分析表對表達式符號串進行堆棧(或其他)操作,輸出分析結(jié)果,如果遇到錯誤則顯示錯誤信息。四、實驗學(xué)時4學(xué)時五、實驗步驟1.定義部分:定義常量、變量、數(shù)據(jù)結(jié)構(gòu)。2.初始化:設(shè)立LL(1)分析表、初始化變量空間(包括堆棧、結(jié)構(gòu)體、數(shù)組、臨時變量等);3.控制部分:從鍵盤輸入一個表達式符號串;4.利用LL(1)分析算法(教材77頁)進行表達式處理,結(jié)合符號棧棧頂符號及表達式符號串當前符號,根據(jù)LL(1)分析表進行分析,輸出分析結(jié)果,如果遇到錯誤則顯示錯誤信息。六、參考源代碼/*LL(1)分析法源程序,只能在VC++中運行*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<dos.h>charA[20];/*分析棧*/charB[20];/*剩余串*/charv1[20]={'i','+','*','(',')','#'};/*終結(jié)符*/charv2[20]={'E','G','T','S','F'};/*非終結(jié)符*/intj=0,b=0,top=0,l;/*L為輸入串長度*/typedefstructtype/*產(chǎn)生式類型定義*/{charorigin;/*大寫字符*/chararray[5];/*產(chǎn)生式右邊字符*/intlength;/*字符個數(shù)*/}type;typee,t,g,g1,s,s1,f,f1;/*結(jié)構(gòu)體變量*/typeC[10][10];/*預(yù)測分析表*/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]*//*把文法產(chǎn)生式賦值結(jié)構(gòu)體*/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','+','*','(',')'構(gòu)成的以'#'結(jié)束的字符串進行分析,\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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工程監(jiān)理居間合同
- 公司與個人汽車租賃合同
- 企業(yè)員工培訓(xùn)合作協(xié)議
- 醫(yī)療設(shè)備購銷協(xié)議書
- 重大項目管理活動策劃方案
- 工業(yè)廠房買賣協(xié)議書
- 農(nóng)業(yè)社會化服務(wù)培訓(xùn)方案
- 農(nóng)業(yè)種植技術(shù)指導(dǎo)與培訓(xùn)方案
- 商場零售行業(yè)智能導(dǎo)購與庫存管理方案
- 勞動合同的簽訂原則
- 4地球-我們的家園《我們共同的責任》說課稿 -2023-2024學(xué)年道德與法治六年級下冊統(tǒng)編版
- 護理交接班改進
- 2024版房屋市政工程生產(chǎn)安全重大事故隱患判定標準內(nèi)容解讀
- GB 21258-2024燃煤發(fā)電機組單位產(chǎn)品能源消耗限額
- 工程項目部安全生產(chǎn)治本攻堅三年行動實施方案
- 教學(xué)能力大賽-教學(xué)實施報告《大學(xué)英語2c》
- 2024三農(nóng)新政策解讀
- HGE系列電梯安裝調(diào)試手冊(ELS05系統(tǒng)SW00004269,A.4 )
- 酒店前臺績效考核表
- 建筑公司項目目標管理責任書
- 北京市懷柔區(qū)京都黃金冶煉有限公司氰化氫泄漏
評論
0/150
提交評論