📄 term.h
字号:
#ifndef TERM_H__
#define TERM_H__
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string>
#include <sstream>
#include <iostream>
#include <stdexcept>
#include "IoUtils.h"
using namespace std;
/* 异常类, 在客户端调用了错误的操作时被抛出
*/
class operation_infeasible : public std::runtime_error {
public:
/* 构造函数
*/
explicit operation_infeasible(const string& what_arg)
: runtime_error(what_arg) {}
/* 析构函数
*/
virtual ~operation_infeasible()
{}
}; // operation_infeasible
/* 本文件中定义了表达式的各个项
* 以及这些项的访问器
*/
class Term; // 表达式项
class Operator; // 运算符
class Operand; // 操作数
class Variable; // 变量
class Number; // 数值
class TermVisitor { // 表达式项的访问器
public:
/* 访问Operator
*/
virtual
void visitOperator(Operator &) = 0;
/* 访问Operand
*/
virtual
void visitOperand(Operand &) = 0;
/* 访问Variable
*/
virtual
void visitVariable(Variable &) = 0;
/* 访问Number
*/
virtual
void visitNumber(Number &) = 0;
}; // TermVisitor
class Term { // 表达式项
public:
/*查询该表达式项的字符串表述
*/
virtual
string toString() const = 0;
/* 接受访问
*/
virtual
void accept(TermVisitor &) = 0;
}; // Term
class Operand : public Term { // 操作数
public:
/* 查询该操作数的值
*/
virtual
double getValue() = 0;
/* 接受访问
*/
virtual
void accept(TermVisitor &v) {
v.visitOperand(*this);
} // accept
};
class Variable : public Operand { // 变量
private:
string name_; // 变量名
double value_; // 变量值 (需要时从cin读取)
bool gotValue_; // 变量值是否已经读取
public:
/* 构造函数
*/
explicit Variable(string name)
: name_(name), gotValue_(false) {} // Variable(string)
/*查询该表达式项的字符串表述
*/
virtual
string toString() const {
return name_;
} // toString()
/* 查询该操作数的值
* 若尚未读取, 立刻从cin读入
*/
virtual
double getValue() {
if (!gotValue_) {
cout << "输入变量" << name_ << "的值: ";
value_ = getDouble();
gotValue_ = true;
}
return value_;
} // getValue()
/* 接受访问
*/
virtual
void accept(TermVisitor &v) {
v.visitVariable(*this);
} // accept
}; // Variable
class Number : public Operand { // 数值
private:
double value_;
public:
/* 构造函数
*/
explicit Number(double val)
: value_(val) {} // Number(double)
/*查询该表达式项的字符串表述
*/
virtual
string toString() const {
stringstream buf;
buf << value_;
return buf.str();
} // toString()
/* 接受访问
*/
virtual
void accept(TermVisitor &v) {
v.visitNumber(*this);
} // accept
/* 查询该操作数的值
*/
virtual
double getValue() {
return value_;
}
}; // Number
class Operator : public Term { // 运算符
private:
char o_; // 运算符的值
int prec_; // 运算符的优先级
public:
/* 运算符的名称
*/
enum Optr {
Add = '+', Sub = '-',
Mul = '*', Div = '/',
Pow = '^',
LP = '(', RP = ')',
End = ';',
};
/* 构造函数
* 如果参数不是一个运算符, 抛出std::invalid_argument异常
*/
explicit Operator(char o)
: o_(o) {
prec_ = precedenceOf(o_);
if (prec_ == 0) {
stringstream buf;
buf << "Operator: Invalid argument\n"
<< "\tOperation: Operator(char)"
<< "\tArgument: " << o_
<< endl;
throw std::invalid_argument(buf.str());
}
} // Operator(char)
/* 查询Operator的值
*/
Optr value() const {
return Optr(o_);
} // value()
/* 求op1和op2作用于该Operator后的结果
* 对于不支持本操作的Optr, 抛出operation_infeasible异常
* 如果除法分母为0 或者 乘方op1为0, op2<0, 抛出std::overflow_error异常
*/
double eval(double op1, double op2) const {
double result = 0;
switch ( value() ) {
case Add: // 加
result = op1 + op2;
break;
case Sub: // 减
result = op1 - op2;
break;
case Mul: // 乘
result = op1 * op2;
break;
case Div: // 除
if (op2 == 0) {
throw std::overflow_error("Operator: Devide by zero!\n"
"\tOperation: eval(double, double)\n");
}
result = op1 / op2;
break;
case Pow: // 乘
if (op1 == 0.0 && op2 < 0) {
throw std::overflow_error("Operator: Pow error!\n"
"\tReason: x^y is invalid when x==0.0 and y<0\n"
"\tOperation: eval(double, double)\n");
}
result = pow(op1, op2);
break;
default: // 不支持本操作
stringstream buf;
buf << "Operator: Operation infeasible!\n"
<< "\tOperation: eval(double, double)\n"
<< "\tOperator value: " << o_
<< endl;
throw operation_infeasible( buf.str() );
break;
}
return result;
}
/* 查询Operator的优先级
*/
int prec() const {
return prec_;
} // prec()
/*查询该表达式项的字符串表述
*/
virtual
string toString() const {
stringstream buf;
buf << o_;
return buf.str();
} // toString()
/* 接受访问
*/
virtual
void accept(TermVisitor &v) {
v.visitOperator(*this);
} // accept
/* 查询运算符c的优先级, 优先级高(数值大)的先运算,
* 如果不是运算符返回0
*/
static
int precedenceOf(char c) {
int prec;
switch (Optr(c)) {
case LP: case RP: // 左右括号及结束符
case End:
prec = 1; // 对左括号有一定意义, 对右括号和结束符没什么意义
break;
case Add: case Sub: // 加减
prec = 2;
break;
case Mul: case Div: // 乘除
prec = 3;
break;
case Pow: // 乘方
prec = 4;
break;
default: // 不是运算符
prec = 0;
break;
}
return prec;
} // precedence(char)
/* 查询c是否为运算符
*/
static
bool isOperator(char c) {
return precedenceOf(c) != 0;
} // isOperator(char)
}; // Operator
#endif // TERM_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -