| 1 | #include <parsers/where/grammar/grammar.hpp>
|
|---|
| 2 | #include <iostream>
|
|---|
| 3 | #include <fstream>
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 | namespace qi = boost::spirit::qi;
|
|---|
| 7 | namespace ascii = boost::spirit::ascii;
|
|---|
| 8 | namespace phoenix = boost::phoenix;
|
|---|
| 9 |
|
|---|
| 10 | namespace parsers {
|
|---|
| 11 | namespace where {
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 | template<typename THandler>
|
|---|
| 15 | struct build_expr {
|
|---|
| 16 | template <typename A, typename B = unused_type, typename C = unused_type>
|
|---|
| 17 | struct result { typedef expression_ast<THandler> type; };
|
|---|
| 18 |
|
|---|
| 19 | expression_ast<THandler> operator()(expression_ast<THandler> const & expr1, operators const & op, expression_ast<THandler> const & expr2) const {
|
|---|
| 20 | return expression_ast<THandler>(binary_op<THandler>(op, expr1, expr2));
|
|---|
| 21 | }
|
|---|
| 22 | };
|
|---|
| 23 |
|
|---|
| 24 | template<typename THandler>
|
|---|
| 25 | struct build_string {
|
|---|
| 26 | template <typename A>
|
|---|
| 27 | struct result { typedef expression_ast<THandler> type; };
|
|---|
| 28 |
|
|---|
| 29 | template <typename A>
|
|---|
| 30 | expression_ast<THandler> operator()(A const & v) const {
|
|---|
| 31 | return expression_ast<THandler>(string_value(v));
|
|---|
| 32 | }
|
|---|
| 33 | };
|
|---|
| 34 |
|
|---|
| 35 | template<typename THandler>
|
|---|
| 36 | struct build_copy {
|
|---|
| 37 | template <typename A>
|
|---|
| 38 | struct result { typedef expression_ast<THandler> type; };
|
|---|
| 39 |
|
|---|
| 40 | template <typename A>
|
|---|
| 41 | expression_ast<THandler> operator()(A const v) const {
|
|---|
| 42 | return v;
|
|---|
| 43 | }
|
|---|
| 44 | };
|
|---|
| 45 |
|
|---|
| 46 | template<typename THandler>
|
|---|
| 47 | struct build_int {
|
|---|
| 48 | template <typename A>
|
|---|
| 49 | struct result { typedef expression_ast<THandler> type; };
|
|---|
| 50 |
|
|---|
| 51 | //template <typename A>
|
|---|
| 52 | expression_ast<THandler> operator()(unsigned int const & v) const {
|
|---|
| 53 | return expression_ast<THandler>(int_value(v));
|
|---|
| 54 | }
|
|---|
| 55 | };
|
|---|
| 56 |
|
|---|
| 57 | template<typename THandler>
|
|---|
| 58 | struct build_variable {
|
|---|
| 59 | template <typename A>
|
|---|
| 60 | struct result { typedef expression_ast<THandler> type; };
|
|---|
| 61 |
|
|---|
| 62 | //template <typename A>
|
|---|
| 63 | expression_ast<THandler> operator()(std::wstring const & v) const {
|
|---|
| 64 | return expression_ast<THandler>(variable<THandler>(v));
|
|---|
| 65 | }
|
|---|
| 66 | };
|
|---|
| 67 |
|
|---|
| 68 | template<typename THandler>
|
|---|
| 69 | struct build_function {
|
|---|
| 70 | template <typename A, typename B>
|
|---|
| 71 | struct result { typedef expression_ast<THandler> type; };
|
|---|
| 72 | expression_ast<THandler> operator()(std::wstring const name, expression_ast<THandler> const & var) const {
|
|---|
| 73 | return expression_ast<THandler>(unary_fun<THandler>(name, var));
|
|---|
| 74 | }
|
|---|
| 75 | };
|
|---|
| 76 |
|
|---|
| 77 | template<typename THandler>
|
|---|
| 78 | struct build_function_convert {
|
|---|
| 79 | template <typename A, typename B>
|
|---|
| 80 | struct result { typedef expression_ast<THandler> type; };
|
|---|
| 81 | expression_ast<THandler> operator()(wchar_t const unit, expression_ast<THandler> const & vars) const {
|
|---|
| 82 | list_value<THandler> args = list_value<THandler>(vars);
|
|---|
| 83 | args += string_value(std::wstring(1, unit));
|
|---|
| 84 | return expression_ast<THandler>(unary_fun<THandler>(_T("convert"), args));
|
|---|
| 85 | }
|
|---|
| 86 | };
|
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 | template<typename THandler>
|
|---|
| 90 | struct build {
|
|---|
| 91 |
|
|---|
| 92 | };
|
|---|
| 93 |
|
|---|
| 94 |
|
|---|
| 95 | ///////////////////////////////////////////////////////////////////////////
|
|---|
| 96 | // Our calculator grammar
|
|---|
| 97 | ///////////////////////////////////////////////////////////////////////////
|
|---|
| 98 | template <typename THandler, typename Iterator>
|
|---|
| 99 | where_grammar<THandler, Iterator>::where_grammar() : where_grammar<THandler, Iterator>::base_type(expression, "where") {
|
|---|
| 100 | using qi::_val;
|
|---|
| 101 | using qi::uint_;
|
|---|
| 102 | using qi::_1;
|
|---|
| 103 | using qi::_2;
|
|---|
| 104 | using qi::_3;
|
|---|
| 105 |
|
|---|
| 106 | boost::phoenix::function<build_expr<THandler> > build_e;
|
|---|
| 107 | boost::phoenix::function<build_string<THandler> > build_is;
|
|---|
| 108 | boost::phoenix::function<build_int<THandler> > build_ii;
|
|---|
| 109 | boost::phoenix::function<build_variable<THandler> > build_iv;
|
|---|
| 110 | boost::phoenix::function<build_function<THandler> > build_if;
|
|---|
| 111 | boost::phoenix::function<build_function_convert<THandler> > build_ic;
|
|---|
| 112 | boost::phoenix::function<build_copy<THandler> > build_c;
|
|---|
| 113 |
|
|---|
| 114 | expression
|
|---|
| 115 | = and_expr [_val = _1]
|
|---|
| 116 | >> *(ascii::no_case["or"] >> and_expr) [_val |= _1]
|
|---|
| 117 | ;
|
|---|
| 118 | and_expr
|
|---|
| 119 | = not_expr [_val = _1]
|
|---|
| 120 | >> *(ascii::no_case["and"] >> not_expr) [_val &= _1]
|
|---|
| 121 | ;
|
|---|
| 122 | not_expr
|
|---|
| 123 | = cond_expr [_val = _1]
|
|---|
| 124 | >> *(ascii::no_case["not"] >> cond_expr) [_val != _1]
|
|---|
| 125 | ;
|
|---|
| 126 |
|
|---|
| 127 | cond_expr
|
|---|
| 128 | = (identifier_expr >> op >> identifier_expr) [_val = build_e(_1, _2, _3) ]
|
|---|
| 129 | | (identifier_expr >> ascii::no_case["not in"]
|
|---|
| 130 | >> '(' >> value_list >> ')') [_val = build_e(_1, op_nin, _2) ]
|
|---|
| 131 | | (identifier_expr >> ascii::no_case["in"]
|
|---|
| 132 | >> '(' >> value_list >> ')') [_val = build_e(_1, op_in, _2) ]
|
|---|
| 133 | | ('(' >> expression >> ')') [_val = _1 ]
|
|---|
| 134 | ;
|
|---|
| 135 |
|
|---|
| 136 | identifier_expr
|
|---|
| 137 | = (identifier >> bitop >> identifier) [_val = build_e(_1, _2, _3) ]
|
|---|
| 138 | | ('(' >> identifier >> bitop >> identifier >> ')') [_val = build_e(_1, _2, _3) ]
|
|---|
| 139 | | identifier [_val = _1 ]
|
|---|
| 140 | ;
|
|---|
| 141 |
|
|---|
| 142 | identifier
|
|---|
| 143 | = "str" >> string_literal_ex [_val = build_is(_1)]
|
|---|
| 144 | | (variable_name >> '(' >> list_expr >> ')') [_val = build_if(_1, _2)]
|
|---|
| 145 | | variable_name [_val = build_iv(_1)]
|
|---|
| 146 | | string_literal [_val = build_is(_1)]
|
|---|
| 147 | | qi::lexeme[
|
|---|
| 148 | (uint_ >> ascii::alpha) [_val = build_ic(_2, build_ii(_1))]
|
|---|
| 149 | ]
|
|---|
| 150 | | '-' >> qi::lexeme[
|
|---|
| 151 | (uint_ >> ascii::alpha) [_val = build_if(std::wstring(_T("neg")), build_ic(_2, build_ii(_1)))]
|
|---|
| 152 | ]
|
|---|
| 153 | | number [_val = build_ii(_1)]
|
|---|
| 154 | | '-' >> number [_val = build_if(std::wstring(_T("neg")), build_ii(_1))]
|
|---|
| 155 | ;
|
|---|
| 156 |
|
|---|
| 157 | list_expr
|
|---|
| 158 | = value_list [_val = _1 ]
|
|---|
| 159 | ;
|
|---|
| 160 |
|
|---|
| 161 | value_list
|
|---|
| 162 | = string_literal [_val = build_is(_1) ]
|
|---|
| 163 | >> *( ',' >> string_literal ) [_val += build_is(_1) ]
|
|---|
| 164 | | number [_val = build_ii(_1) ]
|
|---|
| 165 | >> *( ',' >> number ) [_val += build_ii(_1) ]
|
|---|
| 166 | | variable_name [_val = build_is(_1) ]
|
|---|
| 167 | >> *( ',' >> variable_name ) [_val += build_is(_1) ]
|
|---|
| 168 | ;
|
|---|
| 169 |
|
|---|
| 170 | op = qi::lit("<=") [_val = op_le]
|
|---|
| 171 | | qi::lit("<") [_val = op_lt]
|
|---|
| 172 | | qi::lit("=") [_val = op_eq]
|
|---|
| 173 | | qi::lit("!=") [_val = op_ne]
|
|---|
| 174 | | qi::lit(">=") [_val = op_ge]
|
|---|
| 175 | | qi::lit(">") [_val = op_gt]
|
|---|
| 176 | | ascii::no_case[qi::lit("le")] [_val = op_le]
|
|---|
| 177 | | ascii::no_case[qi::lit("lt")] [_val = op_lt]
|
|---|
| 178 | | ascii::no_case[qi::lit("eq")] [_val = op_eq]
|
|---|
| 179 | | ascii::no_case[qi::lit("ne")] [_val = op_ne]
|
|---|
| 180 | | ascii::no_case[qi::lit("ge")] [_val = op_ge]
|
|---|
| 181 | | ascii::no_case[qi::lit("gt")] [_val = op_gt]
|
|---|
| 182 | | ascii::no_case[qi::lit("like")] [_val = op_like]
|
|---|
| 183 | | ascii::no_case[qi::lit("regexp")] [_val = op_regexp]
|
|---|
| 184 | | ascii::no_case[qi::lit("not like")] [_val = op_not_like]
|
|---|
| 185 | ;
|
|---|
| 186 |
|
|---|
| 187 | bitop = qi::lit("&") [_val = op_binand]
|
|---|
| 188 | | qi::lit("|") [_val = op_binor]
|
|---|
| 189 | ;
|
|---|
| 190 |
|
|---|
| 191 | number
|
|---|
| 192 | = uint_ [_val = _1]
|
|---|
| 193 | ;
|
|---|
| 194 | variable_name
|
|---|
| 195 | = qi::lexeme[+(ascii::alpha | ascii::char_('_')) [_val += _1]]
|
|---|
| 196 | ;
|
|---|
| 197 | string_literal
|
|---|
| 198 | = qi::lexeme[ '\''
|
|---|
| 199 | >> +( ascii::char_ - '\'' ) [_val += _1]
|
|---|
| 200 | >> '\'']
|
|---|
| 201 | ;
|
|---|
| 202 | string_literal_ex
|
|---|
| 203 | = qi::lexeme[ '('
|
|---|
| 204 | >> +( ascii::char_ - ')' ) [_val += _1]
|
|---|
| 205 | >> ')']
|
|---|
| 206 | ;
|
|---|
| 207 |
|
|---|
| 208 | // qi::on_error<qi::fail>( expression , std::wcout
|
|---|
| 209 | // << phoenix::val(_T("Error! Expecting "))
|
|---|
| 210 | // << _4 // what failed?
|
|---|
| 211 | // << phoenix::val(_T(" here: \""))
|
|---|
| 212 | // << phoenix::construct<std::wstring>(_3, _2) // iterators to error-pos, end
|
|---|
| 213 | // << phoenix::val(_T("\""))
|
|---|
| 214 | // << std::endl
|
|---|
| 215 | // );
|
|---|
| 216 |
|
|---|
| 217 | using phoenix::val;
|
|---|
| 218 | qi::on_error<qi::fail>( expression , std::cout << val("Error! Expecting ") << std::endl );
|
|---|
| 219 |
|
|---|
| 220 | // << ("Error! Expecting ")
|
|---|
| 221 | // << _4 // what failed?
|
|---|
| 222 | // << (" here: \"")
|
|---|
| 223 | // << construct<std::string>(_3, _2) // iterators to error-pos, end
|
|---|
| 224 | // << ("\"")
|
|---|
| 225 | // << std::endl
|
|---|
| 226 |
|
|---|
| 227 | }
|
|---|
| 228 |
|
|---|
| 229 | }
|
|---|
| 230 | }
|
|---|
| 231 |
|
|---|
| 232 |
|
|---|