編譯原理課程設(shè)計(jì)報(bào)告_第1頁
編譯原理課程設(shè)計(jì)報(bào)告_第2頁
編譯原理課程設(shè)計(jì)報(bào)告_第3頁
編譯原理課程設(shè)計(jì)報(bào)告_第4頁
編譯原理課程設(shè)計(jì)報(bào)告_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、精選優(yōu)質(zhì)文檔-傾情為你奉上編譯原理課程設(shè)計(jì)報(bào)告1、 分析通過設(shè)計(jì),編制,調(diào)試一個(gè)語法及語義分析程序,加深對語法及語義分析原理的理解。IF 布爾表達(dá)式 THEN 賦值語句 ELSE 賦值語句 其中(1)、可以選擇遞歸下降法、LL(1)、算符優(yōu)先分析法、LR法完成以上任務(wù),中間代碼選用四元式。 (2)、 寫出符合分析方法要求的文法,給出分析方法的思想,完成分析程序設(shè)計(jì)。(3)、 編制好分析程序后,設(shè)計(jì)若干用例,上機(jī)測試并通過所設(shè)計(jì)的分析程序。2、 算法設(shè)計(jì) 程序要求有三部分組成,即詞法分析、語法分析、以及語義分析。其中詞法分析部分要求完成對輸入程序關(guān)鍵字、標(biāo)識(shí)符、常數(shù)、運(yùn)算符進(jìn)行識(shí)別;并分析詞法分

2、析的結(jié)果,檢查程序輸入的關(guān)鍵字是否為符合設(shè)計(jì)文法的關(guān)鍵字,檢查標(biāo)志符是否是合法標(biāo)志符,識(shí)別運(yùn)算符的種類。語法分析部分主要是以算符優(yōu)先文法的設(shè)計(jì)思想和步驟完成對詞法分析結(jié)果的的語法分析工作,判斷輸入的程序是否符合設(shè)計(jì)的IF-THEN-ELSE文法。在語法分析通過的基礎(chǔ)上進(jìn)行語義分析,其主要任務(wù)是完成對語法分析后的程序的語義分析,根據(jù)語法制導(dǎo)翻譯去翻譯輸入的程序,從而得到程序的中間代碼表示形式四元式。 詞法分析、語法分析和語義分析的流程圖如下:(1) 詞法分析A 詞法分析器的功能和輸出形式輸入:所給文法的源程序字符串輸出:二元組(單詞種別,單詞符號(hào)的屬性值)構(gòu)成的序列B. 待分析的簡單語言的詞法因

3、為是模擬簡單編譯器, 所以就以C語言的小型子集作為模擬編譯器的詞法.模擬程序語言的單詞符號(hào)可分為下列五種; 關(guān)鍵字: (相當(dāng)于Pascal語言中的begin) , if ,else , while , (相當(dāng)于Pascal語言中的end ) 所有的關(guān)鍵字都是小寫字母 . 運(yùn)算符: + , - , * , / , = , < , <= , = , > , >= ,<> , && ,| , ! 界 符: 逗號(hào) ,分號(hào) ,左圓括號(hào) , 右圓括號(hào) , # 常 數(shù): 在這里只涉及到int型常量 其他單詞是標(biāo)識(shí)符(ID)和整形常數(shù)(NUM),通過以下正規(guī)

4、式定義: ID = letter(letter|digit)*NUM = digit digit *空格由空白,制表符和換行符組成,空格一般用來分隔ID,NUM,運(yùn)算符,界符和關(guān)鍵字,詞法分析階段通常會(huì)被過濾掉。C.詞法分析的設(shè)計(jì)思想:算法的基本任務(wù)是從字符串表示的源程序中識(shí)別出其具有獨(dú)立意義的單詞符號(hào), 其基本思想是根據(jù)掃描到的單詞符號(hào)的第一個(gè)字符的種類, 拼出相應(yīng)的單詞符號(hào)。(2)語法分析語法分析要處理的輸入是詞法分析的輸出即單詞序列。該部分主要用到兩個(gè)棧,一個(gè)用來保存單詞標(biāo)志號(hào)的狀態(tài)棧另一是用來保存單詞本身信息的符號(hào)棧。程序從詞法分析輸出的單詞序列中讀取一個(gè)單詞,檢查單詞是否是合法單詞,

5、如果是合法的,則取符號(hào)棧的棧頂元素,和當(dāng)前單詞的標(biāo)志號(hào)進(jìn)行優(yōu)先級(jí)比較,如果小于當(dāng)前單詞的優(yōu)先級(jí)那么將當(dāng)前單詞壓入符號(hào)棧,將其標(biāo)志號(hào)壓入狀態(tài)棧;如果大于當(dāng)前單詞的優(yōu)先級(jí)那么繼續(xù)彈出狀態(tài)棧的元素,和上一個(gè)符號(hào)棧彈出的元素進(jìn)行比較,如果兩優(yōu)先級(jí)相等則繼續(xù)彈,如果小于上一次彈出的元素的優(yōu)先級(jí),則彈的所有元素按先后彈的倒置順序排列為一個(gè)句柄,查找產(chǎn)生式找到相應(yīng)的產(chǎn)生式進(jìn)行規(guī)約,把規(guī)約或的元素當(dāng)多當(dāng)前一的元素繼續(xù)進(jìn)行比較,直到詞法分析輸出結(jié)果全部遍歷完。在規(guī)約的過程中記下規(guī)約的次數(shù),和每次規(guī)約的元素,以便語義分析和中間代碼生成。(3) 語義分析語義分析主要是將語義分析結(jié)果轉(zhuǎn)化成三地址碼表示的中間代碼的過程

6、。在語法分析的過程中,在每次規(guī)約的過程中記錄規(guī)約的類型和各個(gè)類型規(guī)約的次數(shù)。即當(dāng)規(guī)約的語句是布爾表達(dá)式時(shí)每規(guī)約一次都將規(guī)約的語句轉(zhuǎn)化成三地址碼的形式保存在字符串E中并記錄E中規(guī)約產(chǎn)生式的次數(shù)在m1.quad中;如果規(guī)約的產(chǎn)生式是第一個(gè)賦值語句塊中的賦值語句,則將規(guī)約的產(chǎn)生式以三地址形式保存在字符串B1中并記錄B1中規(guī)約產(chǎn)生式的次數(shù)在m2.quad中;如果規(guī)約的產(chǎn)生式是第二個(gè)賦值語句塊中的賦值語句,則將規(guī)約的產(chǎn)生式以三地址形式保存在字符串B2中并記錄B2中規(guī)約產(chǎn)生式的次數(shù)在 m3.quad中。最后控制將B1、B2和E中的內(nèi)容輸入。3、 LL(1)文法 LL(1)文法分析流程圖: 構(gòu)造不帶回溯的自

7、上而下分析的文法條件1. 文法不含左遞歸,2. 對于文法中每一個(gè)非終結(jié)符A的各個(gè)產(chǎn)生式的候選首符集兩兩不相交。即,若Aa 1|a 2|a n 則 FIRST(a i)FIRST(a j)f (i¹j)3. 對文法中的每個(gè)非終結(jié)符A,若它存在某個(gè)候選首符集包含e,則FIRST(A)FOLLOW(A)=f如果一個(gè)文法G滿足以上條件,則稱該文法G為LL(1)文法。構(gòu)造預(yù)測分析表的步驟:對每個(gè)產(chǎn)生式Aa1|an執(zhí)行,。對FIRST(A)中每個(gè)終結(jié)符a, 把Aai加入到MA,a, 其中a FIRST(ai)若FIRST(ai), 則對任何屬于FOLLOW(A)的終結(jié)符b,將A ai加入MA,b

8、。把所有無定義的MA,a標(biāo)記為出錯(cuò)。在上面的屬性文法中我們使用了這樣的假定:每當(dāng)需要臨時(shí)變量時(shí),newtemp產(chǎn)生新的臨時(shí)名字; lookup()用于根據(jù)名字的拼寫檢查符號(hào)表中是否存在該名字的條目。如果有,返回該條目的指針,否則lookup返回nil,以表示沒有找到;E的屬性place用來存放E值的變量名在符號(hào)表的登錄項(xiàng)或一整數(shù)碼(若此變量是一個(gè)臨時(shí)變量);函數(shù)newtemp用來產(chǎn)生一個(gè)新的臨時(shí)變量的名字,把該名字也存入符號(hào)表,并返回該條目的地址。過程emit將其參數(shù)寫到輸出文件上。emit的參數(shù)構(gòu)成一個(gè)三地址語句;變量nextstat給出在輸出序列中下一個(gè)三地址語句的序號(hào),em

9、it在產(chǎn)生每個(gè)三地址語句后將nextstat加1。我們給relop以屬性op,用來確定該關(guān)系算符究竟代表哪個(gè)關(guān)系運(yùn)算。E.true,E.falsen和S.next都是三地址語句的標(biāo)號(hào),它們都是繼承屬性.。E.true和E.false分別表示E為真和為假時(shí)控制流應(yīng)該轉(zhuǎn)向的標(biāo)號(hào),這兩個(gè)屬性由E的上下文決定;S.next表示執(zhí)行完S后應(yīng)該執(zhí)行的第一個(gè)三地址語句的標(biāo)號(hào),它也是由S的上下文決定語法分析方法描述開始時(shí),將"#"和文法開始符號(hào)放入棧底??偪爻绦蛟谌魏螘r(shí)候都是根據(jù)棧頂符號(hào)X和當(dāng)前的輸入符號(hào)進(jìn)行工作的,它與文法無關(guān) 總控程序根據(jù)現(xiàn)行棧頂符號(hào)X和當(dāng)前輸入符號(hào)a,執(zhí)行下列三種動(dòng)作

10、之一:1. 若Xa,則宣布分析成功,停止分析。2. 若Xa ,則把X從STACK棧頂逐出,讓指針指向下一個(gè)輸入符號(hào)。3.若X是一個(gè)非終結(jié)符,則查看分析表M。 若MX,a中存放著關(guān)于X的一個(gè)產(chǎn)生式,把X逐出STACK棧頂,把產(chǎn)生式的右部符號(hào)串按反序一一推進(jìn)STACK棧(若右部符號(hào)為,則意味不推什么東西進(jìn)棧)。在把產(chǎn)生式的右部符號(hào)推進(jìn)棧的同時(shí)應(yīng)做這個(gè)產(chǎn)生式相應(yīng)的語義動(dòng)作。若MX,a中存放著“出錯(cuò)標(biāo)志”,則調(diào)用出錯(cuò)診察程序ERROR。四、詳細(xì)設(shè)計(jì)4.1 語法規(guī)則定義的文法,如下: (0) Z-àS(1) S-àAB(2) A->CDE(3) C-àvoid(4)

11、D-àmain(5) E-à()(6) B-àF(7) F-àGF(8) F-àG(9) G->HIJ(10) H-àint(11) I-àKLM(12) K-àcharacter(13) L-à=(14) M->num(15) J-à4.2程序流程圖語法分析是編譯程序的核心部分,其主要任務(wù)是確定語法結(jié)構(gòu),檢查 語法錯(cuò)誤,報(bào)告錯(cuò)誤的性質(zhì)和位置,并進(jìn)行適當(dāng)?shù)募m錯(cuò)工作.法分析的方法有多種多樣,常用的方法有遞歸子程序方法、運(yùn)算符優(yōu)先數(shù)法、狀態(tài)矩陣法、LL(K)方法和LR(K)方法。歸納起來

12、,大體上可分為兩大類,即自頂向下分析方法和自底向上分析方法. Syntax進(jìn)行語法分析.對于語法分析,這里采用LR(1)分析法,判斷程序是否滿足規(guī)定的結(jié)構(gòu).構(gòu)造LR(1)分析程序,利用它進(jìn)行語法分析,判斷給出的符號(hào)串是否為該文法識(shí)別的句子,了解LR(K)分析方法是嚴(yán)格的從左向右掃描,和自底向上的語法分析方法。4.3基本樹形結(jié)構(gòu):if語句: if語句表達(dá)式語句語句while語句:while語句表達(dá)式語句表達(dá)式語句表達(dá)式for語句表達(dá)式for循環(huán)語句:復(fù)合語句:語句復(fù)合語句語句語句聲明五、 實(shí)驗(yàn)結(jié)果要編譯的文件:詞法分析:輸出的四元式:六、 心得體會(huì)這段時(shí)間的課程設(shè)計(jì)讓我知道計(jì)算機(jī)將高級(jí)語言翻譯成

13、機(jī)器語言的過程,并且體會(huì)到了中間的設(shè)計(jì)分析處理過程,再一次熟悉了C語言的編寫。也學(xué)到了許多課本上沒寫的東西,在實(shí)驗(yàn)的編寫中有許多的坎坷,但是在大家集體和老師的幫助下,都慢慢的克服,也沒有什么困難是不可克服的!經(jīng)過這個(gè)實(shí)驗(yàn),也深入體會(huì)到計(jì)算機(jī)的內(nèi)部世界,進(jìn)一步的摸清楚計(jì)算機(jī)的構(gòu)架。為以后的學(xué)習(xí)工作再一次奠定了基礎(chǔ),受益匪淺!七、 源代碼#include<iostream.h>#include<fstream.h>#include<string.h>#include<iomanip.h>#include<malloc.h>enum key

14、word $right_paren,$left_paren,$mul,$div,$add,$sub,$fenhao, $equal,$IF,$THEN,$ELSE,$greater,$less,$id,$num,$end;/關(guān)鍵字的枚舉typedef struct Tokenkeyword type;char ch;Token;/定義的token結(jié)構(gòu)typedef enumJUMP,JG,JL,equal,END,add,mul,sub,divOpKind;/操作符定義為opkindtypedef structint label;/標(biāo)號(hào)OpKind op;/操作符char par1,par2;

15、/操作數(shù)unionchar result;/結(jié)果int address;/地址;Quad; /四元式入口#define MAX_TOKEN 256/Token表大小#define MAX_QUAD 256/四元式數(shù)組大小Token tokentableMAX_TOKEN;Quad quadMAX_QUAD;int token_index;/token表索引int total_len;/token表有效長度int quad_len;/四元式表有效長度int quad_index;/四元式索引Token cur;Token queue10;int label,k,one; /標(biāo)記接口char cu

16、rchar;/存儲(chǔ)當(dāng)前待比較字符char curtocmp;/存儲(chǔ)當(dāng)前棧頂字符ifstream ins;int trueadd,falseadd,end; int table58=1,0,0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,1,0,0,0,1,1,1,1,0,1,1,1,0,0,0,0,1,0,0; /存儲(chǔ)預(yù)測分析表,1為有產(chǎn)生式,0為沒有int i,j;int flag;struct Lcharchar char_ch;struct Lchar *next;Lchar,*temp,*top,*base;int right;/定義開關(guān)項(xiàng)bool init

17、ialize(char filename255);/文件打開初始化bool accidence();/詞法分析void print();/輸出單詞表void backpath(int,int);/回填出口void ERROR();void sentence();/分析語句void boolean();/ 分析E->id < id | id > id語句bool nexttoken();/讀下一單詞char newchar();void push();/進(jìn)隊(duì)列char dosome(void);/算法函數(shù)void pushs(char pchar);/入棧函數(shù)void pop(

18、void);/出棧函數(shù)void doforpush(int t);/根據(jù)數(shù)組下標(biāo)計(jì)算的值產(chǎn)生式入棧void changchartoint();/根據(jù)curchar,curtocmp轉(zhuǎn)為數(shù)字以判斷是否有產(chǎn)生式void semantic();/語法語義分析char LL1();/LL(1)文法分析void printQuad();/輸出四元式void ERROR(char str20);void AD_ADDRESS(int nlabel,OpKind nop,char npar1,char npar2,int naddress);void AD_RESULT(int nlabel,OpKind

19、nop,char npar1,char npar2, char nresult);void main() cout<<" "<<endl <<" 基于LL(1)法的條件語句語法語義分析程序 "<<endl <<" "<<endl;cout<<"輸入您要編譯編譯文件的文件名(文件名.txt):"char fname100;cin>>fname;if(!initialize(fname)/初始化文件return;if(!ac

20、cidence()/詞法分析return;char ch;while(1)if(ins.eof()/ifstream ins;文件輸入串,若文件已完。則break break;ins>>ch;/繼續(xù)讀入文件內(nèi)容cout<<endl<<"詞法分析結(jié)果如下:"print();/打印詞法分析的結(jié)果cout<<endl;cout<<"詞法分析結(jié)束。"<<endl<<endl;semantic(); /語法語義分析cout<<endl<<"輸出四元

21、式:"<<endl;printQuad();/輸出四元式if(right=1)cout<<"分析成功"<<endl;elsecout<<"分析失敗"<<endl;cout<<"語法語義分析結(jié)束"<<endl;char newchar() char p; p=char(k); /int label,k,one; /標(biāo)記接口k+;return p; /文件打開初始化bool initialize(char filename100) one=0;t

22、oken_index=0;/token表索引total_len=0;/token表有效長度quad_len=0;/四元表有效長度quad_index=0;/四元表索引label=0; /int label,k,one; /標(biāo)記接口end=0;/ 前面定義的全局變量int trueadd,falseadd,end; k=48;ins.open(filename,ios:nocreate | ios:in);if(ins.fail()cout<<"文件打開出錯(cuò)!"<<endl;return false;return true;/詞法分析bool acci

23、dence()int k=0;char buf16;/暫存數(shù)組單元char ch;while(1)ins>>ch;if(ins.fail()break;while(ch=' ')ins>>ch;if(ch='I')ins>>buf; /對關(guān)鍵字分析if(strcmp(buf,"F")=0)tokentabletotal_len+.type=$IF;else if(ch='T')ins>>buf;if(strcmp(buf,"HEN")=0)tokentable

24、total_len+.type=$THEN;else if(ch='E')ins>>buf;if(strcmp(buf,"LSE")=0)tokentabletotal_len+.type=$ELSE; /對關(guān)系運(yùn)算符分析else if(ch='>')tokentabletotal_len+.type=$greater;else if(ch='<')tokentabletotal_len+.type=$less;else if(ch='=')tokentabletotal_len+.ty

25、pe=$equal; /對字母的分析else if(ch>='A'&& ch<='Z' )| (ch>='a' && ch<='z')tokentabletotal_len.type=$id;tokentabletotal_len+.ch=ch;/對數(shù)字的分析else if(ch>='0' && ch<='9')tokentabletotal_len.type=$num; tokentabletotal_len+.c

26、h =ch;Else /采用switch語句對運(yùn)算符,括號(hào)分析switch (ch)case '+' :tokentabletotal_len.type=$add; tokentabletotal_len+.ch =ch; break; case '-' :tokentabletotal_len.type=$sub; tokentabletotal_len+.ch =ch; break; case '/' : tokentabletotal_len.type=$div; tokentabletotal_len+.ch =ch; break; ca

27、se '*' :tokentabletotal_len.type=$mul; tokentabletotal_len+.ch =ch;break; case '' :tokentabletotal_len.type=$fenhao; tokentabletotal_len+.ch =ch;break;case '(' :tokentabletotal_len.type=$left_paren; tokentabletotal_len+.ch =ch; break;case ')' :tokentabletotal_len.type

28、=$right_paren; tokentabletotal_len+.ch =ch;break; default:cout<<"!"<<endl; return true;/詞法分析結(jié)束/語法語義分析void semantic() if(!nexttoken()ERROR("s(0)"); cout<<"開始進(jìn)行語法語義分析:"<<endl <<"所使用的產(chǎn)生式:"<<endl <<"<if語句> ->

29、 if E then S else S"<<endl <<"S->if E then p1 else P2"<<endl <<"E->a>b"<<endl <<"P1->x:=a*c"<<endl <<"P2->x:=b*c"<<endl <<"語法語義分析過程如下:"<<endl; if(cur.type=$IF) bool

30、ean();/分析布爾語句 if(!nexttoken()ERROR("S(0)");if(cur.type=$THEN) backpath(trueadd,quad_len);/回填出口sentence();/分析語句end=quad_len; AD_ADDRESS(quad_len,JUMP,'-','-',end); /產(chǎn)生跳轉(zhuǎn)地址的四元式 if(cur.type=$ELSE)backpath(falseadd,quad_len); sentence(); backpath(end,quad_len); elseERROR("

31、S(else)");elseERROR("S(then)"); elseERROR("S(if)");AD_RESULT(quad_len,END,0,0,'-'); /產(chǎn)生數(shù)值語句的四元式/讀下一單詞bool nexttoken()if(token_index>=total_len)return false;if(tokentabletoken_index.type=$fenhao)token_index+;cur.type=tokentabletoken_index.type;cur.ch=tokentabletoke

32、n_index.ch;token_index+;return true;/進(jìn)隊(duì)列void push() one=0; while(tokentabletoken_index.type!=$fenhao) queueone.type=tokentabletoken_index.type;queueone.ch=tokentabletoken_index.ch;cout<<queueone.ch;token_index+;one+; queueone.type=$end; queueone.ch='#'cout<<queueone.ch;/隊(duì)列下一個(gè)字符vo

33、id next() cur.type=queueone.type; cur.ch =queueone.ch ; one+;/ 分析E->id < id | id > id語句void boolean() char a,b;int c; if(!nexttoken()ERROR("E(0)");if(cur.type=$id|cur.type=$num)a=cur.ch;if(!nexttoken()ERROR("E(0)"); if(cur.type=$greater|cur.type=$less) c=cur.type ;if(!ne

34、xttoken() ERROR("E(0)");if(cur.type=$id|cur.type=$num) b=cur.ch;else ERROR("E(id/num)"); if(c=$greater) trueadd=quad_len-1; falseadd=quad_len; AD_ADDRESS(quad_len,JG,a,b,trueadd); AD_ADDRESS(quad_len,JUMP,0,0,falseadd); else trueadd=quad_len; falseadd=quad_len+1; AD_ADDRESS(quad_

35、len,JL,a,b,trueadd); AD_ADDRESS(quad_len,JUMP,0,0,falseadd); else ERROR("E(id/num)");elseERROR("E(greater/less)");/分析語句void sentence() char rtn; char c;if(!nexttoken() ERROR("S(0)");if(cur.type=$id) c=cur.ch;if(!nexttoken() ERROR("S(0)");if(cur.type!=$equal)ER

36、ROR("S(equal)");push();one=0;rtn=LL1(); AD_RESULT(quad_len,equal,rtn,'-',c);nexttoken();while(cur.type=$id)c=cur.ch;if(!nexttoken() ERROR("S(0)");if(cur.type!=$equal)ERROR("S(equal)");push();one=0;rtn=LL1(); AD_RESULT(quad_len,equal,rtn,'-',c);nexttoken(

37、);/LL(1)文法分析char LL1() right=1;/開關(guān)項(xiàng)為1flag=0;char t;base=(struct Lchar *)malloc(sizeof(Lchar);/初始化堆棧base->next=NULL;base->char_ch='#'temp=(struct Lchar *)malloc(sizeof(Lchar);temp->next=base;temp->char_ch='E'top=temp;/初始化堆棧 t=dosome();/開始識(shí)別if(right)/如果開關(guān)項(xiàng)為1cout<<&quo

38、t;OK!"<<endl<<endl;elsecout<<"Error!"<<endl; return t;/入棧函數(shù)void pushs(char pchar) temp=(struct Lchar *)malloc(sizeof(Lchar);temp->char_ch=pchar;temp->next=top;top=temp;/出棧函數(shù)void pop(void) curtocmp=top->char_ch;if(top->char_ch!='#')top=top-&g

39、t;next; /根據(jù)數(shù)組下標(biāo)計(jì)算的值產(chǎn)生式入棧void doforpush(int t) switch(t)case 0:pushs('A');pushs('T');break;case 5:pushs('A');pushs('T');break;case 11:pushs('A');pushs('T');pushs('+');break;case 12:pushs('A');pushs('T');pushs('-');break;c

40、ase 20:pushs('B');pushs('F');break;case 25:pushs('B');pushs('F');break;case 33:pushs('B');pushs('F');pushs('*');break;case 34:pushs('B');pushs('F');pushs('/');break;case 40:pushs('i');break;case 45:pushs(')&#

41、39;);pushs('E');pushs('(');/根據(jù)curchar,curtocmp轉(zhuǎn)為數(shù)字以判斷是否有產(chǎn)生式void changchartoint() switch(curtocmp)case 'A':i=1;break;case 'B':i=3;break;case 'E':i=0;break;case 'T':i=2;break;case 'F':i=4;switch(curchar)case 'i':j=0;break;case '+'

42、:j=1;break;case '-':j=2;break;case '*':j=3;break;case '/':j=4;break;case '(':j=5;break;case ')':j=6;break;case '#':j=7;/算法函數(shù)char dosome(void) int t,a=0;char bian1,bian2; OpKind opa;char c='$'next();for(;)pop();if(cur.type!=$id && cur.ty

43、pe!=$num)curchar=cur.ch;elsecurchar='i'cout<<endl;cout<<curchar<<" "<<curtocmp<<endl;if(curtocmp='#' && curchar='#')break;if(curtocmp='A' | curtocmp='B' | curtocmp='E' | curtocmp='T' | curtocmp=&#

44、39;F')/當(dāng)前字符為非終結(jié)符 if(curtocmp!='#')/當(dāng)前比較字符不為'#'changchartoint();if(j=0) a+;flag+; if(flag=1) if(c='$') bian1=cur.ch; elsebian1=c; else if(flag=3) bian2=cur.ch; flag=1; c=newchar(); AD_RESULT(quad_len,opa,bian1,bian2,c);/產(chǎn)生四元式else switch(j) case 1:opa=add;flag+;break; case

45、2:opa=sub;flag+;break; case 3:opa=mul;flag+;break; case 4:opa=div;flag+;if(tableij) /有產(chǎn)生式t=10*i+j; /計(jì)算產(chǎn)生式在數(shù)組中的位置doforpush(t);continue;else /沒有產(chǎn)生式right=0; /出錯(cuò)break;else /當(dāng)前比較字符為'#'if(curtocmp!=curchar)right=0;/出錯(cuò)break;elsebreak; /正確else /當(dāng)前字符為終結(jié)符if(curtocmp!=curchar)right=0; /出錯(cuò)break;elsenext

46、(); /讀取下一個(gè)字符continue;if(a>1) return c;elsereturn bian1;/產(chǎn)生數(shù)值語句的四元式void AD_RESULT(int nlabel,OpKind nop,char npar1,char npar2, char nresult)quadquad_len.label=nlabel; quadquad_len.op=nop; quadquad_len.par1=npar1; quadquad_len.par2=npar2; quadquad_len.result=nresult; quad_len+; /產(chǎn)生跳轉(zhuǎn)地址的四元式void AD_A

47、DDRESS(int nlabel,OpKind nop,char npar1,char npar2,int naddress) quadquad_len.label=nlabel; quadquad_len.op=nop;quadquad_len.par1=npar1;quadquad_len.par2=npar2; quadquad_len.address=naddress;quad_len+; /回填出口void backpath(int nlabel,int addr)quadnlabel.address=addr;/錯(cuò)誤處理void ERROR(char str20) label+;

48、cout<<endl;cout<<"error! "<<str<<endl;/詞法分析。輸出單詞表tokenvoid print() for(token_index=0;token_index<total_len;token_index+) if(token_index%100=0) cout<<endl;if(tokentabletoken_index.type=$IF)cout<<setw(2)<<"IF (0),"if(tokentabletoken_inde

49、x.type=$ELSE)cout<<setw(2)<<" ELSE (1),"if(tokentabletoken_index.type=$THEN)cout<<setw(2)<<" THEN (-),"if(tokentabletoken_index.type=$id) /字母cout<<setw(2)<<""<<tokentabletoken_index.ch<<" (25)"<<",&quo

50、t;if(tokentabletoken_index.type=$num) /數(shù)字cout<<setw(2)<<""<<tokentabletoken_index.ch<<" (26)"<<","if(tokentabletoken_index.type=$equal)cout<<setw(2)<<""<<'='<<" (18)"<<","i

51、f(tokentabletoken_index.type=$greater)cout<<setw(1)<<""<<'>'<<" (22)"<<","if(tokentabletoken_index.type=$less)cout<<setw(2)<<""<<'<'<<" (22)"<<"," if(tokentab

52、letoken_index.type=$add)cout<<setw(2)<<""<<'+'<<" (14)"<<","if(tokentabletoken_index.type=$sub)cout<<setw(2)<<""<<'-'<<" (15)"<<","if(tokentabletoken_index.type=$mu

53、l)cout<<setw(2)<<""<<'*'<<" (16)"<<","if(tokentabletoken_index.type=$div)cout<<setw(2)<<""<<'/'<<" (17)"<<","if(tokentabletoken_index.type=$fenhao)cout<<setw(

54、2)<<""<<''<<" (6)"<<","if(tokentabletoken_index.type=$left_paren)cout<<setw(2)<<""<<'('<<" (23)"<<","if(tokentabletoken_index.type=$right_paren)cout<<setw(2)<<

55、;""<<')'<<" (24)"<<","token_index=0;/輸出四元式void printQuad()for(int i=0;i<quad_len;i+)if(quadi.label>-1)cout<<"("<<quadi.label<<")"<<": "else cout<<endl;if(quadi.op=JG)cout<<

56、"("<<"j>,"<<quadi.par1<<","<<quadi.par2<<","<<quadi.address<<")"<<endl;else if(quadi.op=JL)cout<<"("<<"j<,"<<quadi.par1<<","<<quadi.par2

57、<<","<<quadi.address<<")"<<endl;else if(quadi.op=JUMP)cout<<"("<<"j ,"<<"-,-,"<<quadi.address<<")"<<endl;else if(quadi.op=equal) if(quadi-1.result=quadi.par1)cout<<"(&qu

58、ot;<<":= ,"<<"T"<<quadi.par1<<",-,"<<quadi.result<<")"<<endl;else cout<<"("<<":= ,"<<quadi.par1<<",-,"<<quadi.result<<")"<<endl;else if(quadi.op=END)cout<<"("<<"-,-,-,-"<<")"

溫馨提示

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

評(píng)論

0/150

提交評(píng)論