欧美色欧美亚洲高清在线观看,国产特黄特色a级在线视频,国产一区视频一区欧美,亚洲成a 人在线观看中文

  1. <ul id="fwlom"></ul>

    <object id="fwlom"></object>

    <span id="fwlom"></span><dfn id="fwlom"></dfn>

      <object id="fwlom"></object>

      編譯原理課程設(shè)計(jì)報(bào)告(格式)

      時(shí)間:2019-05-12 20:49:42下載本文作者:會(huì)員上傳
      簡(jiǎn)介:寫寫幫文庫(kù)小編為你整理了多篇相關(guān)的《編譯原理課程設(shè)計(jì)報(bào)告(格式)》,但愿對(duì)你工作學(xué)習(xí)有幫助,當(dāng)然你在寫寫幫文庫(kù)還可以找到更多《編譯原理課程設(shè)計(jì)報(bào)告(格式)》。

      第一篇:編譯原理課程設(shè)計(jì)報(bào)告(格式)

      編譯原理課程設(shè)計(jì)報(bào)告

      課題名稱:

      提交文檔學(xué)生姓名:提交文檔學(xué)生學(xué)號(hào):同組 成 員 名 單:無(wú)指導(dǎo) 教 師 姓 名:

      指導(dǎo)教師評(píng)閱成績(jī):指導(dǎo)教師評(píng)閱意見(jiàn):

      提交報(bào)告時(shí)間:年月日

      1.課程設(shè)計(jì)目標(biāo)

      構(gòu)造的編譯器的組成部分,能實(shí)現(xiàn)的功能。

      2.分析與設(shè)計(jì)

      ?

      ?

      ?

      ?

      ? 實(shí)現(xiàn)方法:編程語(yǔ)言、編程方法 系統(tǒng)總圖,各部分的實(shí)現(xiàn)原理、方法、中間結(jié)果、最后輸出 掃描器:各單詞的狀態(tài)轉(zhuǎn)換圖、轉(zhuǎn)換表 分析器:分析表 代碼設(shè)計(jì)說(shuō)明:程序結(jié)構(gòu)圖,文件和函數(shù)的設(shè)計(jì)說(shuō)明,關(guān)鍵數(shù)據(jù)結(jié)構(gòu)

      3.程序代碼實(shí)現(xiàn)

      按文件列出主要程序代碼, 添加必要的注釋。

      4.測(cè)試結(jié)果

      ?

      ?

      ?

      標(biāo)準(zhǔn)測(cè)試程序的分析結(jié)果 修改后的測(cè)試程序分析結(jié)果(正確和錯(cuò)誤)詞法分析和語(yǔ)法分析的結(jié)果輸出(P79,P182)

      5.總結(jié)

      ?

      ? 收獲 不足

      第二篇:編譯原理課程設(shè)計(jì)報(bào)告

      武 漢 紡 織 大 學(xué)

      編譯原理課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告

      學(xué)院:數(shù)學(xué)與計(jì)算機(jī) 專業(yè):計(jì)算機(jī) 姓名: 班級(jí): 學(xué)號(hào): 編譯原理

      編譯原理課設(shè)報(bào)告

      一、實(shí)驗(yàn)?zāi)康?/p>

      加強(qiáng)對(duì)編譯程序的整體認(rèn)識(shí)和了解,鞏固《編譯原理》課程所學(xué)知識(shí)。通過(guò)本次課程設(shè)計(jì)掌握編譯程序調(diào)試技巧和設(shè)計(jì)編譯程序一般的原則,加深對(duì)詞法分析、語(yǔ)法分析、語(yǔ)義分析等編譯階段及實(shí)用編譯系統(tǒng)的認(rèn)識(shí)。使學(xué)生能將編譯理論與實(shí)際應(yīng)用結(jié)合起來(lái),提高學(xué)生軟件開(kāi)發(fā)的能力。

      二、實(shí)驗(yàn)內(nèi)容

      1)仔細(xì)閱讀PL/0編譯程序文本(編譯原理(第二版)張素琴 呂映芝 蔣維杜 戴桂蘭 主編

      清華大學(xué)出版社),并上機(jī)調(diào)試通過(guò)。

      2)對(duì)PL/0語(yǔ)言進(jìn)行下列擴(kuò)充(1)擴(kuò)充一維整型數(shù)組。

      擴(kuò)充var數(shù)組:VAR <數(shù)組標(biāo)識(shí)名>(<下界>:<上界>)〈下界〉和〈上界〉可用常量標(biāo)識(shí)名。

      (2)擴(kuò)充條件語(yǔ)句的功能使其為:IF<條件>THEN<語(yǔ)句>[ELSE<語(yǔ)句>](3)增加repeat重復(fù)語(yǔ)句: REPEAT<語(yǔ)句>{;<語(yǔ)句>}UNTIL<條件> 可根據(jù)自己具體情況從中選擇2個(gè)以上題目進(jìn)行擴(kuò)充。

      三、實(shí)驗(yàn)原理

      PL/0語(yǔ)言可以看成PASCAL語(yǔ)言的子集,它的編譯程序是一個(gè)編譯解釋執(zhí)行系統(tǒng)。PL/0的目標(biāo)程序?yàn)榧傧霔J接?jì)算機(jī)的匯編語(yǔ)言,與具體計(jì)算機(jī)無(wú)關(guān)。

      PL/0的編譯程序和目標(biāo)程序的解釋執(zhí)行程序都是用PASCAL語(yǔ)言書寫的,因此PL/0語(yǔ)言可在配備PASCAL語(yǔ)言的任何機(jī)器上實(shí)現(xiàn)。其編譯過(guò)程采用一趟掃描方式,以語(yǔ)法分析程序?yàn)楹诵?,詞法分析和代碼生成程序都作為一個(gè)獨(dú)立的過(guò)程,當(dāng)語(yǔ)法分析需要讀單詞時(shí)就調(diào)用詞法分析程序,而當(dāng)語(yǔ)法分析正確需要生成相應(yīng)的目標(biāo)代碼時(shí),則調(diào)用代碼生成程序。

      用表格管理程序建立變量、常量和過(guò)程表示符的說(shuō)明與引用之間的信息聯(lián)系。

      當(dāng)源程序編譯正確時(shí),PL/0編譯程序自動(dòng)調(diào)用解釋執(zhí)行程序,對(duì)目標(biāo)代碼進(jìn)行解釋執(zhí)行,并按用戶程序的要求輸入數(shù)據(jù)和輸出運(yùn)行結(jié)果。

      四、實(shí)驗(yàn)分析

      PL/0語(yǔ)言編譯程序采用以語(yǔ)法分析為核心、一遍掃描的編譯方法。詞法分析和代碼生成作為獨(dú)立的子程序供語(yǔ)法分析程序調(diào)用。語(yǔ)法分析的同時(shí),提供了出錯(cuò)報(bào)告和出錯(cuò)恢復(fù)的功能。在源程序沒(méi)有錯(cuò)誤編譯通過(guò)的情況下,調(diào)用類PCODE解釋程序解釋執(zhí)行生成的類PCODE代碼。

      詞法分析子程序分析:

      詞法分析子程序名為GETSYM,功能是從源程序中讀出一個(gè)單詞符號(hào)(TOTAKEN),把它的信息放入全局變量 SYM、ID和NUM中,字符變量放入CH中,語(yǔ)法分析器需要單詞時(shí),直接從這三個(gè)變量中獲得。Getch過(guò)程通過(guò)反復(fù)調(diào)用Getch子過(guò)程從源程序過(guò)獲取字符,并把它們拼成單詞。GETCH過(guò)程中使用了行緩沖區(qū)技術(shù)以提高程序運(yùn)行效率。

      詞法分析器的分析過(guò)程:調(diào)用GETSYM時(shí),它通過(guò)GETCH過(guò)程從源程序中獲得一個(gè)字符。如果這個(gè)字符是字母,則繼續(xù)獲取字符或數(shù)字,最終可以拼成一個(gè)單詞,查保留字表,如果查到為保留字,則把SYM變量賦成相應(yīng)的保留字類型值;如果沒(méi)有查到,則這個(gè)單詞應(yīng)是一個(gè)用戶自定義的標(biāo)識(shí)符(可能是變量名、常量名或是過(guò)程的名字),把SYM置為IDENT,把這個(gè)單詞存入ID變量。查保留字表時(shí)使用了二分法查找以提高效率。如果Getch獲得的字符是數(shù)字,則繼續(xù)用Getch獲取數(shù)字,并把它們拼成一個(gè)整數(shù)或?qū)崝?shù),然后把SYM置為 INTEGER或REAL,并把拼成的數(shù)值放入NUM變量。如果識(shí)別出其它合法的符號(hào)(比如:賦值號(hào)、大于號(hào)、小于等于號(hào)等),則把SYM則成相應(yīng)的類型。如果遇到不合法的字符,把SYM置成NUL。

      語(yǔ)法分析子程序分析:

      語(yǔ)法分析子程序采用了自頂向下的遞歸子程序法,語(yǔ)法分析同時(shí)也根據(jù)程序的語(yǔ)義生成相應(yīng)三元代碼,并提供了出錯(cuò)處理的機(jī)制。語(yǔ)法分析主要由分程序分析過(guò)程(BLOCK)、參數(shù)變量分析過(guò)程(ParaDeclaration)、參數(shù)變量處理過(guò)程(ParaGetSub)、數(shù)組處理過(guò)程(ParaGetSub)、常量定義分析過(guò)程(ConstDeclaration)、變量定義分析過(guò)程(Vardeclaration)、語(yǔ)句分析過(guò)程(Statement)、表達(dá)式處理過(guò)程(Expression)、項(xiàng)處理過(guò)程(Term)、因子處理過(guò)程(Factor)和條件處理過(guò)程(Condition)構(gòu)成。這些過(guò)程在結(jié)構(gòu)上構(gòu)成一個(gè)嵌套的層次結(jié)構(gòu)。除此之外,還有出錯(cuò)報(bào)告過(guò)程(Error)、代碼生成過(guò)程(Gen)、測(cè)試單詞合法性及出錯(cuò)恢復(fù)過(guò)程(Test)、登錄名字表過(guò)程(Enter)、查詢名字表函數(shù)(Position)以及列出類 PCODE代碼過(guò)程(Listcode)作過(guò)語(yǔ)法分析的輔助過(guò)程。

      由PL/0的語(yǔ)法圖可知:一個(gè)完整的PL/0程序是由分程序和句號(hào)構(gòu)成的。因此,本編譯程序在運(yùn)行的時(shí)候,通過(guò)主程序中調(diào)用分程序處理過(guò)程block來(lái)分析分程序部分(分程序分析過(guò)程中還可能會(huì)遞歸調(diào)用block過(guò)程),然后,判斷最后讀入的符號(hào)是否為句號(hào)。如果是句號(hào)且分程序分析中未出錯(cuò),則是一個(gè)合法的PL/0程序,可以運(yùn)行生成的代碼,否則就說(shuō)明源PL/0程序是不合法的,輸出出錯(cuò)提示即可。

      if-then-else語(yǔ)句的處理:

      按if語(yǔ)句的語(yǔ)法,首先調(diào)用邏輯表達(dá)式處理過(guò)程處理if語(yǔ)句的條件,把相應(yīng)的真假值放到數(shù)據(jù)棧頂。接下去記錄下代碼段分配位置(即下面生成的jpc指令的位置),然后生成 條件轉(zhuǎn)移jpc指令(遇0或遇假轉(zhuǎn)移),轉(zhuǎn)移地址未知暫時(shí)填0。然后調(diào)用語(yǔ)句處理過(guò)程處理 then語(yǔ)句后面的語(yǔ)句或語(yǔ)句塊。then后的語(yǔ)句處理完后,如果遇到else,就調(diào)用語(yǔ)句處理過(guò)程處理else語(yǔ)句后面的語(yǔ)句或語(yǔ)句塊,這時(shí)當(dāng)前代碼段分配指針的位置就應(yīng)該是上面的jpc指令的轉(zhuǎn)移位置。通過(guò)前面記錄下的jpc指令的位置,把它的跳轉(zhuǎn)位置改成當(dāng)前的代碼段指針位置,否則沒(méi)遇到else,那么此時(shí)的當(dāng)前代碼段分配指針的位置也是上面jpc指令的轉(zhuǎn)移位置,也是通過(guò)前面記錄下的jpc位置指令的位置,把它的跳轉(zhuǎn)到當(dāng)前的代碼段指針位置。

      Repeat語(yǔ)句的處理:

      首先用CX1變量記下當(dāng)前代碼段分配位置,作為循環(huán)的開(kāi)始位置。然后通過(guò)遞歸調(diào)用語(yǔ)句分析過(guò)程分析,直到遇到until保留字,如果未對(duì)應(yīng)until則出錯(cuò)。調(diào)用條件表達(dá)式處理過(guò)程生成相應(yīng)代碼把結(jié)果放在數(shù)據(jù)棧頂,再生成條件轉(zhuǎn)移指令,轉(zhuǎn)移位置為上面記錄的CX1。

      五、相關(guān)代碼及運(yùn)行結(jié)果

      實(shí)驗(yàn)代碼; PL0.h代碼: #include #include #include #include #include #include

      #ifndef WIRTH_ZYC_ #define WIRTH_ZYC_ using namespace std;

      const int norw = 16;

      // no.of reserved words 保留字的個(gè)數(shù)

      const int txmax = 100;

      // length of identifier table 標(biāo)示符表的長(zhǎng)度(容量)const int al = 10;

      // length of identifiers 標(biāo)示符的最大長(zhǎng)度

      const int nmax = 14;

      // max.no.of digits in numbers 數(shù)字的最大長(zhǎng)度 const int amax = 2047;

      // maximum address 尋址空間

      const int levmax = 3;

      // maximum depth of block nesting 最大允許的塊嵌套層數(shù) const int cxmax = 200;

      // size of code array 類PCODE目標(biāo)代碼數(shù)組長(zhǎng)度(可容納代碼行數(shù))

      const int lineLength = 82;// 行緩沖區(qū)長(zhǎng)度

      typedef enum {NUL,IDENT,NUMBER,PLUS,MINUS,TIMES,SLASH,ODDSYM,EQL,NEQ,LSS,LEQ,GTR,GEQ,LPAREN,RPAREN,COMMA,SEMICOLON,PERIOD,BECOMES,BEGINSYM,ENDSYM,IFSYM,THENSYM,WHILESYM,WRITESYM,READSYM,DOSYM,CALLSYM,CONSTSYM,VARSYM,PROCSYM,ELSESYM,REPEATSYM,UNTILSYM} symbol;// symobl類型標(biāo)識(shí)了不同類型的詞匯

      typedef char alfa[al+1];

      // alfa類型用于標(biāo)識(shí)符 typedef enum {CONSTANT,VARIABLE,PROCEDURE,ARRAY} obj0;

      // 三種標(biāo)識(shí)符的類型 typedef enum {LIT,OPR,LOD,STO,CAL,INT,JMP,JPC} fct;

      // functions typedef set symset;

      struct instruction{ fct f;// function code int l;// level,cann't big than levmax

      int a;// displacement address,cann't big than amax };

      // 類PCODE指令類型,包含三個(gè)字段:指令f、層差l和另一個(gè)操作數(shù)a

      /******************************************* * lit 0,a: load constant a

      * * opr 0,a: execute operation a

      * * lod l,a: load variable l,a

      * * sto l,a: store variable l,a

      * * cal l,a: call procedure a at level l

      * * int 0,a: increment t-register by a

      * * jmp 0,a: jump to a

      * * jpc 0,a: jump conditional to a

      * *******************************************/

      typedef struct{ alfa name;obj0 kind;union {

      struct{int level,adr,size;}inOther;

      int val;}other;} Table;

      class PL0 {

      protected:

      bool listswitch,sourceEnd;char ch;

      // last character read symbol sym;

      // last symbol read alfa id;

      // last identifier read int num;

      // last number read

      int cc;

      // character count int ll;

      // line length int kk,err;int cx;

      // code allocation index int codeNo;

      // code line no.static string errStr[];

      // error string

      char line[lineLength];

      // code line vector errorString;

      // error array alfa a;

      // 詞法分析器中用于臨時(shí)存放正在分析的詞

      instruction code[cxmax+1];

      // destination code array

      alfa word[norw+1];

      // 保留字表

      symbol wsym[norw+1];

      // 保留字表中每一個(gè)保留字對(duì)應(yīng)的symbol類型

      symbol ssym[100];

      // 一些符號(hào)對(duì)應(yīng)的symbol類型表

      合 char mnemonic[8][6];

      // 類PCODE指令助記符表

      symset declbegsys,statbegsys,facbegsys;// 聲明開(kāi)始、表達(dá)式開(kāi)始和項(xiàng)開(kāi)始符號(hào)集 Table table[txmax+1];

      // 符號(hào)表

      FILE* fin,*fout;

      public:

      PL0(char* source,char*destination);

      ~PL0(){fclose(fin),fclose(fout);}

      void error(int n);

      位置和出錯(cuò)代碼

      void getsym();

      個(gè)單詞

      void getch();

      個(gè)字符

      void gen(fct x,int y,int z);

      程序區(qū)

      void test(symset s1,symset s2,int n);

      合法

      void block(int lev,int tx,symset fsys);

      void enter(obj0 k,int &tx,int &dx,int lev);

      int position(alfa id,int tx);的位置

      void constdeclaration(int&tx,int&dx,int lev);

      void vardeclaration(int&tx,int&dx,int lev);

      void listcode(int cx0);

      void statement(symset fsys,int tx,int lev);

      void expression(symset fsys,int tx,int lev);

      void term(symset fsys,int tx,int lev);

      void factor(symset fsys,int tx,int lev);

      void condition(symset fsys,int tx,int lev);

      void arraydeclaration(int& tx,int& dx,int lev);

      void interpret();

      執(zhí)行程序

      int base(int l,int b,int s[]);

      基地址

      void SaveCode();

      // 構(gòu)造函數(shù)

      // 析構(gòu)函數(shù)

      // 出錯(cuò)處理,打印出錯(cuò)

      // 詞法分析,讀取一

      // 漏掉空格,讀取一// 生成目標(biāo)代碼,并送入目標(biāo)

      // 測(cè)試當(dāng)前單詞符號(hào)是否

      // 分程序分析處理過(guò)程

      // 登入名字表

      // 查找標(biāo)示符在名字表中

      // 常量定義處理

      // 變量說(shuō)明處理

      // 列出目標(biāo)代碼清單

      // 語(yǔ)句部分處理

      // 表達(dá)式處理

      // 項(xiàng)處理

      // 因子處理

      // 條件處理

      // 數(shù)組說(shuō)明處理

      // 對(duì)目標(biāo)代碼的解釋

      // 通過(guò)靜態(tài)鏈求出數(shù)據(jù)區(qū)的 // 保存代碼

      };#endif PL0.cpp代碼: #include “pl0.h”

      // 錯(cuò)誤字符串?dāng)?shù)組

      string PL0::errStr[]={“",”error 0001: 常數(shù)說(shuō)明中“=”寫成“:=”“, ”error 0002: 常數(shù)說(shuō)明中的“=”后應(yīng)為數(shù)字“, ”error 0003: 常數(shù)說(shuō)明中的標(biāo)識(shí)符后應(yīng)是“=”“, ”error 0004: const,var,procedure后應(yīng)為標(biāo)識(shí)符“, ”error 0005: 漏掉了‘,’或‘;’“, ”error 0006: 過(guò)程說(shuō)明后的符號(hào)不正確(應(yīng)是語(yǔ)句開(kāi)始符或過(guò)程開(kāi)始符)“, ”error 0007: 應(yīng)是語(yǔ)句開(kāi)始符“, ”error 0008: 過(guò)程體內(nèi)語(yǔ)句部分的后跟符不正確“, ”error 0009: 程序皆為丟了句號(hào)‘.’“, ”error 0010: 語(yǔ)句之間漏了‘;’“, ”error 0011: 標(biāo)識(shí)符沒(méi)說(shuō)明“, ”error 0012: 賦值語(yǔ)句中,賦值號(hào)左部標(biāo)識(shí)符屬性應(yīng)是變量“, ”error 0013: 賦值語(yǔ)句左部標(biāo)識(shí)符應(yīng)是賦值號(hào):=“, ”error 0014: call后應(yīng)為標(biāo)識(shí)符“, ”error 0015: call后標(biāo)識(shí)符屬性應(yīng)為過(guò)程“, ”error 0016: 條件語(yǔ)句中丟了then“, ”error 0017: 丟了end或;“, ”error 0018: while型循環(huán)語(yǔ)句中丟了do“, ”error 0019: 語(yǔ)句后的標(biāo)識(shí)符不正確“, ”error 0020: 應(yīng)為關(guān)系運(yùn)算符“, ”error 0021: 表達(dá)式內(nèi)標(biāo)識(shí)符屬性不能是過(guò)程“, ”error 0022: 表達(dá)式中漏掉了右括號(hào)‘)’“, ”error 0023: 因子后的非法符號(hào)“, ”error 0024: 表達(dá)式開(kāi)始符不能是此符號(hào)“, ”error 0025: 文件在不該結(jié)束的地方結(jié)束了“, ”error 0026: 結(jié)束符出現(xiàn)在不該結(jié)束的地方“, ”error 0027: “,”error 0028: “,”error 0029: “,”error 0030: “, ”error 0031: 數(shù)越界“, ”error 0032: read語(yǔ)句括號(hào)中標(biāo)識(shí)符不是變量“, ”error 0033: else附近錯(cuò)誤“ , ”error 0034: repeat附近錯(cuò)誤“};

      // PL0構(gòu)造函數(shù)

      PL0::PL0(char* source,char*destination){ listswitch=true,sourceEnd=false;

      strcpy(word[1],”begin“);

      // 初始化存儲(chǔ)保留字

      strcpy(word[2],”call“);strcpy(word[3],”const“);

      strcpy(word[4],”do“);strcpy(word[5],”else“);strcpy(word[6],”end“);strcpy(word[7],”if“);strcpy(word[8],”odd“);strcpy(word[9],”procedure“);strcpy(word[10],”read“);

      strcpy(word[11],”repeat“);strcpy(word[12],”then“);strcpy(word[13],”until“);strcpy(word[14],”var“);

      strcpy(word[15],”while“);strcpy(word[16],”write“);

      wsym[1]= BEGINSYM;

      wsym[2]= CALLSYM;留字對(duì)應(yīng)的symbol類型

      wsym[3]= CONSTSYM;

      wsym[4]= DOSYM;wsym[5]= ELSESYM;

      wsym[6]= ENDSYM;wsym[7]= IFSYM;

      wsym[8]= ODDSYM;wsym[9]= PROCSYM;

      wsym[10]= READSYM;

      wsym[11]= REPEATSYM;wsym[12]= THENSYM;wsym[13]= UNTILSYM;wsym[14]= VARSYM;

      wsym[15]= WHILESYM;wsym[16]= WRITESYM;

      memset(code,0,sizeof(code));memset(ssym,0,100*sizeof(symbol));memset(table,0,sizeof(table));memset(line,0,sizeof(line));

      ssym['+']= PLUS;

      類型表

      ssym['-']= MINUS;ssym['*']= TIMES;ssym['/']= SLASH;ssym['(']= LPAREN;ssym[')']= RPAREN;ssym['=']= EQL;ssym[',']= COMMA;ssym['.']= PERIOD;

      // 初始化保留字表中每一個(gè)保

      // 初始化一些符號(hào)對(duì)應(yīng)的symbol

      ssym['#']= NEQ;ssym['<']= LSS;ssym['>']= GTR;ssym[';']= SEMICOLON;

      strcpy(mnemonic[LIT],” lit “);

      // 初始化類PCODE指令助記符表

      strcpy(mnemonic[OPR],” opr “);strcpy(mnemonic[LOD],” lod “);strcpy(mnemonic[STO],” sto “);strcpy(mnemonic[CAL],” cal “);strcpy(mnemonic[INT],” int “);strcpy(mnemonic[JMP],” jmp “);strcpy(mnemonic[JPC],” jpc “);

      declbegsys.insert(CONSTSYM),declbegsys.insert(VARSYM),declbegsys.insert(PROCSYM);// 初始化聲明開(kāi)始符號(hào)集合 statbegsys.insert(BEGINSYM),statbegsys.insert(CALLSYM),statbegsys.insert(IFSYM),statbegsys.insert(WHILESYM);// 初始化表達(dá)式開(kāi)始符號(hào)集合facbegsys.insert(IDENT),facbegsys.insert(NUMBER),facbegsys.insert(LPAREN);// 初始化項(xiàng)開(kāi)始符號(hào)集合

      err= 0;cc= 0;

      // 行緩沖區(qū)指針

      cx= 0;

      // 代碼分配指針,代碼生成模塊總在cx所指位置生成新的代碼

      ll= 0;

      // 行緩沖區(qū)長(zhǎng)度

      ch= ' ';

      // last character read

      }

      kk= al;

      // 引入此變量是出于程序性能考慮 codeNo=0;

      // code line no.fin=fopen(source,”r“);fout=fopen(destination,”w“);// 出錯(cuò)處理,打印出錯(cuò)位置和出錯(cuò)代碼 void PL0::error(int n){ char s[10];sprintf(s,”第 %d 行:“,codeNo);errorString.push_back(s+errStr[n]);err= err+1;//error count }//error end // 詞法分析,讀取一個(gè)單詞

      void PL0::getsym(){ if(sourceEnd)

      return;int i,j,k;while(ch ==' '||ch==9)

      getch();

      // cls space and tab if(isalpha(ch))// id or reserved word {

      k=0;

      memset(a,0,al+1);

      // 檢測(cè)一個(gè)單詞長(zhǎng)度 do{ if(k < al){

      a[k]= ch;

      k= k+1;} getch();if(sourceEnd)

      return;}while(isalpha(ch)||isdigit(ch));if(k >= kk)kk = k;else { do{

      a[kk]= ' ';

      kk= kk-1;}while(kk > k);} strcpy(id,a);i= 1;j= norw;// 判斷是否是關(guān)鍵字(二分搜索)do{ k=(i+j)/ 2;if(strcmp(id, word[k])<=0)

      j= k-1;if(strcmp(id,word[k])>=0)

      i= k+1;}while(i<=j);if(i-1 > j)

      sym= wsym[k];else

      sym= IDENT;} else if(isdigit(ch))// number { k= 0;num= 0;sym= NUMBER;do{

      num= 10 * num + ch-'0';

      k= k+1;

      getch();}while(isdigit(ch));if(k > nmax)

      error(30);} else if(ch == ':'){ getch();if(ch == '='){

      sym= BECOMES;

      getch();} else

      sym= NUL;} else if(ch == '<')

      // extra stuff added to support <= { getch();if(ch== '='){

      sym= LEQ;

      getch();} else

      sym= LSS;} else if(ch == '>'){ getch();if(ch == '='){

      sym= GEQ;

      getch();} else

      sym= GTR;} else

      // end of extra stuff { sym= ssym[ch];// 其它符號(hào)的賦值

      getch();} }

      // 漏掉空格,讀取一個(gè)字符

      void PL0::getch(){ if(cc == ll){

      if(feof(fin))

      {

      if(sym!=PERIOD)

      error(25);

      sourceEnd=true;

      return;

      }

      cc= 0;

      fgets(line,lineLength,fin);

      codeNo++;

      ll=strlen(line);

      if(line[ll-1]==10)ll--;} ch= line[cc];cc= cc+1;}

      // 生成目標(biāo)代碼,并送入目標(biāo)程序區(qū)void PL0::gen(fct x,int y,int z){ if(cx > cxmax){

      cout<<”Program too longn“;

      return;}

      code[cx].f= x;code[cx].l= y;code[cx].a= z;

      cx= cx+1;}//gen end

      // 測(cè)試當(dāng)前單詞符號(hào)是否合法

      void PL0::test(symset s1,symset s2,int n){ if(sourceEnd)

      return;if(s1.find(sym)==s1.end()){

      error(n);

      symset::iterator it;

      for(it=s2.begin();it!=s2.end();it++)

      s1.insert(*it);//s1=s1+s2

      while(s1.find(sym)==s1.end())

      getsym();} }//test end

      // 分程序分析處理過(guò)程

      void PL0::block(int lev,int tx,symset fsys){ if(sourceEnd)

      return;int dx;// data allocation index int tx0;// initial table index int cx0;// initial code index

      dx= 3;

      // 變量的個(gè)數(shù) tx0= tx;// 表指針

      table[tx].other.inOther.adr= cx;gen(JMP,0,0);if(lev>levmax)error(32);do{

      if(sym == CONSTSYM)

      // 處理常量聲明

      {

      getsym();

      do{

      constdeclaration(tx,dx,lev);

      while(sym == COMMA)

      {

      }

      getsym();

      constdeclaration(tx,dx,lev);} if(sym ==SEMICOLON)

      getsym();else

      error(5);}while(sym==IDENT);if(sym == VARSYM)

      // 處理變量聲明 { getsym();do{

      vardeclaration(tx,dx,lev);

      while(sym == COMMA){

      getsym();

      vardeclaration(tx,dx,lev);

      }

      if(sym ==SEMICOLON)

      getsym();

      else

      error(5);}while(sym==IDENT);} while(sym ==PROCSYM)

      // 處理過(guò)程的聲明 { getsym();if(sym ==IDENT){

      enter(PROCEDURE,tx,dx,lev);

      getsym();} else

      error(4);if(sym ==SEMICOLON)

      getsym();else

      error(5);symset tmp = fsys;tmp.insert(SEMICOLON);block(lev+1,tx,tmp);if(sym == SEMICOLON){

      getsym();

      symset tmp = statbegsys;

      for(int i= IDENT;i<=PROCSYM;i++)

      tmp.insert((symbol)i);

      test(tmp,fsys,6);

      }

      else

      error(5);

      }

      symset tmp=statbegsys;

      tmp.insert(IDENT);

      test(tmp,declbegsys,7);}while(declbegsys.find(sym)!=declbegsys.end());

      code[table[tx0].other.inOther.adr].a= cx;table[tx0].other.inOther.adr= cx;// start adr of code table[tx0].other.inOther.size=dx;

      cx0= cx;gen(INT,0,dx);symset tmp=statbegsys;for(int i=SEMICOLON;i <= ENDSYM;i++)

      tmp.insert((symbol)i);statement(tmp,tx,lev);gen(OPR,0,0);// return symset s2;test(fsys,s2,8);listcode(cx0);}// block end

      // 登入名字表

      void PL0::enter(obj0 k,int &tx,int &dx,int lev){ tx= tx+1;strcpy(table[tx].name,id);table[tx].kind=k;switch(k){ case CONSTANT:

      if(num>amax)

      {

      error(31);

      num=0;

      }

      table[tx].other.val=num;

      break;case VARIABLE:

      table[tx].other.inOther.level=lev;

      table[tx].other.inOther.adr=dx;

      dx++;

      break;case PROCEDURE:

      table[tx].other.inOther.level=lev;

      break;case ARRAY:

      table[tx].other.inOther.size = lev;

      break;} }//enter end

      // 查找標(biāo)示符在名字表中的位置

      int PL0::position(alfa id,int tx)//find identifier id in table { int i;strcpy(table[0].name, id);i= tx;while(strcmp(table[i].name,id)!=0)i--;return i;}//position end

      // 常量定義處理

      void PL0::constdeclaration(int&tx,int&dx,int lev){ if(sym == IDENT){

      getsym();

      if(sym>=EQL&&sym<=BECOMES)

      {

      if(sym ==BECOMES)

      error(1);

      getsym();

      if(sym == NUMBER)

      {

      enter(CONSTANT,tx,dx,lev);

      getsym();

      }

      else

      error(2);

      }

      else

      error(3);} else

      error(4);}// constdeclaration end

      // 變量說(shuō)明處理

      void PL0::vardeclaration(int&tx,int&dx,int lev){ if(sym == IDENT){

      enter(VARIABLE,tx,dx,lev);

      getsym();} else

      error(4);}//vardeclaration end

      // 數(shù)組說(shuō)明處理

      void PL0::arraydeclaration(int&tx,int&dx,int lev){

      int upscript=0,downscript=0;getsym();if(sym == NUMBER || sym == CONSTSYM){

      if(num == 0)

      {

      upscript = num;

      getsym();

      }

      else

      error(32);} if(sym == COMMA)

      getsym();else

      error(32);if(sym == NUMBER || sym == CONSTSYM){

      downscript = num;

      getsym();} if(sym!= RPAREN)

      } error(32);else { enter(ARRAY,tx,dx,downscript+1);getsym();} // 列出目標(biāo)代碼清單

      void PL0::listcode(int cx0)//list code generated for this block { int i;if(listswitch)

      for(i= cx0;i

      cout<<”“<

      <<”“<

      // 語(yǔ)句部分處理

      void PL0::statement(symset fsys,int tx,int lev){ if(sourceEnd)

      return;int i,cx1,cx2;if(sym ==IDENT){

      i= position(id,tx);

      if(i == 0)

      error(11);

      else if(table[i].kind!=VARIABLE)

      {

      error(12);

      i= 0;

      }

      getsym();

      if(sym ==BECOMES)

      getsym();

      else

      error(13);

      expression(fsys,tx,lev);

      if(sym!= SEMICOLON)

      error(10);

      if(i!= 0)

      gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr);

      } else if(sym == READSYM){ getsym();if(sym!=LPAREN)

      error(34);else

      do{

      getsym();

      if(sym==IDENT)

      i=position(id,tx);

      else

      i=0;

      if(i==0)

      error(35);

      else

      {

      gen(OPR,0,16);

      gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr);

      }

      getsym();

      }while(sym == COMMA);

      if(sym!= RPAREN)

      {

      error(33);

      while(fsys.find(sym)!=fsys.end())getsym();

      }

      else

      getsym();} else if(sym == WRITESYM){ getsym();if(sym==LPAREN){

      do{

      getsym();

      symset tmp=fsys;

      for(int t=RPAREN;t<=COMMA;t++)

      tmp.insert((symbol)t);

      expression(tmp,tx,lev);

      gen(OPR,0,14);

      }while(sym==COMMA);

      if(sym!=RPAREN)

      error(33);

      else

      getsym();} gen(OPR,0,15);} else if(sym ==CALLSYM){ getsym();if(sym!=IDENT)

      error(14);else {

      i= position(id,tx);

      if(i == 0)

      error(11);

      else if(table[i].kind = PROCEDURE)

      gen(CAL,lev-table[i].other.inOther.level,table[i].other.inOther.adr);

      else

      error(15);

      getsym();} } else if(sym ==IFSYM){ getsym();symset tmp=fsys;for(int i = THENSYM;i<= DOSYM;i++)

      tmp.insert((symbol)i);condition(tmp,tx,lev);if(sym == THENSYM)

      getsym();else

      error(16);cx1= cx;gen(JPC,0,0);tmp.insert(ELSESYM);statement(tmp,tx,lev);getsym();

      code[cx1].a= cx;

      if(sym == ELSESYM){

      getsym();

      cx2=cx;

      gen(JMP,0,0);

      code[cx1].a=cx;

      statement(fsys,tx,lev);

      code[cx2].a=cx;} } else if(sym ==BEGINSYM){ getsym();symset tmp=fsys;for(int i=SEMICOLON;i<=ENDSYM;i++)

      tmp.insert((symbol)i);statement(tmp,tx,lev);tmp=statbegsys;tmp.insert(SEMICOLON);while(tmp.find(sym)!=tmp.end()){

      if(sourceEnd)return;

      if(sym ==SEMICOLON||sym ==ENDSYM)

      getsym();

      else if(sym=PERIOD)

      {

      error(26);

      getsym();

      }

      else

      error(10);

      tmp=fsys;

      for(i=SEMICOLON;i<=ENDSYM;i++)

      tmp.insert((symbol)i);

      if(sourceEnd)return;

      if(sym==ENDSYM)

      break;

      statement(tmp,tx,lev);} if(sym ==ENDSYM)

      getsym();else if(!sourceEnd)

      error(17);} else if(sym ==WHILESYM){ cx1= cx;

      // 記下當(dāng)前代碼分配位置,這是while循環(huán)的開(kāi)始位置

      getsym();symset tmp=fsys;tmp.insert(DOSYM);condition(tmp,tx,lev);

      cx2= cx;

      // 記下當(dāng)前代碼分配位置,這是while的do中的語(yǔ)句的開(kāi)始位置

      gen(JPC,0,0);

      if(sym ==DOSYM)

      getsym();

      else

      error(18);

      statement(fsys,tx,lev);

      gen(JMP,0,cx1);

      code[cx2].a= cx;} else if(sym == REPEATSYM){

      symset temp1, temp2;

      temp1= fsys,temp1.insert(SEMICOLON),temp1.insert(UNTILSYM);

      cx1= cx;

      getsym();

      statement(temp1,tx,lev);

      temp2 = statbegsys;

      temp2.insert(SEMICOLON);

      while(temp2.find(sym)!= temp2.end())

      {

      if(sym == SEMICOLON)

      getsym();

      else

      error(34);

      statement(temp1,tx,lev);

      }

      if(sym == UNTILSYM)

      {

      getsym();

      condition(fsys,tx,lev);

      gen(JPC,0,cx1);

      }

      else

      error(34);

      } symset setT;test(fsys,setT,19);}//statement end

      // 表達(dá)式處理

      void PL0::expression(symset fsys,int tx,int lev){ symbol addop;symset tmp=fsys;for(int t=PLUS;t<=MINUS;t++)

      tmp.insert((symbol)t);if(sym>=PLUS&&sym<=MINUS){

      addop= sym;

      getsym();

      term(tmp,tx,lev);

      if(addop ==MINUS)

      gen(OPR,0,1);} else

      term(tmp,tx,lev);while(sym >=PLUS&&sym<=MINUS){

      addop= sym;

      getsym();

      term(tmp,tx,lev);

      if(addop ==PLUS)

      gen(OPR,0,2);

      else

      gen(OPR,0,3);} }// expression end

      // 項(xiàng)處理

      void PL0::term(symset fsys,int tx,int lev){ if(sourceEnd)

      return;symbol mulop;symset tmp=fsys;for(int t=TIMES;t<=SLASH;t++)

      tmp.insert((symbol)t);factor(tmp,tx,lev);while(sym>=TIMES && sym<=SLASH){

      mulop= sym;

      getsym();

      factor(tmp,tx,lev);

      if(mulop ==TIMES)

      gen(OPR,0,4);

      else

      gen(OPR,0,5);} }// term end

      // 因子處理

      void PL0:: factor(symset fsys,int tx,int lev){ int i;test(facbegsys,fsys,24);while(facbegsys.find(sym)!=facbegsys.end()){

      if(sym ==IDENT)

      {

      i= position(id,tx);

      if(i == 0)

      error(11);

      else

      switch(table[i].kind)

      {

      case CONSTANT:

      gen(LIT,0,table[i].other.val);

      break;

      case VARIABLE:

      gen(LOD,lev-table[i].other.inOther.level,table[i].other.inOther.adr);

      break;

      case PROCEDURE:

      error(21);

      break;

      }

      getsym();

      }

      else if(sym ==NUMBER)

      {

      if(num>amax)

      {

      error(31);

      num= 0;

      }

      gen(LIT,0,num);

      getsym();

      }

      else if(sym ==LPAREN)

      {

      getsym();

      symset tmp=fsys;

      tmp.insert(RPAREN);

      expression(tmp,tx,lev);

      if(sym == RPAREN)

      getsym();

      else

      error(22);

      }

      test(fsys,facbegsys,23);} }//factor end

      // 條件處理

      void PL0::condition(symset fsys,int tx,int lev){ symbol relop;symset tmp=fsys;tmp.insert(EQL),tmp.insert(NEQ),tmp.insert(LSS),tmp.insert(LEQ),tmp.insert(GTR),tmp.insert(GEQ);

      if(sym == ODDSYM){

      getsym();

      expression(fsys,tx,lev);

      gen(OPR,0,6);} else {

      expression(tmp,tx,lev);

      if(tmp.find(sym)==tmp.end())

      error(20);

      else

      {

      relop= sym;

      getsym();

      expression(fsys,tx,lev);

      switch(relop)

      {

      case EQL: gen(OPR,0,8);

      break;

      case NEQ: gen(OPR,0,9);

      break;

      case LSS: gen(OPR,0,10);

      break;

      case GEQ: gen(OPR,0,11);

      break;

      case GTR: gen(OPR,0,12);

      break;

      case LEQ: gen(OPR,0,13);

      break;

      }

      } } }//condition end

      // 對(duì)目標(biāo)代碼的解釋執(zhí)行程序

      void PL0::interpret(){ int err1=errorString.size();if(err1>0){

      cout<<”存在%d個(gè)錯(cuò)誤:“<

      cout<

      t= t+1;

      s[t]= i.a;

      break;case OPR:

      switch(i.a)//operator

      { case 0:// return t= b-1;

      p= s[t+3];

      b= s[t+2];break;case 1: s[t]=-s[t];break;case 2: t= t-1;s[t]= s[t]+s[t+1];break;case 3: t= t-1;s[t]= s[t]-s[t+1];break;case 4: t= t-1;s[t]= s[t]*s[t+1];break;case 5: t= t-1;s[t]= s[t] / s[t+1];break;case 6: if(s[t]%2)

      s[t]=1;else

      s[t]=0;break;case 8: t= t-1;if(s[t]==s[t+1])

      s[t]=1;else

      s[t]=0;break;case 9: t= t-1;if(s[t]==s[t+1])

      s[t]=0;else

      s[t]=1;break;

      case 10: t= t-1;if(s[t]

      s[t]=1;else

      s[t]=0;break;case 11: t= t-1;if(s[t]>=s[t+1])

      s[t]= 1;else

      s[t]=0;break;case 12: t= t-1;if(s[t]>s[t+1])

      s[t]= 1;else

      s[t]=0;break;case 13: t= t-1;if(s[t]<=s[t+1])

      s[t]= 1;else

      s[t]=0;break;case 14: cout<<”“<>s[t];break;};break;case LOD:

      t= t+1;

      s[t]= s[base(i.l,b,s)+i.a];

      break;

      case STO:

      s[base(i.l,b,s)+i.a]= s[t];

      t= t-1;

      break;

      case CAL:// generate new block mark

      s[t+1]= base(i.l,b,s);

      s[t+2]= b;

      s[t+3]= p;

      b= t+1;

      p=i.a;

      break;

      case INT:

      t= t+i.a;

      break;

      case JMP:

      p= i.a;

      break;

      case JPC:

      if(s[t] == 0)

      p= i.a;

      t= t-1;

      break;

      }//switch end

      }while(p!=0);

      cout<<” End PL/0n“;} // interpret end

      // 通過(guò)靜態(tài)鏈求出數(shù)據(jù)區(qū)的基地址

      int PL0::base(int l,int b,int s[]){ int b1;b1= b;//find base l levels down while(l>0){

      b1= s[b1];

      l= l-1;} return b1;}

      // 保存代碼

      void PL0::SaveCode(){ if(fout)

      for(int i=0;i

      fprintf(fout,”%d %s %d %dn “,i,mnemonic[code[i].f],code[i].l,code[i].a);} TestPL0.cpp代碼: #include ”pl0.h“ void main(){ PL0 cp(”testPas2.txt“,”nasm.txt");

      symset fsys;

      fsys.insert(PERIOD);fsys.insert(CONSTSYM),fsys.insert(VARSYM),fsys.insert(PROCSYM);fsys.insert(BEGINSYM),fsys.insert(CALLSYM),fsys.insert(IFSYM),fsys.insert(WHILESYM);cp.getsym();

      // 詞法分析,分析一個(gè)詞

      cp.block(0,0,fsys);

      // 分程序分析處理功能

      cp.SaveCode();

      // 保存代碼

      cp.interpret();

      // 對(duì)目標(biāo)代碼的解釋執(zhí)行程序

      } 實(shí)驗(yàn)運(yùn)行結(jié)果:

      運(yùn)行的的文件見(jiàn)下圖右側(cè):實(shí)驗(yàn)中我是固定了文件名的,可以是改寫成動(dòng)態(tài)輸入,由于在測(cè)試中我把所有的測(cè)試語(yǔ)句都放在同一個(gè)文件中了,沒(méi)有太多的必要。

      六、心得體會(huì)

      在編譯程序?qū)崿F(xiàn)的過(guò)程中反復(fù)使用了遞歸調(diào)用的思想,且也使用了模塊化處理問(wèn)題的思想,使用模塊化的思想關(guān)鍵是在抽象階段要抽象出對(duì)應(yīng)的模塊,且模塊的層次必須是清晰的。

      在實(shí)現(xiàn)此程序中,由于要實(shí)現(xiàn)關(guān)鍵字和符號(hào)表中字段的搜索,實(shí)現(xiàn)中就必須注意快速查找的方法,而在實(shí)現(xiàn)的過(guò)程中多次用到了二分搜索的方法,這是個(gè)比較快的搜索方法。

      由于此程序的實(shí)現(xiàn)相對(duì)比較復(fù)雜,且不方便調(diào)試,改進(jìn)時(shí)可以把此程序的詞法分析,語(yǔ)法分析和執(zhí)行原代碼作為單獨(dú)的測(cè)試程序來(lái)測(cè)試,這樣也方便大家來(lái)調(diào)試。

      通過(guò)本次的課設(shè)我知道了一個(gè)算法的設(shè)計(jì)是需要靜下心來(lái)仔細(xì)的研究的,且實(shí)現(xiàn)中必須先了解程序的整個(gè)流程,也就是說(shuō)在編程中首先必須看懂那些對(duì)應(yīng)的UML圖,只有在圖的指導(dǎo)下,編程中才不會(huì)盲目,也有一定的方向性。同樣在編程中必須注意代碼的規(guī)范,多寫一些對(duì)應(yīng)的注釋是很必要的,要時(shí)刻想這代碼并不是給你自己看的,而是必須要給別人看,因此我覺(jué)得代碼的規(guī)范是相當(dāng)重要的。

      第三篇:編譯原理課程設(shè)計(jì)

      課 程 設(shè) 計(jì) 報(bào) 告

      設(shè)計(jì)題目:一個(gè)簡(jiǎn)單文法的編譯器前端的設(shè)計(jì)與實(shí)現(xiàn)

      級(jí): 計(jì)算機(jī)1206 組長(zhǎng)學(xué)號(hào):201239 組長(zhǎng)姓名:閆智宣 指導(dǎo)教師:李曉華 設(shè)計(jì)時(shí)間:2014年12月

      [在此處鍵入]

      設(shè)計(jì)分工

      組長(zhǎng)學(xué)號(hào)及姓名: 20123974

      閆智宣

      分工:

      語(yǔ)法分析,四元式生成,目標(biāo)代碼優(yōu)化及生成 組員1學(xué)號(hào)及姓名:20123977

      廖峭 分工:

      詞法分析,錯(cuò)誤處理 組員2學(xué)號(hào)及姓名:20123959

      郭天龍

      分工:

      符號(hào)表生成,語(yǔ)義動(dòng)作插入,操作界面[在此處鍵入]

      摘要

      編譯原理課程設(shè)計(jì)是通過(guò)C語(yǔ)言編譯器相關(guān)子系統(tǒng)的設(shè)計(jì),進(jìn)一步加深對(duì)編譯器構(gòu)造的理解;第一部分詞法分析,設(shè)計(jì)各單詞的狀態(tài)轉(zhuǎn)換圖,并為不同的單詞設(shè)計(jì)種別碼,制作掃描器識(shí)別一個(gè)個(gè)單詞,返回值為識(shí)別碼的序號(hào),返回Token序列。將詞法分析器設(shè)計(jì)成供語(yǔ)法分析器調(diào)用的子程序。詞法分析器具備預(yù)處理功能。將不翻譯的注釋等符號(hào)先濾掉,只保留要翻譯的符號(hào)串,即要求設(shè)計(jì)一個(gè)供詞法分析調(diào)用的預(yù)處理子程序;第二部分,語(yǔ)法分析,用遞歸下降法,實(shí)現(xiàn)對(duì)表達(dá)式、各種說(shuō)明語(yǔ)句、控制語(yǔ)句進(jìn)行語(yǔ)法分析。若語(yǔ)法正確,則用語(yǔ)法制導(dǎo)翻譯法進(jìn)行語(yǔ)義翻譯;生成并打印出語(yǔ)法樹(shù);若語(yǔ)法錯(cuò)誤,要求指出出錯(cuò)性質(zhì)和出錯(cuò)位置(行號(hào))。

      我們還做了附加功能,即編譯后端,有中間代碼優(yōu)化,生成目標(biāo)代碼匯編語(yǔ)言。通過(guò)此次課程設(shè)計(jì),提高了我們的獨(dú)立分析問(wèn)題、解決問(wèn)題的能力,以及系統(tǒng)軟件設(shè)計(jì)的能力; 提高程序設(shè)計(jì)能力、程序調(diào)試能力,團(tuán)結(jié)協(xié)作能力

      關(guān)鍵詞:詞法分析,語(yǔ)法分析,四元式生成,錯(cuò)誤處理,符號(hào)表生成,語(yǔ)義動(dòng)作插入,中間代碼優(yōu)化,生成目標(biāo)代碼 [在此處鍵入]

      目錄

      摘要

      1.概述

      2.課程設(shè)計(jì)任務(wù)及要求

      2.1 設(shè)計(jì)任務(wù)

      2.2 設(shè)計(jì)要求

      3.算法及數(shù)據(jù)結(jié)構(gòu)

      3.1算法的總體思想(流程)

      3.2 詞法分析模塊

      3.2.1 功能

      3.2.2 數(shù)據(jù)結(jié)構(gòu)

      3.2.3 算法

      3.3 語(yǔ)法分析模塊

      3.3.1功能

      3.3.2 數(shù)據(jù)結(jié)構(gòu)

      3.3.3算法

      3.4 符號(hào)表模塊

      3.4.1功能

      3.4.2 數(shù)據(jù)結(jié)構(gòu)

      3.4.3算法

      3.5 四元式模塊

      3.5.1功能

      [在此處鍵入]

      3.5.2 數(shù)據(jù)結(jié)構(gòu)

      3.5.3算法

      3.6 語(yǔ)義動(dòng)作分析模塊

      3.6.1功能 3.6.2 數(shù)據(jù)結(jié)構(gòu)

      3.6.3算法

      3.7 錯(cuò)誤處理模塊

      3.7.1功能

      3.7.2 數(shù)據(jù)結(jié)構(gòu)

      3.7.3算法

      3.8 目標(biāo)代碼模塊

      3.8.1功能

      3.8.2 數(shù)據(jù)結(jié)構(gòu)

      3.8.3算法

      4.程序設(shè)計(jì)與實(shí)現(xiàn)

      4.1 程序流程圖

      4.2 程序說(shuō)明

      4.3 實(shí)驗(yàn)結(jié)果

      5.結(jié)論 6.參考文獻(xiàn)。7.收獲、體會(huì)和建議。

      [在此處鍵入]

      1.概述

      編譯器是將C語(yǔ)言翻譯為匯編語(yǔ)言代碼的計(jì)算機(jī)程序。編譯器將源程序(source language)編寫的程序作為輸入,翻譯產(chǎn)生目標(biāo)語(yǔ)言(target language)機(jī)器代碼的等價(jià)程序。通常地,源程序?yàn)楦呒?jí)語(yǔ)言(high-level language),C語(yǔ)言程序,而目標(biāo)則是 機(jī)器語(yǔ)言的目標(biāo)代碼(object code),也就是可以在計(jì)算機(jī)硬件中運(yùn)行的機(jī)器代碼軟件程序。這一過(guò)程可以表示為:

      源程序→編譯器 →目標(biāo)機(jī)器代碼程序

      2.課程設(shè)計(jì)任務(wù)及要求

      2.1設(shè)計(jì)任務(wù)

      學(xué)生在學(xué)習(xí)《編譯原理》課程過(guò)程中,結(jié)合各章節(jié)的構(gòu)造編譯程序的基本理論,要求用C#語(yǔ)言描述及上機(jī)調(diào)試,實(shí)現(xiàn)一個(gè) C編譯程序(包括詞法分析,語(yǔ)法分析等重要子程序),使學(xué)生將理論與實(shí)際應(yīng)用結(jié)合起來(lái),受到軟件設(shè)計(jì)等開(kāi)發(fā)過(guò)程的全面訓(xùn)練,從而提高學(xué)生軟件開(kāi)發(fā)的能力。

      2.2設(shè)計(jì)要求 要求:

      (1)設(shè)計(jì)詞法分析器

      設(shè)計(jì)各單詞的狀態(tài)轉(zhuǎn)換圖,并為不同的單詞設(shè)計(jì)種別碼。將詞法分析器設(shè)計(jì)成供語(yǔ)法分析器調(diào)用的子程序。功能包括:

      a.具備預(yù)處理功能。將不翻譯的注釋等符號(hào)先濾掉,只保留要翻譯的符號(hào)串,即要求設(shè)計(jì)一個(gè)供詞法分析調(diào)用的預(yù)處理子程序;

      b.能夠拼出語(yǔ)言中的各個(gè)單詞; [在此處鍵入]

      c.返回(種別碼,屬性值,行號(hào))。

      (2)語(yǔ)法分析

      要求用學(xué)習(xí)過(guò)的自底向上或自頂向下的分析方法等,實(shí)現(xiàn)對(duì)表達(dá)式、各種說(shuō)明語(yǔ)句、控制語(yǔ)句進(jìn)行語(yǔ)法分析。若語(yǔ)法正確,則用語(yǔ)法制導(dǎo)翻譯法進(jìn)行語(yǔ)義翻譯;生成并打印出語(yǔ)法樹(shù);若語(yǔ)法錯(cuò)誤,要求指出出錯(cuò)性質(zhì)和出錯(cuò)位置(行號(hào))。

      3.算法及數(shù)據(jù)結(jié)構(gòu)

      3.1算法的總體思想(流程)

      本節(jié)主要分析程序的代碼結(jié)構(gòu)和代碼工程文件的劃分。(程序由幾個(gè)類組成: Token類和Variable類SymbolTable類ObjectCode類Lexical類Grammar類Four_Yuan類Action類ErrorItem類,分別為詞法分析和語(yǔ)法分析類。工程分為幾個(gè)文件:Form1.cs,Token.cs,Variable.cs,SymbolTable.cs,ObjectCode.cs,Lexical.cs,Grammar.cs,Four_Yuan,cs,Action.cs,ErrorItem.cs分別對(duì)應(yīng)Token類和Variable類SymbolTable類ObjectCode類Lexical類Grammar類Four_Yuan類Action類ErrorItem類的聲明和實(shí)現(xiàn)文件)。本程序采用C#語(yǔ)言以面向?qū)ο蟮乃枷刖帉?,程序分為幾部分:詞法分析(Lexical),語(yǔ)法分析(Grammer),目標(biāo)代碼生成(ObjectCode)。Lexical類主要的工作是詞法分析獲取Token。Grammer類的主要工作是根據(jù)Lexical類詞法分析之后的Token進(jìn)行語(yǔ)法分析,生成語(yǔ)法樹(shù),最后并輸出語(yǔ)法樹(shù)。在處理過(guò)程中,Token類的對(duì)象作為L(zhǎng)exical類的一個(gè)成員變量,配合Grammer類進(jìn)行語(yǔ)法分析。

      工程文件總體上是按照九個(gè)類的格局分為十個(gè)文件,分別是九個(gè)類的聲明文件和實(shí)現(xiàn)文件。十個(gè)文件為Form1.cs,Token.cs,Variable.cs,SymbolTable.cs,ObjectCode.cs,Lexical.cs,Grammar.cs,Four_Yuan,cs,Action.cs,ErrorItem.cs,他們分別是Lexical類聲明文件、Lexical類實(shí)現(xiàn)文件、Grammer類聲明文件、Grammer類實(shí)現(xiàn)文件。[在此處鍵入]

      程序流程

      在程序中,Lexical類的對(duì)象(Token)作為Grammer類中的一個(gè)成員變量,配合Grammer類進(jìn)行語(yǔ)法分析。它們的關(guān)系是這樣的:Grammer類的一個(gè)成員變量temp首先對(duì)源程序刪除注釋,然后進(jìn)行詞法分析獲取所有Token,并將獲取的Token存儲(chǔ)在Token對(duì)象的tokenList(List類型)中。然后Grammer類的語(yǔ)法分析程序就根據(jù)tokenList中的Token進(jìn)行語(yǔ)法分析,生成語(yǔ)法樹(shù),最后打印語(yǔ)法樹(shù)。同時(shí),這也是程序的流程。[在此處鍵入]

      3.2 詞法分析模塊 3.2.1功能

      Lexical類主要的工作是詞法分析獲取Token序列。

      3.2.2數(shù)據(jù)結(jié)構(gòu)

      詞法分析階段的代碼被封裝成一個(gè)類——Lexical,Token中主要是Lexical類的聲明代碼,Lexical.cs中主要是Lexical類的實(shí)現(xiàn)代碼。Lexical類對(duì)外提供的函數(shù)主要有:

      static public int RecogId(string str, int i),static public int RecogDig(string str,int i),static public int RecogOperator(string str, int i),static public int RecogBound(string str, int i),以上幾個(gè)函數(shù)構(gòu)成了詞法分析的骨架,在Lexical類中還有其他成員變量和函數(shù),主要作為這三個(gè)函數(shù)處理過(guò)程的中間步驟,為這三個(gè)函數(shù)服務(wù)。Lexical類的代碼結(jié)構(gòu)和主要的成員變量和函數(shù)及其含義如下圖所示:

      3.2.3算法

      算法的基本任務(wù)是從字符串表示的源程序中識(shí)別出具有獨(dú)立意義的單詞符號(hào),其基本思想是[在此處鍵入]

      根據(jù)掃描到單詞符號(hào)的第一個(gè)字符的種類,拼出相應(yīng)的單詞符號(hào)。

      主程序示意圖:

      主程序示意圖如圖3-1所示。

      ⑴ 關(guān)鍵字表的初值。

      關(guān)鍵字作為特殊標(biāo)識(shí)符處理,把它們預(yù)先安排在一張表格中(稱為關(guān)鍵字表),當(dāng)掃描程序識(shí)別出標(biāo)識(shí)符時(shí),查關(guān)鍵字表。如能查到匹配的單詞,則該單詞為關(guān)鍵字,否則為一般標(biāo)識(shí)符。

      (2)程序中需要用到的主要變量為type和number 掃描子程序的算法思想:

      首先設(shè)置3個(gè)變量: [在此處鍵入]

      ①token用來(lái)存放構(gòu)成單詞符號(hào)的字符串; ②number用來(lái)整型單詞;

      ③type用來(lái)存放單詞符號(hào)的種別碼。

      Token定義

      Token定義:

      Token類型(TokenType):

      3.3 語(yǔ)法分析模塊

      3.3.1功能

      語(yǔ)法分析是編譯過(guò)程的一個(gè)邏輯階段。語(yǔ)法分析的功能是在詞法分析的基礎(chǔ)上將單詞序列組合成各類語(yǔ)法短語(yǔ),如“程序”,“語(yǔ)句”,“表達(dá)式”等等.語(yǔ)法分析程序判斷源程序在結(jié)構(gòu)上是否正確.源程序的結(jié)構(gòu)由上下文無(wú)關(guān)文法描述.3.3.2 數(shù)據(jù)結(jié)構(gòu)

      下圖為實(shí)現(xiàn)語(yǔ)法分析的類Grammar,屬性與方法的作用都已說(shuō)明 在此處鍵入]

      3.3.3算法

      1.文法

      下面終結(jié)符與非終結(jié)符意義

      B程序開(kāi)始

      Z 數(shù)據(jù)類型,如int,char,float等

      V 標(biāo)識(shí)符

      S 語(yǔ)句

      P 語(yǔ)句塊

      E 加減算術(shù)表達(dá)式

      D 逗號(hào)表達(dá)式

      T 乘除算術(shù)表達(dá)式

      C 關(guān)系表達(dá)式

      L 邏輯表達(dá)式

      Q 標(biāo)識(shí)符或圓括號(hào)

      e 表示空

      i 表示標(biāo)識(shí)符 a)函數(shù)文法

      B----ZV()S

      [

      [在此處鍵入]

      b)語(yǔ)句塊文法

      P----SP|e

      S----{P} c)語(yǔ)句文法

      表達(dá)式語(yǔ)句文法

      S----V=E

      goto語(yǔ)句文法

      S----i:S

      S----goto i

      if語(yǔ)句文法

      S----if(E)S[else S]

      while語(yǔ)句文法

      S----while(E)S

      聲明語(yǔ)句文法

      S----ZVD

      D----,VD|=ED|e d)表達(dá)式文法

      E----T|E+T|E-T

      T----F|T*F|T/F

      C----C|CL|C==C|C<= L|C>=L

      L----Q|L&&Q|L||Q

      Q----i|(E)|!Q

      2.遞歸下降程序流程圖

      對(duì)應(yīng)于每個(gè)文法編寫如下遞歸下降子程序

      主程序(B)[在此處鍵入] [在此處鍵入]

      3.4 符號(hào)表模塊

      3.4.1功能

      進(jìn)行符號(hào)表的儲(chǔ)存,添加,更新,查找,保存標(biāo)識(shí)符活躍信息以及輸出。3.4.2 數(shù)據(jù)結(jié)構(gòu)

      在此處鍵入]

      3.4.3算法

      3.5 四元式模塊

      3.5.1功能

      四元式為中間代碼,編譯程序進(jìn)行完語(yǔ)義分析后,先生成中間代碼作為過(guò)渡,此時(shí)中間代碼與目標(biāo)代碼已經(jīng)比較相似

      3.5.2 數(shù)據(jù)結(jié)構(gòu)

      [ 在此處鍵入]

      3.5.3算法

      3.6語(yǔ)義動(dòng)作分析模塊

      3.6.1功能

      在語(yǔ)法分析中嵌入相應(yīng)的語(yǔ)義動(dòng)作,生成四元式 3.6.2 數(shù)據(jù)結(jié)構(gòu)

      [

      [在此處鍵入]

      3.6.3算法 GEQ(+)(-)(*)(/)

      (+,i1,i2,t)PUSH(i)ASSI(=)

      (=,t,_,POP)LABER(i)

      (lb,_,_,i)GOTO(i)

      (gt,_,_,i)IF(if)

      (if,a,_,_)EL(el)

      (el,_,_,_)IE(ie)

      (ie,_,_,_)WH()

      (wh,_,_,_)DO()

      (do,a,_,_)WE(we)

      (we,_,_,_)

      3.7 錯(cuò)誤處理模塊

      3.7.1功能 保存運(yùn)行時(shí)發(fā)現(xiàn)的錯(cuò)誤,儲(chǔ)存行號(hào)已經(jīng)詳細(xì)信息并輸出。

      3.7.2 數(shù)據(jù)結(jié)構(gòu)

      3.7.3算法 [在此處鍵入]

      public static void AddErrorMessage(int lineno,string content)函數(shù)用作在發(fā)現(xiàn)錯(cuò)誤時(shí)保存錯(cuò)誤信息以及行號(hào)。

      public static string PrintErrorList()把所有發(fā)現(xiàn)的錯(cuò)誤格式化后統(tǒng)一輸出。

      錯(cuò)誤信息在語(yǔ)法分析,語(yǔ)義分析,符號(hào)表檢錯(cuò)中添加。3.8 目標(biāo)代碼模塊

      3.8.1功能

      目標(biāo)代碼生成把優(yōu)化后的中間代碼變換成目標(biāo)代碼,此處的目標(biāo)代碼為匯編代碼,采用單寄存器生成目標(biāo)代碼 3.8.2 數(shù)據(jù)結(jié)構(gòu)[在此處鍵入]

      3.8.3算法

      對(duì)于一個(gè)基本塊有如下流程圖

      W:操作符,B:第一操作數(shù),C:第二操作數(shù),R:寄存器

      5.結(jié)論

      網(wǎng)上找一段話抄上 [在此處鍵入]

      6.測(cè)試

      測(cè)試打開(kāi)文件

      測(cè)試保存文件

      如果沒(méi)打開(kāi)文件,直接敲代碼,點(diǎn)保存時(shí)會(huì)彈出另存為窗口[在此處鍵入]

      測(cè)試錯(cuò)誤檢測(cè),程序缺少main函數(shù)的類型,錯(cuò)誤列表中顯示第一行函數(shù)缺少錯(cuò)誤類型。

      測(cè)試錯(cuò)誤檢測(cè),程序缺少分號(hào),錯(cuò)誤列表中顯示該行缺少語(yǔ)句結(jié)束標(biāo)志';' 單擊錯(cuò)誤列表,會(huì)自動(dòng)選定錯(cuò)誤行

      編譯成功,生成并顯示token串、符號(hào)表、四元式與目標(biāo)代碼 [在此處鍵入]

      測(cè)試if與while語(yǔ)句,而且while嵌套在if當(dāng)中

      測(cè)試goto語(yǔ)句,結(jié)果正確。[在此處鍵入]

      測(cè)試優(yōu)化,輸入課件中的代碼,結(jié)果與課件一樣

      6.參考文獻(xiàn)。

      1、陳火旺.《程序設(shè)計(jì)語(yǔ)言編譯原理》(第3版).北京:國(guó)防工業(yè)出版社.2000.2、美 Alfred V.Aho Ravi Sethi Jeffrey D.Ullman著.李建中,姜守旭譯.《編譯原理》.24 [在此處鍵入]

      北京:機(jī)械工業(yè)出版社.2003.3、美 Kenneth C.Louden著.馮博琴等譯.《編譯原理及實(shí)踐》.北京:機(jī)械工業(yè)出版社.2002.4、金成植著.《編譯程序構(gòu)造原理和實(shí)現(xiàn)技術(shù)》.北京:高等教育出版社.2002.7.收獲、體會(huì)和建議。

      直接拷貝好歹也檢查一下錯(cuò)誤

      對(duì)于編譯原理的這次課程設(shè)計(jì),自己經(jīng)歷了從剛開(kāi)始的不懂?明白任務(wù)的要求和內(nèi)容?理論知識(shí)的了解?開(kāi)始著手寫代碼?完成基本功能?根據(jù)DFA及自頂向下等理論修改完善代碼等這些過(guò)程。

      自己著手寫詞法分析的時(shí)候還不清楚詞法分析的任務(wù)內(nèi)容,還不知道詞法分析的結(jié)果是什么,詞法分析出錯(cuò)的情況和類型有哪些,也總是將詞法分析和語(yǔ)法分析混在一起,不明白哪些錯(cuò)誤在詞法分析中報(bào),哪些錯(cuò)誤在語(yǔ)法分析中判斷,后來(lái)經(jīng)過(guò)查書、網(wǎng)上資料、請(qǐng)教同學(xué)等途徑逐步清晰了詞法分析的工作內(nèi)容是從源代碼文件中獲取出Token,供語(yǔ)法分析使用。在充分了解了語(yǔ)法分析需要哪些信息時(shí),我才真正了解了詞法分析的工作內(nèi)容和目標(biāo),才知道詞法分析需要完成哪些任務(wù)獲取到哪些信息。充分了解了詞法分析的任務(wù)之后,就開(kāi)始理論知識(shí)的學(xué)習(xí)。經(jīng)過(guò)揣摩書上的例子,自己理解和掌握了怎么設(shè)計(jì)過(guò)濾注釋和分析程序中Token的DFA,于是開(kāi)始根據(jù)設(shè)計(jì)好的DFA進(jìn)行編碼,最后經(jīng)過(guò)調(diào)試已經(jīng)可以正確地完成詞法階段的任務(wù)了。這只是詞法分析的原始代碼,在之后還進(jìn)行了兩次徹底的改動(dòng)。雖然之前寫的詞法分析的代碼已經(jīng)完成了詞法分析的需求,也是根據(jù)DFA的原理編寫的,但是在代碼結(jié)構(gòu)上卻難以體現(xiàn),在對(duì)書上的根據(jù)已知DFA寫代碼的例子進(jìn)行了詳細(xì)的研究之后,發(fā)現(xiàn)自己的代碼并沒(méi)有像書上那樣完全按照所依據(jù)的DFA各狀態(tài)轉(zhuǎn)移的關(guān)系進(jìn)行編寫,所以對(duì)代碼進(jìn)行了重寫,像書上一樣嚴(yán)格按照狀態(tài)之間轉(zhuǎn)移的方式進(jìn)行編寫,將狀態(tài)劃分成11個(gè)狀態(tài),狀態(tài)分別按1~11進(jìn)行標(biāo)注,程序也按照DFA來(lái)編寫,也實(shí)現(xiàn)了詞法分析的功能。再后來(lái)寫報(bào)告的時(shí)候,發(fā)現(xiàn)分析出Token的那個(gè)DFA并不是最簡(jiǎn)的,有很多多余的狀態(tài),完全可以用一個(gè)flag標(biāo)志來(lái)標(biāo)識(shí),從而簡(jiǎn)化代碼結(jié)構(gòu),于是又重寫了一次詞法分析函數(shù)scan()的代碼,將狀態(tài)縮減為5個(gè),且不再用1-5來(lái)表示,而是像書上那樣分別取了名字(START、INNUM、INID、INDBSYM、DONE),同時(shí)為了簡(jiǎn)化代碼將輸出Token到文件的部分從scan()中剝離開(kāi)來(lái),而在Lexical類中加了一個(gè)printToken()的函數(shù),使scan()函數(shù)邏輯更加清晰,使讀者能夠容易地將代碼與DFA進(jìn)行查看比照。

      在寫語(yǔ)法分析的時(shí)候,已經(jīng)對(duì)編譯器的語(yǔ)法分析的內(nèi)容有了一定的了解,所以直接進(jìn)行了理論的學(xué)習(xí)。首先自己對(duì)遞歸向下分析法進(jìn)行了學(xué)習(xí),將書上的幾個(gè)遞歸向下分析的偽代碼看過(guò)之后,自己對(duì)遞歸向下的分析方法的原理有了初步的認(rèn)識(shí),大概知道了根據(jù)文法怎么分析,但是對(duì)于如何編寫代碼卻還在此處鍵入]

      是難以下手,于是就對(duì)照TINY語(yǔ)言的文法看了幾遍書后面的TINY語(yǔ)言的遞歸向下分析的語(yǔ)法分析程序,這樣就基本知道了C-語(yǔ)言的語(yǔ)法分析程序怎么寫。由于C-語(yǔ)言給出的文法有左遞歸存在,于是自己將存在左遞歸的文法改寫成EBNF的形式,并據(jù)此進(jìn)行代碼編寫。由于在編寫代碼的過(guò)程中需要確定分析是否正確或選擇多個(gè)文法中的某一個(gè)文法進(jìn)行分析,有時(shí)必須探測(cè)需要的或下一個(gè)Token的類型,在這種情況下需要求First集合,在推導(dǎo)中若存在empty,又需要求Follow集合,所以這樣又需要我了解First集合和Follow集合,自己在程序中也根據(jù)求出的First集合和Follow集合進(jìn)行判斷,以確定程序的走向。在編寫過(guò)程中,還有一類問(wèn)題,就是存在公共左因子,如文法expression→ var = expression | simple-expression,左因子為ID,在分析過(guò)程中,由于已經(jīng)取出了一個(gè)ID的Token,且生成了一個(gè)IdK的節(jié)點(diǎn),但是在當(dāng)前狀態(tài)無(wú)法確定是哪一個(gè)推導(dǎo),然而IdK節(jié)點(diǎn)已經(jīng)生成,又無(wú)法回退,并且是使用自頂向下的分析方法,已經(jīng)生成的IdK在程序上方無(wú)法使用,自己通過(guò)查閱資料等途徑的學(xué)習(xí)確定了在這種情形下的處理方式:將已經(jīng)生成的IdK節(jié)點(diǎn)傳到下方的處理程序,所以TreeNode * simple_expression(TreeNode * k)、TreeNode * additive_expression(TreeNode * k)等函數(shù)都被設(shè)計(jì)成有節(jié)點(diǎn)類型參數(shù)的函數(shù),目的就是將已經(jīng)生成的節(jié)點(diǎn)傳到下面的分析函數(shù)中去。

      通過(guò)這次的編譯原理課程的學(xué)習(xí)和實(shí)踐,自己獲益良多。首先最基本的成果是完成了課程設(shè)計(jì)的任務(wù),實(shí)現(xiàn)了編譯器的詞法分析和語(yǔ)法分析階段的功能,詞法分析主要能過(guò)濾注釋、分析出語(yǔ)法分析階段需要的Token并滿足語(yǔ)法階段的所有要求,能夠判別詞法分析階段是否出錯(cuò)和出錯(cuò)類型和位置。語(yǔ)法分析主要能根據(jù)遞歸向下的分析思想和C-文法對(duì)詞法分析獲取的Token進(jìn)行語(yǔ)法分析,能夠構(gòu)造出語(yǔ)法樹(shù),能夠判別語(yǔ)法分析過(guò)程中是否出錯(cuò)以及出錯(cuò)位置和錯(cuò)誤類型。

      由于在編寫程序過(guò)程中,涉及到了正則表達(dá)式、DFA、提取公共左因子、消除左遞歸、EBNF、求First集合和Follow集合、遞歸向下分析方法以及編程語(yǔ)言方面的知識(shí),所以,通過(guò)本次的課程設(shè)計(jì)的實(shí)踐,使得自己對(duì)編譯原理這門課的許多知識(shí)點(diǎn)有了更加深刻和具體的理解,而不再只限制于做題。此外,對(duì)以前那些已掌握的知識(shí)有了溫習(xí)和動(dòng)手鍛煉的機(jī)會(huì)。如:以前在編譯原理課上雖然知道First集合和Follow集合怎么求的,卻不知道First集合和Follow集合到底是干什么的,通過(guò)編寫程序自己明白了他們的實(shí)際作用,使得自己不僅知其然還知其所以然,從而使得自己加深了對(duì)知識(shí)點(diǎn)的理解和掌握。由于以前編寫代碼都是使用JAVA語(yǔ)言,所以C/C++很多內(nèi)容都忘記了,通過(guò)本次的實(shí)踐,自己又重新拾起了以前的知識(shí)。此外,由于在做報(bào)告的時(shí)候,需要描繪DFA和程序流程圖,使得自己初步掌握了使用visio和word畫圖的能力。此外,對(duì)于文檔的編寫和美化自己也獲得了許多有用的經(jīng)驗(yàn)。[

      第四篇:編譯原理課程設(shè)計(jì)設(shè)計(jì)任務(wù)書

      編譯原理課程設(shè)計(jì)任務(wù)書

      1、目的學(xué)生在學(xué)習(xí)《程序設(shè)計(jì)語(yǔ)言編譯原理》課程過(guò)程中,結(jié)合各章節(jié)的構(gòu)造編譯程序的基本理論,總共用10個(gè)課時(shí)完成課程設(shè)計(jì)。在基本實(shí)驗(yàn)完成的基礎(chǔ)上,逐步完成課程設(shè)計(jì)。要求用C或C++語(yǔ)言描述及上機(jī)調(diào)試,實(shí)現(xiàn)一個(gè)小編譯器(詞法分析,語(yǔ)法分析,中間代碼產(chǎn)生,優(yōu)化,目標(biāo)代碼生成等重要子程序,其中詞法分析、語(yǔ)法分析及語(yǔ)義分析功能必須完成),使學(xué)生將理論與實(shí)際應(yīng)用結(jié)合起來(lái),受到軟件設(shè)計(jì)等開(kāi)發(fā)過(guò)程的全面訓(xùn)練,從而提高學(xué)生軟件開(kāi)發(fā)的能力。

      2、課程設(shè)計(jì)的任務(wù)

      (1)設(shè)計(jì)符號(hào)表

      確定符號(hào)表的組織方式,一般應(yīng)包括名字欄和信息欄,其中名字欄作為關(guān)鍵字。要考慮能夠存儲(chǔ)有關(guān)名字的信息,并可以高效地完成如下操作:

      a.查找:根據(jù)給定的名字,在符號(hào)表中查找其信息。如果該名字在符號(hào)表中不存在,則將其加入到符號(hào)表中,否則返回指向該名字的指針;

      b.刪除:從符號(hào)表中刪除給定名字的表項(xiàng)。

      (2)設(shè)計(jì)詞法分析器

      設(shè)計(jì)各單詞的狀態(tài)轉(zhuǎn)換圖,并為不同的單詞設(shè)計(jì)種別碼。將詞法分析器設(shè)計(jì)成供語(yǔ)法分析器調(diào)用的子程序。功能包括:

      a.具備預(yù)處理功能。將不翻譯的注釋等符號(hào)先濾掉,只保留要翻譯的符號(hào)串,即要求設(shè)計(jì)一個(gè)供詞法分析調(diào)用的預(yù)處理子程序;

      b.能夠拼出語(yǔ)言中的各個(gè)單詞;

      c.將拼出的標(biāo)識(shí)符填入符號(hào)表;

      d.返回(種別碼,屬性值)。

      (3)語(yǔ)法分析與中間代碼產(chǎn)生器

      要求用預(yù)測(cè)分析法、遞歸下降分析法、算符優(yōu)先分析法、SLR分析法(幾種方法任選),實(shí)現(xiàn)對(duì)表達(dá)式、各種說(shuō)明語(yǔ)句、控制語(yǔ)句進(jìn)行語(yǔ)法分析。

      若語(yǔ)法正確,則用語(yǔ)法制導(dǎo)翻譯法進(jìn)行語(yǔ)義翻譯:對(duì)說(shuō)明語(yǔ)句,要求將說(shuō)明的各符號(hào)記錄到相應(yīng)符號(hào)表中;對(duì)可執(zhí)行語(yǔ)句,應(yīng)產(chǎn)生出四元式中間代碼并填寫到三地址碼表中;

      若語(yǔ)法錯(cuò)誤,要求指出出錯(cuò)性質(zhì)和出錯(cuò)位置(行號(hào))。出錯(cuò)處理應(yīng)設(shè)計(jì)成一個(gè)出錯(cuò)處理子程序。

      (4)優(yōu)化器

      a.局部?jī)?yōu)化:設(shè)計(jì)出劃分基本塊的算法,在每一個(gè)基本塊中實(shí)現(xiàn):合并已知量、刪除多余運(yùn)算和刪除無(wú)用賦值三種局部?jī)?yōu)化。設(shè)計(jì)構(gòu)造基本塊的DAG圖的算法,以及將DAG圖還原實(shí)現(xiàn)基本塊的優(yōu)化的算法。

      b.循環(huán)優(yōu)化:只做一重循環(huán)優(yōu)化,完成代碼外提,強(qiáng)度削弱和刪除歸納變量等三種優(yōu)化。要求實(shí)現(xiàn)while循環(huán)和for循環(huán)語(yǔ)句的優(yōu)化。

      (5)目標(biāo)代碼生成器

      能完成指定寄存器個(gè)數(shù)的情況下將一中間代碼程序段翻譯成匯編語(yǔ)言目標(biāo)代碼(匯編指令應(yīng)包括加、減、乘、除),要求指令條數(shù)最少的情況下,盡量使用寄存器,盡量少訪問(wèn)內(nèi)存,這樣才能做到運(yùn)行效率高。

      3、樣本語(yǔ)言

      樣本語(yǔ)言為C-語(yǔ)言(見(jiàn)附錄),其中基本的語(yǔ)句要求必須實(shí)現(xiàn),其余部分可根據(jù)自己的實(shí)際情況選擇實(shí)現(xiàn)。

      4、要求

      各函數(shù)和過(guò)程應(yīng)有框圖描述,有功能說(shuō)明,有入口和出口參數(shù)說(shuō)明。

      5、參考資料

      《程序設(shè)計(jì)語(yǔ)言編譯原理》,陳火旺編著,國(guó)防工業(yè)出版社

      《編譯原理》,呂映芝、張素琴、蔣維杜編著,清華大學(xué)出版社

      《編譯原理》,Alfred V.Aho等,李建中譯,機(jī)械工業(yè)出版社

      6、考察方式

      最終完成一個(gè)完整的編譯程序。要求輸入一小段完整的C-語(yǔ)言源程序,輸出各編譯階段的運(yùn)行結(jié)果。在課程設(shè)計(jì)結(jié)束時(shí)上機(jī)運(yùn)行,展示運(yùn)行效果。

      7、作業(yè)提交

      最晚在期末(第17周課程結(jié)束時(shí))提交紙質(zhì)作業(yè)及可運(yùn)行程序,格式參考學(xué)院的規(guī)定課程設(shè)計(jì)任務(wù)書模板。

      第五篇:編譯原理課程設(shè)計(jì)心得體會(huì)

      經(jīng)過(guò)一個(gè)星期的編譯原理課程設(shè)計(jì),本人在劉貞老師的指導(dǎo)下,順利完成該課程設(shè)計(jì)。通過(guò)該課程設(shè)計(jì),收獲頗多。

      一、對(duì)實(shí)驗(yàn)原理有更深的理解

      通過(guò)該課程設(shè)計(jì),掌握了什么是編譯程序,編譯程序工作的基本過(guò)程及其各階段的基本任務(wù),熟悉了編譯程序總流程框圖,了解了編譯程序的生成過(guò)程、構(gòu)造工具及其相關(guān)的技術(shù)對(duì)課本上的知識(shí)有了更深的理解,課本上的知識(shí)師機(jī)械的,表面的。通過(guò)把該算法的內(nèi)容,算法的執(zhí)行順序在計(jì)算機(jī)上實(shí)現(xiàn),把原來(lái)以為很深?yuàn)W的書本知識(shí)變的更為簡(jiǎn)單,對(duì)實(shí)驗(yàn)原理有更深的理解。

      二、對(duì)該理論在實(shí)踐中的應(yīng)用有深刻的理解

      通過(guò)把該算法的內(nèi)容,算法的執(zhí)行順序在計(jì)算機(jī)上實(shí)現(xiàn),知道和理解了該理論在計(jì)算機(jī)中是怎樣執(zhí)行的,對(duì)該理論在實(shí)踐中的應(yīng)用有深刻的理解。

      三、激發(fā)了學(xué)習(xí)的積極性本文轉(zhuǎn)載在004km.cn代寫之家

      通過(guò)該課程設(shè)計(jì),全面系統(tǒng)的理解了編譯原理程序構(gòu)造的一般原理和基本實(shí)現(xiàn)方法。把死板的課本知識(shí)變得生動(dòng)有趣,激發(fā)了學(xué)習(xí)的積極性。把學(xué)過(guò)的計(jì)算機(jī)編譯原理的知識(shí)強(qiáng)化,能夠把課堂上學(xué)的知識(shí)通過(guò)自己設(shè)計(jì)的程序表示出來(lái),加深了對(duì)理論知識(shí)的理解。以前對(duì)與計(jì)算機(jī)操

      copyright

      www.chazidian

      作系統(tǒng)的認(rèn)識(shí)是模糊的,概念上的,現(xiàn)在通過(guò)自己動(dòng)手做實(shí)驗(yàn),從實(shí)踐上認(rèn)識(shí)了操作系統(tǒng)是如何處理命令的,如何協(xié)調(diào)計(jì)算機(jī)內(nèi)部各個(gè)部件運(yùn)行,對(duì)計(jì)算機(jī)編譯原理的認(rèn)識(shí)更加深刻。課程設(shè)計(jì)中程序比較復(fù)雜,在調(diào)試時(shí)應(yīng)該仔細(xì),在程序調(diào)試時(shí),注意指針,將不必要的命令去除。

      在這次課程設(shè)計(jì)中,我就是按照實(shí)驗(yàn)指導(dǎo)的思想來(lái)完成。加深了理解文件系統(tǒng)的內(nèi)部功能及內(nèi)部實(shí)現(xiàn),培養(yǎng)實(shí)踐動(dòng)手能力和程序開(kāi)發(fā)能力的目的。

      下載編譯原理課程設(shè)計(jì)報(bào)告(格式)word格式文檔
      下載編譯原理課程設(shè)計(jì)報(bào)告(格式).doc
      將本文檔下載到自己電腦,方便修改和收藏,請(qǐng)勿使用迅雷等下載。
      點(diǎn)此處下載文檔

      文檔為doc格式


      聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),未作人工編輯處理,也不承擔(dān)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)有涉嫌版權(quán)的內(nèi)容,歡迎發(fā)送郵件至:645879355@qq.com 進(jìn)行舉報(bào),并提供相關(guān)證據(jù),工作人員會(huì)在5個(gè)工作日內(nèi)聯(lián)系你,一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

      相關(guān)范文推薦

        編譯原理課程設(shè)計(jì)要求

        題目:書中任選一文法對(duì)它進(jìn)行LR分析和語(yǔ)義分析(語(yǔ)言不限制)文檔不可少的內(nèi)容: ? 實(shí)現(xiàn)原理 ? 程序流程圖 ? 子函數(shù)說(shuō)明或者類的說(shuō)明 ? 程序代碼及運(yùn)行結(jié)果 ? 心得體會(huì)文檔不少于12頁(yè)......

        99《編譯原理》課程設(shè)計(jì)(最終定稿)

        第 1 頁(yè) 共 3 頁(yè)《編譯原理》課程設(shè)計(jì) 《編譯原理》課程設(shè)計(jì) 一、 課程設(shè)計(jì)的目的 通過(guò)課程設(shè)計(jì),真正掌握設(shè)計(jì)和構(gòu)造編譯程序的基本原理和常用的編譯技術(shù),具備系統(tǒng)軟件調(diào)試能......

        編譯原理課程設(shè)計(jì)教案

        黃岡師范學(xué)院 《編譯原理課程設(shè)計(jì)》教案 (2011·春) 授 課 教 師: 張 瑞 紅 授 課 班 級(jí): 計(jì)科2008級(jí) 授 課 時(shí) 間: 2010-2011 二 課題一 有限自動(dòng)機(jī)的運(yùn)行 一、設(shè)計(jì)題目:有限......

        編譯原理課程設(shè)計(jì)心得體會(huì)

        編譯原理課程設(shè)計(jì)心得體會(huì) 經(jīng)過(guò)一個(gè)星期的編譯原理課程設(shè)計(jì),本人在劉貞老師的指導(dǎo)下,順利完成該課程設(shè)計(jì)。通過(guò)該課程設(shè)計(jì),收獲頗多。一、對(duì)實(shí)驗(yàn)原理有更深的理解通過(guò)該課程......

        《編譯原理》課程設(shè)計(jì)要求

        《編譯原理》課程設(shè)計(jì)實(shí)施方案 課程設(shè)計(jì)的具體內(nèi)容以傳至QQ群共享《編譯原理課程設(shè)計(jì)具體內(nèi)容.ppt》中,由于學(xué)校沒(méi)有足夠大的機(jī)房供我們課程設(shè)計(jì),所以課程設(shè)計(jì)采取單獨(dú)輔導(dǎo)形......

        編譯原理課程設(shè)計(jì)2011級(jí)

        2011級(jí)《編譯原理課程設(shè)計(jì)》任務(wù)書一、課程設(shè)計(jì)的性質(zhì)和目的 編譯原理課程設(shè)計(jì)是計(jì)算機(jī)專業(yè)課程,通過(guò)課程設(shè)計(jì)使學(xué)生進(jìn)一步鞏固課堂所學(xué)知識(shí),全面熟悉、掌握編譯程序編寫的基......

        編譯原理課程設(shè)計(jì)任務(wù)

        編譯原理課程設(shè)計(jì)任務(wù)1設(shè)計(jì)報(bào)告的規(guī)范和要求 設(shè)計(jì)任務(wù)完成后寫出實(shí)踐報(bào)告。實(shí)踐報(bào)告包括程序設(shè)計(jì)時(shí)考慮的算法和方法;調(diào)試過(guò)程中出現(xiàn)的問(wèn)題和解決的措施;打印出程序清單和調(diào)試......

        編譯原理課程設(shè)計(jì)大綱

        《編譯原理》課程設(shè)計(jì)大綱《編譯原理》課程設(shè)計(jì)指導(dǎo)書一、課程設(shè)計(jì)的目的 編譯原理課程兼有很強(qiáng)的理論性和實(shí)踐性,是計(jì)算機(jī)專業(yè)的一門非常重要的專業(yè)基礎(chǔ)課程,它在系統(tǒng)軟件中......