将四则运算拆分成一个个数字和符号后
就进行运算分析
使用以下语法规则:(参考《自编编程语言》)
exPRession:
#pragma once#include <string>#include <deque>#include <iostream> enum TokenType { BAD_TOKEN, NUM_TOKEN, ADD_TOKEN, SUB_TOKEN, MUL_TOKEN, DIV_TOKEN, LPAREN_TOKEN, RPAREN_TOKEN, ENDFILE_TOKEN}; class Token {private: TokenType type_; std::string valueStr_;public: Token() : type_(BAD_TOKEN) {} Token(TokenType t,std::string s) : type_(t),valueStr_(s) {} bool Operator ==(const Token& t) { if (type_ == t.type_ && valueStr_ == t.valueStr_) { return true; } return false; } Token(const Token& t) { if (*this != t) { type_ = t.type_; valueStr_ = t.valueStr_; } } bool operator != (const Token& t) { return !(*this == t); } Token& operator=(const Token& t) { if (*this != t) { type_ = t.type_; valueStr_ = t.valueStr_; } return *this; } /*void SetType(TokenType type) { type_ = type; } void SetValue(double value) { value_ = value; } void SetValStr(std::string valueStr) { valueStr_ = valueStr; }*/ TokenType GetType() { return type_; } std::string GetValStr() { return valueStr_; }}; class Expression2Tokens { std::string contentStr_; Expression2Tokens& operator=(const Expression2Tokens&) {}; Expression2Tokens(const Expression2Tokens&); enum Status { INIT_STATUS, NUM_STATUS, OPERATOR_STATUS, LPAREN_STATUS, RPAREN_STATUS, END_STATUS, ERROR_STATUS };public: std::deque<Token> tokenDeque_; Expression2Tokens(std::string s):contentStr_(s){} bool Analyzer(); void PrintTokens() { for (std::deque<Token>::iterator it = tokenDeque_.begin(); it != tokenDeque_.end(); it++) { std::cout << "type: " << (*it).GetType() << ", string: " << (*it).GetValStr() << std::endl; } std::cout << std::endl; } }; class ParseExpression { Expression2Tokens express2token_; ParseExpression& operator=(const ParseExpression&) {}; ParseExpression(const ParseExpression&); double result_; double ParseTerm(); double ParsePrimaryExpression();public: ParseExpression(std::string s) : express2token_(s), result_(0.0){} bool StartParse(); double GetResult() { return result_; } };#include "token.h"#include <iostream> bool Expression2Tokens::Analyzer() { bool bRet = false; size_t index = 0, valueBeg = 0, valueEnd = 0; Status status = INIT_STATUS; for (;index < contentStr_.size();index++) { if (isdigit(contentStr_[index])) { if (status != NUM_STATUS) { status = NUM_STATUS; valueBeg = index; } continue; } //对于 非数字进行判断 if (NUM_STATUS == status ) { std::string s(contentStr_.substr(valueBeg, index - valueBeg)); Token t(NUM_TOKEN,s); tokenDeque_.push_back(t); valueBeg = 0; } if (contentStr_[index] == '+') { Token t(ADD_TOKEN, "+"); tokenDeque_.push_back(t); status = OPERATOR_STATUS; continue; }else if (contentStr_[index] == '-') { Token t(SUB_TOKEN, "-"); tokenDeque_.push_back(t); status = OPERATOR_STATUS; continue; }else if (contentStr_[index] == '*') { Token t(MUL_TOKEN, "*"); tokenDeque_.push_back(t); status = OPERATOR_STATUS; continue; }else if (contentStr_[index] == '/') { Token t(DIV_TOKEN,"/"); tokenDeque_.push_back(t); status = OPERATOR_STATUS; continue; }else if (contentStr_[index] == ';') { Token t(ENDFILE_TOKEN, ";"); tokenDeque_.push_back(t); status = END_STATUS; bRet = true; return bRet; } else { std::cerr << "analyzer error (" << contentStr_[index] << ")" << std::endl; status = ERROR_STATUS; return false; } } return bRet;} double ParseExpression::ParsePrimaryExpression() { Token token; token = express2token_.tokenDeque_.front(); if (token.GetType() == NUM_TOKEN) { //return atof(token.GetValStr().c_str()); express2token_.tokenDeque_.pop_front(); return stod(token.GetValStr()); } std::cerr << "syntax error." << std::endl; exit(1); return 0.0;} double ParseExpression::ParseTerm() { double dRet; double v; Token token; dRet = ParsePrimaryExpression(); for (;;) { token = express2token_.tokenDeque_.front(); if (token.GetType() != MUL_TOKEN && token.GetType() != DIV_TOKEN) { break; } express2token_.tokenDeque_.pop_front(); v = ParsePrimaryExpression(); if (token.GetType() == MUL_TOKEN) { dRet *= v; } else if (token.GetType() == DIV_TOKEN) { dRet /= v; } } return dRet;} bool ParseExpression::StartParse() { bool bRet = false; if (!express2token_.Analyzer()) return bRet; express2token_.PrintTokens(); double v; Token token; result_ = ParseTerm(); for (;;) { token = express2token_.tokenDeque_.front(); if (token.GetType() != ADD_TOKEN && token.GetType() != SUB_TOKEN) { break; } express2token_.tokenDeque_.pop_front(); v = ParseTerm(); if (token.GetType() == ADD_TOKEN) { result_ += v; } else if (token.GetType() == SUB_TOKEN) { result_ -= v; } } bRet = true; return bRet; }测试代码如下:#include "token.h"#include <iostream> int main(){ Expression2Tokens e("1+2/3*45-67-89+999;"); if (e.Analyzer()) { e.PrintTokens(); } ParseExpression p("132+243/7*4455-6-89+34;"); if(p.StartParse()) std::cout << "result: " << p.GetResult() << std::endl; return 0;}type: 1, string: 1type: 2, string: +type: 1, string: 2type: 5, string: /type: 1, string: 3type: 4, string: *type: 1, string: 45type: 3, string: -type: 1, string: 67type: 3, string: -type: 1, string: 89type: 2, string: +type: 1, string: 999type: 8, string: ;
type: 1, string: 132type: 2, string: +type: 1, string: 243type: 5, string: /type: 1, string: 7type: 4, string: *type: 1, string: 4455type: 3, string: -type: 1, string: 6type: 3, string: -type: 1, string: 89type: 2, string: +type: 1, string: 34type: 8, string: ;
result: 154723请按任意键继续. . .
新闻热点
疑难解答