posts - 134,comments - 22,trackbacks - 0
           

          PL/X編譯器

          軟件設計說明書

           

          1.介紹

          本編譯器可以按照PLX語言語法要求進行詞法、語法、語義、出錯處理,并最終成生目標代碼,通過解釋執行得到最終結果。

          2.編譯器系統結構

          2.1 編譯器

          2.1.1 PL/X語法圖








          擴展部分:

          1) 支持帶參數的函數調用,函數可平行或嵌套定義,只允許內層訪問外層,外層不能訪問內層

          2)支持單行注釋

          3)支持read語句,因此可從終端獲取輸入

          4)支持for語句

          5)支持空程序體

          關于出錯處理:分為詞法分析錯誤、句法分析錯誤、運行時錯誤(如除數為0)

          允許變量名或函數名重復,但訪問的時候以最后一次聲明的為有效

          2.1.2判斷是否符合兩條限制規則

          規則1:找出圖中每一個分支點,考察每個分支點的各個分支的頭符號是否相異

          規則2:找出圖中每一個透明結構,考察每個透明結構的頭符號集合與其跟隨符號是否相異

          判斷結果:根據兩條限制規則,發現該語法圖分析符合兩條限制規則

          2.1.3 過程調用相關圖

          2.1.5 語法出錯表定義

            1switch (errorNum)
            2    {
            3    case 0:
            4        errorInfo="程序需以'.'結束";
            5        break;
            6    case 1:
            7        errorInfo="用了未定義的變量";
            8        break;
            9    case 2:
           10        errorInfo="算術因子里出現非整型變量";
           11        break;
           12    case 3:
           13        errorInfo="丟失')'";
           14        break;
           15    case 4:
           16        errorInfo="算術表示不能以此符號開始";
           17        break;
           18    case 5:
           19        errorInfo="邏輯表達式里出現函數名";
           20        break;
           21    case 6:
           22        errorInfo="邏輯表達式不能以此符號開始";
           23        break;
           24    case 7:
           25        errorInfo="非法的變量名";
           26        break;
           27    case 8:
           28        errorInfo="丟失')'";
           29        break;
           30    case 9:
           31        errorInfo="非法的參數名";
           32        break;
           33    case 10:
           34        errorInfo="丟失begin關鍵字";
           35        break;
           36    case 11:
           37        errorInfo="丟失end關鍵字";
           38        break;
           39    case 12:
           40        errorInfo="開始符號不是program";
           41        break;
           42    case 13:
           43        errorInfo="此處應為整型變量";
           44        break;
           45    case 14:
           46        errorInfo="關系表達式不能以此符號開始";
           47        break;
           48    case 15:
           49        errorInfo="此處應為一個比較符號";
           50        break;
           51    case 16:
           52        errorInfo="丟失';'";
           53        break;
           54    case 17:
           55        errorInfo="語句后出現非法字符";
           56        break;
           57    case 18:
           58        errorInfo="變量定義后出現非法字符";
           59        break;
           60    case 19:
           61        errorInfo="丟失','";
           62        break;
           63    case 20:
           64        errorInfo="變量定義不能以此符號開始";
           65        break;
           66    case 21:
           67        errorInfo="變量定義后出現非法字符";
           68        break;
           69    case 22:
           70        errorInfo="此處應為\":=\"";
           71        break;
           72    case 23:
           73        errorInfo="此處不能為函數名";
           74        break;
           75    case 24:
           76        errorInfo="缺了then";
           77        break;
           78    case 25:
           79        errorInfo="缺了from";
           80        break;
           81    case 26:
           82        errorInfo="缺了do";
           83        break;
           84    case 27:
           85        errorInfo="缺了until";
           86        break;
           87    case 28:
           88        errorInfo="缺了to";
           89        break;
           90    case 29:
           91        errorInfo="此處應為函數名";
           92        break;
           93    case 30:
           94        errorInfo="語句不能以此符號開始";
           95        break;
           96    case 31:
           97        errorInfo="語句后不能跟此符號";
           98        break;
           99    case 32:
          100        errorInfo="算術表達式不能以此符號開始";
          101        break;
          102    case 33:
          103        errorInfo="丟失'('";
          104        break;
          105    case 34:
          106        errorInfo="邏輯表達式后出現非法字符";
          107        break;
          108    case 35:
          109        errorInfo="函數定義后出現非法字符";
          110        break;
          111    case 36:
          112        errorInfo="多余的';'";
          113        break;
          114    case 37:
          115        errorInfo="這里等待一個'*'或'/'";
          116        break;
          117    case 38:
          118        errorInfo="這里等待一個'+'或'-'";
          119        break;
          120    case 39:
          121        errorInfo="參數個數不符";
          122        break;
          123    case 40:
          124        errorInfo="函數定義需以procedure開始";
          125        break;
          126    case 41:
          127        errorInfo="函數定義后出現非法字符";
          128        break;
          129    case 42:
          130        errorInfo="外層不能訪問內層的變量或調用內層函數";
          131        break;
          132    case 43:
          133        errorInfo="除數為0";
          134        break;
          135    }

          136


          2.2 虛擬機

          2.2.1 虛擬機組織結構

          i

          指令寄存器

          Code

          程序存儲器

          s

          數據存儲器

          P

          程序地址寄存器

          b

          基本地址存儲器

          T

          地址寄存器

          2.2.2 虛擬機指令格式

          l      LIT指令,把一個常數置入棧頂

          l      LOD指令,把一個變量置入棧頂

          l      STO指令,從棧頂把數置入到一個變量單元里

          l      CAL指令,調用一個過程

          l      INT指令,預留數據存儲位置

          l      JMP指令,是無條件轉移指令

          l      JPC指令,是有條件轉移指令

          l      OPR指令,一組算術和關系運算指令

          l       ADP指令,傳遞函數參數

          2.2.3虛擬機指令系統及其解釋

          1.LIT 0,a (t++;s[t]=a;)(將數a置入棧頂)

          2.OPR 0,a (a = 0:t = b - 1;p = s[t + 3];b = s[t + 2];)返回調用程序)

                     (a=1:s[t] = -s[t];)(取負)

                       (a=2:t--;s[t] = s[t] + s[t + 1];)(加法)

                       (a=3; t--;s[t] = s[t] - s[t + 1];)(減法)

                       (a=4; t--;s[t] = s[t] * s[t + 1];)(乘法)

                       (a=5: t--;if (s[t + 1] == 0){ 報錯 }else{ s[t] = s[t] / s[t + 1]; })(除法)

                       (a=6; if (s[t] > 0){ s[t] = 0; }else { s[t] = 1; })(邏輯not)

                       (a=7; t--;if (s[t] == s[t + 1]){ s[t] = 1; }else { s[t] = 0; })(等于)

                       (a=8; t--;if (s[t] != s[t + 1]){ s[t] = 1; }else { s[t] = 0; })(不等于)

                       (a=9; t--;if (s[t] < s[t + 1]){ s[t] = 1; }else { s[t] = 0; })(小于)

                       (a=10; t--;if (s[t] >= s[t + 1]){ s[t] = 1; }else { s[t] = 0; })(大于等于)

                       (a=11; t--;if (s[t] > s[t + 1]){ s[t] = 1; }else { s[t] = 0; })(大于)

                       (a=12; t--;if (s[t] <= s[t + 1]){ s[t] = 1; }else { s[t] = 0; })(小于等于)

                       (a=13; t--;if (s[t] != 0 && s[t + 1] != 0){ s[t] = 1; }else { s[t] = 0; })(邏輯and)

                       (a=14; t--;if (s[t] == 0 && s[t + 1] == 0){ s[t] = 0; }else { s[t] = 1; })(邏輯or)

                       (a=15; t--;輸出s[t])(輸出)

                       (a=16;t++;s[t]=輸入)(輸入)

          3. LOD l,a    (t++;s[t] = s[Base(l) + a];)( la形成的棧地址變量置入棧頂)

          4. STO l,a    (s[Base(l) + a] = s[t];t--;)(將棧頂值存到la形成的棧地址變量)

          5. CAL l,a    (s[t + 1] = Base(l);s[t + 2] = b;s[t + 3] = p;b = t + 1;p = a - 1;)[調用子程序
          SL(靜態鏈地址)DL(動態鏈地址)RA(返回地址)]

          6. INT 0,a    (t = t + a;)(預留a個存儲位置); 

          7. JMP 0,a    (p = a - 1;)(無條件跳轉); 

          8. JPC 0,a    (if (s[t] == 0){ p = a - 1; t--; })(條件跳轉);

          9.ADP 0,a (參數壓棧)

          3.全局數據結構、常量和變量

           1//整型,邏輯、函數
           2
           3typedef enum
           4
           5{
           6
           7       aident,bident,pident
           8
           9}
          objectt;
          10
          11//符號表項
          12
          13typedef struct
          14
          15{
          16
          17       alfa      name; //變量名(函數、整型、邏輯型)
          18
          19       objectt   kind; //類型
          20
          21       int       num ; //函數參數個數
          22
          23       int       level; //層級
          24
          25       int       adr ; //偏移量
          26
          27       int       size ; //局部變量+函數參數的大小
          28
          29}
          item;
          30
          31//定義指令格式
          32
          33typedef struct
          34
          35{
          36
          37       fct    f;   //指令碼
          38
          39       int    l;   //層號
          40
          41       int    a;   //偏移量
          42
          43}
          instruction;
          44
          45//定義跟隨符號集合類型
          46
          47typedef set<symbol> symset;
          48
          49typedef vector<instruction> PCODE;
          50
          51


          4.函數原型

           1//begin accidence analyze(詞法分析器)
           2
           3void getCh();
           4
           5void getSym();
           6
           7//end analyze
           8
           9    //語法分析器
          10
          11    void RelationExpression(int level,symset fsys);
          12
          13    void ArithmeticExpression(int level,symset fsys);
          14
          15    void ArithmeticTerm(int level,symset fsys);
          16
          17    void ArithmeticFactor(int level,symset fsys);
          18
          19    void BoolExpression(int level,symset fsys);
          20
          21    void BoolTerm(int level,symset fsys);
          22
          23    void BoolFactor(int level,symset fsys);
          24
          25    void Procedure(int level,symset fsys);
          26
          27    void ProcedureSque(int level,symset fsys);
          28
          29    void Sentence(int level,symset fsys);
          30
          31    void Definition(int level,int &dx,symset fsys);
          32
          33    void SentenceSque(int level,symset fsys);
          34
          35    void DefinitionSque(int level,int &dx,symset fsys);
          36
          37    void Program(symset fsys);
          38
          39       //生成中間代碼
          40
          41    void gen(fct f,int l,int a);
          42
          43    //
          44
          45    //PLX虛擬機
          46
          47    int base(int l);
          48
          49    void plxInterpret();
          50
          51//出錯處理
          52
          53    void error(int errorNum);
          54
          55    void test(symset s1,symset s2,int errorNum);
          56

           

          PL/X編譯器

          軟件測試說明書

           

          測試1

          1. 概述

          u       測試描述:

              通過運行幾個不同的plx實例,來檢查PLX Compiler是否能解析plx語言,進行基本的語法分析,以及出錯的正確報錯、解釋執行等功能。

          u       測試環境:

          Windows XP   VC++6.0

          2. 測試用例描述

           

           1 //find prime number between s to b
           2 
           3 program
           4 
           5 integer s ,b
           6 
           7 begin
           8 
           9 procedure findPrime(integer small,big)
          10 
          11 integer i,j,k,c,t
          12 
          13 begin
          14 
          15        i:=small;
          16 
          17        for i from small to big
          18 
          19        do
          20 
          21               j:=2;
          22 
          23               if(i>=3) then
          24 
          25                      k:=i/2+1;
          26 
          27                      c:=0;
          28 
          29                      for j from 2 to k
          30 
          31                      do
          32 
          33                             if i=(i/j)*j then //由于沒有提供取余運算,只能這樣了~_~
          34 
          35                                    c:=c+1
          36 
          37                             end         
          38 
          39                      end;
          40 
          41                      if c=0 then
          42 
          43                             write i
          44 
          45                      end 
          46 
          47               end
          48 
          49        end
          50 
          51 end
          52 
          53 read s;
          54 
          55 read b;
          56 
          57 call findPrime s b
          58 
          59 end.
          60 

           

          報錯:
           

          修改后運行結果: 
                                             

          中間代碼:

          測試2

          u       測試目標:求兩數的最大公約數

          u       測試用例:

           1program
           2
           3integer a,b;
           4
           5integer temp
           6
           7begin
           8
           9        a:=12;
          10
          11       b:=42;
          12
          13       if a < b
          14
          15       then
          16
          17               temp := a;
          18
          19               a := b;
          20
          21               b := temp
          22
          23       end;
          24
          25        temp := a- a/ b*b;
          26
          27        while temp>0
          28
          29        do
          30
          31                a := b;
          32
          33                b := temp;
          34
          35                temp := a- a/ b*b
          36
          37       end;
          38
          39       temp := b;
          40
          41     if (a = 0 or b = 0)
          42
          43     then
          44
          45        write 0
          46
          47     else
          48
          49       write temp
          50
          51     end
          52
          53end.
          54
          55


          中間代碼:

          結果:

          posted on 2008-05-29 18:26 何克勤 閱讀(1523) 評論(9)  編輯  收藏

          FeedBack:
          # re: PL/X編譯器設計與實現
          2008-12-31 01:36 | susan
          您好,我看了您這份PLX語言編譯器的說明書,很受啟發。我自己也在寫一個PLX的編譯器,和您這個主體、語法結構都非常相似,只在call語句的實現部分有些不同。現在我的程序遇到些問題,請問您方不方便把您的編譯器源代碼發給我參考一下呢?非常感謝!  回復  更多評論
            
          # re: PL/X編譯器設計與實現
          2008-12-31 01:40 | susan
          呃。。留下我的郵箱吧,windmoon_1987@163.com
          麻煩您了。。  回復  更多評論
            
          # re: PL/X編譯器設計與實現
          2009-11-19 16:15 | rainbow
          高手,是ECNU嗎?  回復  更多評論
            
          # re: PL/X編譯器設計與實現
          2009-11-30 19:26 | Saturn
          ecnu 的人 V.S PL/X...,hehe@rainbow
            回復  更多評論
            
          # re: PL/X編譯器設計與實現
          2009-12-27 00:53 | gantian
          哈哈滿世界找到的PL/X都是華師大的~  回復  更多評論
            
          # re: PL/X編譯器設計與實現
          2009-12-28 16:59 | fuck all
          請問你認識靚姐么?  回復  更多評論
            
          # re: PL/X編譯器設計與實現
          2009-12-28 18:50 | 何克勤
          @fuck all
          竇亮?  回復  更多評論
            
          # re: PL/X編譯器設計與實現
          2009-12-30 02:03 | fuck all
          yes就是亮姐!
          haha  回復  更多評論
            
          # re: PL/X編譯器設計與實現[未登錄]
          2010-11-07 15:48 | FRANK WANG
          我擦,果然都是亮姐的。。。  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 绥宁县| 临汾市| 西宁市| 大英县| 永胜县| 丽江市| 汉沽区| 卓尼县| 张家川| 贡山| 沭阳县| 吴忠市| 姜堰市| 吉安市| 博罗县| 罗田县| 峨眉山市| 墨玉县| 夹江县| 聊城市| 合川市| 澄江县| 嘉峪关市| 正安县| 晴隆县| 阿城市| 周口市| 左权县| 怀化市| 石狮市| 霸州市| 新和县| 武清区| 凌源市| 宁夏| 轮台县| 杭锦后旗| 平泉县| 松江区| 确山县| 西峡县|