
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 <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <iostream> #include <string> #include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/container/vector.hpp> #include <boost/fusion/container/vector/convert.hpp> #include <boost/fusion/include/io.hpp> 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<iterator, calculation(), ascii::space_type> { qi::rule <iterator, calculation(), ascii::space_type> 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; CParser<std::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