Instantly share code, notes, and snippets.

# alextsui05/polynomial.cpp Last active Aug 29, 2015

polynomial parser using boost spirit
 #include #include #include #include #include #include #include #include #include #include #include #include namespace client { namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; struct term { boost::optional coefficient; boost::optional x_exponent; boost::optional y_exponent; }; void print( const term& tt ) { int coefficient = (tt.coefficient)? *tt.coefficient : 1; int x_exponent = (tt.x_exponent)? *tt.x_exponent : 0; int y_exponent = (tt.y_exponent)? *tt.y_exponent : 0; std::cout << "term\n"; std::cout << " coefficient: " << coefficient << "\n" << " x_exponent: " << x_exponent << "\n" << " y_exponent: " << y_exponent << "\n"; } } namespace client { template struct polynomial_parser : qi::grammar(), ascii::space_type> { polynomial_parser() : polynomial_parser::base_type(start) { namespace phx = boost::phoenix; using qi::int_; using qi::lit; using qi::double_; using qi::lexeme; using ascii::char_; using qi::_val; using qi::eps; exponent %= '^' >> int_; x_term %= 'x' >> ( exponent | eps[_val = 1] ); y_term %= 'y' >> ( exponent | eps[_val = 1] ); poly_term = eps[_val = term()] >> -int_[phx::bind(&term::coefficient, _val) = qi::_1] >> -x_term[phx::bind(&term::x_exponent, _val) = qi::_1] >> -y_term[phx::bind(&term::y_exponent, _val) = qi::_1] ; negative_poly_term = eps[_val = term()] >> ( int_[phx::bind(&term::coefficient, _val) = -1 * qi::_1] | eps[phx::bind(&term::coefficient, _val) = -1] ) >> -x_term[phx::bind(&term::x_exponent, _val) = qi::_1] >> -y_term[phx::bind(&term::y_exponent, _val) = qi::_1] ; start = eps[_val = std::vector()] >> poly_term[phx::push_back(_val, qi::_1)] >> *( ('+' >> poly_term[phx::push_back(_val, qi::_1)]) | ('-' >> negative_poly_term[phx::push_back(_val, qi::_1)]) ) ; } qi::rule exponent; qi::rule x_term; qi::rule y_term; qi::rule poly_term; qi::rule negative_poly_term; qi::rule(), ascii::space_type> start; }; } //////////////////////////////////////////////////////////////////////////// // Main program //////////////////////////////////////////////////////////////////////////// int main() { std::cout << "/////////////////////////////////////////////////////////\n\n"; std::cout << "\t\tA polynomial parser for Spirit...\n\n"; std::cout << "/////////////////////////////////////////////////////////\n\n"; std::cout << "Give me a polynomial with terms of the form :" << "\"A*x^Ny^M\", where A, N, and M are integers\n"; std::cout << "Type [q or Q] to quit\n\n"; using boost::spirit::ascii::space; typedef std::string::const_iterator iterator_type; typedef client::polynomial_parser polynomial_parser; polynomial_parser pparser; std::string str; while (getline(std::cin, str)) { if (str.empty() || str[0] == 'q' || str[0] == 'Q') break; std::vector poly; client::term term; std::string::const_iterator iter = str.begin(); std::string::const_iterator end = str.end(); bool r = phrase_parse(iter, end, pparser, space, poly); if (r && iter == end) { std::cout << boost::fusion::tuple_open('['); std::cout << boost::fusion::tuple_close(']'); std::cout << boost::fusion::tuple_delimiter(", "); std::cout << "-------------------------\n"; std::cout << "Parsing succeeded\n"; for ( std::vector< client::term >::iterator it = poly.begin( ); it != poly.end( ); ++it ) { client::print( *it ); } std::cout << "\n-------------------------\n"; } else { std::cout << "-------------------------\n"; std::cout << "Parsing failed\n"; std::cout << "-------------------------\n"; } } std::cout << "Bye... :-) \n\n"; return 0; }