OSDN Git Service

5d6d2e751024983688e6f862d4a159fdf2e263de
[nysol/mining.git] / include / kgCalParser.h
1 /* ////////// LICENSE INFO ////////////////////
2
3  * Copyright (C) 2013 by NYSOL CORPORATION
4  *
5  * Unless you have received this program directly from NYSOL pursuant
6  * to the terms of a commercial license agreement with NYSOL, then
7  * this program is licensed to you under the terms of the GNU Affero General
8  * Public License (AGPL) as published by the Free Software Foundation,
9  * either version 3 of the License, or (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF 
13  * NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
14  *
15  * Please refer to the AGPL (http://www.gnu.org/licenses/agpl-3.0.txt)
16  * for more details.
17
18  ////////// LICENSE INFO ////////////////////*/
19 // =============================================================================
20 // kgCalParser.h kgcal,kgselで用いる構文解析パーサークラス
21 // =============================================================================
22 #pragma once
23 #include <boost/spirit/include/classic.hpp>
24 #include <boost/spirit/include/classic_utility.hpp>
25 #include <boost/spirit/include/classic_ast.hpp>
26 #include <kgFunction.h>
27
28 using namespace boost::spirit::classic;
29 using namespace std;
30
31 namespace kgmod { ////////////////////////////////////////////// start namespace
32
33 struct kgCalParser : public grammar<kgCalParser>{
34 public:
35         // paserタグのセット
36         // 目的:parse時に定数,項目,関数(演算子)の区別を構文木のノードに
37         // 記録しておくため.setparamにてこのIDに基づき定数は値として評価し,
38         // 項目はCSVデータにおける項目番号として評価し,そして関数・演算子は
39         // 関数クラスのインスタンス化を行う.
40         // これらの値は構文木ノード構造体(struct tree_node)のメンバーである
41         // データ値構造体(struct node_val_data)のメンバーidにセットされる
42         static const int exprID       =  0; // 0固定
43         static const int constIDstr   =  1;
44         static const int constIDreal  =  2;
45         static const int constIDdate  =  3;
46         static const int constIDtime  =  4;
47         static const int constIDbool  =  5;
48         static const int fieldIDstr   =  6;
49         static const int fieldIDreal  =  7;
50         static const int fieldIDdate  =  8;
51         static const int fieldIDtime  =  9;
52         static const int fieldIDbool  = 10;
53         static const int pfieldIDstr  = 11;
54         static const int pfieldIDreal = 12;
55         static const int pfieldIDdate = 13;
56         static const int pfieldIDtime = 14;
57         static const int pfieldIDbool = 15;
58
59         template<typename ScannerT> struct definition{
60
61                 // 項目値用(文字列,整数,実数,日付,時刻,bool)
62                 rule<ScannerT, parser_context<>, parser_tag<fieldIDstr > > field_str;
63                 rule<ScannerT, parser_context<>, parser_tag<fieldIDreal> > field_real;
64                 rule<ScannerT, parser_context<>, parser_tag<fieldIDdate> > field_date;
65                 rule<ScannerT, parser_context<>, parser_tag<fieldIDtime> > field_time;
66                 rule<ScannerT, parser_context<>, parser_tag<fieldIDbool> > field_bool;
67
68                 // 前行項目値用(文字列,整数,実数,日付,時刻,bool)
69                 rule<ScannerT, parser_context<>, parser_tag<pfieldIDstr > > pfield_str;
70                 rule<ScannerT, parser_context<>, parser_tag<pfieldIDreal> > pfield_real;
71                 rule<ScannerT, parser_context<>, parser_tag<pfieldIDdate> > pfield_date;
72                 rule<ScannerT, parser_context<>, parser_tag<pfieldIDtime> > pfield_time;
73                 rule<ScannerT, parser_context<>, parser_tag<pfieldIDbool> > pfield_bool;
74
75                 // 定数値用(文字列,整数,実数,日付,時刻,bool)
76                 rule<ScannerT, parser_context<>, parser_tag<constIDstr > > const_str;
77                 rule<ScannerT, parser_context<>, parser_tag<constIDreal> > const_real;
78                 rule<ScannerT, parser_context<>, parser_tag<constIDdate> > const_date;
79                 rule<ScannerT, parser_context<>, parser_tag<constIDtime> > const_time;
80                 rule<ScannerT, parser_context<>, parser_tag<constIDbool> > const_bool;
81
82                 //関数・演算子用
83                 rule<ScannerT, parser_context<>, parser_tag<exprID> >
84                         term1,term2,term3,term4,term5,term6,term7,term8,expr,
85                         function1,function2,fctr;
86                         
87                 // 文法定義(コンストラクタ)
88                 definition(const kgCalParser& self){
89
90                         // -----------------------------------------------------------------------
91                         // [項目の指定] $x{xxx}の部分
92                         // ${項目名}   : 数値, 12  12.1
93                         // $s{項目名}  : 文字, "abc"
94                         // $d{項目名}  : 日付, 20080912
95                         // $t{項目名}  : 時刻, 121522
96                         // -----------------------------------------------------------------------
97                         // 文字列項目指定
98                         field_str = discard_node_d[*space_p >> str_p("$s{")]
99                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') ]]
100                                 >> discard_node_d[ch_p('}') >> *space_p];
101
102                         // 数値項目指定
103                         field_real = discard_node_d[*space_p >> str_p("${")]
104                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') ]]
105                                 >> discard_node_d[ch_p('}') >> *space_p];
106
107                         // 日付項目指定
108                         field_date =  discard_node_d[*space_p >> str_p("$d{")]
109                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') ]]
110                                 >> discard_node_d[ch_p('}') >> *space_p];
111
112                         // 時刻項目指定
113                         field_time = discard_node_d[*space_p >> str_p("$t{")]
114                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') ]]
115                                 >> discard_node_d[ch_p('}') >> *space_p];
116
117                         // bool項目指定
118                         field_bool = discard_node_d[*space_p >> str_p("$b{")]
119                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') ]]
120                                 >> discard_node_d[ch_p('}') >> *space_p];
121
122                         // -----------------------------------------------------------------------
123                         // [前行項目の指定]
124                         // #{項目名}   : 数値, 12  12.1
125                         // #s{項目名}  : 文字, "abc"
126                         // #d{項目名}  : 日付, 20080912
127                         // #t{項目名}  : 時刻, 121522
128                         // -----------------------------------------------------------------------
129                         // 文字列項目指定
130                         pfield_str = discard_node_d[*space_p >> str_p("#s{")]
131                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') | eps_p ]]
132                                 >> discard_node_d[ch_p('}') >> *space_p];
133
134                         // 数値項目指定
135                         pfield_real = discard_node_d[*space_p >> str_p("#{")]
136                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') | eps_p ]]
137                                 >> discard_node_d[ch_p('}') >> *space_p];
138
139                         // 日付項目指定
140                         pfield_date =  discard_node_d[*space_p >> str_p("#d{")]
141                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') | eps_p ]]
142                                 >> discard_node_d[ch_p('}') >> *space_p];
143
144                         // 時刻項目指定
145                         pfield_time = discard_node_d[*space_p >> str_p("#t{")]
146                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') | eps_p ]]
147                                 >> discard_node_d[ch_p('}') >> *space_p];
148
149                         // bool項目指定
150                         pfield_bool = discard_node_d[*space_p >> str_p("#b{")]
151                                 >> lexeme_d[leaf_node_d[ *(anychar_p-'}') | eps_p ]]
152                                 >> discard_node_d[ch_p('}') >> *space_p];
153
154                         // -----------------------------------------------------------------------
155                         // [定数の指定]
156                         // const_str  : 文字列, "abc"
157                         // const_real : 数値, 12 12.1
158                         // const_date : 日付, 0d20080912
159                         // const_time : 日付, 0t20080912121102
160                         // const_bin  : 2進数, 0b110100
161                         // const_oct  : 8進数, 0b7022
162                         // const_hex  : 16進数,0x8bff
163                         // -----------------------------------------------------------------------
164                         // 文字列の指定 "xxx"の部分
165                         const_str  = discard_node_d[*space_p >> ch_p('\"')]
166                         >> lexeme_d[leaf_node_d[*(c_escape_ch_p-'\"')]]
167                                 >> discard_node_d[ch_p('\"') >> *space_p];
168
169                         // 数値の指定
170                         const_real = discard_node_d[*space_p]
171                           >> leaf_node_d[real_p]
172                           >> discard_node_d[*space_p];
173
174                         // 日付の指定
175                         const_date = discard_node_d[*space_p >> str_p("0d")]
176                                 >> lexeme_d[leaf_node_d[repeat_p(8)[digit_p]]]
177                                 >> discard_node_d[*space_p];
178
179                         // 時刻の指定
180                         const_time = discard_node_d[*space_p >> str_p("0t")]
181                                 >> lexeme_d[leaf_node_d[repeat_p(14)[digit_p] | repeat_p(6)[digit_p] ]]
182                                 >> discard_node_d[*space_p];
183
184                         // boolの指定
185                         const_bool = discard_node_d[*space_p >> str_p("0b")]
186                                 >> lexeme_d[leaf_node_d[ch_p('0') | ch_p('1')]]
187                                 >> discard_node_d[*space_p];
188
189                         // -----------------------------------------------------------------------
190                         // [関数の指定] 
191                         // function1 : 引数をとる関数, fff(x1,x2,...)
192                         // function2 : 引数をとらない関数, fff()
193                         // -----------------------------------------------------------------------
194                         // 引数をとる関数
195                         function1 = root_node_d[leaf_node_d[
196                                    alpha_p >> *(alpha_p|digit_p|ch_p('_'))]]
197                                 >> discard_node_d[ch_p('(') >> *space_p]
198                                 >> ( expr % discard_node_d[ch_p(',') >> *space_p])
199                                 >> discard_node_d[ch_p(')')];
200
201                         // 引数をとらない関数
202                         function2 = root_node_d[leaf_node_d[alpha_p >> *(alpha_p|digit_p)]]
203                                 >> discard_node_d[str_p("(") >> *space_p >> str_p(")")];
204
205                         // 二項演算子の指定 (優先順位込み)
206                         expr = term7 % root_node_d[
207                                          discard_node_d[*space_p] >>
208                                          str_p("||")              >>
209                                          discard_node_d[*space_p] |
210                                          discard_node_d[*space_p] >>
211                                          str_p("^^")              >>
212                                          discard_node_d[*space_p]
213                                        ];
214
215                         term7= term4 % root_node_d[
216                                          discard_node_d[*space_p] >>
217                                          str_p("&&")              >>
218                                          discard_node_d[*space_p]
219                                        ];
220
221                         term4= term3 % root_node_d[
222                                          discard_node_d[*space_p] >>
223                                          str_p("==")              >>
224                                          discard_node_d[*space_p] |
225                                          discard_node_d[*space_p] >>
226                                          str_p("!=")              >>
227                                          discard_node_d[*space_p] 
228                                        ];
229
230                         term3= term2 % root_node_d[
231                                          discard_node_d[*space_p] >>
232                                          str_p(">=")              >>
233                                          discard_node_d[*space_p] |
234                                          discard_node_d[*space_p] >>
235                                          str_p("<=")              >>
236                                          discard_node_d[*space_p] |
237                                          discard_node_d[*space_p] >>
238                                          str_p(">")               >>
239                                          discard_node_d[*space_p] |
240                                          discard_node_d[*space_p] >>
241                                          str_p("<")               >>
242                                          discard_node_d[*space_p]
243                                        ];
244
245                         term2= term1 % root_node_d[
246                                          discard_node_d[*space_p] >>
247                                          str_p("+")              >>
248                                          discard_node_d[*space_p] |
249                                          discard_node_d[*space_p] >>
250                                          str_p("-")               >>
251                                          discard_node_d[*space_p]
252                                        ];
253
254                         term1= fctr  % root_node_d[
255                                          discard_node_d[*space_p] >>
256                                          str_p("*")               >>
257                                          discard_node_d[*space_p] |
258                                          discard_node_d[*space_p] >>
259                                          str_p("/")               >>
260                                          discard_node_d[*space_p] |
261                                          discard_node_d[*space_p] >>
262                                          str_p("%")               >>
263                                          discard_node_d[*space_p] |
264                                          discard_node_d[*space_p] >>
265                                          str_p("^")               >>
266                                          discard_node_d[*space_p]
267                                        ];
268
269                         fctr = function2  | function1  | const_date | const_time  |
270                                const_bool | const_real | const_str  |
271                                field_str  | field_real | field_date | field_time | field_bool |
272                                                  pfield_str |pfield_real |pfield_date |pfield_time |pfield_bool |
273                                inner_node_d[discard_node_d[*space_p]>>'('>>discard_node_d[*space_p]>>expr>>')'>>discard_node_d[*space_p]>>discard_node_d[*space_p]];            
274                 }
275                 rule<ScannerT, parser_context<>, parser_tag<exprID> >
276                 const& start() const {return expr;}
277         };
278 };
279
280 } //////////////////////////////////////////////////////////////////////////////
281