zoukankan      html  css  js  c++  java
  • <编译原理

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

    背景

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

    • 设计思路:

      • 将语法分析器并入绘图功能

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

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

      • semanticfunc.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 !
    ")
            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):

  • 相关阅读:
    如何使用SQL语句 查看存储过程的内容
    sl第一篇
    winForm连接数据库(sqlserver2005)
    Format
    dual使用
    ThreadLocal与事务
    oracle中的常用函数
    Oracle中merge into的使用
    API设计中token的思路
    SVN常用功能
  • 原文地址:https://www.cnblogs.com/ymjun/p/12006048.html
Copyright © 2011-2022 走看看