Created
January 9, 2012 09:25
-
-
Save sehe/1582163 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <boost/config/warning_disable.hpp> | |
#include <boost/spirit/include/qi.hpp> | |
#include <boost/spirit/include/phoenix.hpp> | |
#include <iostream> | |
#include <string> | |
namespace client | |
{ | |
namespace qi = boost::spirit::qi; | |
namespace ascii = boost::spirit::ascii; | |
namespace phx = boost::phoenix; | |
struct vars_ : qi::symbols<char, double> { | |
vars_() { | |
add("ans" , 0); | |
} | |
} vars; | |
template <typename Iterator> | |
struct parser : qi::grammar<Iterator, double()> | |
{ | |
parser() : parser::base_type(function) | |
{ | |
using qi::eps; | |
using qi::lit; | |
using qi::_val; | |
using qi::_1; | |
using ascii::char_; | |
using qi::double_; | |
using qi::string; | |
using qi::lexeme; | |
using boost::phoenix::if_; | |
using qi::alpha; | |
using qi::alnum; | |
MAX = lexeme[string("max") | string("MAX")]; //define max symbol | |
MIN = lexeme[string("min") | string("MIN")]; //define min symbol | |
D = lexeme[string("d") | string("D")]; //define distance symbol | |
ANS = lexeme[string("ans") | string("ANS")]; //not working yet | |
function = | |
expression [_val = _1] | |
| declaration | |
| assignment | |
| ( MAX >> "(" >> function [_val = _1] >> | |
+(',' >> function [if_(_1 > _val)[_val = _1]]) >> ')') // call : max(function,...) | |
| ( MIN >> "(" >> function [_val = _1] >> | |
+(',' >> function [if_(_1 < _val)[_val = _1]]) >> ')') // call : min(function,...) | |
| ( D >> "(" >> (function >> ',' >> function) >> ')'); // call : d(point1,point2) not implemented yet | |
expression = | |
term [_val = _1] | |
>> *( ('+' >> term [_val += _1]) | |
| ('-' >> term [_val -= _1])); | |
term = | |
factor [_val = _1] | |
>> *( ('*' >> factor [_val *= _1]) | |
| ('/' >> factor [_val /= _1])); | |
factor = | |
double_ [_val = _1] | |
| (vars [_val += _1] ) | |
| '(' >> expression [_val = _1] >> ')' | |
| ('-' >> factor [_val = -_1]) | |
| ('+' >> factor [_val = _1]) | |
| declaration; | |
; | |
assignment = | |
vars >> '=' >> function; | |
var_decl = | |
lexeme [ qi::raw [ ( alpha >> *( alnum | '_' ) ) - vars ] ] | |
[ phx::bind(vars.add, _1) ] | |
; | |
declaration = | |
"var " >> var_decl >> *( ',' >> var_decl ); | |
} | |
qi::rule<Iterator, double()> MAX, MIN, D, ANS, expression, term, factor, | |
function, assignment, var_decl, declaration; | |
}; | |
} | |
/////////////////////////////////////////////////////////////////////////////// | |
// Main program | |
/////////////////////////////////////////////////////////////////////////////// | |
int main() | |
{ | |
std::cout << "**********************************************************" << std::endl; | |
std::cout << "* *" << std::endl; | |
std::cout << "* Command interface for VideoTraction4 *" << std::endl; | |
std::cout << "* *" << std::endl; | |
std::cout << "**********************************************************" << std::endl << std::endl; | |
std::cout << "Type an expression...or [q or Q] to quit" << std::endl << std::endl; | |
typedef std::string::const_iterator iterator_type; | |
typedef client::parser<iterator_type> parser; | |
parser _parser; // Our grammar | |
std::string str; | |
double result; | |
while (std::getline(std::cin, str)) | |
{ | |
if (str.empty() || str[0] == 'q' || str[0] == 'Q') | |
break; | |
std::string::const_iterator iter = str.begin(); | |
std::string::const_iterator end = str.end(); | |
bool r = parse(iter, end, _parser, result); | |
if (r && iter == end) | |
{ | |
std::cout << "-------------------------\n"; | |
std::cout << "Parsing succeeded\n"; | |
std::cout << "result = " << result << std::endl; | |
std::cout << "-------------------------\n"; | |
client::vars.remove("ans"); | |
client::vars.add("ans",result); | |
} | |
else | |
{ | |
std::string rest(iter, end); | |
std::cout << "-------------------------\n"; | |
std::cout << "Parsing failed\n"; | |
std::cout << "stopped at: \": " << rest << "\"\n"; | |
std::cout << "-------------------------\n"; | |
} | |
} | |
std::cout << "Bye... :-) \n\n"; | |
return 0; | |
} |
Author
sehe
commented
Jan 9, 2012
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment