編譯原理課程設(shè)計(jì)-C-詞法掃描器及語法分析器實(shí)現(xiàn)(共37頁)_第1頁
編譯原理課程設(shè)計(jì)-C-詞法掃描器及語法分析器實(shí)現(xiàn)(共37頁)_第2頁
編譯原理課程設(shè)計(jì)-C-詞法掃描器及語法分析器實(shí)現(xiàn)(共37頁)_第3頁
編譯原理課程設(shè)計(jì)-C-詞法掃描器及語法分析器實(shí)現(xiàn)(共37頁)_第4頁
編譯原理課程設(shè)計(jì)-C-詞法掃描器及語法分析器實(shí)現(xiàn)(共37頁)_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、編譯原理課程設(shè)計(jì)報(bào)告 xx xxxxxxxxx 指導(dǎo)老師 :金軍 編譯(biny)原理課程設(shè)計(jì)報(bào)告課題(kt)名稱: C-詞法(cf)掃描器及語法分析器實(shí)現(xiàn) 提交文檔學(xué)生姓名: 提交文檔學(xué)生學(xué)號(hào): 同組 成 員 名 單: 無 指導(dǎo) 教 師 姓 名: 金軍 指導(dǎo)教師評(píng)閱成績: 指導(dǎo)教師評(píng)閱意見: . . 提交報(bào)告時(shí)間:2014年 6月 xx日目錄(ml)TOC o 1-3 h u HYPERLINK l _Toc29856 目錄(ml) PAGEREF _Toc29856 2 HYPERLINK l _Toc27515 1 課程設(shè)計(jì)目標(biāo)(mbio) PAGEREF _Toc27515 2 HYP

2、ERLINK l _Toc5285 2 分析與設(shè)計(jì) PAGEREF _Toc5285 4 HYPERLINK l _Toc2471 2.1 程序結(jié)構(gòu) PAGEREF _Toc2471 4 HYPERLINK l _Toc19472 3 程序代碼實(shí)現(xiàn) PAGEREF _Toc19472 9 HYPERLINK l _Toc1975 3.1 代碼結(jié)構(gòu) PAGEREF _Toc1975 9 HYPERLINK l _Toc22161 3.2.1 globals.h PAGEREF _Toc22161 9 HYPERLINK l _Toc1346 3.2.2 scan.c PAGEREF _Toc13

3、46 11 HYPERLINK l _Toc1379 3.2.3 parser.c PAGEREF _Toc1379 18 HYPERLINK l _Toc1685 3.4 util.c PAGEREF _Toc1685 30 HYPERLINK l _Toc19376 3.5 test.cpp PAGEREF _Toc19376 36 HYPERLINK l _Toc31224 4 測試結(jié)果 PAGEREF _Toc31224 38 HYPERLINK l _Toc12100 4.1.給出標(biāo)準(zhǔn)測試程序的詞法和語法分析結(jié)果: PAGEREF _Toc12100 38 HYPERLINK l _

4、Toc25637 4.1.1 詞法分析結(jié)果 PAGEREF _Toc25637 38 HYPERLINK l _Toc18340 4.1.2 語法分析結(jié)果 PAGEREF _Toc18340 41 HYPERLINK l _Toc21879 4.2.修改代碼后的結(jié)果: PAGEREF _Toc21879 42 HYPERLINK l _Toc1788 4.2.1修改 PAGEREF _Toc1788 42 HYPERLINK l _Toc5534 5. 本課程設(shè)計(jì)我的獨(dú)創(chuàng)工作 PAGEREF _Toc5534 44 HYPERLINK l _Toc9107 6.總結(jié) PAGEREF _Toc9

5、107 44 1 課程設(shè)計(jì)目標(biāo)(mbio)學(xué)生在學(xué)習(xí)編譯原理課程過程(guchng)中,結(jié)合各章節(jié)的構(gòu)造編譯程序的基本理論,要求用C或C+語言(yyn)描述及上機(jī)調(diào)試,實(shí)現(xiàn)一個(gè) C-Minus 小編譯程序(包括詞法分析,語法分析等重要子程序),使學(xué)生將理論與實(shí)際應(yīng)用結(jié)合起來,受到軟件設(shè)計(jì)等開發(fā)過程的全面訓(xùn)練,從而提高學(xué)生軟件開發(fā)的能力。 要求:(1)設(shè)計(jì)詞法分析器設(shè)計(jì)各單詞的狀態(tài)轉(zhuǎn)換圖,并為不同的單詞設(shè)計(jì)種別碼。將詞法分析器設(shè)計(jì)成供語法分析器調(diào)用的子程序。功能包括:a. 具備預(yù)處理功能。將不翻譯的注釋等符號(hào)先濾掉,只保留要翻譯的符號(hào)串,即要求設(shè)計(jì)一個(gè)供詞法分析調(diào)用的預(yù)處理子程序;b. 能夠拼出

6、語言中的各個(gè)單詞;c. 返回(種別碼, 屬性值)。(2)語法分析要求用學(xué)習(xí)過的自底向上或自頂向下的分析方法等,實(shí)現(xiàn)對(duì)表達(dá)式、各種說明語句、控制語句進(jìn)行語法分析。若語法正確,則用語法制導(dǎo)翻譯法進(jìn)行語義翻譯;生成并打印出語法樹;若語法錯(cuò)誤,要求指出出錯(cuò)性質(zhì)和出錯(cuò)位置(行號(hào))。2 分析(fnx)與設(shè)計(jì)2.1 程序結(jié)構(gòu)本程序(chngx)采用C+語言以面向?qū)ο蟮乃枷刖帉?binxi),程序分為兩部分:詞法分析(Scanner)和語法分析(Parser)。掃描程序執(zhí)行詞法分析,并將字符序列收集到token中,并將每一行的Token打印出來。實(shí)現(xiàn)方法:Scanner:手工實(shí)現(xiàn)Parser:遞歸下降系統(tǒng)總圖

7、:ParserScannersource code Token Syntax Tree 程序流程:在程序中,詞法分析獲取所有Token,并將獲取的Token存儲(chǔ)在scanner對(duì)象的tokenString中。然后Parser類的語法分析程序就根據(jù)tokenString中的Token進(jìn)行語法分析,生成語法樹,最后打印語法樹。同時(shí),這也是程序的流程。整體程序流程圖開始刪除注釋出錯(cuò)詞法分析TF結(jié)束語法分析出錯(cuò)出錯(cuò)輸出出錯(cuò)信息TFFT從文件獲取源代碼掃描器:C慣用(gunyng)的詞法1、語言(yyn)的關(guān)鍵字:else if int return void while2、專用(zhunyng)符號(hào):

8、+ - * / = = != = ; , ( ) /* */3、其他標(biāo)記是ID和NUM,通過下列正則表達(dá)式定義:ID = letter letter*NUM = digit digit*letter = a|.|z|A|.|Zdigit = 0|.|94、空格由空白、換行符和制表符組成??崭裢ǔ1缓雎?hl),除了它必須分開ID、NUM關(guān)鍵字。5. 注釋用通常的C語言符號(hào)/ * . . . * /圍起來。注釋可以放在任何空白(kngbi)出現(xiàn)的位置(即注釋不能放在標(biāo)記內(nèi))上,且可以超過一行。注釋不能嵌套。DFA圖如下(rxi):初始狀態(tài)設(shè)置為START,當(dāng)需要得到下一個(gè)token時(shí),取得此to

9、ken的第一個(gè)字符,并且按照DFA與對(duì)此字符的類型的分析,轉(zhuǎn)換狀態(tài)。重復(fù)此步驟,直到DONE為止,輸出token類型。參考課本中所給的TINY掃描程序的DFA,C-的DFA不同之處在于注釋以及(= =,! = , =)的處理:注釋部分參考了課本中C風(fēng)格注釋的DFA; Other other *54321 / * * / Other other 處理(= =,! = , =)時(shí)并沒有新建狀態(tài),而是在狀態(tài)INASSIGN中分了4種情況,通過一個(gè)變量分別處理。INENDCOMMENT語法分析: C-語法(yf)與語義:1. program declaration-list 2. declaratio

10、n-list declaration-list declaration | declaration 3. declaration var-declaration | fun-declaration 4. var-declaration type-specifier ID ; | type-specifier ID NUM ; 5. type-specifier int | void 6. fun-declaration type-specifier ID ( params ) compound-stmt (在課后解釋中compound-stmt前面(qin mian)沒有“|”符號(hào)(fho))

11、 7. params params-list | void 8. param-list param-list , param | param 9. param type-specifier ID | type-specifier ID 10. compound-stmt local-declarations statement-list 11. local-declarations local-declarations var-declaration | empty 12. statement-list statement-list statement | empty 13. statemen

12、t expression-stmt | compound-stmt | selection-stmt | iteration-stmt | return-stmt 14. expression-stmt expression ; | ; 15. selection-stmt if ( expression ) statement | if ( expression ) statement else statement 16. iteration-stmt while(expression) statement 17. return-stmt return ; | return expressi

13、on ; 18. expression var = expression | simple-expression 19. var ID | ID expression 20. simple-expression additive-expression relop additive-expression | additive-expression 21. relop = | | = | = | != 22. additive-expression additive-expression addop term | term 23. addop + | - 24. term term mulop f

14、actor | factor 25. mulop * | / 26. factor ( expression ) | var | call | NUM 27. call ID ( args ) 28. args arg-list | empty 29. arg-list arg-list , expression | expression代碼設(shè)計(jì)(shj)格式:程序結(jié)構(gòu):語法分析函數(shù)parser通過調(diào)用詞法分析函數(shù)getToken實(shí)現(xiàn)語法分析。文件(wnjin)和函數(shù)的設(shè)計(jì)說明:文件main.c包含相應(yīng)頭文件,及main函數(shù)的實(shí)現(xiàn);文件golbals.h包含符號(hào)表和分析數(shù)的數(shù)據(jù)結(jié)構(gòu)及在其它文件

15、中使用的變量;文件util.h 和util.c實(shí)現(xiàn)與詞法分析和語法分析輸出相關(guān)的函數(shù)printToken和printTree,以及分析樹節(jié)點(diǎn)初始化相關(guān)的函數(shù)newStmtNode,newExpNode(Expkind)和copyString;文件scan.h 和scan.c實(shí)現(xiàn)詞法分析,主要函數(shù)為getToken;文件parser.h 和parser.c實(shí)現(xiàn)語法分析,函數(shù)為與文法(wnf)規(guī)則對(duì)應(yīng)的函數(shù)。3 程序代碼實(shí)現(xiàn)(shxin)3.1 代碼結(jié)構(gòu)3.2.1 globals.h#ifndef _GLOBALS_H_#define _GLOBALS_H_#include #include #i

16、nclude #include #include#include using namespace std;#ifndef FALSE#define FALSE 0#endif#ifndef TRUE#define TRUE 1;#endif/ 保留字的個(gè)數(shù)#define MAXRESERVED 6typedef enum/book-keeping tokensENDFILE,ERROR,/reserved wordsIF,ELSE,INT,RETURN,VOID,WHILE,/multicharacter tokensID,NUM,/special symbols/LBRACKET/RBRAC

17、KET - LBRACE/RBRACE ASSIGN,EQ,LT,RT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI,LBRACKET,RBRACKET,NEQ,COMMA,LBRACE,RBRACE,LTEQ,RTEQTokenType;extern FILE* source; /源代碼文件extern FILE* listing; /listing output text fileextern FILE* code; /extern int lineno; /語法分析樹typedef enum NodeKindStmtK, ExpK, Declarati

18、onK,;typedef enum StmtKindIfK, WhileK, AssignK, ReturnK, VoidK,;typedef enum ExpKindOpK, ConstK, IdK, Array_expK,Function_expK,;typedef enum ExpTypeVoid,Integer;typedef enum DeclarationKind FunctionK, VarK, ArrayK, ParaMeterK ;#define MAXCHILDREN 3typedef struct treeNodestruct treeNode *declaration;

19、struct treeNode *childMAXCHILDREN;struct treeNode *sibling;struct treeNode *params;int lineno;NodeKind nodekind;union kindStmtKind stmt;ExpKind exp;DeclarationKind declaration;kind;struct MyStruct TokenType op;int val;char *name;int size;attr;ExpType type;TreeNode;extern int EchoSource;extern int Tr

20、aceScan;extern int TraceParse;extern int TraceAnalyze;extern int TraceCode;extern int Error;#endif3.2.2 scan.c最主要的過程是GetToken,它消耗輸入字符并根據(jù)DFA圖返回下一個(gè)被識(shí)別的記號(hào)。這個(gè)實(shí)現(xiàn)利用了雙重嵌套情況分析,以及一個(gè)有關(guān)狀態(tài)的大型情況列表,在大列表中是基于當(dāng)前(dngqin)輸入字符的單獨(dú)列表。記號(hào)本身被定義成globals.h中的枚舉類型。掃描(somio)程序的狀態(tài)也被定義(dngy)為一個(gè)枚舉類型,位于掃描程序之中。掃描程序使用了三個(gè)全局變量,文件變量sourc

21、e,listing.在globals.h中聲明且在main.c中被分配和初始化的整型變量lineno。由getToken過程完成的額外的簿記如下所述:表reserved和過程reservedlookup完成位于由getToken的主要循環(huán)識(shí)別的標(biāo)識(shí)符之后的保留字的查找,currentToken的值也隨之改變。標(biāo)志變量save被用作指示是否將第一個(gè)字符增加到tokenString之上;由于需要包括空白格和非消耗的先行,因此這些東西都是必要的。到掃描程序的字符輸入由getNextChar函數(shù)提供,該函數(shù)將一個(gè)256字符緩沖區(qū)內(nèi)部的lineBuf中的字符取到掃描程序中,如果已經(jīng)耗盡了這個(gè)緩沖區(qū),且假

22、設(shè)每一次都獲取了一個(gè)新的源代碼行,那么getNextChar就利用fget從source文件更新該緩沖區(qū)。最后由于從INUM和INID到最終狀態(tài)的轉(zhuǎn)換是非消耗的??梢酝ㄟ^一個(gè)ungetnextChar的過程在輸入緩沖區(qū)的反填一個(gè)字符來完成這一任務(wù)。#include globals.h#include util.h#include scan.htypedef enum START, INASSIGN, INCOMMENT,INENDCOMMENT,INNUM, INID, DONE,INLT,INRT ,INNEQStateType;char tokenStringMAXTOKENLEN+1;#

23、define BUFLEN 1024static char lineBufBUFLEN;static int linepos=0;static int bufsize=0;/getNextChar 從lineBuf獲得下一個(gè)非空字符,讀入新的一行如果lineBuf 耗盡static char getNextCHar(void)if (!(lineposbufsize)lineno+;if (fgets(lineBuf,BUFLEN-1,source)if (EchoSource)fprintf(listing,%4d,%s,lineno,lineBuf);bufsize=strlen(line

24、Buf);linepos=0;return lineBuflinepos+;else return EOF;else return lineBuflinepos+; / backtracks one character in lineBufstatic void ungetNextChar(void)linepos-;/查找表的保留字static struct char *str;TokenType tok;reservedWordsMAXRESERVED=if,IF,int,INT,else,ELSE,return,RETURN,void,VOID,while,WHILE;/查找一個(gè)標(biāo)識(shí)符,

25、看看這是否是一個(gè)保留字/使用線性搜索static TokenType reservedLookup(char *s)int i;for(i=0;i)state = INRT;else if (c = )state = INLT;else if (c = !)state = INNEQ;elsestate = DONE;switch (c)default:currentToken = ERROR;break;case EOF:save = FALSE;currentToken = ENDFILE;break;case :currentToken = LBRACKET;break;case :cu

26、rrentToken = RBRACKET;break;case ,:currentToken = COMMA;break;case +:currentToken = PLUS;break;case -:currentToken = MINUS;break;case *:currentToken = TIMES;break;case :currentToken = LBRACE;break;case :currentToken = RBRACE;break;case (:currentToken = LPAREN;break;case ):currentToken = RPAREN;break

27、;case ;:currentToken = SEMI;break;break;/*=注釋改動(dòng)=*/case INENDCOMMENT:if (c = *&getNextCHar() = /) /token是*且下一個(gè)token是/則結(jié)束注釋save = FALSE;state = START; /注釋不作處理,直到注釋結(jié)束,elsesave = FALSE;state = INENDCOMMENT;break;case INCOMMENT:if (c = *) /“/”后是*則進(jìn)入注釋/ungetNextChar();save = FALSE; state = INENDCOMMENT; /

28、若是注釋開頭,轉(zhuǎn)入注釋結(jié)尾處理else if (c = EOF)state = DONE;currentToken = ENDFILE;else / “/”后不是*則為除法ungetNextChar();save = FALSE;currentToken = OVER;state = DONE;break;/*=賦值改動(dòng)=*/case INASSIGN:state = DONE;if (c = =) /下一個(gè)仍是等號(hào)就為相等currentToken = EQ;else /否則回退,ungetNextChar();save = FALSE;currentToken = ASSIGN;break;

29、/*=小于等于=*/case INLT:state = DONE;if (c = =)currentToken = LTEQ;elseungetNextChar();save = FALSE;currentToken = LT;break;/*=大于等于=*/case INRT:state = DONE;if (c = =)currentToken = RTEQ;elseungetNextChar();save = FALSE;currentToken = RT;break;/*=不等于=*/case INNEQ:state = DONE;if (c = =)currentToken = NE

30、Q;elseungetNextChar();save = FALSE;currentToken = ERROR;break;case INNUM:if (! isdigit(c)ungetNextChar();save = FALSE;state = DONE;currentToken = NUM;break;case INID:if (!isalpha(c)ungetNextChar();save = FALSE;state = DONE;currentToken = ID;break;case DONE:default:fprintf(listing, Scanner Bug:state=

31、%dn, state);state = DONE;currentToken = ERROR;break;if (save) & (tokenStringIndex );fprintf(listing, Syntax error at line %d: %s, lineno, message);Error = TRUE;static void match(TokenType expected)if (token = expected)token = getToken();elsesyntaxError(unexpected token-);printToken(token, tokenStrin

32、g);fprintf(listing, );TreeNode * stmt_sequence(void)TreeNode *t = statement();TreeNode *p = t;while (token != ENDFILE) & (token != RBRACE) )TreeNode *q;/match(SEMI);q = statement();if (token != RBRACE)if (q != NULL)if (t = NULL)t = p = q;elsep-sibling = q;p = q;return t;TreeNode * statement(void)Tre

33、eNode *t = NULL;switch (token)case IF:t = if_stmt();break;case WHILE:t = while_stmt();break;case ID: /若為ID不直接進(jìn)行賦值,進(jìn)入 exp()至factor(),將賦值加入至factor()t = exp();break;case RETURN:t = return_stmt();break;case INT:t = int_stmt();break;case VOID:t = void_stmt();break;case SEMI:match(SEMI);break;default:synt

34、axError(unexpected token - );printToken(token, tokenString);token = getToken();break;return t;TreeNode *declaration(void)TreeNode *t = newDeclarationNode(token);if (t != NULL)/名稱token = getToken();/ID賦給t- = copyString(tokenString);token = getToken();/token是( 則為函數(shù)聲明if (token = LPAREN)t-kind.declarati

35、on = FunctionK;match(LPAREN);TreeNode *paramets = parameter(); /函數(shù)參數(shù)匹配if (paramets != NULL)t-child0 = paramets;match(RPAREN);match(LBRACE);/匹配函數(shù)體TreeNode *body = stmt_sequence();if (body = NULL)syntaxError(error body! );elset-child1 = body;match(RBRACE);/token后不是(則是變量聲明else/普通變量類型t-kind.declaration

36、= VarK;/進(jìn)入數(shù)組類型if (token = LBRACKET)match(LBRACKET);t-kind.declaration = ArrayK;t-attr.size = atoi(tokenString);token = getToken();match(RBRACKET);match(SEMI);return t;TreeNode *parameter(void)TreeNode *t = NULL;if (token = VOID)match(VOID);/結(jié)束else if (token = RBRACE)return t;/有參數(shù)elset = newDeclarati

37、onNode(token);token = getToken();t- = copyString(tokenString);token = getToken();/數(shù)組if (token = LBRACKET)t-kind.declaration = ArrayK;match(LBRACKET);t-attr.size = 0;match(RBRACKET);/IDelset-kind.declaration = VarK;if (token = COMMA)match(COMMA);t-sibling = parameter();return t;TreeNode *if_stmt(void

38、)TreeNode *t = newStmtNode(IfK);match(IF);if (t != NULL)match(LPAREN);t-child0 = exp();match(RPAREN);if (t != NULL)/如果帶大括號(hào)if (token = LBRACE)match(LBRACE);while (token != RBRACE)t-child1 = statement();match(RBRACE);/無括號(hào)elset-child1 = statement();if (token = ELSE)match(ELSE);if (t != NULL)/如果帶大括號(hào)if (

39、token = LBRACE)match(LBRACE);while (token != RBRACE)t-child2 = statement();match(RBRACE);/無括號(hào)elset-child2 = statement();return t;TreeNode *while_stmt(void)TreeNode *t = newStmtNode(WhileK);match(WHILE);TreeNode *p = NULL;match(LPAREN);while (token != RPAREN)if (t-child0 = NULL)p = exp();t-child0 = p

40、;elsep = p-child0;p = exp();match(RPAREN);/while函數(shù)大括號(hào)可有可無/如果有括號(hào)if (token = LBRACE)match(LBRACE);while (token!=RBRACE)t-child1 = statement();match(RBRACE);/無elset-child1 = statement();if (token = SEMI)match(SEMI);return t;TreeNode *return_stmt(void)TreeNode *t = newStmtNode(ReturnK);t- = copyString(t

41、okenString);match(RETURN);if (token != SEMI)t-child0 = exp();match(SEMI);return t;TreeNode *int_stmt(void)TreeNode *t = newDeclarationNode(INT);match(INT);t- = copyString(tokenString);match(ID);/函數(shù)if (token = LPAREN)match(LPAREN);t-kind.declaration = FunctionK;if (token = VOID)match(VOID);else/函數(shù)參數(shù)匹

42、配inFunction();match(RPAREN);/函數(shù)體match(LBRACE);while (token != RBRACE)statement();match(RBRACE);/數(shù)組else if (token = LBRACKET)t-kind.exp = Array_expK;match(LBRACKET);t-child0 = exp();match(RBRACKET);/變量if (token = SEMI)t-kind.declaration = VarK;match(SEMI);return t;/void 函數(shù)TreeNode *void_stmt(void)Tre

43、eNode *t = newDeclarationNode(VOID);match(VOID);t- = copyString(tokenString);match(ID);match(LPAREN);if (token = VOID)match(VOID);elseinFunction();match(RPAREN);match(LBRACE);while (token!=RBRACE)statement();match(RBRACE);return t;/函數(shù)參數(shù)匹配void inFunction(void)match(INT);match(ID);if (token = LBRACKET

44、)match(LBRACKET);match(RBRACKET);if (token = COMMA)match(COMMA);inFunction();TreeNode *exp(void)TreeNode *t = simple_exp();if (token = LT) |(token=ASSIGN) | (token = EQ) | (token = RT) | (token = LTEQ) | (token = RTEQ) | (token = NEQ)TreeNode *p = newExpNode(OpK);if (p != NULL)p-child0 = t;p-attr.op

45、 = token;p- = copyString(tokenString);t = p;match(token);if (t != NULL)t-child1 = simple_exp();return t;TreeNode *simple_exp(void)TreeNode *t = term();while (token = PLUS) | (token = MINUS)TreeNode *p = newExpNode(OpK);if (p != NULL)p-child0 = t;p-attr.op = token;p- = copyString(tokenString);t = p;m

46、atch(token);t-child1 = simple_exp();return t;TreeNode *term(void)TreeNode *t = factor();if (token = TIMES) | (token = OVER)TreeNode *p = newExpNode(OpK);if (p != NULL)p-child0 = t;p-attr.op = token;p- = copyString(tokenString);t = p;match(token);p-child1 = term();return t;TreeNode *factor(void)TreeN

47、ode *t = NULL;switch (token)case NUM:t = newExpNode(ConstK);if (t != NULL) & (token = NUM)t-attr.val = atoi(tokenString);match(NUM);break;case ID:t = newExpNode(IdK);/變量if (t != NULL) & (token = ID)t- = copyString(tokenString);match(ID);/函數(shù)if (token = LPAREN)match(LPAREN);t-kind.exp = Function_expK;

48、TreeNode *p = NULL;while (token != RPAREN)if (t-child0 = NULL)p = exp();t-child0 = p;elsep-sibling = exp();p = p-sibling;if (token = COMMA)match(COMMA);match(RPAREN);/數(shù)組else if (token = LBRACKET)t-kind.exp = Array_expK;match(LBRACKET);t-child0 = exp();match(RBRACKET);/賦值if (token = ASSIGN)TreeNode *

49、temp = newExpNode(OpK);temp-attr.op = token;temp- = copyString(tokenString);match(ASSIGN);temp-child0 = t;t = temp;t-child1 = exp();if (token = SEMI)match(SEMI);break;case LPAREN:match(LPAREN);t = exp();match(RPAREN);break;default:syntaxError(unexpected token - );printToken(token, tokenString);token

50、 = getToken();break;return t;/*the primary fuction of the parser*/TreeNode *parse(void)TreeNode *t;TreeNode *q;token = getToken();t = declaration();q = t;while (token != ENDFILE)t-sibling = declaration();t = t-sibling;if (token != ENDFILE)syntaxError(Code ends before filen);fprintf(listing, nparser

51、treenn);return t;3.4 util.c包括(boku)void printToken(TokenType token, const char* tokenString)函數(shù)(hnsh),void printTree(TreeNode * t)函數(shù)(hnsh),以及建立節(jié)點(diǎn)函數(shù)的實(shí)現(xiàn)TreeNode*newExpNode(Expkind kind)和TreeNode*newStmtNode(Stmtkind kind)#includeglobals.h#includeutil.hvoid printToken(TokenType token, const char *tokenS

52、tring)switch (token)case IF:case INT:case ELSE:case RETURN:case VOID:case WHILE:fprintf(listing, reserved word:%sn, tokenString);break;case ASSIGN:fprintf(listing,:=n);break;case LT:fprintf(listing, n);break;case LTEQ:fprintf(listing, =n);break;case EQ:fprintf(listing, =n);break;case LPAREN:fprintf(

53、listing, (n);break;case RPAREN:fprintf(listing, )n);break;case SEMI:fprintf(listing, ;n);break;case PLUS:fprintf(listing, +n);break;case MINUS:fprintf(listing, -n);break;case TIMES:fprintf(listing, *n);break;case OVER:fprintf(listing, /n);break;case ENDFILE:fprintf(listing, EOFn);break;case LBRACKET

54、:fprintf(listing, n);break;case RBRACKET:fprintf(listing, n);break;case NEQ:fprintf(listing, !=n);break;case COMMA:fprintf(listing, ,n);break;case LBRACE:fprintf(listing, n);break;case RBRACE:fprintf(listing, n);break;case NUM:fprintf(listing, NUM,val=%sn,tokenString);break;case ID:fprintf(listing,

55、ID,name=%sn, tokenString);break;case ERROR:fprintf(listing, ERROR:%sn, tokenString);break;default:fprintf(listing, Unknown token:%dn, token);break;/Fuction newStmtNode creat a new statement node for syntax tree constructionTreeNode *newStmtNode(StmtKind kind)TreeNode *t = (TreeNode*)malloc(sizeof(Tr

56、eeNode);int i;if (t = NULL)fprintf(listing, Out of memory error at line %dn, lineno);elsefor (i = 0; i childi = NULL;t-sibling = NULL;t-nodekind = StmtK;t-kind.stmt = kind;t-lineno = lineno;return t;/*Fuction newExpNode creat a new expression node for syntax tree construction*/TreeNode *newExpNode(E

57、xpKind kind)TreeNode *t = (TreeNode*)malloc(sizeof(TreeNode);int i;if (t = NULL)fprintf(listing, Out of memory error at line %dn, lineno);elsefor (i = 0; i childi = NULL;t-sibling = NULL;t-nodekind = ExpK;t-kind.exp= kind;t-lineno = lineno;t-type = Void;return t;/聲明類型節(jié)點(diǎn)TreeNode *newDeclarationNode(T

58、okenType kind)TreeNode * t = (TreeNode*)malloc(sizeof(TreeNode);if (t = NULL)fprintf(listing, out of memory error at line %dn, lineno);elset-nodekind = DeclarationK;t-lineno = lineno;for (int i = 0; i childi = NULL;t-sibling = NULL;if (kind = INT | kind = VOID)/設(shè)置類型if (kind = INT)t-type = Integer;el

59、se if (kind = VOID)t-type = Void;elsefprintf(listing, statement error at line %dn, lineno);return t;/*Fuction copyString allocates and makes a new copy of an existing string*/char * copyString(char *s)int n;char * t;if (s = NULL)return NULL;n = strlen(s)+1;t =(char *) malloc(n);if (t = NULL)fprintf(

60、listing, Out of memory error at line %dn, lineno);elsestrcpy(t, s);return t;/*變量indentno 被printTree用于存儲(chǔ)當(dāng)前空格的縮進(jìn)數(shù)目 */static int indentno = 0;/*增加/減少縮進(jìn)的宏*/#define INDENT indentno+=2#define UNIDENT indentno-=2/*printSpaces 通過打印空格實(shí)現(xiàn)縮進(jìn)*/static void printSpacees(void)int i;for (i = 0; i nodekind = StmtK)sw

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論