函數繪圖語言解釋器


一、實驗目的

通過做上機題加深對編譯器構造原理和方法的理解,鞏固所學知識。

<1> 會用正規式和產生式設計簡單語言的語法;

<2> 會用遞歸下降子程序編寫編譯器或解釋器;

<3> 會寫上機報告。

二、實驗環境

Dev C++ 5.11

三、題目及要求

為函數繪圖語言編寫一個解釋器,解釋器接受用繪圖語言編寫的源程序,經語法和語義分析之后,將源程序所規定的圖形顯示在顯示屏(或窗口)中。通過自己動手編寫解釋器,掌握語言翻譯特別是語言識別的基本方法。

四、實驗內容

1、詞法分析器的構造

步驟:正規式-NFADFA-最小DFA-編寫程序-測試

1.1 記號的設計

<1> 詞法分析器的三個任務:

1.濾掉源程序中的無用成分;

2.輸出記號供語法分析器使用;

3.識別非法輸入,並將其標記為“出錯記號”。

<2> 記號的組成:記號的類別和屬性。

<3> 記號的數據結構:

struct Token // 記號的數據結構

{ Token_Type  type; // 類別

char * lexeme; // 屬性,原始輸入的字符串

double value; // 屬性,若記號是常數則是常數的值

double (* FuncPtr)(double);

// 屬性,若記號是函數則是函數指針

};

<4> 函數繪圖語言中記號的分類與表示

enum Token_Type   // 記號的類別,共22

{ ORIGIN, SCALE, ROT, IS,   // 保留字(一字一碼)

TO, STEP, DRAW,FOR, FROM, // 保留字

T,   // 參數

SEMICO, L_BRACKET, R_BRACKET, COMMA,// 分隔符

PLUS, MINUS, MUL, DIV, POWER, // 運算符

FUNC,   // 函數(調用)

CONST_ID,   // 常數

NONTOKEN,   // 空記號(源程序結束)

ERRTOKEN   // 出錯記號(非法輸入)

};

1.2 模式的正規式表示

1.3 區分記號的符號表

2、語法分析器的構造

2.1 語法分析器的任務:分析語言的結構

1)為句子(表達式)構造語法樹;

2)檢查程序(語句)中的語法錯誤。

2.2 主要工作:

1)設計函數繪圖語言的文法,使其適合遞歸下降分析;

2)設計語法樹的節點,用於存放表達式的語法樹;

3)設計遞歸下降子程序,分析句子並構造表達式的語法樹;

4)設計測試程序和測試用例,檢驗分析器是否正確。

2.3 函數繪圖語言的文法
<1> 文法

Program   → ε| Program Statement SEMICO

Statement →  OriginStatment | ScaleStatment

        |  RotStatment    | ForStatment

OriginStatment ORIGIN IS

L_BRACKET Expression COMMA Expression R_BRACKET

ScaleStatment  SCALE IS

L_BRACKET Expression COMMA Expression R_BRACKET

RotStatment ROT IS Expression

<2> 改寫文法為無二義文法

<3> 消除左遞歸和提取左因子

消除program產生式的左遞歸

Program    Program Statement SEMICO |ε

Program   → ε Program

Program’ →  Statement SEMICO Program|ε

Program  Statement SEMICO Program |ε

<4> 改寫左結合的產生式為EBNF形式(避免子程序調用)

改寫為EBNF形式,以減少不必要的子程序調用。

Program  { Statement SEMICO }的子程序:

void Program()

{  while (token != NONTOKEN)

   { Statement(); MathchToken(SEMICO); }

}

3、語法制導翻譯繪制圖形

3.1 繪圖語言的語義

1)表達式值的計算:深度優先后序遍歷語法樹

2)圖形的繪制:畫出每個坐標點

3.2 繪圖所需的語義處理:

1)從originrotscale中得到坐標變換所需的信息;

2for_draw語句根據t的每一個值進行如下處理:

計算被繪制點的橫、縱坐標值;

根據坐標變換信息進行坐標變換,得到實際坐標;

根據點的實際坐標畫出該點。

3.3 語法制導翻譯的基本步驟

1)為文法符號設計屬性;

2)設計語義規則中所需的輔助函數;

3)為產生式設計語義規則。

3.4 語義函數的設計

<1> 全程變量:

double Parameter=0;     // 為參數T分配的變量

double Origin_x=0.0, Origin_y=0.0;// 用於記錄平移距離

double Rot_ang=0.0;     // 用於記錄旋轉角度

double Scale_x=1, Scale_y=1;     // 用於記錄比例因子

<2> 輔助語義函數

a) 計算表達式的值:深度優先后序遍歷語法樹

   double GetExprValue(struct ExprNode * root);

b) 計算點的坐標值:首先獲取坐標值,然后進行坐標變換

static void CalcCoord( struct ExprNode * x_nptr,

  struct ExprNode * y_nptr,

  double &x_val,

  double &y_val);

c) 繪制一個點(與環境有關):

void DrawPixel(unsigned long x, unsigned long y);

d) 循環繪制所有的點:

void DrawLoop(  double Start,

 double End,

    double Step,

    struct ExprNode * HorPtr,

    struct ExprNode * VerPtr);

4、解釋器的源程序組織(看實際環境)

一、心得體會

  C++C的發展不僅是提供了對面向對象方法的支持,還擴展了常量定義、類屬機制、異常處理,等等;靈活利用C++提供的機制可提高程序的可讀性與可維護性;低層次的語言支持機制,可以給程序員以更大的靈活性,並產生更高效的目標代碼;

    通過編譯原理的實驗,在自已動手體驗的情況下,我們更加透徹地理解了詞法分析的過程以及該算法。對於以后由模型向程序代碼的轉化能力上,有了很大的鍛煉。我們會更加專心的研究計算機知識,不斷將現實中遇到的實際問題,向程序方面轉變,做到靈活運用所學知識。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM