source: nscp/include/parsers/where/grammar/grammar_impl.hpp @ 79f191a

stable
Last change on this file since 79f191a was 79f191a, checked in by Michael Medin <michael@…>, 23 months ago

Release of 0.3.9

  • Property mode set to 100644
File size: 7.7 KB
Line 
1#include <parsers/where/grammar/grammar.hpp>
2#include <iostream>
3#include <fstream>
4
5
6namespace qi = boost::spirit::qi;
7namespace ascii = boost::spirit::ascii;
8namespace phoenix = boost::phoenix;
9
10namespace 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
Note: See TracBrowser for help on using the repository browser.