#include <iostream>
#include <iomanip>
#include <stdexcept>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
namespace qi = boost::spirit::qi;
template <typename Parser, typename Skipper, typename ... Args>
void PhraseParseOrDie(
const std::string& input, const Parser& p, const Skipper& s,
Args&& ... args)
{
std::string::const_iterator begin = input.begin(), end = input.end();
boost::spirit::qi::phrase_parse(
begin, end, p, s, std::forward<Args>(args) ...);
if (begin != end) {
std::cout << "Unparseable: "
<< std::quoted(std::string(begin, end)) << std::endl;
throw std::runtime_error("Parse error");
}
}
class ArithmeticGrammar1 : public qi::grammar<
std::string::const_iterator,
int(), qi::space_type>
{
public:
using Iterator = std::string::const_iterator;
ArithmeticGrammar1() : ArithmeticGrammar1::base_type(start)
{
start =
product [qi::_val = qi::_1]
>> *('+' >> product [qi::_val += qi::_1]);
product = factor [qi::_val = qi::_1]
>> *('*' >> factor [qi::_val *= qi::_1]);
factor %= qi::int_ | group;
group %= '(' >> start >> ')';
}
qi::rule<Iterator, int(), qi::space_type> start, group, product, factor;
};
void test1(std::string input)
{
int out_int;
PhraseParseOrDie(input, ArithmeticGrammar1(), qi::space, out_int);
std::cout << "test1() parse result: "
<< out_int << std::endl;
}
int main(int argc, char* argv[])
{
test1(argc >= 2 ? argv[1] : "1 + 2 * 3");
return 0;
}