// 词法分析,解析表达式 bool ParseExpr(const string & expr, TokenVector & tokens) { // 表达式的解析较简单,就不用状态机了,直接一个一个解析。。。 int i = 0; Token token; string buffer; tokens.clear(); while (i < expr.length()) { // 空白跳过 if (isblank(expr[i])) { ++i; continue; } // 单个字符的操作符和括号 if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/' || expr[i] == '%' || expr[i] == '^' || expr[i] == '(' || expr[i] == ')') { token.type = OP; if (expr[i] == '+') token.value.op = ADD; else if (expr[i] == '-') token.value.op = SUB; else if (expr[i] == '*') token.value.op = MUL; else if (expr[i] == '/') token.value.op = DIV; else if (expr[i] == '%') token.value.op = MOD; else if (expr[i] == '^') token.value.op = POW; else if (expr[i] == '(') token.value.op = LEFT; else if (expr[i] == ')') token.value.op = RIGHT; tokens.push_back(token); ++i; continue; } // 整数或浮点数 else if (isdigit(expr[i])) { buffer.clear(); buffer += expr[i++]; bool point = false; while (i < expr.length()) { if (isdigit(expr[i])) { buffer += expr[i++]; } else if (expr[i] == '.' && !point) { buffer += expr[i++]; point = true; } else { break; } } if (point) { token.type = FLOAT; token.value.f = strtof(buffer.c_str(), NULL); } else { token.type = INT; token.value.i = strtoul(buffer.c_str(), NULL, 0); } tokens.push_back(token); } // 随机数 else if (expr[i] == 'r') { token.type = RAND; token.value.i = 0; tokens.push_back(token); ++i; } // 参数 else if (expr[i] == 'x') { ++i; buffer.clear(); while (i < expr.length() && isdigit(expr[i])) { buffer += expr[i]; ++i; } if (buffer.empty()) { return false; } token.type = ARG; token.value.index = strtoul(buffer.c_str(), NULL, 0); tokens.push_back(token); continue; } // > 或 >= else if (expr[i] == '>') { token.type = OP; ++i; if (i < expr.length() && expr[i] == '=') { token.value.op = GE; ++i; } else { token.value.op = GT; } tokens.push_back(token); } // < 或 <= else if (expr[i] == '<') { token.type = OP; ++i; if (i < expr.length() && expr[i] == '=') { token.value.op = LE; ++i; } else { token.value.op = LT; } tokens.push_back(token); } // == else if (i + 1 < expr.length() && expr[i] == '=' && expr[i + 1] == '=') { token.type = OP; token.value.op = EQ; tokens.push_back(token); i += 2; } // != else if (i + 1 < expr.length() && expr[i] == '!' && expr[i + 1] == '=') { token.type = OP; token.value.op = NE; tokens.push_back(token); i += 2; } // && else if (i + 1 < expr.length() && expr[i] == '&' && expr[i + 1] == '&') { token.type = OP; token.value.op = AND; tokens.push_back(token); i += 2; } // || else if (i + 1 < expr.length() && expr[i] == '|' && expr[i + 1] == '|') { token.type = OP; token.value.op = OR; tokens.push_back(token); i += 2; } else { return false; } } return true; }
// 把解析好的表达式转换成逆波兰式 bool ConvertExpr(const TokenVector & input, TokenVector & output) { TokenStack stack; output.clear(); TokenVector::const_iterator it = input.begin(); for (; it != input.end(); ++it) { if (it->type == OP) { // 左括号,直接压进操作符栈 if (it->value.op == LEFT) { stack.push(*it); } // 右括号,从栈里弹出操作符,直到碰到右括号 else if (it->value.op == RIGHT) { bool find_left = false; while (!stack.empty()) { if (stack.top().value.op == LEFT) { find_left = true; stack.pop(); break; } else { output.push_back(stack.top()); stack.pop(); } } if (!find_left) return false; } // 其它操作符,和栈顶操作符比较优先级 else { while (!stack.empty() && stack.top().value.op != LEFT && OPPriority(stack.top().value.op) >= OPPriority(it->value.op)) { output.push_back(stack.top()); stack.pop(); } stack.push(*it); } } // 非操作符直接输出 else { output.push_back(*it); } } while (!stack.empty()) { output.push_back(stack.top()); stack.pop(); } return true; }