版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、詞法分析程序+語法語義分析四元式生成+實驗報告記錄作者:日期:#編譯原理實驗報告本文檔集合了編譯原理大作業(yè)的實驗報告加代碼實驗主要內(nèi)容為用C+實現(xiàn)了詞法分析程序;語法語義以及四元式生成程序代碼見附錄,復(fù)制進(jìn)VS后程序絕對可編譯執(zhí)行。文檔代碼為原創(chuàng),謹(jǐn)慎使用(姚礪的大作業(yè))3實驗設(shè)計一、實驗名稱詞法分析程序二、實驗?zāi)康?1) 設(shè)計一個詞法分析程序,每調(diào)用一次就從源程序文件中順序識別出一個單詞符號,并返回 該單詞符號的內(nèi)部編碼、單詞符號自身、行列位置信息。(2) 要能處理單行注釋。三、實驗內(nèi)容及要求單詞種類與識別規(guī)則(1) 標(biāo)識符:首字符為字母或下劃線,其后由字母、數(shù)字或下劃線組成、長度不超過25
2、5個字符;(2) 整數(shù):由1到8個數(shù)字組成。(3) 小數(shù):數(shù)字串1 .數(shù)字串2,其中:數(shù)字串1由1-8個數(shù)字符組成;數(shù)字串2由0-8個數(shù)字符組成,即:數(shù)字串2可以為空。(4) 字符串:由一對“”括起來的符號串,長度不超過255個字符;(5) 保留字:if、else while、do、in teger、float、stri ng、in put、output、and、or、function、end、def、as、beg in(6) 數(shù)學(xué)運算符: +、*、/、=(7) 比較運算符: 、=、=、=(8) 邏輯運算符:and、or(9) 分隔符:、(、)、;、,四、實驗環(huán)境操作系統(tǒng):Win7/其他編譯工
3、具:VC+6.0/ CFree /VS2012五、設(shè)計1設(shè)計大體思路將讀取的文件采用一遍掃描的方法,即從左到右只掃描一次源程序,將讀取的數(shù)據(jù)存放在一個二維 數(shù)組里。然后通過掃描函數(shù) sea n,再從數(shù)組中一行一行的讀取數(shù)據(jù),每調(diào)用其依次返回一個單詞的 類型,同時單詞本身以及行列號存放在全局變量中。而說詞法分析作為語法分析的一個子程序,故 在編寫詞法分析程序時,將會反復(fù)調(diào)用scan函數(shù)來獲取一個個單詞信息。53設(shè)計流程圖1 1-3 r -和忙訂 j Jj ij !-j%' j- r. Jr4函數(shù)設(shè)計/*詞法分析函數(shù)*/int sea n( stri ng s ,int line )框架:
4、初始化工作是空格直接跳過,知直到讀取到一個字符if(是字母)查表判斷是否為關(guān)鍵字判斷是否為邏輯運算符and或orElse則為標(biāo)識符else if( 是否為數(shù)字 )判斷是整數(shù)Else是小數(shù)Else其余情況判斷是否為運算符,字符串等else if( getehar= ' / 'if( contentlinei+1='/')向前看一個,確定是否為行注釋;如果是,則游標(biāo)指向行末,跳過行注釋if( co nte ntli nei+1='/*')如果向前看一個發(fā)現(xiàn)時塊注釋則一直向前掃描直到出現(xiàn)“*/”停止,略過塊注釋如果都不是則Else判斷為除號,返回運算符
5、類型2對其中部分實現(xiàn)的說明(1)數(shù)字識別while (contentlinei>='O' && contentlinei<=9 )/ 判斷是否為數(shù)字text += conten tli nei;i+;flag=1;if ( flag=1 )if ( contentlinei='.')text += conten tli nei;i+;/判斷是否while ( contentlinei>='0' && contentlinei<=9 )11#為數(shù)字#return 3;/ 小數(shù)每讀入一個字符,判
6、斷是否數(shù)字,然后找小數(shù)點,找到即為小數(shù)(2)標(biāo)識符處理/判斷是否while ( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=122) | contentlinei>='O' && contentlinei<=9 )為數(shù)字或者字母或者下劃線text += conten tli nei;i+;for ( j=0; j<=13 ; j+ )if ( text=keyj)/查表判斷是否為保留
7、字return 5;檢查到讀取的字符為字母時,進(jìn)行查表判斷,找到即說明為關(guān)鍵字空格,注釋,行號的處理if( mode=0 )if( i<co nte ntke ngth() ) i+;/如果為行注釋直接跳到下一行elseif( mode=-1 )/如果為塊注釋找回行號k=templi ne;六、程序源代碼見源代碼文件。七、實驗數(shù)據(jù)、結(jié)果測試數(shù)據(jù)見文件湄試數(shù)據(jù)如下;functionIregfintenp3 til;此處變量春定義就使用def temple tunp2 as float此處少分號input tempi,temp2:def tenpl as float; /*此處變量重復(fù)定義*
8、/tenpl = 123;empl = tempi + tenp2; if tempi >= tenp2begintempi 123;+ 4*2;end else begin tempi endcnidend function數(shù)數(shù)數(shù)數(shù)感IW皺IWIB眾 列-1 4<2 果 11112 3 3 3 3 4 A 士口 - 8 I 婁戮蓼婁謝費婁 丁-T!- r-T-r - TJ- _J-T1-T' 為mtts列JMll119 9 3 9 1 s s 1 6 50 3 4013 3 11114 2 8 119-1 funct ion g: aaa單詞為:<單乎|應(yīng):hejg
9、in 單詞為;tempS勺:def八、總結(jié)之前的每周作業(yè)曾經(jīng)寫過一個詞法分析程序,所以這次寫詞法分析程序沒什么太多困難。在讀取源文件時,最初的想法是一行一行的讀取,讀一次就存一行,這樣可以節(jié)省空間資源,提高效 率。但是仔細(xì)一想考慮到塊注釋分布在不同的行中,而且這樣對行列的操作十分麻煩,而且許多地方 涉及到要向前看,(比如判斷注釋與/除號運算符時),最后只好一次全部讀完,存在一個二維數(shù)組中。 再用scan函數(shù)來處理。這樣一來行列的處理就自由多了。第二點,在寫scan函數(shù)的時候,最初的想法是每調(diào)用一次,返回一個單詞,然后在語法分析時 不斷調(diào)用它。但是僅僅返回單詞是不夠的,于是打算返回一個結(jié)構(gòu)體,把
10、單詞信息行列號什么的全部 存進(jìn)去,這個在后來的語法語義分析中可以看到,這里任然采用的是返回一個單詞類型。單詞本身, 和行列號作為全局變量保存。然后只要按照流程圖一步一步判斷,慢慢寫就行了,沒有太多難度,唯一要注意的是單詞位置行列的計算一定要細(xì)心。這個是要穿插在整個詞法分析的全部地方的。 所有涉及到讀入一個字符的地 方都需要考慮到如何修改行列變量。尤其是本程序拓展了塊注釋,要注意行列變化。13實驗設(shè)計二注:由于語義分析和四元式生成都是在語法分析的基礎(chǔ)上拓展得到的,這一章實驗報 告囊括了語法,語義和四元式。一、實驗名稱語法語義以及四元式分析程序二、實驗?zāi)康脑O(shè)計一個語法語義以及生成四元式的分析程序三
11、、實驗內(nèi)容及要求設(shè)計要求:構(gòu)造相應(yīng)文法的語法分析程序,應(yīng)能指出源程序中出現(xiàn)的錯誤。為語法分析程序中添加類型檢查功能,包括:變量重復(fù)定義;15 變量未定義就使用; 變量未賦值就引用;將語法正確的源程序翻譯成四元式。文法見附錄四、實驗環(huán)境操作系統(tǒng):Win7/其他編譯工具:VC+6.0/ CFree /VS2012五、設(shè)計1語法分析設(shè)計(1) 相關(guān)數(shù)據(jù)機(jī)構(gòu)struct Toke n Istri ng value; /值intmode;/類型introw;/行intcol;/列toke n;說明:這本應(yīng)是詞法分析時的結(jié)構(gòu),但是scan函數(shù)返回的是但單一值,于是又設(shè)計了Token函數(shù),對scan函數(shù)進(jìn)行
12、擴(kuò)充,每個單詞的信息均保存一次在結(jié)構(gòu)體中,方便錯誤報告函數(shù)進(jìn)行處理。(2) 各個非終結(jié)符函數(shù)形式/*/*語法語義 各產(chǎn)生式 函數(shù)*/void chengxu();void hanshukuai();void bianliangdingyiyuju();void shujuleixing();void shuruyuju();void shuchuyuju();void fuzhiyuju();void fenzhiyuju();void xunhuanyuju();void biaodashi();void xiang();void yinzi();void buerbiaodashi();v
13、oid guanxibiaodashi();void guanxi();其他函數(shù):void error();void warning();每個函數(shù)具體作用在代碼中都有注釋說明(3) 語法分析整體設(shè)計思路采用遞歸下降的方法,為每個非終結(jié)符設(shè)計一個函數(shù),在函數(shù)中對此處可能出現(xiàn)的語 法錯誤進(jìn)行處理。處理也語法錯誤的思路主要分兩種:1. 查找關(guān)鍵字由于進(jìn)行語法分析時檢查到錯誤不可能就此停下,要一次性盡量找到所有的錯誤,而且測試數(shù)據(jù)的語法錯誤形式千奇百怪,這就要求發(fā)現(xiàn)錯誤之后如何找到繼續(xù)進(jìn)行 分析的位置。這里對于一些不常見的錯誤采取查找關(guān)鍵字的方法,一旦出現(xiàn)錯誤在 相應(yīng)函數(shù)中查找下一個出現(xiàn)的關(guān)鍵字的位置
14、,然后繼續(xù)分析。2. 跳過錯誤單詞,直接分析下一個單詞由于查找關(guān)鍵字方法會跳過許多代碼,從而有可能造成一些信息不必要的遺漏。尤 其是對于漏分號這種錯誤,與是這里采取,直接當(dāng)前錯誤,默認(rèn)后續(xù)單詞可能就是 正確單詞,繼續(xù)分析。但是這個方法在一些地方并不適用,可能會導(dǎo)致一連串的錯誤出現(xiàn),于是在使用時要考慮好取舍編譯錯誤處理函數(shù):void error( Token token , char * msg/ 編譯錯誤處理函數(shù) |cout << "編譯錯誤:”;printf( "%s", msg; cout << endl <<"錯
15、誤位置:第"<< token .row<< "行,第"<< token .col <<"列-> "<< token.value;cout << en dl;cout << en dl;error nu m+;每出現(xiàn)錯誤時,通過傳遞錯誤信息參數(shù)以及單詞信息,調(diào)用編譯錯誤處理函數(shù)進(jìn)行實 時報錯。(3) 測試數(shù)據(jù)和結(jié)果見后文語義分析部分(4) 語法分析部分的小總結(jié)原本打算試試自底向上歸約方法設(shè)計的,結(jié)果想了想發(fā)現(xiàn)實在麻煩,老師給的文法又 挺龐雜的,創(chuàng)建分析表什么
16、的就要好久。后來一想用遞歸下降方法好處很多,做到之 后的語義分析和四元式生成的時候在語法分析的基礎(chǔ)上拓展很方便,整體框架非常清 晰。在錯誤處理方面考慮的還是挺合理的,對于一些常見錯誤都能有效指出。并且程 序只有一個出口,任何代碼輸入都會從那一個出口結(jié)束,不會引起程序崩潰。2、語義分析設(shè)計語義分析主要實現(xiàn)3個功能 變量重復(fù)定義; 變量未定義就使用; 變量未賦值就引用;(1) 相關(guān)數(shù)據(jù)結(jié)構(gòu)struct Symtable / 符號表結(jié)構(gòu)stri ng n ame;int type;bool value;S;structcompare: binary_function vSymtable, strin
17、g , bool > /仿函數(shù)和綁定器bool operator()( Symtable s, stringstr ) constif ( = str )return true ;elsereturn false ;相關(guān)函數(shù)void push_in_token(Token token )/ 進(jìn)表操作S.name = token .value;S.type = -1;S.value = false ;ST.push_back( S );vector <Symtable> : iterator find_token( Token token )/查表操作it = fi
18、nd_if( ST.begin(), ST.end(), bind2nd(compare(), token .value );return it;(2) 測試數(shù)據(jù)和結(jié)果(4)設(shè)計思路語義部分主要采用符號表結(jié)構(gòu),符號表中記錄了每個非終結(jié)符的信息。(名稱,類型,是否賦值)。然后再程序中每次調(diào)用 Token函數(shù)發(fā)現(xiàn)讀取到標(biāo)識符時都進(jìn)行查表操作。 根據(jù)查表結(jié)果進(jìn)行相關(guān)分析。在賦值函數(shù)中,如果查表找到其信息就說明重復(fù)定義。再其余函數(shù)中1沒有找到說明為聲明就使用。2找到發(fā)現(xiàn)未賦值說明未賦值就引用。(5)語義部分小總結(jié)假如只實現(xiàn)以上3個功能語義部分并不難,關(guān)鍵是符號表的構(gòu)建以及進(jìn)表查表等操作。 在這一部分我
19、使用了仿函數(shù)和綁定器進(jìn)行查表。由于我把相應(yīng)表結(jié)構(gòu)都存在 vector內(nèi),導(dǎo)致查找結(jié)構(gòu)內(nèi)成員信息的不便,但是自己寫一套查找操作代碼估計效率不高,索性 使用仿函數(shù)進(jìn)行查找,泛型操作一般效率較高而且代碼較少也很清晰。假如時間更充 足一點其實還可以把數(shù)據(jù)類型匹配這一部分拓展一下,畢竟也是查表比較,但是時間 有限只好先完成要求的3個任務(wù)。3、四元式分析設(shè)計(1)相關(guān)數(shù)據(jù)結(jié)構(gòu)struct Quaternary / 四元式結(jié)構(gòu)int serial;string op;stri ng v1;string v2;stri ng result;Q;stack <string > operator_st
20、ack;/操作數(shù)堆棧stack <string > operand_stack;/ 操作符堆棧(2)相關(guān)函數(shù)result )Quaternary Quaternary_generater(int serial , string op, string v1, string v2, string/四元式生成函數(shù)Q.serial = serialQ.op = op;Q.v1 = v1;Q.v2 = v2;Q.result = result return Q;while ( !operand_stack.empty() && !operator_stack.empty()
21、25op = operator_stack.top();operator_stack.pop();v1 = opera nd_stack.top();opera nd_stack.pop();v2 = opera nd_stack.top();opera nd_stack.pop();res = resultr;r+;Q = Quater nary_ge nerater( serial, op, v1, v2, res );serial+;QV.push_back( Q );/for ( it2=QV.begin(); it2!=QV.end(); it2+ )/ 找回真出口if ( (*it
22、2).result= "null")stri ngstream ss;ss«QV.back().serial;stri ng s=ss.str();(*it2).result=s;break;/opera nd_stack.push( res ); _void Quaternary_output() _while ( !QV.empty() cout << QV.fr on t().serial <<"("<< QV.fro nt().op <<<< QV.fro nt().v2 &l
23、t;<II")"<< endl;"<< QV.fro nt().v1 <<" , "<< QV.fro nt().result <<it2 = QV.begi n();QV.erase( it2 );(3) 測試數(shù)據(jù)和結(jié)果四兀式如下:1 < / ,2 , 4 , tl )2 < + ,itl . t2 )3 < + ,t2 , 3 , t34 < =,a , t3 , 14 >5 C + ,b , a , t5 >6 < =,bt5t6
24、)7 C >=,a , h , 9 )9 < J ,-,-,10)9 < -,a 亠 123 , t7 >10 ( -*a . 1 , te )11 < *j. a j- b j- ±912 < -,ts ,f tin >13 < -,b . tie ,>(4) 設(shè)計思路賦值運算部分整體結(jié)構(gòu)流程如下:#* '"-"ETr 工右孤ng衛(wèi)結(jié)束,說明:首先建立操作符棧和運算符棧。每次掃描遇到操作符遍進(jìn)棧,遇到運算符如果當(dāng)前??談t進(jìn)棧,否則和棧頂操作符的優(yōu)先級進(jìn)行比較,如果小于等于其優(yōu)先級,則pop棧頂符號,進(jìn)
25、行四元式生成,再將四元式壓入四元式隊列,然后繼續(xù)與棧頂元素比較直 至其優(yōu)先級大于其優(yōu)先級或??談t進(jìn)棧。If語句部分在對布爾表達(dá)式進(jìn)行判斷時,先讓操作符和運算符進(jìn)棧,轉(zhuǎn)移序號先賦為null等到掃描到if then之后的部分通過對其四元式生成確定了序號,這時候再查找隊列進(jìn) 行回填序號。xian g();while ( token.value="+" | token.value="-")/四元式while ( !operator_stack.empty() && operator_stack.top()!="=" )/ 此處
26、要注意用while循環(huán),if會出錯,因為需要不斷判斷直至棧頂?shù)姆杻?yōu)先級小于需要壓棧的符號此處生成四元式,四元式進(jìn)隊列for ( it2=QV.begin(); it2!=QV.end(); it2+ )/ 找回真出口if ( (*it2).result= "null")stri ngstream ss;ss<<QV.back().serial; stri ngs=ss.str();(*it2).result=s;break; I/如果??栈蛘邷?zhǔn)備進(jìn)棧的operator_stack.push( toke n. value );符號的優(yōu)先級大于棧頂?shù)膬?yōu)先級則進(jìn)棧t
27、oke n = getToke n(); xia ng();(5)四元式的總結(jié):這部分是我覺得此次試驗最難的一部分。而且也是我花費時間最多的一部分。在寫賦值運算的那部分時,把一個while循環(huán)寫成了 if (我一開始以為運算符進(jìn)棧只需 判斷一次)導(dǎo)致測試數(shù)據(jù)結(jié)果出錯找了好久錯誤才找到。If語句那部分的四元式的編寫也十分困難,尤其是找回真假出口讓我考慮了很久。而且測試數(shù)據(jù)整個代碼有許多 這種語句,應(yīng)當(dāng)在每個語句結(jié)束時就輸出一次四元式,不然會導(dǎo)致次序的混亂。(一開始我沒發(fā)現(xiàn),是把所有四元式進(jìn)隊列到最后程序結(jié)束時一起輸出的),最后調(diào)試了許久, 才發(fā)現(xiàn)問題,于是在語句結(jié)果判斷分號時,就調(diào)用四元式輸出函
28、數(shù)進(jìn)行輸出。20六、整體總結(jié)這次編譯原理大作業(yè)讓真的我受益良多,整個近千行代碼基本都是我一點一點慢慢敲 出來的,過程固然辛苦但是學(xué)到了不少。尤其是在做語法分析和四元式生成的部分, 代碼量較大,一開始思路也不太清晰,但是還是一點一點硬著頭皮往下寫,結(jié)果在寫 的過程中一些思路就出來了,看來有時候還是要多動手,光苦思冥想并不行。對于這 次作業(yè)我自己是比較滿意的但是還是有一些不足:語法部分本來想對文法進(jìn)行拓展把 布爾表達(dá)式那部分的附加題解決掉,無奈時間有限,實在來不及寫,可能留到暑假自 己再完善吧。四元式部分其實做得并不完完善,有些測試數(shù)據(jù)會出現(xiàn)錯誤結(jié)果,主要 是還是因為布爾表達(dá)式那部分文法沒有拓展,
29、在進(jìn)行復(fù)雜布爾表達(dá)式判斷時會出錯, 而且if語句真假口如果遇到復(fù)雜的算數(shù)運算可能會出口回填錯誤??傮w來說,這次作 業(yè)基本任務(wù)還是都完成了,通過這次大作業(yè)也對整個編譯器的設(shè)計有了比以前更深的 了解和體會,看來還是實踐才能出真知。29附錄文法如下:1. 程序 函數(shù)塊2. 函數(shù)塊 函數(shù) 函數(shù)3. 函數(shù) functionid () 語句塊 end function4. 語句塊 begin 語句語句end5. 語句 分支語句| 賦值語句| 循環(huán)語句|輸入語句| 輸出語句| 變量定義語句6. 變量定義語句 def id , id as 數(shù)據(jù)類型 ;7. 數(shù)據(jù)類型 integer | float | str
30、ing8. 輸入語句 in put id , id ;9. 輸出語句 output 表達(dá)式 ,表達(dá)式;10. 賦值語句 id= 表達(dá)式 ;11. 分支語句 if 布爾表達(dá)式 語句塊 else 語句塊 12. 循環(huán)語句 while 布爾表達(dá)式 do 語句塊13. 表達(dá)式 項 +| 項 14. 項 因子 *| / 因子 15. 因子 id | con | deci |( 表達(dá)式 )14.布爾表達(dá)式- 關(guān)系表達(dá)式and | or 布爾表達(dá)式 15.關(guān)系表達(dá)式- 表達(dá)式 關(guān)系 表達(dá)式16.關(guān)系 |=| | = | = |附錄:詞法分析完整代碼(復(fù)制可執(zhí)行)/*詞法分析程序BY謝卓函ON June 20
31、th*/#include <iostream>#include <algorithm>#include <cstring>#include <fstream>#include <string>#define MAXLINE 30using namespace std;/標(biāo)識符1,整數(shù)2,小數(shù)3,字符串4,保留字5,數(shù)學(xué)運算符6,比較運算符7,邏輯運算符8,分隔符9/保5string key14="if","else","while","do","
32、float","string","begin","end","def","integer","input","output","as","function"留字string border5= "", "" , "" , "("/ 分隔符string arithmetic9="+" , "-"
33、; , "*" , "/" ,"<" , "<=" , "=" , ">" , ">=" ;/ 運算符 6string text;/記錄標(biāo)識符1string contentMAXLINE;/保存從文件讀取的內(nèi)容int i=0;int templine = 0;/i為字符游標(biāo)31#int scan( string s ,int line )int j, flag =0;text = ""/賦空 textwhile(
34、 contentlinei='')判斷空格i+;/是空格跳過/判斷是否為字母或者下if( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=122)劃線text += contentlinei;i+;while( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=12
35、2) | contentlinei>='0'&& contentlinei<='9')判斷是否為數(shù)字或者字母或者下劃線text += contentlinei;i+;for( j=0; j<=13 ; j+ )if( text=keyj )/查表判斷是否為保留字return 5;if( text="and" | text="or")判斷是否為邏輯運算符return 8;if( j=14 )return 1;若查表失敗說明為標(biāo)識符elsewhile( contentlinei>=
36、9;0' && contentlinei<='9')判斷是否為數(shù)字text += contentlinei;i+;flag=1;if( flag=1 )if( contentlinei='.')text += contentlinei;i+;while( contentlinei>='0' && contentlinei<='9')判斷是否為數(shù)字text += contentlinei;i+;return 2;整數(shù)return 3;小數(shù)if( contentlinei= &
37、#39;'| contentlinei='' | contentlinei='' | contentlinei='(' | contentlinei=')' |contentlinei=',')判斷是否為分隔符 text = contentlinei;i+; return 9;if( contentlinei= '+' | contentlinei='-' | contentlinei='*' | contentlinei='=' )/ 判斷是
38、否為運算符 text = contentlinei; i+;return 6;if( conten tli nei='v' | conten tli nei='>')if( contentlinei+1='=')text = contentlinei;text += contentlinei+1;i=i+2;return 7;else text = contentlinei;i+; return 7;if( contentlinei=' “')判斷是否為字符串text += contentlinei;i+;while( co
39、ntentlinei!='” ')text += contentlinei;i+;text += contentlinei;i+;return 4;if( contentlinei='/')判斷是否為注釋if( contentlinei+1='/')i=contentline.length();return 0;如果為行注釋那么游標(biāo)指向行末elseif( contentlinei+1='*')i=i+2;while( contentlinei!='*' | contentlinei+1!='/')i
40、f( i=contentline.length()line+;i=0;elsei+;i=i+2;templine = line;return -1;-1 代表塊注釋else text = contentlinei;i+; return 0;return 0;int main()ifstream infile("ceshi1.txt",ios:in);if( infile )cout << "文件讀取成功! "<< endl;elsecout << "文件讀取失敗!" << endl;in
41、t hang, mode,k=1,numline;k 用于定位行數(shù)cout << endl;cout << "測試數(shù)據(jù)如下:"<< endl;while ( getline(infile,contentk)cout << contentk << endl;k+;numline = k-; /numline 記錄了文件總行數(shù)cout << endl;cout << "詞法分析結(jié)果:"<< endl;for( k=1; k<=numline; k+ )whi
42、le( i!=contentk.length()mode = scan( contentk, k );if( mode!=0 && mode!= -1)單詞cout << " 所在行數(shù):"<< k << " 所在列數(shù):"<< i-text.length()+1 << "單詞類別:"<< mode <<為:"<< text <<endl ;elseif( mode=0 )if( i<contentk
43、.length() ) i+;如果為行注釋 直接跳到下一行elseif( mode=-1 )/如果為塊注釋找回行號k=templine;i = 0;一行結(jié)束定位到下一行行頭getchar();return 0;附錄二 語法語義四元式生成代碼(復(fù)制可執(zhí)行)/*語法+語義+四元式分析程序BY謝卓函ON June 25th*/#include <iostream>#include <algorithm>#include <cstring>#include <fstream>#include <string>#include <cstd
44、io>#include <vector>#include <iterator>#includealgorithm#includefunctional#include <stack>#include <queue>#include <cstdlib>#include <sstream>#define MAXLINE 30using namespace std;/標(biāo)識符1,整數(shù)2,小數(shù)3,字符串4,保留字5,數(shù)學(xué)運算符6,比較運算符7,邏輯運算符8,分隔符9/保string key14="if",&q
45、uot;else","while","do","float","string","begin","end","def","integer","input","output","as","function"留字string border5= "", "" , "" , "(&quo
46、t;/分隔符 5string arithmetic9="+" , "-" , "*" , "/" ,"<" , "<=" , "=" , ">" , ">=" ;/ 運算符6string text;/記錄標(biāo)識符 1string contentMAXLINE;/保存從文件讀取的內(nèi)容string resultMAXLINE = "t1","t2","
47、;t3","t4","t5","t6","t7","t8","t9","t10"/*/*語法語義各產(chǎn)生式函數(shù)*/void chengxu();void hanshukuai();void hanshu();void yujukuai();void yuju();void bianliangdingyiyuju();void shujuleixing();void shuruyuju();void shuchuyuju();void fuzhiyu
48、ju();void fenzhiyuju();void xunhuanyuju();void biaodashi();void xiang();void yinzi();void buerbiaodashi();void guanxibiaodashi();void guanxi();void error();void Quaternary_output();void Quaternary_maker();int i=0,k=1,numline,mode;i為字符游標(biāo),k為行號,numline記錄了文件總行數(shù)int templine = 0;int errornum = 0;int warni
49、ngnum = 0;int r = 0, serial = 1;string op,v1,v2,res;struct Tokenstring value;/ 值int mode;類型int row;行int col;列token;struct Symtable/ 符號表結(jié)構(gòu)string name;int type;bool value;S;struct Quaternary/ 四元式結(jié)構(gòu)int serial;string op;string v1;string v2;string result;Q;/函數(shù)聲明Quaternary Quaternary_generater( int serial
50、, string op, string v1, string v2, string result );vector<Symtable> ST;vector<Symtable> : iterator it;vector<Quaternary> QV;vector<Quaternary> : iterator it2;stack<string> operator_stack;/ 操作數(shù)堆棧stack<string> operand_stack;/ 操作符堆棧/仿函數(shù)和綁定器struct compare: binary_func
51、tion<Symtable, string,bool>bool operator()( Symtable s, string str) const if (= str)return true;elsereturn false;;void push_in_token( Token token )/ 進(jìn)表操作S.name = token.value;S.type = -1;S.value = false;ST.push_back( S );vector<Symtable> : iterator find_token( Token token )/ 查表操作it
52、= find_if( ST.begin(), ST.end(), bind2nd( compare(),token.value ); return it; int scan( string s ,int line )int j, flag =0;text = ""/賦空 textwhile( contentlinei='')判斷空格i+;是空格跳過if( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<
53、=122) )/ 判斷是否為字母或者下劃線text += contentlinei;i+;while( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=122) | contentlinei>='0'&& contentlinei<='9')判斷是否為數(shù)字或者字母或者下劃線text += contentlinei;i+;for( j=0; j<=13 ; j+ )if(
54、text=keyj )/查表判斷是否為保留字return 5;if( text="and" | text="or")判斷是否為邏輯運算符return 8;if( j=14 )return 1;若查表失敗說明為標(biāo)識符 else39while( contentlinei>='0' && contentlinei<='9')text += contentlinei;i+;flag=1;if( flag=1 )if( contentlinei='.')text += contentlin
55、ei;i+;while( contentlinei>='0' && contentlinei<='9')text += contentlinei;i+;return 2;整數(shù)return 3;小數(shù)if( contentlinei= ''| contentlinei='' | contentlinei='' |/判斷是否為數(shù)字判斷是否為數(shù)字contentlinei='(' | contentlinei=')' |contentlinei=','
56、;)判斷是否為分隔符 text = contentlinei;i+; return 9;if( contentlinei= '+' | contentlinei='-' | contentlinei='*' | contentlinei='=') text = contentlinei; i+;return 6;if( conten tli nei='v' | conten tli nei='>')if( contentlinei+1='=')text = contentlinei;text += contentlinei+1;i=i+2;return
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 植物園彩鋼板施工協(xié)議
- 裝修合同報價單模板
- 美發(fā)沙龍場地租賃合同
- 優(yōu)化工作流程:委派人員管理辦法
- 藝術(shù)畫廊展示防滑地板施工合同
- 辦公室物資智能化采購
- 軟件研發(fā)租賃協(xié)議
- 咨詢顧問解除聘用合同模板
- 保健行業(yè)按摩師管理指南
- 2024年高品質(zhì)宣傳欄制作協(xié)議模板版B版
- 2024年1月國開電大專科《渠道管理》期末考試試題及答案
- JGT302-2022卷簾門窗規(guī)范
- 居家養(yǎng)老單項服務(wù)及收費
- 長輸管道項目管道封堵施工技術(shù)方案
- 傳統(tǒng)文化與生態(tài)文明建設(shè)智慧樹知到期末考試答案章節(jié)答案2024年云南大學(xué)
- 預(yù)防醫(yī)學(xué)教案與講義(修訂版)
- 醫(yī)療器械質(zhì)量安全承諾書
- 敦煌學(xué)智慧樹知到期末考試答案章節(jié)答案2024年西北師范大學(xué)
- 湘美版三年級美術(shù)上冊《12. 盤泥條-瓶子變裝秀》教學(xué)設(shè)計
- 湖南省長沙市長郡教育集團(tuán)2024-2025學(xué)年八年級上學(xué)期期末考試語文試卷
- 國際貿(mào)易代收款協(xié)議書
評論
0/150
提交評論