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

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

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

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

 

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

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

image

 

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);             //从文件中加载内容到符号表和变量表中
  };
posted @ 2015-02-11 23:43  Ljian1992  阅读(520)  评论(0编辑  收藏  举报