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

<编译原理 - 函数绘图语言解释器(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: [email protected]
@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: [email protected]
@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):

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

时间: 2024-08-24 11:58:56

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

CI框架源码阅读笔记3 全局函数Common.php

从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap引导文件都会最先引入全局函数,以便于之后的处理工作). 打开Common.php中,第一行代码就非常诡异: if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 上一篇(CI框架源码阅读笔记2 一切的入口 index

IOS测试框架之:athrun的InstrumentDriver源码阅读笔记

athrun的InstrumentDriver源码阅读笔记 作者:唯一 athrun是淘宝的开源测试项目,InstrumentDriver是ios端的实现,之前在公司项目中用过这个框架,没有深入了解,现在回来记录下. 官方介绍:http://code.taobao.org/p/athrun/wiki/instrumentDriver/ 优点:这个框架是对UIAutomation的java实现,在代码提示.用例维护方面比UIAutomation强多了,借junit4的光,我们可以通过junit4的

Yii源码阅读笔记 - 日志组件

?使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category);Yii::trace($message, $category); 两者的区别在于后者依赖于应用开启调试模式,即定义常量YII_DEBUG: defined('YII_DEBUG') or define('YII_DEBUG', true); Yii::log方法的调用需要指定message的level和category.category是格式为“xxx.yyy.z

源码阅读笔记 - 1 MSVC2015中的std::sort

大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格式化,去掉或者展开用于条件编译或者debug检查的宏,依重要程度重新排序函数,但是不会改变命名方式(虽然MSVC的STL命名实在是我不能接受的那种),对于代码块的解释会在代码块前(上面)用注释标明. template<class _RanIt, class _Diff, class _Pr> in

CI框架源码阅读笔记5 基准测试 BenchMark.php

上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功能,各模块之间可以相互调用,共同构成了CI的核心骨架. 从本篇开始,将进一步去分析各组件的实现细节,深入CI核心的黑盒内部(研究之后,其实就应该是白盒了,仅仅对于应用来说,它应该算是黑盒),从而更好的去认识.把握这个框架. 按照惯例,在开始之前,我们贴上CI中不完全的核心组件图: 由于BenchMa

CI框架源码阅读笔记2 一切的入口 index.php

上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里这次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中,我们并不会逐行进行解释,而只解释核心的功能和实现. 1.       设置应用程序环境 define('ENVIRONMENT', 'development'); 这里的development可以是任何你喜欢的环境名称(比如dev,再如test),相对应的,你要在下面的switch case代码块中

Apache Storm源码阅读笔记

欢迎转载,转载请注明出处. 楔子 自从建了Spark交流的QQ群之后,热情加入的同学不少,大家不仅对Spark很热衷对于Storm也是充满好奇.大家都提到一个问题就是有关storm内部实现机理的资料比较少,理解起来非常费劲. 尽管自己也陆续对storm的源码走读发表了一些博文,当时写的时候比较匆忙,有时候衔接的不是太好,此番做了一些整理,主要是针对TridentTopology部分,修改过的内容采用pdf格式发布,方便打印. 文章中有些内容的理解得益于徐明明和fxjwind两位的指点,非常感谢.

CI框架源码阅读笔记4 引导文件CodeIgniter.php

到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.com/usr/reg 经过引导文件,实际上会交给Application中的UsrController控制器的reg方法去处理. 这之中,CodeIgniter.php做了哪些工作?我们一步步来看. 1.    导入预定义常量.框架环境初始化 之前的一篇博客(CI框架源码阅读笔记2 一切的入

jdk源码阅读笔记之java集合框架(二)(ArrayList)

关于ArrayList的分析,会从且仅从其添加(add)与删除(remove)方法入手. ArrayList类定义: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Monaco } span.s1 { color: #931a68 } public class ArrayList<E> extends AbstractList<E> implements List<E> ArrayList基本属性: /** *

dubbo源码阅读笔记--服务调用时序

上接dubbo源码阅读笔记--暴露服务时序,继续梳理服务调用时序,下图右面红线流程. 整理了调用时序图 分为3步,connect,decode,invoke. 连接 AllChannelHandler.connected(Channel) line: 38 HeartbeatHandler.connected(Channel) line: 47 MultiMessageHandler(AbstractChannelHandlerDelegate).connected(Channel) line: