編譯原理實驗報告_第1頁
編譯原理實驗報告_第2頁
編譯原理實驗報告_第3頁
編譯原理實驗報告_第4頁
編譯原理實驗報告_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

實驗一詞法分析器設(shè)計【實驗目的】1.熟悉詞法分析的基本原理,詞法分析的過程以及詞法分析中要注意的問題。2.復習高級語言,進一步加強用高級語言來解決實際問題的能力。3.通過完成詞法分析程序,了解詞法分析的過程。【實驗內(nèi)容】(編寫)用C語言編寫一個PL/0詞法分析器,為語法語義分析提供單詞,使之能把輸入的字符串形式的源程序分割成一個個單詞符號傳遞給語法語義分析,并把分析結(jié)果(基本字,運算符,標識符,常數(shù)以及界符)輸出?!緦嶒灢襟E和要求】要求繪出詞法分析過程的流程圖。根據(jù)詞法分析的目的以及內(nèi)容,確定完成分析過程所需模塊。寫出每個模塊的源代碼。整理程序清單及所得結(jié)果。源代碼:intIsword(chargetword[])//判斷是否為關(guān)鍵字{ for(inti=0;i<13;i++) { if(strcmp(word[i],getword)==0) return1; } return0;}intIsoperator(charch)//判斷是否為單字符符號{ inti=0; for(i;i<11;i++) if(ch==symbols[i]) returni; return-1;}voidWrite(chars1[],chars2[]){ FILE*fp; if((fp=fopen("PL0詞法分析.txt","a+"))==NULL) { printf("無法打開文件?。n"); exit(-1); } fprintf(fp,"%-30s\t",s1); fprintf(fp,"%10s\n",s2); fclose(fp);}voidWriteNum(inta,chars2[]){ FILE*fp; if((fp=fopen("PL0詞法分析.txt","a+"))==NULL) { printf("無法打開文件?。n"); exit(-1); } fprintf(fp,"%-30d\t",a); fprintf(fp,"%10s\n",s2); fclose(fp);}voidWriteChar(charch,chars2[]){ FILE*fp; if((fp=fopen("PL0詞法分析.txt","a+"))==NULL) { printf("無法打開文件??!\n"); exit(-1); } fprintf(fp,"%-30c\t",ch); fprintf(fp,"%10s\n",s2); fclose(fp);}intAnalysis(void)//詞法分析{ chargetword[NameMax],ch; inti,flag=0,num; FILE*fp; if((fp=fopen("PL0程序.txt","r"))==NULL) { printf("無法打開PL0程序.txt??!\n"); exit(-1); } do { ch=fgetc(fp);if(ch>='a'&&ch<='z')//讀取的是字母,先判斷是否為關(guān)鍵字 { for(i=0;(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')&&i<NameMax;i++) { if(i<NameMax) { getword[i]=ch; ch=fgetc(fp); } elseif(i=NameMax) {printf("數(shù)據(jù)長度超出范圍\n"); flag=-1; break; } } if(flag!=-1) { getword[i]=0; if(Isword(getword)==1) Write(getword,"關(guān)鍵字"); else Write(getword,"標識符"); } } else { if(ch>='0'&&ch<='9')//判斷是否數(shù)字打頭 { intk=0; num=0; do { num=10*num+ch-'0'; k++; ch=fgetc(fp); } while(ch>='0'&&ch<='9'); k--; if(k>NumMax) { printf("數(shù)據(jù)長度超出范圍\n"); } else { WriteNum(num,"常數(shù)"); } } else {if(ch==':')//判斷賦值符號 { ch=fgetc(fp); if(ch=='=') { Write(":=","運算符"); } else { printf("不能識別的符號"); } } else { if(ch=='<')//判斷小于等于 { ch=fgetc(fp); if(ch=='=') { Write("<=","運算符"); } else { printf("不能識別的符號"); } } else { if(ch=='>')//判斷大于等于 { ch=fgetc(fp); if(ch=='=') { Write(">=","運算符"); } else { printf("不能識別的符號"); } } else { if(Isoperator(ch)>-1&&Isoperator(ch)<5) { WriteChar(ch,"運算符"); } else { if(Isoperator(ch)>=5) { WriteChar(ch,"界符"); } } } } } } }} while(ch!=EOF); fclose(fp); returnflag;}voidmain(void){ FILE*fp; chars1[30],s2[10],ch; Analysis();printf("\n詞法分析如下:\n"); printf("-----------------------------------------------------\n"); if((fp=fopen("PL0詞法分析.txt","r"))==NULL) { printf("無法打開文件!!\n"); exit(-1); } do { fscanf(fp,"%s",s1); fscanf(fp,"%s",s2); printf("%-30s\t",s1);printf("%10s\n",s2); s1[0]=0; s2[0]=0; } while((ch=fgetc(fp))!=EOF);}運行結(jié)果:實驗二LL(1)語法分析程序設(shè)計【實驗目的】1.熟悉判斷LL(1)文法的方法及對某一輸入串的分析過程。2.學會構(gòu)造表達式文法的預測分析表。【實驗內(nèi)容】(改寫)編寫一個語法分析程序,對于給定的輸入串,能夠判斷識別該串是否為給定文法的句型?!緦嶒灢襟E和要求】從鍵盤讀入輸入串,并判斷正誤;若無誤,由程序自動構(gòu)造FIRST、FOLLOW集以及SELECT集合,判斷是否為LL(1)文法;若符合LL(1)文法,由程序自動構(gòu)造LL(1)分析表;由算法判斷輸入符號串是否為該文法的句型。(可參考教材96頁的例題1)源代碼:voidInit()/*初始化*/{inti,j;vnNum=0;vtNum=0;PNum=0;for(i=0;i<=MaxVnNum;i++)Vn[i]='\0';for(i=0;i<=MaxVtNum;i++)Vt[i]='\0';for(i=0;i<MaxRuleNum;i++){P[i].lCursor=NULL;P[i].rHead=NULL;P[i].rLength=0;}PNum=0;for(i=0;i<=MaxPLength;i++)buffer[i]='\0';for(i=0;i<MaxVnNum;i++){first[i]=NULL;follow[i]=NULL;}for(i=0;i<=MaxVnNum;i++){for(j=0;j<=MaxVnNum+1;j++)analyseTable[i][j]=-1;}}/*返回Vn在Vn表中的位置+100、Vt在Vt表中的位置,-1表示未找到*/intIndexCh(charch){intn;n=0;/*isVn?*/while(ch!=Vn[n]&&'\0'!=Vn[n])n++;if('\0'!=Vn[n])return100+n;n=0;/*isVt?*/while(ch!=Vt[n]&&'\0'!=Vt[n])n++;if('\0'!=Vt[n])returnn;return-1;}/*輸出Vn或Vt的內(nèi)容*/voidShowChArray(char*collect){intk=0;while('\0'!=collect[k]){printf("%c",collect[k++]);}printf("\n");}/*輸入非終結(jié)符*/voidInputVn(){intinErr=1;intn,k;charch;while(inErr){printf("\n請輸入所有的非終結(jié)符,注意:");printf("請將開始符放在第一位,并以#號結(jié)束:\n");ch='';n=0;/*初始化數(shù)組*/while(n<MaxVnNum){Vn[n++]='\0';}n=0;while(('#'!=ch)&&(n<MaxVnNum)){if(''!=ch&&'\n'!=ch&&-1==IndexCh(ch)){Vn[n++]=ch;vnNum++;}ch=getchar();}Vn[n]='#';/*以"#"標志結(jié)束用于判斷長度是否合法*/k=n;/*k用于記錄n以便改Vn[n]='\0'*/if('#'!=ch){if('#'!=(ch=getchar())){while('#'!=(ch=getchar()));printf("\n符號數(shù)目超過限制!\n");inErr=1;continue;}}/*正確性確認,正確則,執(zhí)行下下面,否則重新輸入*/Vn[k]='\0';ShowChArray(Vn);ch='';while('y'!=ch&&'n'!=ch){if('\n'!=ch){printf("輸入正確確認?(y/n):");}scanf("%c",&ch);}if('n'==ch){printf("錄入錯誤重新輸入!\n");inErr=1;}else{inErr=0;}}}/*輸入終結(jié)符*/voidInputVt(){intinErr=1;intn,k;charch;while(inErr){printf("\n請輸入所有的終結(jié)符,注意:");printf("以#號結(jié)束:\n");ch='';n=0;/*初始化數(shù)組*/while(n<MaxVtNum){Vt[n++]='\0';}n=0;while(('#'!=ch)&&(n<MaxVtNum)){if(''!=ch&&'\n'!=ch&&-1==IndexCh(ch)){Vt[n++]=ch;vtNum++;}ch=getchar();}Vt[n]='#';/*以"#"標志結(jié)束*/k=n;/*k用于記錄n以便改Vt[n]='\0'*/if('#'!=ch){if('#'!=(ch=getchar())){while('#'!=(ch=getchar()))printf("\n符號數(shù)目超過限制!\n");inErr=1;continue;}}/*正確性確認,正確則,執(zhí)行下下面,否則重新輸入*/Vt[k]='\0';ShowChArray(Vt);ch='';while('y'!=ch&&'n'!=ch){if('\n'!=ch){printf("輸入正確確認?(y/n):");}scanf("%c",&ch);}if('n'==ch){printf("錄入錯誤重新輸入!\n");inErr=1;}else{inErr=0;}}}/*產(chǎn)生式輸入*/voidInputP(){charch;inti=0,n,num;printf("請輸入文法產(chǎn)生式的個數(shù):");scanf("%d",&num);PNum=num;getchar();/*消除回車符*/printf("\n請輸入文法的%d個產(chǎn)生式,并以回車分隔每個產(chǎn)生式:",num);printf("\n");while(i<num){printf("第%d個:",i);/*初始化*/for(n=0;n<MaxPLength;n++)buffer[n]='\0';/*輸入產(chǎn)生式串*/ch='';n=0;while('\n'!=(ch=getchar())&&n<MaxPLength){if(''!=ch)buffer[n++]=ch;}buffer[n]='\0';/*printf("%s",buffer);*/if(CheckP(buffer)){/*填寫入產(chǎn)生式結(jié)構(gòu)體*/pRNode*pt,*qt;P[i].lCursor=IndexCh(buffer[0]);pt=(pRNode*)malloc(sizeof(pRNode));pt->rCursor=IndexCh(buffer[3]);pt->next=NULL;P[i].rHead=pt;n=4;while('\0'!=buffer[n]){qt=(pRNode*)malloc(sizeof(pRNode));qt->rCursor=IndexCh(buffer[n]);qt->next=NULL;pt->next=qt;pt=qt;n++;}P[i].rLength=n-3;i++;/*調(diào)試時使用*/}elseprintf("輸入符號含非法在成分,請重新輸入!\n");}}/*判斷產(chǎn)生式正確性*/boolCheckP(char*st){intn;if(100>IndexCh(st[0]))returnfalse;if('-'!=st[1])returnfalse;if('>'!=st[2])returnfalse;for(n=3;'\0'!=st[n];n++){if(-1==IndexCh(st[n]))returnfalse;}returntrue;}/*====================first&follow======================*//*計算first集,U->xx...*/voidFirst(intU){inti,j;for(i=0;i<PNum;i++){if(P[i].lCursor==U){structpRNode*pt;pt=P[i].rHead;j=0;while(j<P[i].rLength){if(100>pt->rCursor){AddFirst(U,pt->rCursor);break;}else{if(NULL==first[pt->rCursor-100]){First(pt->rCursor);}AddFirst(U,pt->rCursor);if(!HaveEmpty(pt->rCursor)){break;}else{pt=pt->next;}}j++;}if(j>=P[i].rLength)/*當產(chǎn)生式右部都能推出空時*/AddFirst(U,-1);}}}/*加入first集*/voidAddFirst(intU,intnCh)/*當數(shù)值小于100時nCh為Vt*//*當處理非終結(jié)符時,AddFirst不添加空項(-1)*/{structcollectNode*pt,*qt;intch;/*用于處理Vn*/pt=NULL;qt=NULL;if(nCh<100){pt=first[U-100];while(NULL!=pt){if(pt->nVt==nCh)break;else{qt=pt;pt=pt->next;}}if(NULL==pt){pt=(structcollectNode*)malloc(sizeof(structcollectNode));pt->nVt=nCh;pt->next=NULL;if(NULL==first[U-100]){first[U-100]=pt;}else{qt->next=pt;/*qt指向first集的最后一個元素*/}pt=pt->next;}}else{pt=first[nCh-100];while(NULL!=pt){ch=pt->nVt;if(-1!=ch){AddFirst(U,ch);}pt=pt->next;}}}/*判斷first集中是否有空(-1)*/boolHaveEmpty(intnVn){if(nVn<100)/*為終結(jié)符時(含-1),在follow集中用到*/returnfalse;structcollectNode*pt;pt=first[nVn-100];while(NULL!=pt){if(-1==pt->nVt)returntrue;pt=pt->next;}returnfalse;}/*計算follow集,例:U->xVy,U->xV.(注:初始符必含#--"-1")*/voidFollow(intV){inti;structpRNode*pt;if(100==V)/*當為初始符時*/AddFollow(V,-1,0);for(i=0;i<PNum;i++){pt=P[i].rHead;while(NULL!=pt&&pt->rCursor!=V)/*注此不能處理:U->xVyVz的情況*/pt=pt->next;if(NULL!=pt){pt=pt->next;/*V右側(cè)的符號*/if(NULL==pt)/*當V后為空時V->xV,將左符的follow集并入V的follow集中*/{if(NULL==follow[P[i].lCursor-100]&&P[i].lCursor!=V){Follow(P[i].lCursor);}AddFollow(V,P[i].lCursor,0);}else/*不為空時V->xVy,(注意:y->),調(diào)用AddFollow加入Vt或y的first集*/{while(NULL!=pt&&HaveEmpty(pt->rCursor)){AddFollow(V,pt->rCursor,1);/*y的前綴中有空時,加如first集*/pt=pt->next;}if(NULL==pt)/*當后面的字符可以推出空時*/{if(NULL==follow[P[i].lCursor-100]&&P[i].lCursor!=V){Follow(P[i].lCursor);}AddFollow(V,P[i].lCursor,0);}else/*發(fā)現(xiàn)不為空的字符時*/{AddFollow(V,pt->rCursor,1);}}}}}/*當數(shù)值小于100時nCh為Vt*//*#用-1表示,kind用于區(qū)分是并入符號的first集,還是follow集kind=0表加入follow集,kind=1加入first集*/voidAddFollow(intV,intnCh,intkind){structcollectNode*pt,*qt;intch;/*用于處理Vn*/pt=NULL;qt=NULL;if(nCh<100)/*為終結(jié)符時*/{pt=follow[V-100];while(NULL!=pt){if(pt->nVt==nCh)break;else{qt=pt;pt=pt->next;}}if(NULL==pt){pt=(structcollectNode*)malloc(sizeof(structcollectNode));pt->nVt=nCh;pt->next=NULL;if(NULL==follow[V-100]){follow[V-100]=pt;}else{qt->next=pt;/*qt指向follow集的最后一個元素*/}pt=pt->next;}}else/*為非終結(jié)符時,要區(qū)分是加first還是follow*/{if(0==kind){pt=follow[nCh-100];while(NULL!=pt){ch=pt->nVt;AddFollow(V,ch,0);pt=pt->next;}}else{pt=first[nCh-100];while(NULL!=pt){ch=pt->nVt;if(-1!=ch){AddFollow(V,ch,1);}pt=pt->next;}}}}/*輸出first或follow集*/voidShowCollect(structcollectNode**collect){inti;structcollectNode*pt;i=0;while(NULL!=collect[i]){pt=collect[i];printf("\n%c:\t",Vn[i]);while(NULL!=pt){if(-1!=pt->nVt){printf("%c",Vt[pt->nVt]);}elseprintf("#");pt=pt->next;}i++;}printf("\n");}/*計算first和follow*/voidFirstFollow(){inti;i=0;while('\0'!=Vn[i]){if(NULL==first[i])First(100+i);i++;}i=0;while('\0'!=Vn[i]){if(NULL==follow[i])Follow(100+i);i++;}}/*=================構(gòu)造預測分析表,例:U::xyz=============*/voidCreateAT(){inti;structpRNode*pt;structcollectNode*ct;for(i=0;i<PNum;i++){pt=P[i].rHead;while(NULL!=pt&&HaveEmpty(pt->rCursor)){/*處理非終結(jié)符,當為終結(jié)符時,定含空為假跳出*/ct=first[pt->rCursor-100];while(NULL!=ct){if(-1!=ct->nVt)analyseTable[P[i].lCursor-100][ct->nVt]=i;ct=ct->next;}pt=pt->next;}if(NULL==pt){/*NULL==pt,說明xyz->,用到follow中的符號*/ct=follow[P[i].lCursor-100];while(NULL!=ct){if(-1!=ct->nVt)analyseTable[P[i].lCursor-100][ct->nVt]=i;else/*當含有#號時*/analyseTable[P[i].lCursor-100][vtNum]=i;ct=ct->next;}}else{if(100<=pt->rCursor)/*不含空的非終結(jié)符*/{ct=first[pt->rCursor-100];while(NULL!=ct){analyseTable[P[i].lCursor-100][ct->nVt]=i;ct=ct->next;}}else/*終結(jié)符或者空*/{if(-1==pt->rCursor)/*-1為空產(chǎn)生式時*/{ct=follow[P[i].lCursor-100];while(NULL!=ct){if(-1!=ct->nVt)analyseTable[P[i].lCursor-100][ct->nVt]=i;else/*當含有#號時*/analyseTable[P[i].lCursor-100][vtNum]=i;ct=ct->next;}}else/*為終結(jié)符*/{analyseTable[P[i].lCursor-100][pt->rCursor]=i;}}}}}/*輸出分析表*/voidShowAT(){inti,j;printf("構(gòu)造預測分析表如下:\n");printf("\t|\t");for(i=0;i<vtNum;i++){printf("%c\t",Vt[i]);}printf("#\t\n");printf("---\t|---\t");for(i=0;i<=vtNum;i++)printf("---\t");printf("\n");for(i=0;i<vnNum;i++){printf("%c\t|\t",Vn[i]);for(j=0;j<=vtNum;j++){if(-1!=analyseTable[i][j])printf("R(%d)\t",analyseTable[i][j]);elseprintf("\t");}printf("\n");}}/*=================主控程序=====================*/voidIdentify(char*st){intcurrent,step,r;/*r表使用的產(chǎn)生式的序號*/printf("\n%s的分析過程:\n",st);printf("步驟\t分析符號棧\t當前指示字符\t使用產(chǎn)生式序號\n");step=0;current=0;/*符號串指示器*/printf("%d\t",step);ShowStack();printf("\t\t%c\t\t--\n",st[current]);while('#'!=st[current]){if(100>analyseStack[topAnalyse])/*當為終結(jié)符時*/{if(analyseStack[topAnalyse]==IndexCh(st[current])){/*匹配出棧,指示器后移*/Pop();current++;step++;printf("%d\t",step);ShowStack();printf("\t\t%c\t\t出棧、后移\n",st[current]);}else{printf("%c-%c不匹配!",analyseStack[topAnalyse],st[current]);printf("此串不是此文法的句子!\n");return;}}else/*當為非終結(jié)符時*/{r=analyseTable[analyseStack[topAnalyse]-100][IndexCh(st[current])];if(-1!=r){Push(r);/*產(chǎn)生式右部代替左部,指示器不移動*/step++;printf("%d\t",step);ShowStack();printf("\t\t%c\t\t%d\n",st[current],r);}else{printf("無可用產(chǎn)生式,此串不是此文法的句子!\n");return;}}}if('#'==st[current]){if(0==topAnalyse&&'#'==st[current]){step++;printf("%d\t",step);ShowStack();printf("\t\t%c\t\t分析成功!\n",st[current]);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論