c – 构建数学表达式求值程序

c – 构建数学表达式求值程序,第1张

概述我不能在我的环境中使用boost :: spirit.但是我想使用STL并尽可能地提高构建自己的表达式求值程序.是否有这样的替代方法来提升::精神? 以下代码包括单元测试和我在ACCU 200x(8或9)的大约90分钟会话中写的完整解析器.如果你需要更多的话,这可能很容易扩展.您可以通过定义Parse :: value_type,或者将其解压缩到一个单独的头文件中并使其成为一个模板类,使其可以加倍 我不能在我的环境中使用boost :: spirit.但是我想使用STL并尽可能地提高构建自己的表达式求值程序.是否有这样的替代方法来提升::精神?解决方法 以下代码包括单元测试和我在ACCU 200x(8或9)的大约90分钟会话中写的完整解析器.如果你需要更多的话,这可能很容易扩展.您可以通过定义Parse :: value_type,或者将其解压缩到一个单独的头文件中并使其成为一个模板类,使其可以加倍.

或者你可以拿测试用例,尝试一下自己. (它使用来自http://cute-test.com的CUTE)

#include "cute.h"#include "IDe_Listener.h"#include "cute_runner.h"#include <cctype>#include <map>namespace {class Parser {    typedef int value_type;    typedef std::vector<value_type> valuestack;    typedef std::vector<char> opstack;    typedef std::map<std::string,value_type> memory;public:    memory  variables;    private:    voID evaluateSingleOperator(char op,value_type &result,value_type operand) {        switch(op) {            case '+': result += operand; break;            case '-': result -= operand; break;            case '*': result *= operand; break;            case '/': result /= operand; break;            default: throw("invalID operand");        }    }    voID evaluateStacks(valuestack &values,opstack &ops) {        while(ops.size() && values.size()>1) {            char op = ops.back(); ops.pop_back();            value_type operand = values.back(); values.pop_back();            evaluateSingleOperator(op,values.back(),operand);        }    }    bool higherPrecedenceOrleftAssociative(char last,char current) {        return (last == current)||(last == '*' || last == '/') ;    }    bool shouldEvaluate(char op,opstack const &ops) {        return ops.size() > 0 && higherPrecedenceOrleftAssociative(ops.back(),op);    }    std::string parseVariablename(std::istream &is) {        std::string variable;        char nextchar=0;        while ((is >> nextchar) && isAlpha(nextchar)) {            variable += nextchar;               }         if (variable.size() == 0) throw std::string("internal parse error");        is.unget();        return variable;        }    int peekWithSkipwhiteSpace(std::istream &is) {        int nextchar = EOF;        while(isspace(nextchar = is.peek())) is.get();        return nextchar;    }    value_type getoperand(std::istream &is) {        int nextchar = peekWithSkipwhiteSpace(is);        if (nextchar == EOF) throw std::string("Syntax error operand expected");        if (isdigit(nextchar)){            value_type operand=0;            if (!(is >> operand)) throw std::string("Syntax error getting number") ;            return operand;        } else if ('(' == nextchar) {            is.get();            return parse(is);        } else if (isAlpha(nextchar)) {            std::string variable= parseVariablename(is);            if( parseAssignmentoperator(is)) {                variables[variable] = parse(is);            } else {                if (!variables.count(variable)) throw std::string("undefined variable: ")+variable;            }             return variables[variable];         }        throw std::string("Syntax error");              }    bool parseAssignmentoperator(std::istream &is) {        int nextchar = peekWithSkipwhiteSpace(is);        if ('=' != nextchar) {            return false;        }        is.get();        return true;    }    public:    value_type parse(std::istream &is) {        is >> std::skipws;        valuestack values;        opstack ops;        values.push_back(getoperand(is));        char op=')';        while((is  >>op) && op != ')') {            if (shouldEvaluate(op,ops)) {                evaluateStacks(values,ops);            }            values.push_back(getoperand(is));            ops.push_back(op);        }        evaluateStacks(values,ops);        return values.back();    }    value_type eval(std::string s) {        std::istringstream is(s);        return parse(is);    }};int eval(std::string s) {    return Parser().eval(s);}voID shouldThrowEmptyExpression() {    eval("");}voID shouldThrowSyntaxError() {    eval("()");}voID testSimpleNumber() {    ASSERT_EQUAL(5,eval("5"));}voID testSimpleAdd() {    ASSERT_EQUAL(10,eval("5 +5"));}voID testMultiAdd() {    ASSERT_EQUAL(10,eval("1   +    2 + 3+4"));}voID testSimpleSubtract() {    ASSERT_EQUAL(5,eval("6-1"));}voID testTenPlus12Minus100() {    ASSERT_EQUAL(-78,eval("10+12-100"));}voID testMultiply() {    ASSERT_EQUAL(50,eval("10*5"));}voID testdivision() {    ASSERT_EQUAL(7,eval("21/3"));}voID testAddThenMultiply() {    ASSERT_EQUAL(21,eval("1+4 *5"));}voID testAddThenMultiplyAdd() {    ASSERT_EQUAL(16,eval("1+4*5 -5"));}voID testAddSubSub() {    ASSERT_EQUAL(-4,eval("1+2-3-4"));}voID testSimpleParenthesis() {    ASSERT_EQUAL(1,eval("(1)"));}voID testSimpleOperandParenthesis() {    ASSERT_EQUAL(2,eval("1+(1)"));}voID testParenthesis() {    ASSERT_EQUAL(5,eval("2*(1+4)-5"));}voID testnestedParenthesis() {    ASSERT_EQUAL(16,eval("2*(1+(4*3)-5)"));}voID testDeeplynestedParenthesis() {    ASSERT_EQUAL(8,eval("((2*((1+(4*3)-5)))/2)"));}voID testSimpleAssignment() {    Parser p;    ASSERT_EQUAL(1,p.eval("a=1*(2-1)"));    ASSERT_EQUAL(8,p.eval("a+7"));    ASSERT_EQUAL(1,p.eval("2-a"));}voID testLongerVariables() {    Parser p;    ASSERT_EQUAL(1,p.eval("aLongVariablename=1*(2-1)"));    ASSERT_EQUAL(42,p.eval("AnotherVariable=7*(4+2)"));    ASSERT_EQUAL(1,p.eval("2-(aLongVariablename*AnotherVariable)/42"));}voID shouldThrowUndefined() {    eval("2 * undefinedVariable");}voID runSuite(){    cute::suite s;    //Todo add your test here    s.push_back(CUTE_EXPECT(CUTE(shouldThrowEmptyExpression),std::string));    s.push_back(CUTE_EXPECT(CUTE(shouldThrowSyntaxError),std::string));    s.push_back(CUTE(testSimpleNumber));    s.push_back(CUTE(testSimpleAdd));    s.push_back(CUTE(testMultiAdd));    s.push_back(CUTE(testSimpleSubtract));    s.push_back(CUTE(testTenPlus12Minus100));    s.push_back(CUTE(testMultiply));    s.push_back(CUTE(testdivision));    s.push_back(CUTE(testAddThenMultiply));    s.push_back(CUTE(testAddSubSub));    s.push_back(CUTE(testAddThenMultiplyAdd));    s.push_back(CUTE(testSimpleParenthesis));    s.push_back(CUTE(testSimpleOperandParenthesis));    s.push_back(CUTE(testParenthesis));    s.push_back(CUTE(testnestedParenthesis));    s.push_back(CUTE(testDeeplynestedParenthesis));    s.push_back(CUTE(testSimpleAssignment));    s.push_back(CUTE(testLongerVariables));    s.push_back(CUTE_EXPECT(CUTE(shouldThrowUndefined),std::string));    cute::IDe_Listener lis;    cute::makeRunner(lis)(s,"The Suite");}}int main(){runSuite();}
总结

以上是内存溢出为你收集整理的c – 构建数学表达式求值程序全部内容,希望文章能够帮你解决c – 构建数学表达式求值程序所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1252285.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存