fork download
  1. #define BOOST_SPIRIT_DEBUG
  2. #define BOOST_SPIRIT_USE_PHOENIX_V3
  3.  
  4. #include <boost/spirit/include/qi.hpp>
  5. #include <boost/config/warning_disable.hpp>
  6. #include <boost/spirit/include/qi.hpp>
  7. #include <boost/spirit/include/phoenix.hpp>
  8. #include <string>
  9. #include <iostream>
  10.  
  11. namespace client
  12. {
  13. namespace qi = boost::spirit::qi;
  14. namespace ascii = boost::spirit::ascii;
  15.  
  16. struct binary_op;
  17. struct unary_op;
  18. struct nil {};
  19.  
  20. struct expression_ast
  21. {
  22. typedef
  23. boost::variant<
  24. nil // can't happen!
  25. , double
  26. , std::string
  27. , boost::recursive_wrapper<expression_ast>
  28. , boost::recursive_wrapper<binary_op>
  29. , boost::recursive_wrapper<unary_op>
  30. >
  31. type;
  32.  
  33. expression_ast()
  34. : m_expr(nil()) {}
  35.  
  36. template <typename Expr>
  37. expression_ast(Expr const& expr)
  38. : m_expr(expr) {}
  39.  
  40. expression_ast& operator+=(expression_ast const& rhs);
  41. expression_ast& operator-=(expression_ast const& rhs);
  42. expression_ast& operator*=(expression_ast const& rhs);
  43. expression_ast& operator/=(expression_ast const& rhs);
  44.  
  45. type m_expr;
  46. };
  47.  
  48. struct binary_op
  49. {
  50. binary_op(
  51. char op
  52. , expression_ast const& left
  53. , expression_ast const& right)
  54. : m_op(op), m_left(left), m_right(right) {}
  55.  
  56. char m_op;
  57. expression_ast m_left;
  58. expression_ast m_right;
  59. };
  60.  
  61. struct unary_op
  62. {
  63. unary_op(
  64. char op
  65. , expression_ast const& subject)
  66. : m_op(op), m_subject(subject) {}
  67.  
  68. char m_op;
  69. expression_ast m_subject;
  70. };
  71.  
  72. expression_ast& expression_ast::operator+=(expression_ast const& rhs)
  73. {
  74. m_expr = binary_op('+', m_expr, rhs);
  75. return *this;
  76. }
  77.  
  78. expression_ast& expression_ast::operator-=(expression_ast const& rhs)
  79. {
  80. m_expr = binary_op('-', m_expr, rhs);
  81. return *this;
  82. }
  83.  
  84. expression_ast& expression_ast::operator*=(expression_ast const& rhs)
  85. {
  86. m_expr = binary_op('*', m_expr, rhs);
  87. return *this;
  88. }
  89.  
  90. expression_ast& expression_ast::operator/=(expression_ast const& rhs)
  91. {
  92. m_expr = binary_op('/', m_expr, rhs);
  93. return *this;
  94. }
  95.  
  96.  
  97. struct ast_print
  98. {
  99. typedef std::string result_type;
  100.  
  101. std::string operator()(qi::info::nil) const
  102. {
  103. return "";
  104. }
  105. std::string operator()(std::string const& str) const
  106. {
  107. return str;
  108. }
  109. std::string operator()(double d) const
  110. {
  111. std::ostringstream oss;
  112. oss << d;
  113. return oss.str();
  114. }
  115.  
  116. std::string operator()(expression_ast const& ast) const
  117. {
  118. return boost::apply_visitor(*this, ast.m_expr);
  119. }
  120.  
  121. std::string operator()(binary_op const& expr) const
  122. {
  123. std::ostringstream oss;
  124. oss << "op:" << expr.m_op << "(";
  125. oss << boost::apply_visitor(*this, expr.m_left.m_expr);
  126. oss << ", ";
  127. oss << boost::apply_visitor(*this, expr.m_right.m_expr);
  128. oss << ')';
  129. return oss.str();
  130. }
  131.  
  132. std::string operator()(unary_op const& expr) const
  133. {
  134. std::ostringstream oss;
  135. oss << "op:" << expr.m_op << "(";
  136. oss << boost::apply_visitor(*this, expr.m_subject.m_expr);
  137. oss << ')';
  138. return oss.str();
  139. }
  140. };
  141.  
  142. std::ostream& operator << (std::ostream& stream, const expression_ast& expr)
  143. {
  144. ast_print printer;
  145. stream << printer(expr) << std::endl;
  146. return stream;
  147. }
  148.  
  149. // CODE ADDED HERE ------------------------------------------------------------
  150. #if 1
  151. template <char OP> struct operator_expr {
  152. template <typename T, typename=T> struct result
  153. { typedef expression_ast type; };
  154.  
  155. expression_ast operator()(expression_ast const& expr) const
  156. { return expression_ast(unary_op(OP, expr)); }
  157.  
  158. expression_ast operator()(expression_ast const&a, expression_ast const&b) const
  159. { return binary_op(OP, a, b); }
  160. };
  161.  
  162. boost::phoenix::function<operator_expr<'-'>> neg;
  163. boost::phoenix::function<operator_expr<'>'>> gt;
  164. #else
  165. expression_ast neg_expr(expression_ast const&a) { return unary_op ('-', a); }
  166. expression_ast gt_expr (expression_ast const&a, expression_ast const&b) { return binary_op('>', a, b); }
  167.  
  168. BOOST_PHOENIX_ADAPT_FUNCTION(expression_ast, neg, neg_expr, 1)
  169. BOOST_PHOENIX_ADAPT_FUNCTION(expression_ast, gt, gt_expr, 2)
  170. #endif
  171. // CODE ADDED END HERE -------------------------------------------------------
  172.  
  173. template <typename Iterator>
  174. struct ParserGenerator : qi::grammar<Iterator, expression_ast(), ascii::space_type>
  175. {
  176. ParserGenerator() : ParserGenerator::base_type(expression)
  177. {
  178. using qi::_val;
  179. using qi::_1;
  180. using qi::double_;
  181. using qi::iso8859_1::char_;
  182. using qi::iso8859_1::space;
  183. using qi::eol;
  184. using boost::spirit::ascii::string;
  185.  
  186. comment =
  187. space >> ("//" >> *(char_ - eol) >> eol)
  188. ;
  189.  
  190. expression =
  191. term [_val = _1]
  192. >> *( ('+' >> term [_val += _1])
  193. | ('-' >> term [_val -= _1])
  194. )
  195. ;
  196.  
  197. term =
  198. factor [_val = _1]
  199. >> *( ('*' >> factor [_val *= _1])
  200. | ('/' >> factor [_val /= _1])
  201. | ('>' >> factor [_val = gt(qi::_val,_1)])
  202. )
  203. ;
  204.  
  205. factor =
  206. symbol [_val = _1]
  207. | double_ [_val = _1]
  208. | '(' >> expression [_val = _1] >> ')'
  209. | ('-' >> factor [_val = neg(_1)])
  210. | ('+' >> factor [_val = _1])
  211. ;
  212.  
  213. symbol %=
  214. (symbol_raw
  215. >> *( string("[") >> +qi::digit >> string("]"))
  216. >> *( string(".") >> symbol ))
  217. ;
  218.  
  219. symbol_raw %=
  220. +(qi::alpha | qi::char_( "_" ))
  221. ;
  222.  
  223. BOOST_SPIRIT_DEBUG_NODE(expression);
  224. BOOST_SPIRIT_DEBUG_NODE(term);
  225. BOOST_SPIRIT_DEBUG_NODE(factor);
  226. BOOST_SPIRIT_DEBUG_NODE(comment);
  227. BOOST_SPIRIT_DEBUG_NODE(symbol);
  228. BOOST_SPIRIT_DEBUG_NODE(symbol_raw);
  229. }
  230.  
  231. qi::rule<Iterator, expression_ast(), ascii::space_type>
  232. expression, term, factor, comment;
  233.  
  234. qi::rule<Iterator, std::string(), ascii::space_type>
  235. symbol, symbol_raw;
  236. };
  237. }
  238.  
  239. int main(int argc, char* argv[])
  240. {
  241. using boost::spirit::ascii::space;
  242. using client::expression_ast;
  243. using client::ast_print;
  244.  
  245. typedef std::string::const_iterator iterator_type;
  246. typedef client::ParserGenerator<iterator_type> ParserGenerator;
  247.  
  248. ParserGenerator pg; // our grammar
  249. std::string predicate( "i_.c>x[0]" );
  250. expression_ast ast;
  251. ast_print printer;
  252.  
  253. iterator_type iter = predicate.begin(), end = predicate.end();
  254. if ( phrase_parse( iter, end, pg, space, ast ))
  255. {
  256. std::cerr << printer( ast ) << std::endl;
  257. }
  258.  
  259. if (iter != end)
  260. std::cout << "Remaining: '" << std::string(iter, end) << std::endl;
  261.  
  262. return 0;
  263. }
  264.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:4:39: fatal error: boost/spirit/include/qi.hpp: No such file or directory
compilation terminated.
stdout
Standard output is empty