Hello all:
Sorry for all the questions; I am kind of easing into boost and finding
cool things i can do with it, as well as uses for a couple of projects.
Eventually I would like to write a small scripting language using
boost::spirit, just to do it and get the practice using it. As a
starting point, I wrote a quick calculator (that just does small single
operations like x+x, x*x, etc). Now i have two questions. 1) My rule
seems to be off. the first number comes through clearly, but no matter
what I put in, I always get the first number and then a 42.
2) How would I go about extending this to implement order of operations,
parenthases, and longer operations (like 3+3*3)? I'm going to try to
implement a small function table so I can do tan(3), so I assume I will
need nultiple rules, how might that be accomplished?
Any comments and suggestions would be welcome. I have pasted the code
below. I was working from a tutorial, so early appologies if it feels
messy; I plan to clean up the namespace aliases and the using keywords.
/*
A simple calculator, supports multiplication, division, addition and
subtraction.
*/
#include
#include
#include
#include
#include <iostream>
#include <string>
#include
#include
#include
#include
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
using qi::double_;
using qi::_1;
using ascii::space;
using phoenix::ref;
using std::cout;
using std::endl;
typedef struct
{
int a, b;
char op;
} calculation;
BOOST_FUSION_ADAPT_STRUCT(calculation, (int, a) (int, b) (char, op) )
template <typename iterator>
class CParser:public qi::grammar
{
qi::rule crule;
public:
CParser():CParser::base_type(crule)
{
using ascii::char_;
using qi::int_;
crule %= (int_ >>
(char_('+')|char_('-')|char_('*')|char_('/')) >>
int_);
}
};
int main()
{
using std::cout;
using std::cin;
using std::endl;
using boost::fusion::vector;
CParserstd::string::iterator p;
std::string str;
calculation result;
cout << "Enter your calculation>";
cin >> str;
bool r = phrase_parse(str.begin(), str.end(), p, ascii::space, result);
if (r)
{
cout << result.a << " " << result.b << " " << result.op << endl;
switch(result.op)
{
case '+':
cout << "Result: " << (result.a + result.b) << endl;
break;
case '-':
cout << "result: " << (result.a - result.b) << endl;
break;
case '*':
cout << "Result: " << (result.a * result.b) << endl;
break;
case '/':
if (result.a == 0)
{
cout << "Division by zero error." << endl;
break;
}
cout << "result: " << (result.a / result.b) << endl;
break;
default:
cout << "Invalid operation." << endl;
}
}
else
{
cout << "Invalid input." << endl;
}
return 0;
}
--
Thanks,
Ty