码迷,mamicode.com
首页 > 编程语言 > 详细

<编译原理 - 函数绘图语言解释器(3)解释器 - python>

时间:2019-12-08 17:40:38      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:ota   raw   偏移量   scanner   rms   重写   sub   origin   step   

<编译原理 - 函数绘图语言解释器(3)解释器 - python>

背景

  • 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现

  • 设计思路:
    • 将语法分析器并入绘图功能

    • 继承语法分析器覆盖重写

  • 用Pycharm写了一个.py文件:
    • parserclass.py

    • 输入流是语法分析器得到的语法树,输出流是绘制的图像

    • 测试文本序列:

//----------------测试程序1:分别测试------------------------
ORIGIN IS (100,300);                        // Sets the offset of the origin
ROT IS 0;                                   // Set rotation Angle.
SCALE IS (1,1);                             // Set the abscissa and ordinate scale.
FOR T FROM 0 TO 200 STEP 1 DRAW (T,0);      // The trajectory of the x-coordinate.
FOR T FROM 0 TO 150 STEP 1 DRAW (0,-T);     // The trajectory of the y-coordinate.
FOR T FROM 0 TO 120 STEP 1 DRAW (T,-T);     // The trajectory of the function f[t]=t.
FOR T FROM 0 TO 2*PI STEP PI/50 DRAW(COS(T),SIN(T));
//---------测试程序2----------
ORIGIN IS (20, 200);
ROT IS 0;
SCALE IS (40, 40);
FOR T FROM 0 TO 2*PI STEP PI/50 DRAW (T, -SIN(T));
ORIGIN IS (20, 240);
FOR T FROM 0 TO 2*PI STEP PI/50 DRAW (T, -SIN(T));
ORIGIN IS (20, 280);
FOR T FROM 0 TO 2*PI STEP PI/50 DRAW (T, -SIN(T));
//-----------------测试程序3--------------
ORIGIN IS (380, 240);
SCALE IS (80, 80/3);
ROT IS PI/2+0*PI/3 ;
FOR T FROM -PI TO PI STEP PI/50 DRAW (COS(T), SIN(T));
ROT IS PI/2+2*PI/3;
FOR T FROM -PI TO PI STEP PI/50 DRAW (COS(T), SIN(T));
ROT IS PI/2-2*PI/3;
FOR T FROM -PI TO PI STEP PI/50 DRAW (COS(T), SIN(T));
//-------------------测试程序4-------------
ORIGIN IS(580, 240);
SCALE IS (80, 80);
ROT IS 0;
FOR T FROM 0 TO 2*PI STEP PI/50 DRAW(COS(T),SIN(T));
FOR T FROM 0 TO PI*20 STEP PI/50 DRAW((1-1/(10/7))*COS(T)+1/(10/7)*COS(-T*((10/7)-1)),(1-1/(10/7))*SIN(T)+1/(10/7)*SIN(-T*((10/7)-1)));
//-------------------测试程序5------------
//------------ 函数复杂度图形:-----------
ROT IS 0;   -- 不旋转
ORIGIN IS (50, 400);    -- 设置新原点(距系统默认原点的偏移量)
SCALE IS (2,1); -- 设置比例
FOR T FROM 0 TO 300 STEP 1 DRAW (T,0);  -- 横坐标
FOR T FROM 0 TO 300 STEP 1 DRAW (0,-T); -- 纵坐标
SCALE IS (2,1); -- 设置比例
FOR T FROM 0 TO 300 STEP 1 DRAW (T,-T); -- 函数F(T)=T的轨迹
SCALE IS (2,0.1);   -- 设置比例
FOR T FROM 0 TO 55 STEP 1 DRAW (T,-T*T);    -- 函数F(T)=T*T的轨迹
SCALE IS (10,5);    -- 设置比例
FOR T FROM 0 TO 60 STEP 1 DRAW (T,-SQRT(T));    -- 函数F(T)=SQRT(T)的轨迹
SCALE IS (20,0.1);  -- 设置比例
FOR T FROM 0 TO 8 STEP 0.1 DRAW (T,-EXP(T));    -- 函数F(T)=EXP(T)的轨迹
SCALE IS (2,20);    -- 设置比例
FOR T FROM 0 TO 300 STEP 1 DRAW (T,-LN(T)); -- 函数F(T)=LN(T)的轨迹

Step 1 :semanticfunc.py - 继承语法分析器并入绘制功能

#!/usr/bin/env python
# encoding: utf-8
    '''
@author: 黄龙士
@license: (C) Copyright 2019-2021,China.
@contact: iym070010@163.com
@software: xxxxxxx
@file: semanticfunc.py.py
@time: 2019/11/30 10:47
@desc:
    '''

import parserfunc as pf
import scannerclass as sc
import numpy as np
import turtle
import sys
import matplotlib
import matplotlib.pyplot as plt

class semantic(pf.Parsef):
    def initPaint(self):    # 初始化画布
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111)

    def Errmsg(self):   #出错处理
        sys.exit(1)

    def CalcCoord(self,x,y):    # 计算点坐标   即比例旋转平移变换 x,y都是二元组
        x = x * self.Scale_x
        y = y * self.Scale_y     ## 进行比例变换
        tmp_x = x * np.cos(self.Rot_angle) + y * np.sin(self.Rot_angle)
        y = y * np.cos(self.Rot_angle) - x * np.sin(self.Rot_angle)
        x= tmp_x        ## 旋转变换
        x = x + self.Origin_x
        y = y + self.Origin_y   ## 进行平移变换
        return x,y


    def DrawLoop(self):
        x,y = self.CalcCoord(self.x_ptr,self.y_ptr)
        self.ax.scatter(x,y)


    def Statement(self):    ## 重写statement ,让每次ForStatement执行完毕后画图
        self.enter("Statement")
        if self.token.type == sc.Token_Type.ORIGIN:
            self.OriginStatement()
        elif self.token.type == sc.Token_Type.SCALE:
            self.ScaleStatement()
        elif self.token.type == sc.Token_Type.ROT:
            self.RotStatement()
        elif self.token.type == sc.Token_Type.FOR:
            self.ForStatement()
            self.DrawLoop()
        # elif self.token.type == sc.Token_Type.CONST_ID or self.token.type == sc.Token_Type.L_BRACKET or         #     self.Expression()
        else:   self.SyntaxError(2)
        self.back("Statement")

    # 绘图语言解释器入口(与主程序的外部接口)
    def Parser(self):  # 语法分析器的入口
        self.enter("Parser")
        if (self.scanner.fp == None):  # 初始化词法分析器
            print("Open Source File Error !\n")
        else:
            self.FetchToken()  # 获取第一个记号
            self.Program()  # 递归下降分析
            plt.show()
            self.scanner.CloseScanner()  # 关闭词法分析器
            self.back("Parser")

Step 2 :semanticmain.py - 解释器主函数入口

#!/usr/bin/env python
# encoding: utf-8
'''
@author: 黄龙士
@license: (C) Copyright 2019-2021,China.
@contact: iym070010@163.com
@software: xxxxxxx
@file: parsermain.py
@time: 2019/11/26 22:31
@desc:
'''

import scannerfunc as sf
# import parserfunc as pf
import semanticfunc as paint
import os

file_name = 'test.txt'
scanner = sf.scanner(file_name)
semantic = paint.semantic(scanner)
semantic.initPaint()
semantic.Parser()
# parser = pf.Parsef(scanner)
# parser.Parser()

# os.system("pause")

实现结果

  • 对于测试程序(1):

技术图片

  • 对于测试程序(2):

技术图片

  • 对于测试程序(3):

技术图片

  • 对于测试程序(4):

技术图片

  • 对于测试程序(5):

技术图片

<编译原理 - 函数绘图语言解释器(3)解释器 - python>

标签:ota   raw   偏移量   scanner   rms   重写   sub   origin   step   

原文地址:https://www.cnblogs.com/ymjun/p/12006048.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!