# woaidongmao

## 使用boost.spirit制作一个简单的四则计算器

从传统意义上来说，boost.spirit库是一个类似于yacc的库，主要业务是做词法解析，然后提供各种读取数据的接口，但是由于这是一个用C++实现、并且大量运Expression Templates技巧的库...

expression ::= term ( ('+' term) | ('-' term) )*
term ::= factor ( ('*' factor) | ('/' factor) )*
factor ::= REAL | '(' ex ')' | ('-' factor) | ('+' factor)

struct calculator : public grammar<calculator>
{
template <typename ScannerT>
struct definition
{
definition(calculator const& /*self*/)
{
expression
=   term
|   ('-' >> term[do_calc<do_substract>()])
)
;

term
=   factor
>> *(   ('*' >> factor[do_calc<do_multiply>()])
|   ('/' >> factor[do_calc<do_divide>()])
)
;

factor
=   real_p[&push_real]
|   '(' >> expression >> ')'
|   ('-' >> factor[&do_neg])
|   ('+' >> factor)
;
}

rule<ScannerT> expression, term, factor;

rule<ScannerT> const&
start() const { return expression; }
};
};

namespace
{
stack<double> calc_stack;

{
double operator () (double lhs, double rhs) const
{
return lhs + rhs;
}
};

struct do_substract
{
double operator () (double lhs, double rhs) const
{
return lhs - rhs;
}
};

struct do_multiply
{
double operator () (double lhs, double rhs) const
{
return lhs * rhs;
}
};

struct do_divide
{
double operator () (double lhs, double rhs) const
{
return lhs / rhs;
}
};

template <typename op>
struct do_calc
{
void operator () (const char *, const char *) const
{
double result = calc_stack.top();
calc_stack.pop();
result = op()(calc_stack.top(), result);
calc_stack.pop();
calc_stack.push(result);
}
};

void push_real(double d)
{
calc_stack.push(d);
}

void do_neg(char const*, char const*)
{
cout << "NEGATE\n";
double result = calc_stack.top();
calc_stack.pop();
calc_stack.push(-result);
}

double show_result()
{
return calc_stack.top();
}
}

posted on 2008-05-17 00:16 肥仔 阅读(1435) 评论(1)  编辑 收藏 引用 所属分类: Boost & STL