編譯原理詞法分析,語(yǔ)法分析實(shí)驗(yàn)報(bào)告_第1頁(yè)
編譯原理詞法分析,語(yǔ)法分析實(shí)驗(yàn)報(bào)告_第2頁(yè)
編譯原理詞法分析,語(yǔ)法分析實(shí)驗(yàn)報(bào)告_第3頁(yè)
已閱讀5頁(yè),還剩43頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、編譯原理實(shí)驗(yàn)報(bào)告一.LL(1)文法分析1. 設(shè)計(jì)要求(1) 對(duì)輸入文法,它能判斷是否為 LL(1)文法,若是,則轉(zhuǎn)(2);否則報(bào)錯(cuò)并 終止;(2)輸入已知文法,由程序自動(dòng)生成它的 LL(1)分析表;(3)對(duì)于給定的輸入串,應(yīng)能判斷識(shí)別該串是否為給定文法的句型。2. 分析該程序可分為如下幾步:(1)讀入文法(2)判斷正誤(3)若無(wú)誤,判斷是否為L(zhǎng)L(1)文法(4)若是,構(gòu)造分析表;(5)由總控算法判斷輸入符號(hào)串是否為該文法的句型。3. 流程圖是LL(1)文法?4. 源程序/*語(yǔ)法分析程序作者:XXX學(xué)號(hào):XXX*#include<stdlib.h>#include<stdio.

2、h>#include<string.h>/*int count=0; int number; char start;/*分解的產(chǎn)生式的個(gè)數(shù)*/*所有終結(jié)符和非終結(jié)符的總數(shù)*/*開(kāi)始符號(hào)*/char termin50;char non_ter50;char v50;char left50;/*終結(jié)符號(hào)*/*非終結(jié)符號(hào)*/*所有符號(hào)*/*左部*/char right5050;/*右部*/char first5050,follow5050;/* 各產(chǎn)生式右部的 FIRST和左部的 FOLLOW 集合 */char first15050;/*所有單個(gè)符號(hào)的FIRST集合*/char

3、select5050;char f50,F50;char empty20;char TEMP50;int validity=1;/*各單個(gè)產(chǎn)生式的 SELECT集合*/*記錄各符號(hào)的FIRST和 FOLLOW 是否已求過(guò)*/*記錄可直接推岀人的符號(hào)*/*求FOLLOW 時(shí)存放某一符號(hào)串的 FIRST集合*/*表示輸入文法是否有效*/int ll=1;/*表示輸入文法是否為L(zhǎng)L(1)文法*/int M2020; char choose; char empt20; char fo20;/*分析表*/*用戶(hù)輸入時(shí)使用*/*求_emp()時(shí)使用*/*求FOLLOW 集合時(shí)使用*/*判斷一個(gè)字符是否在指

4、定字符串中*/int in(char c,char *p)int i;if(strlen(p)=0)return(0);for(i=0;i+)if(pi=c)return(1);/* 若在,返回 1*/if(i=strlen(p)return(0);/* 若不在,返回 0*/*得到一個(gè)不是非終結(jié)符的符號(hào)*/char c()char c='A'while(in(c,non_ter)=1)c+;return(c);/*分解含有左遞歸的產(chǎn)生式*/void recur(char *point)/*完整的產(chǎn)生式在 point中*/int j,m=0,n=3,k;char temp20,c

5、h;ch=c();/*得到一個(gè)非終結(jié)符*/k=strlen(non_ter);non_terk=ch;non_terk+1='0'for(j=0;jv=strlen(point)-1;j+)if(pointn=point0)/*如果 | '后的首符號(hào)和左部相同*/for(j=n+1;jv=strlen(point)-1;j+)while(pointj!=T&&pointj!='0')tempm+=pointj+;leftcount=ch;memcpy(rightcount,temp,m);rightcountm=ch;rightcount

6、m+1='0:m=0;count+;if(pointj=T)n=j+1;break;else/*如果 | '后的首符號(hào)和左部不同*/leftcount=ch;rightcount0='A'rightcount1='0'count+;for(j=n;j<=strlen(point)-1;j+)if(pointj!='|')tempm+=pointj;elseleftcount=point0;memcpy(rightcount,temp,m);rightcountm=ch;rightcountm+1='0'pri

7、ntf(" count=%d ",count);m=0;count+;leftcount=point0;memcpy(rightcount,temp,m);rightcountm=ch;rightcountm+1='0: count+;m=0;/*分解不含有左遞歸的產(chǎn)生式*/void non_re(char *point)int m=0,j;char temp20;for(j=3;jv=strlen(point)-1;j+)if(pointj!=T)tempm+=pointj;elseleftcount=point0; memcpy(rightcount,temp,

8、m);rightcountm='0:m=0;count+;leftcount=point0;memcpy(rightcount,temp,m);rightcountm='0'count+;m=0;/*讀入一個(gè)文法*/char grammer(char *t,char *n,char *left,char right5050) char vn50,vt50;char s;char p5050;int i,j,k;printf("n請(qǐng)輸入文法的非終結(jié)符號(hào)串:”);scanf("%s",vn);getchar();i=strlen(vn);mem

9、cpy(n,vn,i);ni='O:printf("請(qǐng)輸入文法的終結(jié)符號(hào)串:");scanf("%s",vt);getchar();i=strlen(vt);memcpy(t,vt,i);ti='0'printf("請(qǐng)輸入文法的開(kāi)始符號(hào):”);scanf("%c", &s);getchar();printf("請(qǐng)輸入文法產(chǎn)生式的條數(shù):");scanf("%d",&i);getchar();for(j=1;jv=i;j+)printf("

10、請(qǐng)輸入文法的第 %d條(共%d條)產(chǎn)生式:",j,i);scanf("%s",pj-1);getchar();for(j=0;j<=i-1;j+)if(pj1!='-'l|pj2!='>') printf("ninput error!");validity=O;return('O');/*檢測(cè)輸入錯(cuò)誤*/for(k=0;k<=i-1;k+)/*分解輸入的各產(chǎn)生式*/if(P【k【3=p【k【0)recur(pk);elsenon_re(p【k);return(s);/*將單個(gè)符號(hào)

11、或符號(hào)串并入另一符號(hào)串*/人一并并入目串;void merge(char *d,char *s,int type)/*d是目標(biāo)符號(hào)串,s是源串,type = 1,源串中的type = 2,源串中的人'不并入目串*/int i,j;for(i=0;i<=strlen(s)-1;i+)if(type=2&&si='A')elsefor(j=0;j+)if(j<strlen(d)&&si=dj)break;if(j=strlen(d)dj=s【i;dj+1='0'break;/*求所有能直接推岀A的符號(hào)*/void

12、emp(char c)/*即求所有由a '推出的符號(hào)*/char temp10;int i;for(i=0;i<=count-1;i+)if(righti0=c&&strlen(righti)=1)temp0=lefti;temp1='0'merge(empty,temp,1);emp(lefti);/*求某一符號(hào)能否推岀A '*/int _emp(char c)/*若能推出,返回1 ;否則,返回0*/int i,j,k,result=1,mark=0;char temp20;temp0=c;temp1='0'merge(e

13、mpt,temp,1);if(in(c,empty)=1)return(1);for(i=0;i+)if(i=count)return(0);if(lefti=c)/*找一個(gè)左部為c的產(chǎn)生式*/j=strlen(righti);/*j 為右部的長(zhǎng)度 */if(j=1 &&in(righti0,empty)=1)return(1);else if(j=1 &&in(righti0,termin)=1)return(0);elsefor(k=0;k<=j-1;k+)if(in(righ tik,empt)=1)mark=1;if(mark=1)continue

14、;elsefor(k=0;k<=j-1;k+) result*=_emp(rightik); temp0=rightik;temp1='0' merge(empt,temp,1);if(result=0&&i< count)continue;else if(result=1 &&i <count)return(1);/*判斷讀入的文法是否正確*/int judge()int i,j;for(i=0;i<=count-1;i+)if(in(lefti,non_ter)=0)/*若左部不在非終結(jié)符中,報(bào)錯(cuò)*/printf(&q

15、uot;nerror1!");validity=0;return(0);for(j=0;jv=strlen(righti)-1;j+)A ',報(bào)錯(cuò)*/if(in(rightij,non_ter)=0&&in(rightij,termin)=0&&rightij!='A')/*若右部某一符號(hào)不在非終結(jié)符、終結(jié)符中且不為printf("nerror2!");validity=0;return(0);return(1);/*求單個(gè)符號(hào)的 FIRST*/void first2(int i)/*i為符號(hào)在所有輸入符號(hào)中

16、的序號(hào) */char c,temp20;int j,k,m;c=vi;char ch='A'emp(ch);if(in(c,termin)=1)/* 若為終結(jié)符 */first1i0=c;first1i1='0'/*若為非終結(jié)符*/else if(in(c,non_ter)=1)for(j=0;jv=count-1;j+)if(leftj=c)if(in(rightj0,termin)=1|rightj0='A')temp0=rightj0;temp1='0:merge(first1i,temp,1);else if(in(rightj0

17、,non_ter)=1)if(rightj0=c)continue;for(k=0;k+)if(vk=rightj0)break;if(fk='0')first2(k);fk='1'merge(first1i,first1k,2);for(k=0;k<=strlen(rightj)-1;k+)empt0='0'if(_emp(rightjk)=1 &&k<strlen(rightj)-1)for(m=0;m+)if(vm=rightjk+1) break;if(fm='0')first2(m);fm=&

18、#39;1'merge(first1i,first1m,2);else if(_emp(rightjk)=1 &&k=strlen(rightj)-1)temp0='A'temp1='0: merge(first1i,temp,1);elsebreak;fi='1'/*求各產(chǎn)生式右部的FIRST*/void FIRST(int i,char *p)int length;int j,k,m;char temp20;length=strlen(p);if(length=1)/*如果右部為單個(gè)符號(hào)*/if(p0='A')

19、if(i>=0)firsti0='A:firsti1='0'elseTEMP0='a:TEMP1='0:elsefor(j=0;j+)if(vj=p0)break;if(i>=0)memcpy(firsti,first1j,strlen(first1j); firstistrlen(first1j)='0'elsememcpy (T EMP,first1j,strlen(first1j);TEMPstrlen(first1j)='0' else /*如果右部為符號(hào)串*/for(j=0;j+)if(vj=p0)b

20、reak;if(i>=0)merge(firsti,first1j,2);elsemerge (TEMP,first1j,2);for(k=0;k<=length-1;k+)empt0='0'if(_emp(pk)=1 &&k<length-1)for(m=0;m+) if(vm=rightik+1) break;if(i>=0) merge(firsti,first1m,2); elsemerge (TEMP,first1m,2);else if(_emp(pk)=1 &&k=length-1)temp0='A&

21、#39;temp1='0'if(i>=0) merge(firsti,temp,1);elsemerge(TEMP,temp,1);else if(_emp(pk)=0)break;/*求各產(chǎn)生式左部的FOLLOW*/void FOLLOW(int i)int j,k,m,n,result=1;char c,temp20;c=non_teri;/*c為待求的非終結(jié)符*/temp0=c;temp1='0'merge(fo,temp,1);if(c=start)/*若為開(kāi)始符號(hào)*/temp0='#'temp1='0:merge(foll

22、owi,temp,1);for(j=0;jv=count-1;j+)if(in(c,rightj)=1)/*找一個(gè)右部含有c的產(chǎn)生式*/for(k=0;k+)if(rightjk=c)break;/*k為c在該產(chǎn)生式右部的序號(hào)*/for(m=0;m+)if(vm=leftj)break;/*m為產(chǎn)生式左部非終結(jié)符在所有符號(hào)中的序號(hào)*/if(k=strlen(rightj)-1)/*如果c在產(chǎn)生式右部的最后*/if(in(vm,fo)=1)merge(followi,followm,1);continue;if(Fm='0')FOLLOW(m);Fm='1'mer

23、ge(followi,followm,1);else/*如果c不在產(chǎn)生式右部的最后*/for(n=k+1;n<=strlen(rightj)-1;n+)emptO='O: result*=_emp(rightjn);if(result=1)/*如果右部c后面的符號(hào)串能推出人*/if(in(vm,fo)=1)/*避免循環(huán)遞歸*/merge(followi,followm,1); continue;if(Fm='O')FOLLOW(m);Fm='1' merge(followi,followm,1); for(n=k+1;n<=strlen(ri

24、ghtj)-1;n+) tempn-k-1=rightjn;tempstrlen(rightj)-k-1='O'FIRST(-1,temp); merge(followi,TEMP,2);Fi='1'/*判斷讀入文法是否為一個(gè)LL(1)文法*/int ll1()int i,j,length,result=1;char temp50;/*初始化*/for(j=0;jv=49;j+)firstjO='O:followj0='0'first1j0='0'selectjO='O'TEMPj='0't

25、empj='0'fj='0';Fj='0'for(j=0;jv=strlen(v)_1;j+)first2(j);/*求單個(gè)符號(hào)的FIRST集合*/printf("nfirst1:");for(j=0;jv=strlen(v)_1;j+)printf("%c:%s ",vj,first1j);printf("nempty:%s",empty);printf("n:n_emp:");for(j=0;j<=strlen(v)-1;j+)printf("%d

26、 ",_emp(vj);for(i=0;i<=count-1;i+)FIRST(i,righti);/* 求 FIRST*/printf("n");for(j=0;j<=strlen(non_ter)-1;j+)/* 求 FOLLOW*/if(foj=0)fo0='0'FOLLOW(j);printf("nfirst:");for(i=0;i<=count-1;i+)printf("%s ",firsti);printf("nfollow:");for(i=0;i<

27、=strlen(non_ter)-1;i+)printf("%s ",followi);for(i=0;i<=count-1;i+)/*求每一產(chǎn)生式的 SELECT集合*/memcpy(selecti,firsti,strlen(firsti);selectistrlen(firsti)='0'for(j=0;j<=strlen(righti)-1;j+)result*=_emp(rightij);if(strlen(righ ti)=1 &&righti0='A')result=1;if(result=1)for

28、(j=0;j+)if(vj=lefti)break;merge(selecti,followj,1); printf("nselect:");for(i=0;i<=count-1;i+)printf("%s ",selecti); memcpy(temp,select0,strlen(select0); tempstrlen(select0)='0'for(i=1;i<=count-1;i+)/*判斷輸入文法是否為L(zhǎng)L(1)文法*/length=strlen(temp);if(lefti=lefti-1) merge(temp

29、,selecti,1); if(strlen(temp)<length+strlen(selecti) return(0);elsetemp0='0' memcpy(temp,selecti,strlen(selecti); tempstrlen(selecti)='0'return(1);/*構(gòu)造分析表M*/void MM()int i,j,k,m;for(i=0;i<=19;i+)for(j=0;j<=19;j+)Mij=-1;i=strlen(termin);termini=#;/*將#加入終結(jié)符數(shù)組*/termini+1='0&

30、#39;for(i=0;i<=count-1;i+)for(m=0;m+)if(non_term=lefti)break;/*m為產(chǎn)生式左部非終結(jié)符的序號(hào)*/for(j=0;jv=strlen(selecti)-1;j+)if(in(selectij,termin)=1)for(k=0;k+)if(termink=selectij)break;/*k為產(chǎn)生式右部終結(jié)符的序號(hào)*/Mmk=i;/*總控算法*/void syntax()int i,j,k,m,n,p,q;char ch;char S50,str50;printf("請(qǐng)輸入該文法的句型:”);scanf("%

31、s",str);getchar();i=strlen(str);stri='#'stri+1='0'S0='#'S1=start;S2='0'j=0;ch=strj;while(1)if(in(Sstrlen(S)-1,termin)=1) if(Sstrlen(S)-1!=ch)printf("n該符號(hào)串不是文法的句型!");return;else if(Sstrlen(S)-1=#)printf("n該符號(hào)串是文法的句型.");return;elseSstrlen(S)-1=&

32、#39;0:j+;ch=strj;elsefor(i=0;i+)if(non_teri=Sstrlen(S)-1)break;for(k=0;k+)if(termink=ch)break;if(k=strlen(termin)printf("n詞法錯(cuò)誤!");return;if(Mik=-1)printf("n 語(yǔ)法錯(cuò)誤!");return;elsem=Mik;if(rightm0='A')Sstrlen(S)-1='0'elsep=strlen(S)-1;q=p;for(n=strlen(rightm)-1;n>=

33、0;n-) S【p+=right【m【n;Sq+strlen(rightm)='0:printf("nS:%s str:",S);for(p=j;pv=strlen(str)_1;p+)printf("%c",strp);printf("");/*一個(gè)用戶(hù)調(diào)用函數(shù)*/void menu()syntax();printf("n 是否繼續(xù)? (y or n):");scanf("%c", &choose);getchar();while(choose='y')menu

34、();/* 主函數(shù)*/void main()/*讀入一個(gè)文法*/int i,j;start=grammer(termin,non_ter,left,right); printf("count=%d",count);printf("nstart:%c",start); strcpy(v,non_ter); strcat(v,termin); printf("nv:%s",v);printf("nnon_ter:%s",non_ter);printf("ntermin:%s",termin);pri

35、ntf("nright:");for(i=0;i<=count-1;i+)printf("%s ",righti);printf("nleft:");for(i=0;i<=count-1;i+)printf("%c ",lefti);if(validity=1)validity=judge();printf("nvalidity=%d",validity);if(validity=1)printf("n文法有效");ll=ll1();printf("nl

36、l=%d",ll);if(ll=0)printf("n該文法不是一個(gè) LL1文法!");elseMM();printf("n");for(i=0;i<=19;i+)for(j=0;jv=19;j+)if(Mij>=0)printf("M%d%d=%d ",i,j,Mij);printf("n");menu();5. 執(zhí)行結(jié)果(i)輸入一個(gè)文法聲 XTurbocZXPetjugsynax, eie*1 + 3 呂-E 號(hào)g:數(shù)如尅知纟女工丄£ 3線(xiàn)幵和W-產(chǎn)杓的的 文文文文文交文 入入

37、人入人入入 n- Nn- LSH-(2 )輸入一個(gè)符號(hào)串(3)再次輸入一個(gè)符號(hào)串,然后退出程序二詞法分析一、問(wèn)題描述識(shí)別簡(jiǎn)單語(yǔ)言的單詞符號(hào)識(shí)別簡(jiǎn)單語(yǔ)言的基本字、標(biāo)識(shí)符、無(wú)符號(hào)整數(shù)、運(yùn)算符和界符。1題目選擇計(jì)算機(jī)高級(jí)程序語(yǔ)言之一 一一C語(yǔ)言,運(yùn)用恰當(dāng)?shù)脑~法分析技術(shù)線(xiàn)路,設(shè)計(jì)和實(shí)現(xiàn)其對(duì)應(yīng)的詞法分析器。種別編碼12345610112要求1) .給出一簡(jiǎn)單語(yǔ)言單詞符號(hào)的種別編碼單詞符號(hào)begi nifthe n while do end l ( l I d )2) .詞法分析程序的功能輸入是源程序字符串,以 #'結(jié)束輸出是單詞符號(hào)的二元組分析器輸出結(jié)果存入到磁盤(pán)文件中,具有出錯(cuò)處理功能3) .

38、建議和提示:技術(shù)線(xiàn)路選擇如下兩種之一: 正則式NFA DFA min DFA 程序設(shè)計(jì)或 正則文法NFA DFA min DFA 程序設(shè)計(jì)。系統(tǒng)分析詞法分析器對(duì)應(yīng)的正則文法表達(dá)如下:S 標(biāo)示符或關(guān)鍵字|數(shù)字字符|運(yùn)算符標(biāo)示符或關(guān)鍵字characterAA character| number|(標(biāo)示符或關(guān)鍵字要以字母開(kāi)頭)數(shù)字字符一 number| :(數(shù)字字符只能由數(shù)字組成)character a|b|c |y|z|A|B|C |Y|Znumber 一 0|1|2|3|4|5|6|7|8|9運(yùn) 一算符v>|v|v=|>|>=|:|:=|+H*|/|=|;|(|)|n該詞法分析

39、程序要識(shí)別的字符類(lèi)別包括關(guān)鍵字,標(biāo)示符,數(shù)字字符,運(yùn)算符,結(jié)束符# '。這里把關(guān)鍵字和標(biāo)示符歸 為同一類(lèi),識(shí)別完之后根據(jù)查標(biāo)示符表得到是標(biāo)示符還是關(guān)鍵 字。因此對(duì)于自動(dòng)機(jī)DFA 來(lái)說(shuō),有幾個(gè)相應(yīng)的狀態(tài),對(duì)應(yīng)識(shí) 別不同單詞串。當(dāng)然詞法分析程序還要有過(guò)濾空格字符,注釋 符號(hào),回車(chē)換行符等一些特殊字符。當(dāng)詞法分析器遇到符 號(hào)# '的時(shí)候就表示詞法分析已經(jīng)完成,程序結(jié)束。三、系統(tǒng)設(shè)計(jì)基于以上的討論,我設(shè)計(jì)了本實(shí)驗(yàn)詞法分析器的有限自動(dòng)機(jī)的每當(dāng)讀入完一個(gè)字符串后,自動(dòng)機(jī)回到開(kāi)始狀態(tài) S,讀入 下一個(gè)字符串的第一個(gè)字母。這里所說(shuō)的字符串是指標(biāo)示符或 者關(guān)鍵字或者數(shù)字或者特殊符號(hào)。當(dāng)讀入的第一

40、個(gè)字符是字母的時(shí)候說(shuō)明這個(gè)狀態(tài)機(jī)要識(shí)別 的是標(biāo)示符或者字符串,后面的字符可以是字母或者數(shù)字。所 以在標(biāo)示符或關(guān)鍵字狀態(tài)的時(shí)候讀入的下一個(gè)字符是字母或者 是數(shù)字的時(shí)候其狀態(tài)還是會(huì)轉(zhuǎn)向自己;當(dāng)讀入的下個(gè)字符是回 車(chē)或空格的時(shí)候表示識(shí)別完成;當(dāng)讀入的下個(gè)字符是特殊符號(hào) 的時(shí)候(非字母或數(shù)字)按正常思維狀態(tài)應(yīng)轉(zhuǎn)向出錯(cuò)處理,不 過(guò)由于本實(shí)驗(yàn)是詞法分析,標(biāo)示符不合法應(yīng)該是語(yǔ)義分析階段 做的事,所以本程序沒(méi)有給出出錯(cuò)處理。識(shí)別字符串后還應(yīng)區(qū) 分這個(gè)單詞是標(biāo)示符還是關(guān)鍵字。實(shí)現(xiàn)過(guò)程是查關(guān)鍵字表,將 識(shí)別的字符串同關(guān)鍵字表中的每一個(gè)元素比較,若有相同則說(shuō) 明識(shí)別的是關(guān)鍵字,否則是標(biāo)示符。當(dāng)讀入的第一個(gè)字符是數(shù)字

41、的時(shí)候說(shuō)明這個(gè)狀態(tài)機(jī)要識(shí)別 的是數(shù)字。后面的字符可以是數(shù)字,表示多位數(shù)。所以在數(shù)字 狀態(tài)的時(shí)候讀入的下一個(gè)字符是數(shù)字的時(shí)候其狀態(tài)還是會(huì)轉(zhuǎn)向 自己;當(dāng)讀入的下個(gè)字符是回車(chē)或空格的時(shí)候表示識(shí)別完成; 當(dāng)讀入的下個(gè)字符非數(shù)字時(shí)候,會(huì)發(fā)生語(yǔ)義錯(cuò)誤,本程序是詞 法分析所以沒(méi)有給出。當(dāng)讀入的第一個(gè)字符是特殊字符的時(shí)候說(shuō)明這個(gè)狀態(tài)機(jī)要 識(shí)別的是特殊字符。雙目特殊字符(如:=,>=等)后面的字符還可 以是特殊字符。所以在特殊字符狀態(tài)的時(shí)候讀入的下一個(gè)字符 是特殊字符的時(shí)候其狀態(tài)還是會(huì)轉(zhuǎn)向自己;當(dāng)讀入的下個(gè)字符 是回車(chē)或空格的時(shí)候表示識(shí)別完成;當(dāng)讀入的下個(gè)字符非數(shù)字 時(shí)候,狀態(tài)機(jī)理應(yīng)轉(zhuǎn)向出錯(cuò)處理,不過(guò)本程

42、序同樣沒(méi)有給出。最后程序讀入符號(hào) # '時(shí),說(shuō)明源程序讀入完畢,程序 結(jié)束。四.系統(tǒng)實(shí)現(xiàn)程序流程圖如下所示:其中syn=O ,表示讀到的字符是 # '。關(guān)鍵字表設(shè)置代碼如下:the nchar*rwtab6=“ beg in ” ,“ ifwhiledo , end ;這里只給出了六個(gè)常用的關(guān)鍵字,真正的編譯器的話(huà)應(yīng)該給出所有的關(guān)鍵字。掃描子程序算法:匹配否貝0置syn=11關(guān)鍵字 標(biāo)示符置 Syn=1-6 置 syn=10程序源代碼如下:#in clude<stdio.h>#in clude<stri ng.h>char prog80,token8;/

43、prog存儲(chǔ)源程序字符串,token存儲(chǔ)單個(gè)字符char ch;FILE * fp;int syn, p, m, n ,sum ;char *rwtab 6= "begi n","if","the n","while","do","e nd" ;void sca ner();void main (i nt argc,char* argv)p=0;fp=fope n("./i nput.txt","r");if(!fp) prin tf(

44、"File ope n error!n");do ch=getc(fp);progp+=ch ; while ( ch!='#');p=0;fp=fope n("./output.txt","w");if(!fp) printf("File open error!n");dosea ner();switch(s yn) case 11:fpri ntf (fp,"%2d",sy n);fprintf (fp,"%8dn",sum);break;/ 輸出數(shù)字ca

45、se -1:fprintf(fp,"input error'n");break; /出錯(cuò)/過(guò)濾回車(chē)/輸出保留字或者case 29: break;default:fpri ntf (fp,"%2d",sy n);標(biāo)識(shí)符fprintf (fp,"%8sn",toke n);while (sy n!=0);fclose(fp);void scaner() /詞法掃描子程序m=0,sum=0;for ( n=0; *8; n+ ) toke nn =NULL;/toke n 置為空ch=progp+; /讀入源程序中的一個(gè)字母whil

46、e (ch=' ') ch=progp+ ;/ 跳過(guò)空格if(ch>='A'&&chv二'Z')|(ch>='a'&&ch<='z')(ch>='A'&&ch<='Z')|(ch>='a'&&ch<='z')|(ch>='0'&&ch<='9')/為字母字符或數(shù)字字符toke n m+=c

47、h;ch二progp+;tokenm+二'0:/ 插入空格P-;syn=10;/種別編碼for (n=0 ; n<6; n+ )if(strcmp(toke n,rwtab n )=0)token存儲(chǔ)的是保留字,重新確定syn的值syn二n+1;break ;elseif (ch>='0'&&ch<=9)while/如果 while (ch>='0'&&ch<='9')sum二sum*1O+ch-'O: ch二progp+;P-;syn=11;/ 數(shù)字的 syn 為 1

48、1elseswitch(ch)case '<':m=0; toke n m+=ch;ch=progp+;if (ch='>')/ 字符為 v> syn二 21; toke n m+=ch;else if (ch='=')/ 字符為 <二 syn二 22; toke n m+二ch;else syn=20; / 字符就是 <p-;break;case '>':m=0; toke n m+=ch;ch=progp+;if (ch='=')/ 字符為 >= syn二 24; to

49、ke n m+=ch;else/字符為> syn=23;p-;break;case ':':m=0; toke n m+=ch;ch=progp+;if (ch='=')/ 字符為:二 syn=18; toke n m+=ch;else /字符為: syn=18; p-;break;case '+': syn=13; token0=ch; break;case '-': syn=14; toke n0 =ch; break;case '*': syn=15; toke n0 =ch; break;case '

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論