1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
| 在C++中实现对布尔表达式进行操作和求值。 在这个语言中终结符是布尔变量,即常量true和false。非终结符表示包含运算符and,or和not的布尔表达式。 文法定义如下: BooleanExp ::= VariableExp | Constant | orExp | AndExp | NotExp | '(' BooleanExp ')' AndExp ::= BooleanExp 'and' BooleanExp OrExp ::= BooleanExp 'or' BooleanExp NotExp ::= 'not' BooleanExp Constant ::= 'true' | 'false' VariableExp ::= 'A' | 'B' | ... | 'X' | 'Y' | 'Z' 在这里我们定义布尔表达式上的两个操作。求值和替换。 */ #include <cstring> #include <iostream> #include <unordered_map> class VariableExp;
class Context { public: bool look_up(const char* name) const; void assign(VariableExp* var, bool val); protected: std::unordered_map<const char*, bool> m_inner; };
class BooleanExp { public: BooleanExp(){} virtual ~BooleanExp(){} virtual bool evaluate(Context&) = 0; virtual BooleanExp* replace(const char*, BooleanExp&) = 0; virtual BooleanExp* copy() const = 0; };
class Constant : public BooleanExp { public: Constant(bool val){m_value = val;} virtual bool evaluate(Context& aContext) { return m_value; } virtual BooleanExp* replace(const char* name, BooleanExp& exp) { return exp.copy(); } virtual BooleanExp* copy() const { return new Constant(m_value); } protected: bool m_value; };
class VariableExp : public BooleanExp { public: VariableExp(const char* name) { m_name = strdup(name); } virtual ~VariableExp(){} const char* get_name() const {return m_name;} virtual bool evaluate(Context& aContext) { return aContext.look_up(m_name); } virtual BooleanExp* replace(const char* name, BooleanExp& exp) { if (strcmp(name, m_name) == 0) {return exp.copy();} else {return new VariableExp(m_name);} } virtual BooleanExp* copy() const { return new VariableExp(m_name); } protected: char* m_name; };
class AndExp : public BooleanExp { public: AndExp(BooleanExp* op1, BooleanExp* op2) { m_operand1 = op1; m_operand2 = op2; } virtual ~AndExp(){} virtual bool evaluate(Context& aContext) { return m_operand1->evaluate(aContext) && m_operand2->evaluate(aContext); } virtual BooleanExp* replace(const char* name, BooleanExp& exp) { return new AndExp(m_operand1->replace(name, exp), m_operand2->replace(name, exp)); } virtual BooleanExp* copy() const { return new AndExp(m_operand1->copy(), m_operand2->copy()); } protected: BooleanExp* m_operand1; BooleanExp* m_operand2; };
class OrExp : public BooleanExp { public: OrExp(BooleanExp* op1, BooleanExp* op2) { m_operand1 = op1; m_operand2 = op2; } virtual ~OrExp(){} virtual bool evaluate(Context& aContext) { return m_operand1->evaluate(aContext) || m_operand2->evaluate(aContext); } virtual BooleanExp* replace(const char* name, BooleanExp& exp) { return new OrExp(m_operand1->replace(name, exp), m_operand2->replace(name, exp)); } virtual BooleanExp* copy() const { return new OrExp(m_operand1->copy(), m_operand2->copy()); } protected: BooleanExp* m_operand1; BooleanExp* m_operand2; };
class NotExp : public BooleanExp { public: NotExp(BooleanExp* op) {m_operand = op;} virtual bool evaluate(Context& aContext) { return !(m_operand->evaluate(aContext)); } virtual BooleanExp* replace(const char* name, BooleanExp& exp) { return new NotExp(m_operand->replace(name, exp)); } virtual BooleanExp* copy() const { return new NotExp(m_operand->copy()); } protected: BooleanExp* m_operand; };
bool Context::look_up( const char* name ) const { if (!name) return false; if (m_inner.count(name)) { return m_inner.at(name); } return false; } void Context::assign( VariableExp* var, bool val ) { if (!var) return; m_inner.insert(std::make_pair(var->get_name(), val)); }
int main() { BooleanExp* expression; Context context; VariableExp* x = new VariableExp("x"); VariableExp* y = new VariableExp("y"); expression = new OrExp(new AndExp(new Constant(true), x), new AndExp(y, new NotExp(x))); context.assign(x, false); context.assign(y, true); bool result = expression->evaluate(context); std::cout << (result ? "true" : "false") << std::endl; VariableExp* z = new VariableExp("z"); NotExp not_z(z); BooleanExp* replacement = expression->replace("Y", not_z); context.assign(z, true); result = replacement->evaluate(context); std::cout << (result ? "true" : "false") << std::endl; system("Pause"); }
|