<编译原理 - 函数绘图语言解释器(3)解释器 - python>
<编译原理 - 函数绘图语言解释器(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 !\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>的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- Ubuntu系统下Bazel编译Tensorflow环境
编写此文主要为了介绍在Ubuntu16.04上搭建Tensorflow-lite编译环境,涉及目标硬件为Armv7架构,8核Cortex-A7. 1.开发环境介绍: OS:Ubuntu16.04 64 ...
- 基于FastDFS在SpringBoot上的上传与下载
方法: 1.在application.properties里设置参数,其中tracker-list是tracker的端口 fdfs.so-timeout= fdfs.connect-timeout= ...
- ocvate常用函数
1.生成矩阵相关 https://www.coursera.org/learn/machine-learning/lecture/9fHfl/basic-operations 1. 初始化矩阵 a = ...
- bzoj4165 矩阵 堆维护多路归并
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4165 题解 大概多路归并是最很重要的知识点了吧,近几年考察也挺多的(虽然都是作为签到题的). ...
- java:序列化Serializable 接口
java:序列化Serializable 接口 public class SerializePerson implements Serializable { private String name; ...
- SpringCloud学习系列-Eureka自我保护模式(5)
什么是自我保护模式? 默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒).但是当网络分区故障发生时,微服务与Eur ...
- 【leetcode】522. Longest Uncommon Subsequence II
题目如下: 解题思路:因为given list长度最多是50,我的解法就比较随意了,直接用一个嵌套的循环,判断数组中每个元素是否是其他的subsequence,最后找出不属于任何元素subsequen ...
- delphi datetimetounix 和 unixtodatetime 全平台(FIREMONKEY)时区修正
可能平时在转换UNIX时间时没有注意结果,当转换成UNIX时间后,再转换回来对比发现时间和标准时间差了8个小时.网上有相关的修正方法,但仅适用于WINDOWS平台,以下方法全平台适合. datetim ...
- 14 Spring Boot Shiro限制登录尝试次数
- DI,依赖注入,给对象赋值 ,get,set,list,set,map,properties对象赋值