用boost::spirit实现的表达式求值

来源:互联网 发布:可视化攻击地图 d3.js 编辑:程序博客网 时间:2024/05/28 15:24

用boost::spirit实现一个表达式求值看上去比较简单。我这个还有点问题,有空格时会解析失败,请大家看看是什么原因?

123*34+2323/324
parsing succeeded
result = 4189
2 + 3
parsing failed

#include <iostream>
#include <stack>
#include <functional>

#include <boost/function.hpp>
// #define BOOST_SPIRIT_DEBUG
#include <boost/spirit.hpp>

using namespace std;
stack<int> evaluationStack;

struct Push
{
    void operator()(int d) const
    {
        evaluationStack.push(d);
    }
};

void doOp(boost::function<int(int, int)> op)
{
    int rhs = evaluationStack.top();
    evaluationStack.pop();
    int lhs = evaluationStack.top();
    evaluationStack.pop();
    int result = op(lhs, rhs);
    evaluationStack.push(result);
}

void add2(char const*, char const*) { doOp(std::plus<int>()); }
void sub2(char const*, char const*) { doOp(std::minus<int>()); }
void mul2(char const*, char const*) { doOp(std::multiplies<int>()); }
void div2(char const*, char const*) { doOp(std::divides<int>()); }

int main()
{
    using namespace boost::spirit;

    /*
        group       ::= '(' expression ')'
        factor      ::= integer | group
        term        ::= factor (('*' factor) | ('/' factor))*
        expression  ::= term (('+' term) | ('-' term))*

    Spirit:
        group       = '(' >> expression >> ')';
        factor      = integer | group;
        term        = factor >> *(('*' >> factor) | ('/' >> factor));
        expression  = term >> *(('+' >> term) | ('-' >> term));
    */

    rule<> group, factor, term, expression;

    group = '(' >> expression >> ')';
    factor = int_p[Push()] | group;
    term = factor
           >> *( ('*' >> factor) [&mul2]
           | ('/' >> factor) [&div2] )
           ;
    expression = term
                 >> *( ('+' >> term) [&add2]
                 | ('-' >> term) [&sub2] )
                 ;

    string s;
    while (getline(cin, s))
    {
        if (parse(s.c_str(), expression, space_p).full)
        {
            cout << "parsing succeeded/n";
            cout << "result = " << evaluationStack.top();
            evaluationStack.pop();
        }
        else
        {
            cout << "parsing failed";
        }
        cout << endl;
    }
}

原创粉丝点击