状态机学习 解析四则运算式 语法分析

来源:互联网 发布:蜂窝移动数据设置 编辑:程序博客网 时间:2024/06/06 19:00

将四则运算拆分成一个个数字和符号后

就进行运算分析

使用以下语法规则:(参考《自编编程语言》)

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: 1
type: 2, string: +
type: 1, string: 2
type: 5, string: /
type: 1, string: 3
type: 4, string: *
type: 1, string: 45
type: 3, string: -
type: 1, string: 67
type: 3, string: -
type: 1, string: 89
type: 2, string: +
type: 1, string: 999
type: 8, string: ;

type: 1, string: 132
type: 2, string: +
type: 1, string: 243
type: 5, string: /
type: 1, string: 7
type: 4, string: *
type: 1, string: 4455
type: 3, string: -
type: 1, string: 6
type: 3, string: -
type: 1, string: 89
type: 2, string: +
type: 1, string: 34
type: 8, string: ;

result: 154723
请按任意键继续. . .


0 0
原创粉丝点击