Interpreter For Functional Painting Language
西電 編譯原理大作業
Github地址:https://github.com/izcat/Interpreter4FPL
本項目已同步更新在Github主頁上,具體代碼實現不在此贅述。相關原理及參考資料請移步百度或見項目參考文件。
實驗目的
實現函數繪圖語言的解釋器,通過實驗加深對編譯器構造原理和方法的理解,鞏固所學知識。
- 會用正規式設計簡單語言的詞法;
- 會用產生式設計簡單語言的語法;
- 會用遞歸下降子程序編寫語言的解釋器。
實驗要求
語句原則:
- 各類語句可以按任意次序書寫,且語句以分號結尾。源程序中的語句以它們出現的先后順序處理。
- ORIGIN、ROT和SCALE 語句只影響其后的繪圖語句,且遵循最后出現的語句有效的原則。
例如,若有下述ROT語句序列:
ROT IS 0.7 ;
ROT IS 1.57 ;
則隨后的繪圖語句將按1.57而不是0.7弧度旋轉。 - 無論ORIGIN、ROT和SCALE語句的出現順序如何,圖形的變換順序總是:比例變換→旋轉變換→平移變換
- 語言對大小寫不敏感,例如for、For、FOR等,均被認為是同一個保留字。
- 語句中表達式的值均為雙精度類型,旋轉角度單位為弧度且為逆時針旋轉,平移單位為點。
循環繪圖(FOR-DRAW )語句
語法:FOR T FROM 起點 TO 終點 STEP 步長 DRAW(橫坐標, 縱坐標);
語義:令T從起點到終點、每次改變一個步長,繪制出由(橫坐標,縱坐標)所規定的點的軌跡。
舉例:FOR T FROM 0 TO 2*PI STEP PI/50 DRAW (cos(T), sin(T));
說明:該語句的作用是令T從0到2*PI、步長 PI/50,繪制出各個點的坐標(cos(T),sin(T)),即一個單位圓。
比例設置(SCALE)語句
語法:SCALE IS (橫坐標比例因子,縱坐標比例因子);
語義:設置橫坐標和縱坐標的比例,並分別按照比例因子進行縮放。
舉例:SCALE IS (100, 100);
說明:將橫坐標和縱坐標的比例設置為1:1,且放大100倍。
比例設置(SCALE)語句
語法:SCALE IS (橫坐標比例因子,縱坐標比例因子);
語義:設置橫坐標和縱坐標的比例,並分別按照比例因子進行縮放。
舉例:SCALE IS (100, 100);
說明:將橫坐標和縱坐標的比例設置為1:1,且放大100倍。
坐標平移(ORIGIN)語句
語法:ORIGIN IS (橫坐標,縱坐標);
語義:將坐標系的原點平移到橫坐標和縱坐標規定的點處。
舉例:ORIGIN IS (360, 240);
說明:將原點從(0, 0)平移到(360, 240) 處
角度旋轉(ROT)語句
語法:ROT IS 角度;
語義:逆時針旋轉角度所規定的弧度值。具體計算公式:
旋轉后X=旋轉前XCOS(角度)+旋轉前YSIN(角度)
旋轉后Y=旋轉前YCOS(角度)-旋轉前XSIN(角度)
舉例:ROT IS PI/2;
說明:逆時針旋轉PI/2,即逆時針旋轉90度。
注釋語句
作用:便於理解;
屏蔽暫時不需要的語句。
語法:// This is a comment line
或 -- 此行是注釋
語義:// 或 -- 之后,直到行尾,均是注釋
實驗過程
Version 1
代碼詳見 https://github.com/izcat/Interpreter4FPL/tree/master/version1
完成詞法分析
詞法分析器功能
- 輸入:函數繪圖語言源程序,以字符串形式傳遞給
Lexer
參數 - 輸出:返回源程序進行詞法分析得到的全部 Token,類型為列表
Update:
此版本 Lexer
會無法正確識別帶小數點的浮點數!在version2中的 Lexer
才是正確寫法!
Version 2
代碼詳見 https://github.com/izcat/Interpreter4FPL/tree/master/version2
已實現實驗要求的函數繪圖語言的全部功能
解釋器執行的第一個程序結果(顯示 'OK' 字樣):
修復Bug
由於新加入主界面的模塊 main.py
無法正常 import 寫好的 parser
模塊,因為會與 Python 的同名庫沖突。
將全部模塊改名,加上'my'前綴
不足
詞法分析器與語義分析器沒有完全分離,本解釋器在語法分析階段,未生成源代碼的整體語法樹,直接將繪制的點信息交給painter處理
缺少異常處理機制
沒有完全面向對象開發
Version 3
代碼詳見 https://github.com/izcat/Interpreter4FPL/tree/master/version3
本次版本不涉及代碼修復和功能修改,version2可以正常運行標准繪圖源程序
在完成作業要求的基礎上,本次更新增加了自定義顏色的語法
即
FOR T FROM T_start TO T_end STEP T_step DRAW (Point_x, Point_Y)
[OF (RED|GREEN|BLUE|YELLOW|BLACK)]
更改內容如下
mylexer
模塊新增記號類別TokenType
: OF,RED,GREEN,BLUE,YELLOW, BLACKmylexer
模塊新增字符與記號的字典映射TokenTypeDict
:- OF = Token(TokenType.OF, "OF")
- RED = Token(TokenType.COLOR, "RED")
- GREEN = Token(TokenType.COLOR, "GREEN")
- BLUE = Token(TokenType.COLOR, "BLUE")
- YELLOW = Token(TokenType.COLOR, "YELLOW")
- BLACK = Token(TokenType.COLOR, "BLACK")
myparser
模塊作少量改動,ForStatement
方法新增顏色識別語句,將獲取顏色結果傳給Painter
mypainter
模塊內的paint
方法- plt.plot(Painter.Points['X'], Painter.Points['Y'], '.'+Draw_color)
- 參考自 https://blog.csdn.net/qiurisiyu2016/article/details/80187177
- 第三個參數 'r', 'g', 'b', 'k'(Black),'y'(Yellow)
- '.' 點標記 ',' 像素點
Version 4
代碼詳見 https://github.com/izcat/Interpreter4FPL/tree/master/version4
改進內容:
- 在version3的基礎上,分離語法分析器
myparser
模塊與語義分析器mypainter
模塊 - 重新設計了語法分析過程中的運行提示,增加了層級level參數,使遞歸調用的輸出信息更友好
- 重寫了
mypainter
模塊,改用面向對象方式Painter
類 接收繪圖源程序代碼,調用語法分析器myparser.Parser
- 將獲取到的語法樹交給
analyse
方法進行語義分析 - 語義分析完成后,
showPic
執行繪圖
- 改進
main
程序入口模塊,增加了打開文件選項,可以直接選擇寫好繪圖源程序打開
結果展示