表达式计算器类的设计2(表达式计算器5)

计算器的github下载地址:https://github.com/ljian1992/calculator

符号表,函数表,变量存储表

表达式计算器,需要支持变量和函数,而变量和函数都是些符号,因此设置一个SymbolTable类来存储这些符号。符号有两种,一种是变量,一种是函数,故在设置一个Storage类存储变量中的值,设置一个FunctionTable类来存储函数。由于这三中类存在着联系,现在在设置一个Calc类来管理它们。

SymbolTable类,FunctionTable类,Storage类,Calc类的关系

根据符号表中的符号对应的的ID,在Storage中根据ID找到变量的值,或者是在FunctionTable中根据ID找到相对应得数学函数

SymbolTable类,FunctionTable类,Storage类,Calc类的设计

SymbolTable类
class SymbolTable : public Serializable
{
private:
    std::map<const std::string, unsigned int> dictionary_;  //存储符号与id相对应得关系
    unsigned int curId_;                                    //存储将要加入符号表的符号id
public:
    enum { IDNOTFOUND = 0xFFFFFFFF };                       //IDNOTFOUND代表在符号表中找不到相应的符号
    SymbolTable() : curId_(0) {}
    unsigned int Add(const std::string& str);               //向符号表中加入符号
    unsigned int Find(const std::string& str) const;        //根据符号寻找符号表中是否存储该符号
    unsigned int GetCurId()const;                           //获取下一个的加入符号表的符号id
    void Clear();                                           //清楚符号表
    const std::string &GetSymbolName(unsigned int id) const;//根据id查找并获取符号表中的符号
  virtual void Serialize(Serializer& out) const;          //文件存储
    virtual void DeSerialize(DeSerializer& in);             //文件加载
};    Storage类
class Storage : public Serializable
{
private:
    std::map<unsigned int, double> cells_;        //存储符号表中id与值多对应的关系
  public:
    Storage(SymbolTable& tbl);
    void Clear();                                 //清除数据
    void AddConstants(SymbolTable& tbl);          //增加常量,目前只支持pi e
    double GetValue(unsigned int id) const;       //根据id获得想对于的值
    unsigned int GetSize() const;                 //获取map中有多少个数据
    void SetValue(unsigned int id, double val);   //设置map中的值
    void AddValue(unsigned int id, double val);   //想map中添加值

    virtual void Serialize(Serializer& out) const;//将Storage类中的值存入文件存储
    virtual void DeSerialize(DeSerializer& in);   //将文件中的值加载到Storage类中
};

FunctionTable类   typedef double(*PtrFun)(double);                 //重命名了一种函数指针类
  class FunctionTable
{
private:
    std::map<unsigned int, PtrFun> funsMap_;     //存储符号表中的id与对应的数学函数指针
public:
    FunctionTable(SymbolTable& tbl);
    void Init(SymbolTable& tbl);                 //存储是函数表
    PtrFun GetFunction(unsigned int id) const;   //根据id获取函数表中对应的函数
    unsigned int GetSize() const;                //获得函数表中有多少个函数
   ~FunctionTable();   };

Calc类
class Calc : public Serializable
{
    friend class Parser;          //使到Parser类方便的访问Calc的私有成员
private:
    //由于Storage的构造函数需要用到SymbolTable的引用,故声明顺序SymbolTable在Storage的前面
    SymbolTable symTbl_;
    FunctionTable functionTbl_;   //由于函数表中的函数是固定的,因此把函数表的构造放在符号表的前面
    Storage storage_;             //变量的个数是不固定的
    unsigned int FindSymbol(const std::string& str) const;  //在符号表中查找str符号
    unsigned int AddSymbol(const std::string& str);         //往符号表中添加符号
    Storage& GetStorage();                                  //获取stroage_的引用
    bool IsFunction(unsigned int id) const;                 //判断是否是函数
    PtrFun GetFunction(unsigned int id) const;              //获取函数指针
    double GetVariableValue(unsigned int id) const;         //获取变量的值
public:
    Calc() : symTbl_(), functionTbl_(symTbl_), storage_(symTbl_) {}
    void ListFun() const;                                   //打印函数表
    void ListVariable() const;                              //打印变量表
  virtual void Serialize(Serializer& out) const;          //将函数表和变量表中的内容存储到文件中
    virtual void DeSerialize(DeSerializer& in);             //从文件中加载内容到符号表和变量表中
  };
时间: 2024-12-21 01:34:29

表达式计算器类的设计2(表达式计算器5)的相关文章

表达式计算器类的设计5(面向对象的表达式计算器8)

计算器的github下载地址:https://github.com/ljian1992/calculator 概述 表达式计算器的类基本已经设计完成了,由于在程序运行的时候总会有这样那样的异常,例如:a +2, a没有初始化,对于异常的管理一般而言是需要自定义异常类.这个自定义异常类也是在继承了系统已经定义好的exception类,然后再重新定义内容. 异常的种类 语法异常---->SyntaxError类 赋值时左操作数不是变量:1 = 2; 缺少括号:1 + (2*2 不认识的函数: 函数缺

表达式计算器类的设计4(面向对象的表达式计算器7)

概述 把符号表和变量表中的内容保存到一个文件中,通过IO文件流,来把符号表和变量表存储到文件中.在这之前需要弄明白什么是序列化和反序列化 对象的序列化 序列化:把对象转换为字节序列的过程 反序列化:把字节序列恢复为对象的过程 我们要把SymbolTable类的对象(符号表)和Storage类的对象(变量表)转换成字节序列保存到文件中,这时就可以设置Serializer类来完成这样的功能,同样的设置一个DeSerializer类来完成把保存到文件当中的字节序列恢复为对象的功能.这里要注意的是,所有

表达式计算器类的设计3(面向对象的表达式计算器6)

概述 有了构建语法的类,存储符号的类,现在就可以对表达式进行扫描,解析了.扫描可以抽象出一个Scanner类来完成这一个功能,而解析可以抽象出一个Parser类来完成这一个功能.这两个类存在一定的关系,扫描与解析的互动是这样子的:扫描到一个标识符,然后解析它是什么标识符.由于该表达式计算器是要支持一些命令的,命令的解析和表达式的解析过程完全不一样,所有呢,又要设置一个CommandParser类,来解析命令. Scanner类,Parser类,CommandParser类的设计 Scanner类

表达式计算器类的设计1(表达式计算器4)

计算器的github下载地址:https://github.com/ljian1992/calculator 我们的最终目的是计算出表达式中的值,因此就需要定义一个抽象类用于计算表达式的值,该抽象类定义为:Node 下面所有的类图不使用UML建模语言画的,是通过visual studio自动生成的类关系图(自己用UML建模画的不小心被我删掉了) Node的类图 它继承了个Noncpyable类,由于我们是要做面向对象的表达式计算器,所以呢,通过一个小小的手段,把拷贝给禁止掉.这个小小的手段就是让

使用后缀表达式写的数据结构实验,实现计算器

数据结构实验需要使用后缀表达式进行计算的设计 自己写的可以实现简单的‘+-*/’运算以及包括‘() [] {} 指数 小数 2e3’等的运算,用于交作业,功能很少,代码如下 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <stdbool.h> #include <math.h> //定义操作数的最大位数 #define MAX 64 typedef stru

用antlr4来实现《按编译原理的思路设计的一个计算器》中的计算器

上次在公司内部讲<词法分析--使用正则文法>是一次失败的尝试--上午有十几个人在场,下午就只来了四个听众. 本来我还在构思如何来讲"语法分析"的知识呢,但现在看来已不太可能. 这个课程没有预想中的受欢迎,其原因可能是: 1.课程内容相对复杂,听众知识背景与基础差异比较大. 2.授课技巧不够,不能把复杂的知识简单化的呈现给基础稍差一点的人. 针对这两个可能的原因,我要尝试做出以下调整: 1.使用antlr来实现词法和语法的部分. 2.暂时把"编译"过程改为

《中小学生Python编程入门指南》2.1 设计开发一个计算器

第二章 设计自己的第一个Python应用 1.1 设计开发一个计算器 这一节我们来尝试实现完成一个计算器的应用.毕竟我们是初学者,不可能做得那么完美,也不是真的需要实现,只是想借这一个应用的理解,我们带入一些python的教学和其他的计算机相关知识. 我们先想想,计算器我们需要什么功能?先不想象多么只能的计算器,我们要先实现简单的会加减乘除的就可以了.那么我们就知道了,计算器是要有会加减乘除计算的功能的.那除此之外呢?我们想一下计算的流程,其实就是三个部分组成:①输入.②计算.③输出.好,那我们

条件表达式工具类

internal class ParameterReplacer : ExpressionVisitor { public ParameterReplacer(ParameterExpression paramExpr) { this.ParameterExpression = paramExpr; } public ParameterExpression ParameterExpression { get; private set; } public Expression Replace(Ex

(转载)你好,C++(16)用表达式表达我们的设计意图——4.1 用操作符对数据进行运算

你好,C++(16)用表达式表达我们的设计意图——4.1 用操作符对数据进行运算 第4章    将语句编织成程序 学过C++中的各种数据类型, 就知道如何使用各种数据类型定义变量来描述现实世界中的各种事物了.现在,我们可以将一个工资统计程序大致写成下面这个样子: // 工资统计程序 int main() { // 表示员工个数的常量NUM const int NUM = 100000; // 保存所有工资的数组 int arrSalary[NUM]; // 保存平均工资的变量 float fSa