




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、編譯原理課程設計報告課題名C-一詞法掃描器及語法分析器頭現(xiàn)提交文檔學生姓名:劉佳玉提交文檔學生學號:2012141461134同組成員名單:無指導教師姓名:張縣指導教師評閱成績:指導教師評閱意見:提交報告時間:2015年6月10日目錄 TOC o 1-5 h z HYPERLINK l bookmark0 o Current Document 編譯原理課程設計報告1. HYPERLINK l bookmark4 o Current Document 1、課程設計目標2 HYPERLINK l bookmark6 o Current Document 2、分析與設計2程序結構2程序流程3詞法分析
2、3 HYPERLINK l bookmark21 o Current Document 代碼結構分析3. HYPERLINK l bookmark15 o Current Document token定義和類型3. HYPERLINK l bookmark17 o Current Document DNF分析4. HYPERLINK l bookmark19 o Current Document 語法分析4.代碼結構分析4.節(jié)點定義和類型5. HYPERLINK l bookmark33 o Current Document 遞歸下降語法分析6. HYPERLINK l bookmark35
3、o Current Document 3、測試結果11流程11出錯情況13、總結13 HYPERLINK l bookmark43 o Current Document 收獲13 HYPERLINK l bookmark45 o Current Document 特色14 HYPERLINK l bookmark47 o Current Document 不足14 HYPERLINK l bookmark49 o Current Document 、程序代碼實現(xiàn)14遞歸下降源代碼14C-文法651、課程設計目標學生在學習編譯原理課程過程中,結合各章節(jié)的構造編譯程序的基本理論,要求用C或C+語言
4、描述及上機調(diào)試,實現(xiàn)一個C-Minus小編譯程序(包括詞法分析,語法分析等重要子程序),使學生將理論與實際應用結合起來,受到軟件設計等開發(fā)過程的全面訓練,從而提高學生軟件開發(fā)的能力。要求:實現(xiàn)scanner和parser功能2、分析與設計程序結構語法分析采用遞歸下降方法的程序結構:本程序采用面向?qū)ο蟮乃枷刖帉?,使用C語言實現(xiàn),程序分為兩部分:詞法分析(scan)和語法分析(parse),分別將兩個處理階段寫在兩個函數(shù)中,分別是scan()和parse(),兩個函數(shù)分別完成詞法分析和語法分析的任務。scan()函數(shù)主要的工作是檢查注釋是否合法、詞法分析獲取token。parse()函數(shù)的主要工作
5、是根據(jù)scan()詞法分析之后的token進行語法分析,生成語法樹,最后并輸出語法樹。遞歸下降方法的程序流程圖程序流程詞法分析代碼結構分析詞法分析階段的代碼寫在一個函數(shù)中sean()。main函數(shù)讀取程序數(shù)據(jù),將其存儲在一個二維數(shù)組中,調(diào)用函數(shù)zhushierror(),確定程序是否存在注釋錯誤,注釋的錯誤主要是注釋的符號不匹配。如果不存在注釋錯誤,則調(diào)用sean()進行詞法分析,否則報錯。詞法分析是對輸入的數(shù)據(jù)一個字符一個字符的分析,將所分析出來的token存儲在一個veetor中,方便后面語法分析時調(diào)用。詞法分析沒有什么錯誤限制,基本不會報錯。所以在分析的同時,就會將所分析出的token函
6、數(shù)數(shù)組輸出2.3.2token定義和類型token結構體定義如下:struettoken/token結構體Tokentypetokentype;/token類型ehartokenstring1100;/token串intlineno;/token行號;token類型:/定義的Token的類型(29種),分別對應于else、if、int、return、void、while、/+、-、*、/、=、/!=)、num、id、錯誤、結束typedefenumelsee=1,iff,intt,returnn,voidd,whilee,xiaoyudengyu,dayudengyu,dengyudengyu
7、,budengyu,10jiajian,cheng,chu,dayu,xiaoyu,dengyu,fenhao,douhao,zuokuohao,youkuohao,zuozhongkuohao,/22youzhongkuohao,zuohuakuohao,youhuakuohao,num,id,error,end29Tokentype;2.3.3DNF分析詞法分析的dfA描述:詞法分析的DFA如下所示,一共分為5個狀態(tài):STARTINNUMINID、INDBSYMDON。狀態(tài)STAR表示開始狀態(tài),狀態(tài)INNUM表示數(shù)字類型(NUMToken的狀態(tài),狀態(tài)INID表示字符串類型Token的狀態(tài)(
8、如關鍵字和一般的標示符),狀態(tài)INDBSY表示雙目運算符型Token的狀態(tài)(如=、!=、=),狀態(tài)DON表示接收狀態(tài)。digitother2.4語法分析代碼結構分析語法分析階段的代碼中,每一條文法都有相對應的函數(shù),通過函數(shù)之間的遞歸調(diào)用來達到語法分析的目的。語法分析的過程主要是:在語法分析之前進行詞法分析,然后通過遞歸向下分析法根據(jù)c-語言的文法進行語法分析,并生成語法樹,最后打印語法樹。下面是語法分析所用到的全局變量和函數(shù)的聲明:tokencurrenttoken;當前tokentokenlasttoken;/上一個tokeninttokenxb=0;/token下標intblank=0;/
9、先行空格voidgettoken();/得到tokenvoidparseerror();/輸出錯誤voidmatch(Tokentypett);/匹配treenode*compound_stmt();/函數(shù)聲明voidprintspace(intn);/打印空格voidprinttree(treenode*t);/打印語法分析樹treenode*newnode(Nodekindkind);/創(chuàng)建新節(jié)點treenode*args();treenode*call(treenode*k);/函數(shù)調(diào)用treenode*factor(treenode*k);treenode*term(treenode*
10、k);treenode*additive_expression(treenode*k);/加成的表達式treenode*simple_expression(treenode*k);/簡單表達式treenode*varr();treenode*expression();treenode*expression_stmt();/treenode*return_stmt();/treenode*iteration_stmt();/whiletreenode*selection_stmt();/iftreenode*statement();/treenode*statement_list();/tree
11、node*local_declaration();/treenode*param(treenode*k);/treenode*param_list(treenode*k);/表達式聲明返回式聲明聲明聲明復合語句后者種類復合語句體后者復合語句體前者函參函參列表treenode*compound_stmt();/函數(shù)內(nèi)容,復合語句treenode*params();/函數(shù)參數(shù)treenode*declaration();/函數(shù)聲明treenode*declaration_list();/多個函數(shù)列表treenode*parse();/語法分析6a35c-Numbered_bec32794-fd6d
12、-47a8-a770-7c18d6f74896-節(jié)點定義和類型節(jié)點定義:structtreenode/樹節(jié)點結構體treenode*child;/子節(jié)點treenode*brother;/兄弟節(jié)點intlineno;/所在行Nodekindnodekind;/節(jié)點類型charnodestring1100;/節(jié)點類型所代表的字符串,用于語法樹打印;節(jié)點類型:/19種節(jié)點類型,分別表示int、id、void、數(shù)值、變量聲明、數(shù)組聲明、函數(shù)聲明、/函數(shù)聲明參數(shù)列表、函數(shù)聲明參數(shù)、復合語句體、if、while、return、賦值、運算、節(jié)點種類遞歸下empty var- declarationt ex
13、pression;/數(shù)組元素、函數(shù)調(diào)用、函數(shù)調(diào)用參數(shù)列表、未知節(jié)點typedefenumints,ids,voids,nums,var,shuzu,hanshu,hancanlist,hancan,fuheyuju,ifs,whiles,returns,fuzhi,yunsuan,shuzuyuansu,hanshudiaoyong,hanshudiaoyongcanlist,unknownNodekind;6a35c-Numbered_bec32794-fd6d-47a8-a770-7c18d6f74896-降語法分析2.4310語法programFeclaration-listdeclar
14、ationistTdeclarationdeclarationdeclarationTva-declaration|fun-declarationvar_declarationttype-specifierID;|type-specifierIDNUM;type-specifiertint|voidfun-declatationttype-specifierID(params)|compound-stmtparamstparam_list|voidparam_listtparam,paramparamttype-specifierIDcompounds-tmttlocal-declaratio
15、nstatement-listlocal-declarationststatement-listtstatementstatementtexpression-stmt|compound-stmt|selection-stmt|iteration-stmt|return-stmtexpression-stmtselection-stmttif(expression)statementelsestatementiteration-stmttwhile(expression)statementreturn-stmttreturnexpression;expressiontvar=expression
16、|simple-expressionrelopt=|=|=|!=vartID|IDexpressionsimple-expressionadditive-expressionrelopadditive-expressionadditive-expressionttermaddoptermaddopt+|-termtfactormulopfactormulopt*|/factort(expression)|var|call|NUMcalltID(args)argstarg-list|emptyarg-listtexpression,expression2.4.32遞歸下降語法分析過程以下表格列出
17、了根據(jù)上文中的C-文法使用遞歸向下分析方法分析程序的過程,在代碼部分只列出了函數(shù)名,具體函數(shù)見源代碼。待分析文法programFeclaration-list分析函數(shù)treeNode*parse()分析說明C-諦言編寫的程序由一組聲名序列組成。parse(void)函數(shù)使用遞歸向卜分析方法直接調(diào)用declarationist()函數(shù),并返回樹節(jié)點代碼treenode*parse()待分析文法declarationistdeclarationdeclaration分析函數(shù)treenode*declaration_list()分析說明C-語百編寫的程序由一組聲名序列組成。declarationis
18、t(void)函數(shù)使用遞歸向卜分析方法直接調(diào)用declaration。函數(shù),并返回樹節(jié)點代碼treenode*declaration_list()待分析文法declarationAvar-declaration|fun-declarationvar_declaration”ype-specifierID;|type-specifierIDNUM;fun-declatationMype-specifierID(params)|compound-stmttype-specifierTint|void分析函數(shù)treenode*declaration()分析說明C-諦言的聲明分為變量聲明和函數(shù)聲明。d
19、eclaration(void)函數(shù)并不是直接調(diào)用var-declaration或fun-declaration文法所對應的函數(shù),令其返回節(jié)點,頭際上程序并沒有為var-declaration和fun-declaration文法定義函數(shù),而是在declaration(void)函數(shù)中,通過求First集合的方式先確定是變量定義還是函數(shù)定義,然后分別根據(jù)探測的結果生成變量聲明節(jié)點(Var_DeclK或函數(shù)聲明節(jié)點(FunKo所以var-declaration和fun-declaration文法在declarationTvar-declaration|fun-declaration文法中就都已經(jīng)分
20、析了代碼treenode*declaration()待分析文法paramsAparam_list|void分析函數(shù)treenode*params()分析說明函數(shù)參數(shù)列表要么是void,要么是多個參數(shù)組成。params(void)函數(shù)先判斷弟一個是void還是int,如果是int說明是由param_list組成,則調(diào)用param_list(TreeNode*k)函數(shù)遞歸向卜分析;如果是void說明可能是void型的參數(shù),也可能參數(shù)就是void,所以再求其Follow集合,如果集合求出來是右括號,則說明參數(shù)就是void,于是新建一個VoidK節(jié)點就行;如果集合求出來不是右括號則說明是void型的參
21、數(shù),然后再調(diào)用paramist(TreeNode*k)函數(shù)遞歸向卜分析,并將已經(jīng)取出VoidK節(jié)點傳遞給param_list(TreeNode*k)函數(shù)代碼treenode*params()待分析文法param_listTparam,param分析函數(shù)treenode*param_list(treenode*k)分析說明參數(shù)列表由param序列組成,并由逗方隔開。param_list(TreeNode*k)函數(shù)使用遞歸向卜分析方法直接調(diào)用param(TreeNode*k)函數(shù),并返回樹節(jié)點代碼treenode*param_list(treenode*k)待分析文法paranrtype-spec
22、ifierID分析函數(shù)treenode*param(treenode*k)分析說明參數(shù)由int或void、標不符組成,最后可能有中括號表示數(shù)組。param(TreeNodek)函數(shù)根據(jù)探測先仃Token是int還是void而新建IntK或VoidK下點作為其弟一個子下點,然后新建IdK下點作為其弟一個子節(jié)點,最后探測Follow集合,是否是中括號,而確定是e再新建第二個子節(jié)點表示數(shù)組類型代碼treenode*param(treenode*k)待分析文法compound-stmhlocal-declarationstatement-list分析函數(shù)treenode*compound_stmt()
23、分析說明旻合語句由用花播圍起來的一組嚴明和語句組成。compound_stmt(void)函數(shù)使用遞歸向下分析方法直接調(diào)用local_declaration()函數(shù)和statement_list()函數(shù),并根據(jù)返回的樹節(jié)點作為其第一個子節(jié)點和第二個子節(jié)點代碼treenode*compound_stmt()待分析文法local-declarations八emptyvar-declaration分析函數(shù)treenode*local_declaration()分析說明局部變重嚴明要么是空,要么由許多變重嚴明序列組成。local_declaration(void)函數(shù)通過判斷先行的Token是否是in
24、t或void便可知道局部變量聲明是否為空,如果不為空,則新建一個變量定義節(jié)點(Var_Decl0代碼treenode*local_declaration()待分析文法statement-liststatement分析函數(shù)treenode*statement_list()分析說明由語句列表由0到多個statement組成statement_list(void)函數(shù)通過判斷先行Token尖型是否為statement的First集合確止后面th否是一個statement,如果th,則使用遞歸向卜分析方法直接調(diào)用statement。函數(shù)代碼treenode*statement_list()待分析文法s
25、tatementexpression-stmt|compound-stmt|selection-stmtreturn-stmt|iteration-stmt|分析函數(shù)treenode*statement()分析說明statement由表達式或復合語句或if語句或while語句或return語句構成statement(void)函數(shù)通過判斷先行Token類型確定到底是哪一種類型。如果是IF則是if語句類型,如果是WHILE則是while語句類型,如果是RETURN則是return語句類型,如果是左大括號,則是復合語句類型,如果是ID、SEMILPAREnNUM則是表達式語句類型代碼treenod
26、e*statement()待分析文法expression-stmtexpression;分析函數(shù)treenode*expression_stmt()分析說明表達式語句有一個可選的且后面跟著分號的表達式。expression_stmt(void)函數(shù)通過判斷先行Token類型是否為分號,如果不是則直接調(diào)用函數(shù)expression()代碼treenode*expression_stmt()待分析文法selection-stmtTf(expression)statementelsestatement分析函數(shù):treenode*selection_stmt()分析selection_stmt(void
27、)函數(shù)直接調(diào)用expression()函數(shù)和statement()函數(shù)分別得到其第一個和第二個子節(jié)點,然后通過判斷先行Token類型是否為ELSE如果是則直接調(diào)用statement()函數(shù)得到其第三個子節(jié)點代碼treenode*selection_stmt()待分析文法iteration-stmtawhile(expression)statement分析函數(shù)treenode*iteration_stmt()分析讓eration_stmt(void)函數(shù)直接調(diào)用expression。函數(shù)和statement。函數(shù)分別得到其第一個和第二個子節(jié)點代碼treenode*iteration_stmt()
28、待分析文法return-stmtAreturnexpression;分析函數(shù)treenode*return_stmt()分析return_stmt(void)函數(shù)通過判斷先仃Token類型是否為分號,如果不是則直接調(diào)用函數(shù)expression。得到其子節(jié)點代碼treenode*return_stmt()待分析文法expressionvar=expression|simple-expression分析函數(shù)treenode*expression()分析expression(void)函數(shù)通過判斷先行Token尖型是否為ID,如果不是說明只能是simple_expression情況,則調(diào)用simpl
29、e_expression(TreeNode*k)函數(shù)遞歸向卜分析;如果是ID說明可能是賦值語句,或simple_expression中的var和call類型的情況,所以再求具Follow集封,如果集名、求出來是賦,扈類型的Token,則說明是賦值語句,于是新建一個AssignK節(jié)點就行;如果集合求出來不是賦值類型的Token則說明是simple_expression中的var和call尖型的情況,然后再調(diào)用simple_expression(TreeNode*k)函數(shù)遞歸問卜分析,并將已經(jīng)取出IdK節(jié)點傳遞給simple_expression(TreeNode*k)函數(shù)代碼treenode*e
30、xpression()待分析文法varTD|IDexpression分析函數(shù)treenode*varr()分析varr(void)函數(shù)先新建一個IdK節(jié)點,再通過判斷先行Token類型是否為左中括號,如果是則新建一個數(shù)組節(jié)點Arry_ElemK,將IdK作為Arry_ElemK節(jié)點的第一個子節(jié)點,再直接調(diào)用函數(shù)expression。得至1JArry_ElemK的第二個子節(jié)點,最后返回的節(jié)點時Arry_ElemK如果先行Token類型不是左中括號,則將之前的IdK返回代碼treenode*varr()待分析文法simple-expressionadditive-expressionrelopad
31、ditive-expressionrelopT=|=|=|!=分析函數(shù)treenode*simple_expression(treenode*k)分析simple_expression(TreeNode*k)函數(shù)先調(diào)用additive_expression(TreeNode*k)函數(shù)返回一個節(jié)點,然后再一直判斷后面的Token是否為=、=!=,如果是則新建OpK節(jié)點,然后令之前的節(jié)點為其第一個子節(jié)點,然后繼續(xù)調(diào)用additive_expression(TreeNode*k)函數(shù)返回一個節(jié)點,作為OpK節(jié)點的第二個節(jié)占八、代碼treenode*simple_expression(treenode
32、*k)待分析文法additive-expressionfermaddoptermaddopT+1-分析函數(shù)treenode*additiveexpression(treenode*k)分析additive_expression(TreeNode*k)函數(shù)先調(diào)用term(TreeNode*k)函數(shù)返回一個節(jié)點,然后再一直判斷后面的Token是否為+或-,如果是則新建OpK節(jié)點,然后令之前的節(jié)點為其第一個子節(jié)點,term(TreeNode*k)函數(shù)返回一個節(jié)點,作為OpK節(jié)點的第二個節(jié)點然后繼續(xù)調(diào)用代碼treenode*additive_expression(treenode*k)待分析文法ter
33、mtfactormulopfactormulopT*|/分析函數(shù)treenode*term(treenode*k)分析term(TreeNode*k)函數(shù)先調(diào)用factor(TreeNode*k)函數(shù)返回一個節(jié)點,然后再一直判斷后面的Token是否為*或/,如果是則新建OpK節(jié)點,然后令之前的節(jié)點為其第一個子節(jié)點,然后繼續(xù)調(diào)用actor(TreeNode*k)函數(shù)返回一個節(jié)點,作為OpK節(jié)點的第二個節(jié)點代碼treenode*term(treenode*k)待分析文法factorT(expression)|var|call|NUM分析函數(shù)treenode*factor(treenode*k)分析
34、factor(TreeNode*k)函數(shù)首先判斷k是否為空,如果不為空,則k為上面?zhèn)飨聛淼囊呀?jīng)解析出來的以ID開頭的var,此時可能為call或var的情況,然后判斷后面的Token是否為左括號,如果是則說明是call的情形,如果不是則為var的情形。如果k為空,再根據(jù)先行的Token類型判斷是4中推導中的哪一種,然后直接調(diào)用相關的函數(shù)返回一個節(jié)點代碼treenode*factor(treenode*k)待分析文法callT1D(args)分析函數(shù)treenode*call(treenode*k)分析call(TreeNode*k)函數(shù)新建一個call語句的節(jié)點CallK,如果k不為空,則將k
35、設為CallK的第一個子節(jié)點,然后通過調(diào)用args(void)函數(shù)獲得其第二個節(jié)點,最后返回CallK節(jié)點代碼treenode*call(treenode*k)待分析文法argsTarg-list|emptyarg-listTexpression,expression分析函數(shù)treenode*args()分析factor(TreeNode*k)函數(shù)首先判斷后面的Token是否為右括如果是則說明是empty的情形,如果不是則為至少有一個expression的情形,然后調(diào)用expression。函數(shù)返回節(jié)點,然后一直判斷后面的Token是否為逗方,如果是則說明后面還有一個expression,則再
36、調(diào)用expression。函數(shù),使各expression返回的下點為兄弟節(jié)點,然后再將第一個expression返回的節(jié)點作為函數(shù)調(diào)用語句參數(shù)節(jié)點ArgsK的子節(jié)點代碼treenode*args()3、測試結果流程測試數(shù)據(jù):測試結果:詞法分析:語法分析:出錯情況若注釋沒有結束符號:則提示刪除注釋出錯若含有未知Token比如char則語法分析出錯4、總結收獲在本次課程設計中增加了自己的動手能力,鍛煉了構造一個項目的框架方法,能夠很好的給出系統(tǒng)的框架,并且能夠按照程序流程進行程序的編寫。能夠靈活運用遞歸下降的方法進行分析問題,在詞法分析中掌握了狀態(tài)機的轉變,同時能夠熟練運用狀態(tài)機進行字符的匹配。在
37、語法分析中,學習到了怎么樣通過文法構建代碼,以及根據(jù)文法編寫代碼帶來的相關問題,如左遞歸,節(jié)點的定義等。特別是在寫語法分析器的時候,已經(jīng)對編譯器的語法分析的內(nèi)容有了一定的了解,所以直接進行了理論的學習。首先自己對遞歸向下分析法進行了學習,將書上的幾個遞歸向下分析的偽代碼看過之后,自己對遞歸向下的分析方法的原理有了初步的認識,大概知道了根據(jù)文法怎么分析。但是由于C-語言給出的文法有左遞歸存在,于是自己將存在左遞歸的文法改寫成EBNF勺形式,并據(jù)此進行代碼編寫。整個過程可以說是痛并快樂著,一方面自己在編寫代碼的時候遇到了很多問題,這也是自己動手能力不足的一個表現(xiàn)。特色在詞法分析方面,使用全局變量Z
38、S來判斷當前字符是否是注釋,并且通過ZS的值判斷注釋是否合法。整體來說,代碼簡介明了,沒有復雜的類的關系,樹節(jié)點只有孩子和兄弟兩個子節(jié)點,沒有復雜的節(jié)點之間的關系。不足由于各函數(shù)之間邏輯關系比較復雜,代碼還存在一些錯誤,需要通過測試來修復bug5、程序代碼實現(xiàn)遞歸下降源代碼#include#include#include#include#include#include#includeuSingnameSpaceStd;charS10051005;/文本charp10051005;chart1005;/當前token串charlinShi1100;/臨時數(shù)組intk;/文本行數(shù)intzs;/注釋
39、標記,1表示是注釋,0表示不是注釋voidzhushierror()/注釋錯誤inti,j,len;zs=0;for(i=0;ik-1;i+)len=strlen(si);for(j=0;jlen-1;j+)if(sij=/&sij+1=*)if(zs=0)zs=1;elsereturn;if(sij=*&sij+1=/)if(zs=1)zs=0;elsezs=1;return;/定義的Token的類型(29種),分別對應于else、if、int、return、void、while、/+、-、*、/、=、=、/!=、=、;、,、(、)、numid、錯誤、結束typedefenumelsee=1
40、,iff,intt,returnn,voidd,whilee,xiaoyudengyu,dayudengyu,dengyudengyu,budengyu,/10jia,jian,cheng,chu,dayu,xiaoyu,dengyu,fenhao,douhao,zuokuohao,youkuohao,zuozhongkuohao,/22youzhongkuohao,zuohuakuohao,youhuakuohao,num,id,error,end/29Tokentype;structtoken/token結構體Tokentypetokentype;/token類型chartokenstri
41、ng1100;/token串intlineno;/token行號;Tokentypegettokentype(charc)Tokentypeto;if(!strcmp(c,else)to=elsee;elseif(!strcmp(c,if)to=iff;elseif(!strcmp(c,return)to=returnn;elseif(!strcmp(c,int)to=intt;elseif(!strcmp(c,void)to=voidd;elseif(!strcmp(c,while)to=whilee;elseif(!strcmp(c,+)to=jia;elseif(!strcmp(c,-)
42、to=cheng;elseif(!strcmp(c,/)to=chu;elseif(!strcmp(c,)to=xiaoyu;elseif(!strcmp(c,)to=dayu;elseif(!strcmp(c,=)to=dengyudengyu;elseif(!strcmp(c,!=)to=budengyu;elseif(!strcmp(c,=)to=dengyu;elseif(!strcmp(c,;)to=fenhao;elseif(!strcmp(c,)to=douhao;elseif(!strcmp(c,()to=youkuohao;elseif(!strcmp(c,)to=zuozh
43、ongkuohao;elseif(!strcmp(c,)to=youzhongkuohao;elseif(!strcmp(c,)to=zuohuakuohao;elseif(!strcmp(c,)to=youhuakuohao;elseif(!strcmp(c,num)to=id;elseif(!strcmp(c,end)to=end;returnto;vectortokenlist;/token序列voidscan()inti,j,m,l,n;/下標intf,flag;/標記intlen;/當前行長度charguan101005=else,if,int,return,void,while;/
44、關鍵字charsp101005=,=,!=;/雙目比較符charfu1005=+,-,*,/,=,;,(,),!;/單目符號elseif(!strcmp(c,id)zs=0;for(i=0;ik-1;i+)len=strlen(si);printf(%d:,i+1);printf(%sn,si);if(len=0)/空行continue;for(j=0;j=1&sij-1=*&sij=/)zs=0;/注釋結束空格continue;if(sij=)/continue;if(sij=a)|(sij=A)/l=j;m=0;while(sil=a)|(sil=A)tm+=sil+;tm=0;f=1;/
45、標記for(n=0;n=5;n+)if(!strcmp(t,guann)f=0;printf(%d:reservedword:%sn,i+1,t);tokento;to.tokentype=gettokentype(t);strcpy(to.tokenstring,t);to.lineno=i+1;tokenlist.push_back(to);break;if(f)e_se9一OiOf(smVAnoll.sfrprinffnamecpy(=nshi=id)二sfrcpyao.fokensmngu%swlJ)%八(fo.fokenfypeHge#okeefype(=nshi)+)Hw3foke
46、n%(hq9hHfpshqmm+QOQOse(0-sfri+NUMH/llsm(s=v=kSs=u=u-Qcpy(-inshi=nurrr)八Hprinff+)Astrcpy(to.tokenstring,t);to.lineno=i+1;tokenlist.push_back(to);j=l-1;else/符號l=j;n=0;while(1)flag=0;/標記for(m=0;m=15;m+)if(sil=fum)flag=1;tn+=fum;l+;break;if(!flag)break;tn=0;if(!strcmp(t,/*)/注釋開始zs=1;j-;elseflag=1;for(m=
47、0;m=3;m+)/雙目比較符if(!strcmp(t,spm)tokento;to.tokentype=gettokentype(t);strcpy(to.tokenstring,t);to.lineno=i+1;tokenlist.push_back(to);printf(%d:specialcharacters:%sn,i+1,t);flag=0;break;if(flag)/單目符號for(m=0;mn;m+)tokento;linshi0=tm;linshi1=0;to.tokentype=gettokentype(linshi);strcpy(to.tokenstring,lins
48、hi);to.lineno=i+1;tokenlist.push_back(to);printf(%d:specialcharacters:%cn,i+1,tm);/一個一個輸出j=l-1;tokento;to.lineno=i;to.tokentype=end;strcpy(to.tokenstring,endfile);tokenlist.push_back(to);19種節(jié)點類型,分別表示int、id、void、數(shù)值、變量聲明、數(shù)組聲明、函數(shù)聲明、/函數(shù)聲明參數(shù)列表、函數(shù)聲明參數(shù)、復合語句體、if、while、return、賦值、運算、/數(shù)組元素、函數(shù)調(diào)用、函數(shù)調(diào)用參數(shù)列表、未知節(jié)點ty
49、pedefenumints,ids,voids,nums,var,shuzu,hanshu,hancanlist,hancan,fuheyuju,ifs,whiles,returns,fuzhi,yunsuan,shuzuyuansu,hanshudiaoyong,hanshudiaoyongcanlist,unknownNodekind;/節(jié)點種類typedefenumVoid,IntegerExptype;/表達式種類treenode*child;/子節(jié)點treenode*brother;/兄弟節(jié)點intlineno;/所在行Nodekind nodekind;/節(jié)點類型char node
50、string1100;/節(jié)點類型所代表的字符串,用于語法樹打印用于語法樹打印;tokencurrenttoken;/當前tokentokenlasttoken;/上一個tokeninttokenxb=0;/token下標intblank=0;/先行空格voidgettoken();/得到tokenvoidparseerror();/輸出錯誤voidmatch(Tokentypett);/匹配treenode*compound_stmt();/函數(shù)聲明voidprintspace(intn);/打印空格voidprinttree(treenode*t);/打印語法分析樹treenode*newn
51、ode(Nodekindkind);/創(chuàng)建新節(jié)點treenode*args();treenode*call(treenode*k);/函數(shù)調(diào)用treenode*factor(treenode*k);treenode*term(treenode*k);treenode*additive_expression(treenode*k);/加成的表達式treenode*simple_expression(treenode*k);/簡單表達式treenode*varr();treenode*expression();treenode*expression_stmt();/表達式聲明treenode*re
52、turn_stmt();/返回式聲明treenode*iteration_stmt();/while聲明treenode*selection_stmt();/if聲明treenode*statement();/復合語句后者種類treenode*statement_list();/復合語句體后者treenode*local_declaration();/復合語句體前者treenode*param(treenode*k);/函參treenode*param_list(treenode*k);/函參列表treenode*compound_stmt();/函數(shù)內(nèi)容,復合語句treenode*param
53、s();/函數(shù)參數(shù)treenode*declaration();/函數(shù)聲明treenode*declaration_list();/多個函數(shù)列表treenode*parse();/語法分析voidgettoken()/得到tokenlasttoken=currenttoken;currenttoken=tokenlisttokenxb+;voidparseerror()/輸出錯誤coutcurrenttoken.linenolineparseerror!endl;voidmatch(Tokentypett)/匹配/coutliuendl;/coutct:currenttoken.tokenty
54、pett:ttendl;if(currenttoken.tokentype=tt)gettoken();elsecoutmatcherrorendl;parseerror();voidprintspace(intn)/打印空格inti;for(i=0;in;i+)coutnodekind=ints)printf(intn);elseif(t-nodekind=voids)printf(voidn);elseif(t-nodekind=ids)printf(id:%sn,t-nodestring);elseif(t-nodekind=nums)elseif(t-nodekind=var)prin
55、tf(varn);elseif(t-nodekind=shuzu)printf(shuzushengmingn);elseif(t-nodekind=hanshu)printf(hanshushengmingn);elseif(t-nodekind=hancanlist)printf(hancanlistn);elseif(t-nodekind=hancan)printf(hancann);elseif(t-nodekind=fuheyuju)elseif(t-nodekind=ifs)printf(ifn);elseif(t-nodekind=whiles)printf(whilen);el
56、seif(t-nodekind=returns)printf(returnn);elseif(t-nodekind=fuzhi)printf(fuzhin);elseif(t-nodekind=yunsuan)printf(yunsuan:%sn,t-nodestring);elseif(t-nodekind=shuzuyuansu)elseif(t-nodekind=hanshudiaoyong)printf(hanshudiaoyongn);elseif(t-nodekind=hanshudiaoyongcanlist)printf(hanshudiaoyongcanlistn);elseprintf(unknownn);blank+;/子樹空格多一個if(t-child!=NULL)printtree(t-child);blank-;/兄弟不變t=t-brother;創(chuàng)建新節(jié)點treenode*newnode(Nodekindkind)/treenode*p=(treenode*)malloc(sizeof(treenode);if(p=NULL)coutnewnodeerrorchild=NULL;p-brother=NULL;p-lineno=currenttoken.lineno;p-
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 衢江區(qū)項目報備管理辦法
- 西安養(yǎng)老社會化管理辦法
- 規(guī)范ppp項目管理辦法
- 設計院外委人員管理辦法
- 財政局項目資料管理辦法
- 貴州省倉儲物流管理辦法
- 貸款信息化管理暫行辦法
- 贛州市儲備糧油管理辦法
- 跨境電商實驗室管理辦法
- 車隊職業(yè)健康管理辦法
- 上海黃浦老西門項目概念方案設計(260P)
- 金融服務不良體驗投訴書范文
- 碳排放與財務績效-深度研究
- 食品加工安全生產(chǎn)標準化建設流程
- 2025年上海閔行區(qū)高三一模高考英語模擬試卷(含答案詳解)
- 2025年湖北十堰市竹山縣事業(yè)單位招聘工作人員89人高頻重點提升(共500題)附帶答案詳解
- GB/T 17145-2024廢礦物油回收與再生利用導則
- 網(wǎng)絡營銷的熱點技術與趨勢分析
- 涂料的基礎知識
- 《肥胖與疾病關系的》課件
- 新疆防沙治沙生態(tài)建設可行性研究報告
評論
0/150
提交評論