First answer (full)
I went and implemented a simple recursive expression grammar for functions that have up to three parameters:
for (const std::string input: std::vector<std::string> { "-99", "'string'", "AnswerToLTUAE()", "ReverseString('string')", "Concatenate('string', 987)", "Concatenate('The Answer Is ', AnswerToLTUAE())", }) { auto f(std::begin(input)), l(std::end(input)); const static parser<decltype(f)> p; expr parsed_script; bool ok = qi::phrase_parse(f,l,p,qi::space,parsed_script); if (!ok) std::cout << "invalid input\n"; else { const static generator<boost::spirit::ostream_iterator> g; std::cout << "input:\t" << input << "\n"; std::cout << "tree:\t" << karma::format(g, parsed_script) << "\n"; std::cout << "eval:\t" << evaluate(parsed_script) << "\n"; } if (f!=l) std::cout << "unparsed: '" << std::string(f,l) << "'\n"; }
What prints:
input: -99 tree: -99 eval: -99 input: 'string' tree: 'string' eval: string input: AnswerToLTUAE() tree: nullary_function_call() eval: 42 input: ReverseString('string') tree: unary_function_call('string') eval: gnirts input: Concatenate('string', 987) tree: binary_function_call('string',987) eval: string987 input: Concatenate('The Answer Is ', AnswerToLTUAE()) tree: binary_function_call('The Answer Is ',nullary_function_call()) eval: The Answer Is 42
Some notes:
- I have separated parsing from execution (which is always a good IMO idea)
- I implemented a function evaluation for zero, one or two parameters (this should be easy to expand)
- Values ββare assumed to be integers or strings (they should be easily expanded)
- I added a karma generator to display the parsed expression (with the TODO mark noted in the comment).
Hope this helps:
//#define BOOST_SPIRIT_DEBUG #include <boost/fusion/adapted/struct.hpp>
source share