• 表达式计算器类的设计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();                         //根据解析到的命令执行命令   
     
    };
  • 相关阅读:
    第八周编程总结
    第五周课程总结&试验报告(三)
    第四周课程总结&试验报告(二)
    第三周课程总结&实验报告一
    2019春总结作业
    第一次随笔
    我人生中影响最大的三位老师
    第十二周作业
    第十一周编程总结
    第十周作业
  • 原文地址:https://www.cnblogs.com/Ljian1992/p/4292291.html
Copyright © 2020-2023  润新知