




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、word 編譯原理 實(shí)驗(yàn)報(bào)告本文檔集合了編譯原理大作業(yè)的實(shí)驗(yàn)報(bào)告加代碼實(shí)驗(yàn)主要內(nèi)容為用C+實(shí)現(xiàn)了詞法分析程序;語(yǔ)法語(yǔ)義以及四元式生成程序代碼見(jiàn)附錄,復(fù)制進(jìn)VS后程序絕對(duì)可編譯執(zhí)行。文檔代碼為原創(chuàng),謹(jǐn)慎使用姚礪的大作業(yè)實(shí) 驗(yàn) 設(shè) 計(jì) 一一、實(shí)驗(yàn)名稱(chēng) 詞 法 分 析 程 序二、實(shí)驗(yàn)?zāi)康?設(shè)計(jì)一個(gè)詞法分析程序,每調(diào)用一次就從源程序文件中順序識(shí)別出一個(gè)單詞符號(hào),并返回該單詞符號(hào)的內(nèi)部編碼、單詞符號(hào)自身、行列位置信息。2要能處理單行注釋。 三、實(shí)驗(yàn)內(nèi)容及要求單詞種類(lèi)與識(shí)別規(guī)那么(1) 標(biāo)識(shí)符:首字符為字母或下劃線,其后由字母、數(shù)字或下劃線組成、長(zhǎng)度不超過(guò)255個(gè)字符;(2) 整數(shù):由1到8個(gè)數(shù)字組成。(
2、3) 小數(shù):數(shù)字串1 . 數(shù)字串2,其中:數(shù)字串1由1-8個(gè)數(shù)字符組成; 數(shù)字串2由0-8個(gè)數(shù)字符組成,即:數(shù)字串2可以為空。(4) 字符串:由一對(duì)“括起來(lái)的符號(hào)串,長(zhǎng)度不超過(guò)255個(gè)字符;(5) 保存字:if、else、while、do、integer、float、string、input、output、and、or、function、end、def、as、begin(6) 數(shù)學(xué)運(yùn)算符: 、*、/、= (7) 比擬運(yùn)算符: <、<=、>、>=、<>、=(8) 邏輯運(yùn)算符: and、or(9) 分隔符: 、(、)、;、, 四、實(shí)驗(yàn)環(huán)境操作系統(tǒng):Win7/其他
3、編譯工具:VC+6.0/CFree /VS2012五、設(shè)計(jì) 1設(shè)計(jì)大體思路將讀取的文件采用一遍掃描的方法,即從左到右只掃描一次源程序,將讀取的數(shù)據(jù)存放在一個(gè)二維數(shù)組里。然后通過(guò)掃描函數(shù)scan,再?gòu)臄?shù)組中一行一行的讀取數(shù)據(jù),每調(diào)用其依次返回一個(gè)單詞的類(lèi)型,同時(shí)單詞本身以及行列號(hào)存放在全局變量中。而說(shuō)詞法分析作為語(yǔ)法分析的一個(gè)子程序,故在編寫(xiě)詞法分析程序時(shí),將會(huì)反復(fù)調(diào)用scan函數(shù)來(lái)獲取一個(gè)個(gè)單詞信息。3設(shè)計(jì)流程圖4函數(shù)設(shè)計(jì)/*詞法分析函數(shù)*/int scan( string s ,int line ) 框架:初始化工作是空格直接跳過(guò),知直到讀取到一個(gè)字符if( 是字母 )查表判斷是否為關(guān)鍵字判
4、斷是否為邏輯運(yùn)算符and或orElse那么為標(biāo)識(shí)符else if( 是否為數(shù)字 ) 判斷是整數(shù)Else是小數(shù)Else其余情況判斷是否為運(yùn)算符,字符串等else if( getchar=/ )if( contentlinei+1='/')/向前看一個(gè),確定是否為行注釋?zhuān)蝗绻?,那么游?biāo)指向行末,跳過(guò)行注釋if( contentlinei+1='/*')如果向前看一個(gè)發(fā)現(xiàn)時(shí)塊注釋那么一直向前掃描直到出現(xiàn)“*/停止,略過(guò)塊注釋如果都不是那么Else判斷為除號(hào),返回運(yùn)算符類(lèi)型2對(duì)其中局部實(shí)現(xiàn)的說(shuō)明(1)數(shù)字識(shí)別while( contentlinei>='0
5、' && 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ù)每讀入一個(gè)字符,判斷是否數(shù)字
6、,然后找小數(shù)點(diǎn),找到即為小數(shù) (2) 標(biāo)識(shí)符處理 while( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=122) | contentlinei>='0' && contentlinei<='9' ) /判斷是否為數(shù)字或者字母或者下劃線text += contentlinei;i+;for( j=0; j<=13 ; j+ )if( text=keyj )/查表判斷
7、是否為保存字return 5;檢查到讀取的字符為字母時(shí),進(jìn)行查表判斷,找到即說(shuō)明為關(guān)鍵字(3) 空格,注釋?zhuān)刑?hào)的處理if( mode=0 )if( i<contentk.length() ) i+;/如果為行注釋 直接跳到下一行elseif( mode=-1 )/如果為塊注釋 找回行號(hào)k=templine; 六、程序源代碼見(jiàn)源代碼文件。七、實(shí)驗(yàn)數(shù)據(jù)、結(jié)果測(cè)試數(shù)據(jù)見(jiàn)文件八、總結(jié)之前的每周作業(yè)曾經(jīng)寫(xiě)過(guò)一個(gè)詞法分析程序,所以這次寫(xiě)詞法分析程序沒(méi)什么太多困難。在讀取源文件時(shí),最初的想法是一行一行的讀取,讀一次就存一行,這樣可以節(jié)省空間資源,提高效率。但是仔細(xì)一想考慮到塊注釋分布在不同的行中,而
8、且這樣對(duì)行列的操作十分麻煩,而且許多地方涉及到要向前看,比方判斷注釋與/除號(hào)運(yùn)算符時(shí),最后只好一次全部讀完,存在一個(gè)二維數(shù)組中。再用scan函數(shù)來(lái)處理。這樣一來(lái)行列的處理就自由多了。第二點(diǎn),在寫(xiě)scan函數(shù)的時(shí)候,最初的想法是每調(diào)用一次,返回一個(gè)單詞,然后在語(yǔ)法分析時(shí)不斷調(diào)用它。但是僅僅返回單詞是不夠的,于是打算返回一個(gè)結(jié)構(gòu)體,把單詞信息行列號(hào)什么的全部存進(jìn)去,這個(gè)在后來(lái)的語(yǔ)法語(yǔ)義分析中可以看到,這里任然采用的是返回一個(gè)單詞類(lèi)型。單詞本身,和行列號(hào)作為全局變量保存。然后只要按照流程圖一步一步判斷,慢慢寫(xiě)就行了,沒(méi)有太多難度,唯一要注意的是單詞位置行列的計(jì)算一定要細(xì)心。這個(gè)是要穿插在整個(gè)詞法分析
9、的全部地方的。所有涉及到讀入一個(gè)字符的地方都需要考慮到如何修改行列變量。尤其是本程序拓展了塊注釋?zhuān)⒁庑辛凶兓?。?shí) 驗(yàn) 設(shè) 計(jì) 二注:由于語(yǔ)義分析和四元式生成都是在語(yǔ)法分析的根底上拓展得到的,這一章實(shí)驗(yàn)報(bào)告囊括了語(yǔ)法,語(yǔ)義和四元式。一、實(shí)驗(yàn)名稱(chēng) 語(yǔ) 法 語(yǔ) 義 以 及 四 元 式 分 析 程 序二、實(shí)驗(yàn)?zāi)康脑O(shè)計(jì)一個(gè)語(yǔ) 法 語(yǔ) 義 以 及 生 成 四 元 式 的 分 析 程 序 三、實(shí)驗(yàn)內(nèi)容及要求設(shè)計(jì)要求:構(gòu)造相應(yīng)文法的語(yǔ)法分析程序,應(yīng)能指出源程序中出現(xiàn)的錯(cuò)誤。為語(yǔ)法分析程序中添加類(lèi)型檢查功能,包括: 變量重復(fù)定義; 變量未定義就使用; 變量未賦值就引用;將語(yǔ)法正確的源程序翻譯成四元式。文法見(jiàn)
10、附錄四、實(shí)驗(yàn)環(huán)境操作系統(tǒng):Win7/其他編譯工具:VC+6.0/CFree /VS2012五、設(shè)計(jì) 1.語(yǔ)法分析設(shè)計(jì)(1) 相關(guān)數(shù)據(jù)機(jī)構(gòu) struct Tokenstring value;/值int mode;/類(lèi)型int row;/行int col;/列token;說(shuō)明:這本應(yīng)是詞法分析時(shí)的結(jié)構(gòu),但是scan函數(shù)返回的是但單一值,于是又設(shè)計(jì)了Token函數(shù),對(duì)scan函數(shù)進(jìn)行擴(kuò)充,每個(gè)單詞的信息均保存一次在結(jié)構(gòu)體中,方便錯(cuò)誤報(bào)告函數(shù)進(jìn)行處理。2各個(gè)非終結(jié)符函數(shù)形式/*/*語(yǔ)法語(yǔ)義 各產(chǎn)生式 函數(shù)*/void chengxu();void hanshukuai();void hanshu();
11、void yujukuai();void yuju();void bianliangdingyiyuju();void shujuleixing();void shuruyuju();void shuchuyuju();void fuzhiyuju();void fenzhiyuju();void xunhuanyuju();void biaodashi();void xiang();void yinzi();void buerbiaodashi();void guanxibiaodashi();void guanxi();其他函數(shù):void error();void warning();每個(gè)
12、函數(shù)具體作用在代碼中都有注釋說(shuō)明3語(yǔ)法分析整體設(shè)計(jì)思路采用遞歸下降的方法,為每個(gè)非終結(jié)符設(shè)計(jì)一個(gè)函數(shù),在函數(shù)中對(duì)此處可能出現(xiàn)的語(yǔ)法錯(cuò)誤進(jìn)行處理。處理也語(yǔ)法錯(cuò)誤的思路主要分兩種:1. 查找關(guān)鍵字由于進(jìn)行語(yǔ)法分析時(shí)檢查到錯(cuò)誤不可能就此停下,要一次性盡量找到所有的錯(cuò)誤,而且測(cè)試數(shù)據(jù)的語(yǔ)法錯(cuò)誤形式千奇百怪,這就要求發(fā)現(xiàn)錯(cuò)誤之后如何找到繼續(xù)進(jìn)行分析的位置。這里對(duì)于一些不常見(jiàn)的錯(cuò)誤采取查找關(guān)鍵字的方法,一旦出現(xiàn)錯(cuò)誤在相應(yīng)函數(shù)中查找下一個(gè)出現(xiàn)的關(guān)鍵字的位置,然后繼續(xù)分析。2. 跳過(guò)錯(cuò)誤單詞,直接分析下一個(gè)單詞由于查找關(guān)鍵字方法會(huì)跳過(guò)許多代碼,從而有可能造成一些信息不必要的遺漏。尤其是對(duì)于漏分號(hào)這種錯(cuò)誤,與是
13、這里采取,直接當(dāng)前錯(cuò)誤,默認(rèn)后續(xù)單詞可能就是正確單詞,繼續(xù)分析。但是這個(gè)方法在一些地方并不適用,可能會(huì)導(dǎo)致一連串的錯(cuò)誤出現(xiàn),于是在使用時(shí)要考慮好取舍。編譯錯(cuò)誤處理函數(shù):void error( Token token,char *msg) /編譯錯(cuò)誤處理函數(shù)cout << "編譯錯(cuò)誤:" printf( "%s",msg); cout << endl << "錯(cuò)誤位置:第" << token.row << "行,第" << token.col &
14、lt;< "列 -> " <<token.value;cout << endl;cout << endl;errornum+;每出現(xiàn)錯(cuò)誤時(shí),通過(guò)傳遞錯(cuò)誤信息參數(shù)以及單詞信息,調(diào)用編譯錯(cuò)誤處理函數(shù)進(jìn)行實(shí)時(shí)報(bào)錯(cuò)。3測(cè)試數(shù)據(jù)和結(jié)果見(jiàn)后文語(yǔ)義分析局部(4) 語(yǔ)法分析局部的小總結(jié)原本打算試試自底向上歸約方法設(shè)計(jì)的,結(jié)果想了想發(fā)現(xiàn)實(shí)在麻煩,老師給的文法又挺龐雜的,創(chuàng)立分析表什么的就要好久。后來(lái)一想用遞歸下降方法好處很多,做到之后的語(yǔ)義分析和四元式生成的時(shí)候在語(yǔ)法分析的根底上拓展很方便,整體框架非常清晰。在錯(cuò)誤處理方面考慮的還是挺合理的,對(duì)
15、于一些常見(jiàn)錯(cuò)誤都能有效指出。并且程序只有一個(gè)出口,任何代碼輸入都會(huì)從那一個(gè)出口結(jié)束,不會(huì)引起程序崩潰。2、語(yǔ)義分析設(shè)計(jì)語(yǔ)義分析主要實(shí)現(xiàn)3個(gè)功能 變量重復(fù)定義; 變量未定義就使用; 變量未賦值就引用;(1)相關(guān)數(shù)據(jù)結(jié)構(gòu)struct Symtable /符號(hào)表結(jié)構(gòu)string name;int type;bool value;S;struct compare: binary_function<Symtable, string,bool> /仿函數(shù)和綁定器bool operator()( Symtable s, string str) constif (= str)retur
16、n true;elsereturn false;(2)相關(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 = find_if( ST.begin(), ST.end(), bind2nd( compare(),token.value );return it;(2) 測(cè)試數(shù)據(jù)和結(jié)果4設(shè)計(jì)思路語(yǔ)義局
17、部主要采用符號(hào)表結(jié)構(gòu),符號(hào)表中記錄了每個(gè)非終結(jié)符的信息。名稱(chēng),類(lèi)型,是否賦值。然后再程序中每次調(diào)用Token函數(shù)發(fā)現(xiàn)讀取到標(biāo)識(shí)符時(shí)都進(jìn)行查表操作。根據(jù)查表結(jié)果進(jìn)行相關(guān)分析。在賦值函數(shù)中,如果查表找到其信息就說(shuō)明重復(fù)定義。再其余函數(shù)中1.沒(méi)有找到說(shuō)明為聲明就使用。 2.找到發(fā)現(xiàn)未賦值說(shuō)明未賦值就引用。5語(yǔ)義局部小總結(jié)假設(shè)只實(shí)現(xiàn)以上3個(gè)功能語(yǔ)義局部并不難,關(guān)鍵是符號(hào)表的構(gòu)建以及進(jìn)表查表等操作。在這一局部我使用了仿函數(shù)和綁定器進(jìn)行查表。由于我把相應(yīng)表結(jié)構(gòu)都存在vector內(nèi),導(dǎo)致查找結(jié)構(gòu)內(nèi)成員信息的不便,但是自己寫(xiě)一套查找操作代碼估計(jì)效率不高,索性使用仿函數(shù)進(jìn)行查找,泛型操作一般效率較高而且代碼較少
18、也很清晰。假設(shè)時(shí)間更充足一點(diǎn)其實(shí)還可以把數(shù)據(jù)類(lèi)型匹配這一局部拓展一下,畢竟也是查表比擬,但是時(shí)間有限只好先完成要求的3個(gè)任務(wù)。3、四元式分析設(shè)計(jì)1相關(guān)數(shù)據(jù)結(jié)構(gòu)struct Quaternary/四元式結(jié)構(gòu)int serial;string op;string v1;string v2;string result;Q;stack<string> operator_stack;/操作數(shù)堆棧stack<string> operand_stack;/操作符堆棧2相關(guān)函數(shù)Quaternary Quaternary_generater( int serial, string op,
19、 string v1, string v2, string result )/四元式生成函數(shù)Q.serial = serial;Q.op = op;Q.v1 = v1;Q.v2 = v2;Q.result = result;return Q;void Quaternary_maker()while( !operand_stack.empty() && !operator_stack.empty() )op = operator_stack.top();operator_stack.pop();v1 = operand_stack.top();operand_stack.pop(
20、);v2 = operand_stack.top();operand_stack.pop();res = resultr;r+;Q = Quaternary_generater( serial, op, v1, v2, res );serial+;QV.push_back( Q );/for( it2=QV.begin(); it2!=QV.end(); it2+ )/找回真出口if( (*it2).result="null" )stringstream ss; ss<<QV.back().serial;string s=ss.str(); (*it2).res
21、ult=s;break;/operand_stack.push( res );void Quaternary_output()while( !QV.empty() )cout << QV.front().serial << " ( " << QV.front().op << " , " << QV.front().v2 << " , " << QV.front().v1 << " , " << QV.fron
22、t().result << " ) " << endl;it2 = QV.begin();QV.erase( it2 );(3) 測(cè)試數(shù)據(jù)和結(jié)果4設(shè)計(jì)思路賦值運(yùn)算局部整體結(jié)構(gòu)流程如下:說(shuō)明:首先建立操作符棧和運(yùn)算符棧。每次掃描遇到操作符遍進(jìn)棧,遇到運(yùn)算符如果當(dāng)前??漳敲催M(jìn)棧,否那么和棧頂操作符的優(yōu)先級(jí)進(jìn)行比擬,如果小于等于其優(yōu)先級(jí),那么pop棧頂符號(hào),進(jìn)行四元式生成,再將四元式壓入四元式隊(duì)列,然后繼續(xù)與棧頂元素比擬直至其優(yōu)先級(jí)大于其優(yōu)先級(jí)或??漳敲催M(jìn)棧。If語(yǔ)句局部在對(duì)布爾表達(dá)式進(jìn)行判斷時(shí),先讓操作符和運(yùn)算符進(jìn)棧,轉(zhuǎn)移序號(hào)先賦為null等到掃描到if
23、 then之后的局部通過(guò)對(duì)其四元式生成確定了序號(hào),這時(shí)候再查找隊(duì)列進(jìn)行回填序號(hào)。函數(shù)具體結(jié)構(gòu):void biaodashi()xiang();while( token.value="+" | token.value="-" )/四元式while( !operator_stack.empty() && operator_stack.top()!="=" )/此處要注意用while循環(huán),if會(huì)出錯(cuò),因?yàn)樾枰粩嗯袛嘀敝翖m數(shù)姆?hào)優(yōu)先級(jí)小于需要壓棧的符號(hào)此處生成四元式,四元式進(jìn)隊(duì)列for( it2=QV.begin(); i
24、t2!=QV.end(); it2+ )/找回真出口if( (*it2).result="null" )stringstream ss; ss<<QV.back().serial;string s=ss.str(); (*it2).result=s;break;operator_stack.push( token.value );/如果棧空或者準(zhǔn)備進(jìn)棧的符號(hào)的優(yōu)先級(jí)大于棧頂?shù)膬?yōu)先級(jí)那么進(jìn)棧token = getToken();xiang();5四元式的總結(jié):這局部是我覺(jué)得此次試驗(yàn)最難的一局部。而且也是我花費(fèi)時(shí)間最多的一局部。在寫(xiě)賦值運(yùn)算的那局部時(shí),把一個(gè)whil
25、e循環(huán)寫(xiě)成了if我一開(kāi)始以為運(yùn)算符進(jìn)棧只需判斷一次導(dǎo)致測(cè)試數(shù)據(jù)結(jié)果出錯(cuò)找了好久錯(cuò)誤才找到。If語(yǔ)句那局部的四元式的編寫(xiě)也十分困難,尤其是找回真假出口讓我考慮了很久。而且測(cè)試數(shù)據(jù)整個(gè)代碼有許多這種語(yǔ)句,應(yīng)當(dāng)在每個(gè)語(yǔ)句結(jié)束時(shí)就輸出一次四元式,不然會(huì)導(dǎo)致次序的混亂。一開(kāi)始我沒(méi)發(fā)現(xiàn),是把所有四元式進(jìn)隊(duì)列到最后程序結(jié)束時(shí)一起輸出的,最后調(diào)試了許久,才發(fā)現(xiàn)問(wèn)題,于是在語(yǔ)句結(jié)果判斷分號(hào)時(shí),就調(diào)用四元式輸出函數(shù)進(jìn)行輸出。六、整體總結(jié) 這次編譯原理大作業(yè)讓真的我受益良多,整個(gè)近千行代碼根本都是我一點(diǎn)一點(diǎn)慢慢敲出來(lái)的,過(guò)程固然辛苦但是學(xué)到了不少。尤其是在做語(yǔ)法分析和四元式生成的局部,代碼量較大,一開(kāi)始思路也不太清
26、晰,但是還是一點(diǎn)一點(diǎn)硬著頭皮往下寫(xiě),結(jié)果在寫(xiě)的過(guò)程中一些思路就出來(lái)了,看來(lái)有時(shí)候還是要多動(dòng)手,光苦思冥想并不行。對(duì)于這次作業(yè)我自己是比擬滿意的但是還是有一些缺乏:語(yǔ)法局部本來(lái)想對(duì)文法進(jìn)行拓展把布爾表達(dá)式那局部的附加題解決掉,無(wú)奈時(shí)間有限,實(shí)在來(lái)不及寫(xiě),可能留到暑假自己再完善吧。四元式局部其實(shí)做得并不完完善,有些測(cè)試數(shù)據(jù)會(huì)出現(xiàn)錯(cuò)誤結(jié)果,主要是還是因?yàn)椴紶柋磉_(dá)式那局部文法沒(méi)有拓展,在進(jìn)行復(fù)雜布爾表達(dá)式判斷時(shí)會(huì)出錯(cuò),而且if語(yǔ)句真假口如果遇到復(fù)雜的算數(shù)運(yùn)算可能會(huì)出口回填錯(cuò)誤。總體來(lái)說(shuō),這次作業(yè)根本任務(wù)還是都完成了,通過(guò)這次大作業(yè)也對(duì)整個(gè)編譯器的設(shè)計(jì)有了比以前更深的了解和體會(huì),看來(lái)還是實(shí)踐才能出真知。
27、附錄文法如下:1. <程序>> <函數(shù)塊> 2. <函數(shù)塊>> <函數(shù)> <函數(shù)>3. <函數(shù)>> function id ( ) <語(yǔ)句塊> end function 4. <語(yǔ)句塊>> begin 語(yǔ)句 語(yǔ)句 end 5. <語(yǔ)句>><分支語(yǔ)句>|<賦值語(yǔ)句>|<循環(huán)語(yǔ)句>| <輸入語(yǔ)句>|<輸出語(yǔ)句>|<變量定義語(yǔ)句>6. <變量定義語(yǔ)句>> def id , i
28、d as <數(shù)據(jù)類(lèi)型> ;7. <數(shù)據(jù)類(lèi)型>> integer | float | string8. <輸入語(yǔ)句>> input id , id ;9. <輸出語(yǔ)句>> output <表達(dá)式> , <表達(dá)式> ;10. <賦值語(yǔ)句>> id = <表達(dá)式> ;11. <分支語(yǔ)句>> if <布爾表達(dá)式> <語(yǔ)句塊> else <語(yǔ)句塊> 12. <循環(huán)語(yǔ)句>> while <布爾表達(dá)式> d
29、o <語(yǔ)句塊>13. <表達(dá)式>> <項(xiàng)> +| <項(xiàng)> 14. <項(xiàng)>> <因子> *|/ <因子> 15. <因子>> id | con | deci | ( <表達(dá)式> )14. <布爾表達(dá)式>> <關(guān)系表達(dá)式> and | or <布爾表達(dá)式> 15. <關(guān)系表達(dá)式>> <表達(dá)式> <關(guān)系> <表達(dá)式>16. <關(guān)系>> < | <= |
30、 > | >= | = | <>附錄: 詞法分析完整代碼復(fù)制可執(zhí)行/*詞法分析程序BY 謝卓函ON June 20th */#include <iostream>#include <algorithm>#include <cstring>#include <fstream>#include <string>#define MAXLINE 30using namespace std;/標(biāo)識(shí)符1,整數(shù)2,小數(shù)3,字符串4,保存字5,數(shù)學(xué)運(yùn)算符6,比擬運(yùn)算符7,邏輯運(yùn)算符8,分隔符9string key14=&quo
31、t;if","else","while","do","float","string","begin","end","def","integer","input","output","as","function" /保存字string border5= "" , "" , "&qu
32、ot; , "(" , ")" ; /分隔符 5string arithmetic9="+" , "-" , "*" , "/" ,"<" , "<=" , "=" , ">" , ">=" ; /運(yùn)算符 6string text; /記錄標(biāo)識(shí)符 1string contentMAXLINE; /保存從文件讀取的內(nèi)容int i=0;/i為字符游標(biāo)int
33、templine = 0;int scan( string s ,int line )int j, flag =0;text = "" /賦空textwhile( contentlinei=' ' )/判斷空格i+;/是空格跳過(guò)if( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=122) ) /判斷是否為字母或者下劃線text += contentlinei;i+;while( (contentl
34、inei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=122) | contentlinei>='0' && contentlinei<='9' ) /判斷是否為數(shù)字或者字母或者下劃線text += contentlinei;i+;for( j=0; j<=13 ; j+ )if( text=keyj )/查表判斷是否為保存字return 5;if( text="and" |
35、 text="or" )/判斷是否為邏輯運(yùn)算符return 8;if( j=14 )return 1;/假設(shè)查表失敗說(shuō)明為標(biāo)識(shí)符elsewhile( contentlinei>='0' && contentlinei<='9' )/判斷是否為數(shù)字text += contentlinei;i+;flag=1;if( flag=1 )if( contentlinei='.' )text += contentlinei;i+;while( contentlinei>='0' &
36、;& contentlinei<='9' )/判斷是否為數(shù)字text += contentlinei;i+;return 2; /整數(shù)return 3;/小數(shù)if( contentlinei= '' | contentlinei='' | contentlinei='' | contentlinei='(' | contentlinei=')' | contentlinei=',' )/判斷是否為分隔符 text = contentlinei;i+; return 9;
37、if( contentlinei= '+' | contentlinei='-' | contentlinei='*' | contentlinei='=' )/判斷是否為運(yùn)算符 text = contentlinei; i+;return 6;if( contentlinei='<' | contentlinei='>' )if( contentlinei+1='=' )text = contentlinei;text += contentlinei+1;i=i+2;r
38、eturn 7;else text = contentlinei;i+; return 7;if( contentlinei='“' ) /判斷是否為字符串text += contentlinei;i+;while( contentlinei!='' )text += contentlinei;i+;text += contentlinei;i+;return 4;if( contentlinei='/' )/判斷是否為注釋if( contentlinei+1='/')i=contentline.length();return 0
39、;/如果為行注釋那么游標(biāo)指向行末elseif( contentlinei+1='*' )i=i+2;while( contentlinei!='*' | contentlinei+1!='/' )if( 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&qu
40、ot;,ios:in);if( infile )cout << "文件讀取成功! "<< endl;elsecout << "文件讀取失敗!" << endl;int hang, mode,k=1,numline; /k用于定位行數(shù)cout << endl;cout << "測(cè)試數(shù)據(jù)如下:" << endl;while ( getline(ink) )cout << contentk << endl;k+;numline = k
41、-; /numline記錄了文件總行數(shù)cout << endl;cout << "詞法分析結(jié)果:" << endl;for( k=1; k<=numline; k+ )while( i!=contentk.length() )mode = scan( contentk, k );if( mode!=0 && mode!= -1 )cout << " 所在行數(shù):" << k << " 所在列數(shù):" << i-text.length(
42、)+1 << " 單詞類(lèi)別:"<< mode << " 單詞為:" << text <<endl ;elseif( mode=0 )if( i<contentk.length() ) i+;/如果為行注釋 直接跳到下一行elseif( mode=-1 )/如果為塊注釋 找回行號(hào)k=templine;i = 0;/一行結(jié)束定位到下一行行頭getchar(); return 0;附錄二 語(yǔ)法語(yǔ)義四元式生成代碼復(fù)制可執(zhí)行/*語(yǔ)法+語(yǔ)義+四元式分析程序BY 謝卓函ON June 25th */#i
43、nclude <iostream>#include <algorithm>#include <cstring>#include <fstream>#include <string>#include <cstdio>#include <vector>#include <iterator>#include <algorithm>#include <functional>#include <stack>#include <queue>#include <
44、;cstdlib>#include <sstream>#define MAXLINE 30using namespace std;/標(biāo)識(shí)符1,整數(shù)2,小數(shù)3,字符串4,保存字5,數(shù)學(xué)運(yùn)算符6,比擬運(yùn)算符7,邏輯運(yùn)算符8,分隔符9string key14="if","else","while","do","float","string","begin","end","def","intege
45、r","input","output","as","function" /保存字string border5= "" , "" , "" , "(" , ")" ; /分隔符 5string arithmetic9="+" , "-" , "*" , "/" ,"<" , "<=&quo
46、t; , "=" , ">" , ">=" ; /運(yùn)算符 6string text; /記錄標(biāo)識(shí)符 1string contentMAXLINE; /保存從文件讀取的內(nèi)容string resultMAXLINE = "t1","t2","t3","t4","t5","t6","t7","t8","t9","t10"/*/*語(yǔ)法
47、語(yǔ)義 各產(chǎn)生式 函數(shù)*/void chengxu();void hanshukuai();void hanshu();void yujukuai();void yuju();void bianliangdingyiyuju();void shujuleixing();void shuruyuju();void shuchuyuju();void fuzhiyuju();void fenzhiyuju();void xunhuanyuju();void biaodashi();void xiang();void yinzi();void buerbiaodashi();void guanxibi
48、aodashi();void guanxi();void error();void Quaternary_output();void Quaternary_maker();int i=0,k=1,numline,mode;/i為字符游標(biāo),k為行號(hào),numline記錄了文件總行數(shù)int templine = 0;int errornum = 0;int warningnum = 0;int r = 0, serial = 1;string op,v1,v2,res;struct Tokenstring value;/值int mode;/類(lèi)型int row;/行int col;/列token;s
49、truct Symtable /符號(hào)表結(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;Quaternary Quaternary_generater( int serial, string op, string v1, string v2, string result );/函數(shù)聲明vector<Symtable> ST;vector<Symtable> : iterator it;vec
50、tor<Quaternary> QV;vector<Quaternary> : iterator it2;stack<string> operator_stack;/操作數(shù)堆棧stack<string> operand_stack;/操作符堆棧struct compare: binary_function<Symtable, string,bool> /仿函數(shù)和綁定器bool operator()( Symtable s, string str) constif (= str)return true;elsereturn
51、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 = find_if( ST.begin(), ST.end(), bind2nd( compare(),token.value );return it;int scan( string s ,int line )int j, flag =0
52、;text = "" /賦空textwhile( contentlinei=' ' )/判斷空格i+;/是空格跳過(guò)if( (contentlinei>=65 && contentlinei<=90) | (contentlinei>=91 && contentlinei<=122) ) /判斷是否為字母或者下劃線text += contentlinei;i+;while( (contentlinei>=65 && contentlinei<=90) | (contentlin
53、ei>=91 && contentlinei<=122) | contentlinei>='0' && contentlinei<='9' ) /判斷是否為數(shù)字或者字母或者下劃線text += contentlinei;i+;for( j=0; j<=13 ; j+ )if( text=keyj )/查表判斷是否為保存字return 5;if( text="and" | text="or" )/判斷是否為邏輯運(yùn)算符return 8;if( j=14 )retur
54、n 1;/假設(shè)查表失敗說(shuō)明為標(biāo)識(shí)符elsewhile( contentlinei>='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= '' | contentlinei='' | contentlinei='' | contentlinei='(
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 離婚協(xié)議書(shū)美國(guó)
- 醫(yī)藥研發(fā)合同2024年
- 個(gè)人私家車(chē)租賃合同
- 二手合法房屋買(mǎi)賣(mài)合同
- 電子身份認(rèn)證系統(tǒng)開(kāi)發(fā)授權(quán)協(xié)議
- 手房買(mǎi)賣(mài)學(xué)區(qū)房補(bǔ)充協(xié)議
- 電影拍攝聘用合同
- 企業(yè)年度慶典活動(dòng)方案
- 單元主題二“滄海桑田”-地表形態(tài)的形成與演變-高中地理單元教學(xué)設(shè)計(jì)
- 買(mǎi)賣(mài)合同-油脂油料省間調(diào)撥合同8篇
- 2025年度產(chǎn)業(yè)園區(qū)建設(shè)項(xiàng)目委托代建服務(wù)協(xié)議
- 鄉(xiāng)鎮(zhèn)機(jī)關(guān)考勤管理制度
- 人體解剖生理學(xué)(第2版) 課件 第二章 細(xì)胞
- 教務(wù)主任在教務(wù)管理經(jīng)驗(yàn)大會(huì)上發(fā)言稿
- 自動(dòng)體外除顫器
- 《腦出血護(hù)理》課件
- 水手課件教學(xué)課件
- 《微生物學(xué)發(fā)展史》課件
- 網(wǎng)約車(chē)司機(jī)安全培訓(xùn)
- 以虛報(bào)注冊(cè)資本、虛假出資、抽逃出資為由對(duì)實(shí)行認(rèn)繳資本登記制的公司進(jìn)行處罰無(wú)法律依據(jù)
- 風(fēng)電場(chǎng)生產(chǎn)運(yùn)營(yíng)準(zhǔn)備大綱11.14
評(píng)論
0/150
提交評(píng)論