zoukankan      html  css  js  c++  java
  • 表达式计算器类的设计3(面向对象的表达式计算器6)

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

    概述

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

    Scanner类,Parser类,CommandParser类的设计

    Scanner类

    enum EToken {
        TOKEN_COMMAND,
        TOKEN_ERROR,                 
        TOKEN_END,                   
        TOKEN_NUMBER,               
        TOKEN_IDENTIFIER,            
        TOKEN_PLUS,             
        TOKEN_MINUS, 
        TOKEN_MUTIPLY,
        TOKEN_DIVIDE, 
        TOKEN_LPARENTHESIS, 
        TOKEN_RPARENTHESIS,
        TOKEN_ASSIGN,
    };   class Scanner
    {
    private:
        std::istream& in_;                 //标准输入流
        bool isEmpty_;                     //是否为空
        EToken token_;                     //记录扫描结果
        double number_;                    //扫描到的数字
        std::string symbol_;               //扫描到标识符
        int look_;                         //扫描到的字符
        void ReadChar();                   //从标准输入流中读取字符
      public:
        explicit Scanner(std::istream& in);
        void Accept();                     //扫描一个标识符or操作数or操作数
        void AcceptCommand();              //扫描命令
        void CleanIstream();               //清除标准输入流缓存
        double Number() const;             //获取扫描到的数字
        bool IsEmpty()const;               //判断是否为空
        bool IsDone() const;               //判断是否扫描完毕
        bool IsCommand() const;            //判断是否是命令
        std::string GetSymbol() const;     //获取扫描到的标识符
        EToken Token() const;              //获取扫描结果
        
    };

     

    Parser类

    enum STATUS
    {
        STATUS_OK,
        STATUS_ERROR,
        STATUS_QUIT,
    };     class Parser
    {
    private:
        Scanner& scanner_;         
        std::auto_ptr<Node> tree_;           //表达式语法树
        STATUS status_;                      //状态
        Calc &calc_;                         //要处理的符号信息
      public:
        Parser(Scanner& scanner, Calc& calc);   /*与scanner类相关联*/
        ~Parser();
        STATUS Parse();                         //解析一个表达式生成表达式树
        std::auto_ptr<Node> Expr();             //解析表达式
        std::auto_ptr<Node> Term();             //解析项
        std::auto_ptr<Node> Factor();           //解析因子
        double Calculate() const;               //计算出表达式的值
      };

    CommandParser类

    class CommandParser
    {
    private:
        enum Ecommand   //由于该宏只会在CommandParser类内部用到,故定义在内部
        {
            CMD_HELP,
            CMD_QUIT,
            CMD_VAR,
            CMD_FUN,
            CMD_LOAD,
            CMD_SAVE,
            CMD_ERROR,
        };
    private:
        Scanner& scanner_;
        Calc &calc_;
        ECommand cmd_;                           //解析到的命令
        std::string cmdName_;                    //命令名
      void Help() const;                       //帮助命令
        void ListVar() const;                    //打印出变量表
        void ListFun() const;                    //打印出函数表
        STATUS Load(const std::string& fileName);//从文件中加载内容到变量表和函数表中
        STATUS Save(const std::string& fileName);//存储变量表和函数表到文件中
      public:
        CommandParser(Scanner& scanner, Calc& calc_);   /*与scanner类相关联*/
        STATUS Execute();                         //根据解析到的命令执行命令   
     
    };
  • 相关阅读:
    最近出现很多数据库被攻击案例,在数据库中的文本型字段中加入了script代码
    深入线程,实现自定义的SynchronizationContext
    云计算 (转载)
    VS 2008和.NET 3.5 Beta2新特性介绍(转载)
    js对文字进行编码涉及3个函数
    Sharepoint,MOSS,多语言Webpart (.net2.0)
    Silverlight Toolkit
    Silverlight 2.0正式版下周发布
    搭建Silverlight2.0开发环境(转载)
    如何通过使用 SQL Server 中的 Detach 和 Attach 函数将 SQL Server 数据库移到新位置
  • 原文地址:https://www.cnblogs.com/Ljian1992/p/4292291.html
Copyright © 2011-2022 走看看