source: cfg_itronx+oil_gcc/toppers/oil/oil_parser.hpp@ 54

Last change on this file since 54 was 54, checked in by ertl-ishikawa, 12 years ago

cfg+oil対応コンフィギュレータを追加

File size: 17.9 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
6 *
7 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 */
37
38
39#ifndef OIL_PARSER_H
40#define OIL_PARSER_H
41
42#include <boost/spirit/include/classic_core.hpp>
43#include <boost/spirit/include/classic_error_handling.hpp>
44#include <boost/spirit/include/classic_ast.hpp>
45#include <boost/spirit/include/classic_functor_parser.hpp>
46#include <boost/spirit/include/classic_regex.hpp>
47#include <vector>
48#include <map>
49#include <algorithm>
50
51#include "toppers/text.hpp"
52#include "toppers/oil/oil_object.hpp"
53
54
55
56using namespace boost::spirit::classic;
57
58namespace toppers
59{
60 namespace oil
61 {
62 typedef std::vector<toppers::oil::oil_implementation::oil_object_impl*> oil_impl;
63 typedef std::vector<toppers::oil::oil_definition::object_definition*> oil_def;
64
65 class oil_parser
66 {
67 public:
68 oil_parser(std::string* txt , std::vector<std::string> const& objlist)
69 {
70 description = txt;
71 param_addable = true;
72 m_object_list = objlist;
73 }
74 ~oil_parser()
75 {
76 std::vector<toppers::oil::oil_implementation::oil_object_impl*>::iterator p;
77
78 for(p = impl_list.begin() ; p != impl_list.end() ; p++)
79 {
80 delete *p;
81 }
82
83 std::vector<toppers::oil::oil_definition::object_definition*>::iterator q;
84
85 for(q = def_list.begin() ; q != def_list.end() ; q++)
86 {
87 delete *q;
88 }
89 }
90 int do_parse(oil_impl **impl , oil_def **def);
91 int start_objimpl_analysis(std::string object_name);
92 int start_objdef_analysis(std::string object_name_type);
93 int add_parameter_objimpl(std::string parameter);
94 int set_nextparam_name(std::string name);
95 int add_attr_value(std::string str);
96 int end_objimpl_analysis(void);
97 int end_objdef_analysis(void);
98 void enable_addparam(bool enabled);
99 void dump_implementation(void);
100 void dump_definition(void);
101 void set_error(int position , std::string message);
102 void get_error(int *position , std::string *message);
103
104 std::string* get_description(void)
105 {
106 return description;
107 }
108 std::vector<std::string> m_object_list;
109 protected:
110 std::string *description;
111 oil_impl impl_list;
112 oil_def def_list;
113 private:
114 toppers::oil::oil_implementation::oil_object_impl* current_impl;
115 std::string next_param_name;
116 std::string attr_description;
117 bool param_addable;
118 toppers::oil::oil_definition::object_definition* current_def;
119 std::string error_message;
120 int error_position;
121 };
122
123 // 文法エラー種別
124 enum oil_grammer_error
125 {
126 open_brace , close_brace , semicolon , equal , keyword , comma
127 };
128 // 文法エラー型定義
129 typedef assertion<oil_grammer_error> oil_assertion;
130 typedef boost::spirit::classic::guard<oil_grammer_error> oil_error_guard;
131
132 // エラー処理ハンドラ
133 struct error_handler
134 {
135 oil_parser* container;
136 error_handler(oil_parser* _container) : container(_container)
137 {
138 }
139 template < class Scanner, class oil_grammer_error >
140 boost::spirit::classic::error_status<> operator()( Scanner const& scan, oil_grammer_error const& error ) const
141 {
142 std::string message;
143 int pos;
144 boost::spirit::classic::error_status<> result =
145 boost::spirit::classic::error_status<>( boost::spirit::classic::error_status<>::fail );
146
147 // エラー出現位置の算出
148 pos = error.where - &((container->get_description()->c_str())[0]);
149
150 // メッセージの登録
151 switch ( error.descriptor )
152 {
153 case open_brace:
154 message = "missing '{'";
155 break;
156 case close_brace:
157 message = "missing '}'";
158 break;
159 case semicolon:
160 message = "missing ';'";
161 break;
162 case equal:
163 message = "missing '='";
164 break;
165 case keyword:
166 message = "can't use keyword";
167 break;
168 case comma:
169 message = "missing ','";
170 break;
171 }
172
173 container->set_error(pos , message);
174 return result;
175 }
176 };
177
178 // ファンクタ
179 struct match_objimpl_name
180 {
181 oil_parser* container;
182 match_objimpl_name(oil_parser* _container) : container(_container)
183 {
184 }
185 void operator()(char const *first, char const *last) const
186 {
187 std::string str(first , last);
188 std::vector<std::string>::iterator p;
189 bool hit = false;
190
191 for(p = container->m_object_list.begin() ; p != container->m_object_list.end() ; p++)
192 {
193 if(*p == str)
194 {
195 hit = true;
196 break;
197 }
198 }
199 container->start_objimpl_analysis(str);
200 }
201 };
202
203 struct find_implparam_name
204 {
205 oil_parser* container;
206 find_implparam_name(oil_parser* _container) : container(_container)
207 {
208 }
209
210 void operator()(char const *first, char const *last) const
211 {
212 string str(first , last);
213 container->set_nextparam_name(str);
214 }
215 };
216
217 struct match_impl_parameter
218 {
219 oil_parser* container;
220 match_impl_parameter(oil_parser* _container) : container(_container)
221 {
222 }
223
224 void operator()(char const *first, char const *last) const
225 {
226 string str(first , last);
227 container->add_parameter_objimpl(str);
228 }
229 };
230
231 // 実装部の閉じ括弧を検出するファンクタ
232 struct match_objimpl_end
233 {
234 oil_parser* container;
235 match_objimpl_end(oil_parser* _container) : container(_container)
236 {
237 }
238
239 void operator()(char val) const
240 {
241 container->end_objimpl_analysis();
242 }
243 };
244
245 // オブジェクト定義先頭を検出するファンクタ
246 struct match_objdef_name
247 {
248 oil_parser* container;
249 match_objdef_name(oil_parser* _container) : container(_container)
250 {
251 }
252 void operator()(char const *first, char const *last) const
253 {
254 string str(first , last);
255 container->start_objdef_analysis(str);
256 }
257 };
258
259 // パラメータ定義を追加するファンクタ
260 struct find_attrname
261 {
262 oil_parser* container;
263 find_attrname(oil_parser* _container) : container(_container)
264 {
265 }
266 void operator()(char const *first, char const *last) const
267 {
268 string str(first , last);
269 container->set_nextparam_name(str);
270 }
271 };
272
273 // オブジェクト定義終端を検出するファンクタ
274 struct match_objdef_end
275 {
276 oil_parser* container;
277 match_objdef_end(oil_parser* _container) : container(_container){}
278
279 void operator()(char val) const
280 {
281 container->end_objdef_analysis();
282 }
283 };
284
285 // 定義部のパラメータタイプを識別するファンクタ
286 struct find_attribute
287 {
288 oil_parser* container;
289 find_attribute(oil_parser* _container) : container(_container)
290 {
291 }
292 void operator()(char const *first, char const *last) const
293 {
294 string str(first , last);
295 container->add_attr_value(str);
296 }
297 };
298
299 // 定義部のパラメータタイプを識別する(浮動小数点版)
300 struct find_attribute_float
301 {
302 oil_parser* container;
303 find_attribute_float(oil_parser* _container) : container(_container)
304 {
305 }
306 void operator()(double val) const
307 {
308 char buf[256];
309 // modified by takuya 110823
310 //sprintf_s(buf , "%lf" , val);
311 sprintf(buf , "%lf" , val);
312 string str(buf);
313
314 container->add_attr_value(str);
315 }
316 };
317
318
319
320 // ENUM中のパラメータ無視するためのファンクタ
321 struct enum_start
322 {
323 oil_parser* container;
324 enum_start(oil_parser* _container) : container(_container){}
325
326 void operator()(char val) const
327 {
328 container->enable_addparam(false);
329 }
330 };
331
332 // ENUM中のパラメータ無視を解除するためのファンクタ
333 struct enum_end
334 {
335 oil_parser* container;
336 enum_end(oil_parser* _container) : container(_container){}
337
338 void operator()(char val) const
339 {
340 container->enable_addparam(true);
341 }
342 };
343
344 // OILパーサクラス
345 struct oil_grammer : public grammar<oil_grammer>
346 {
347 oil_parser* m_container;
348 oil_grammer(oil_parser* container)
349 {
350 m_container = container;
351 }
352 template <typename T> struct definition
353 {
354 // 文法エラー種類定義
355 oil_assertion assertion_open_brace , assertion_close_brace , assertion_semicolon;
356 oil_assertion assertion_equal , assertion_keyword , assertion_comma;
357 // エラーハンドリング定義
358 oil_error_guard guard_implementation , guard_object , guard_object_def;
359
360 // BNF
361 rule<T> file;
362 rule<T> oil_version , implementation_definition , application_definition;
363 rule<T> implementation_spec_list , implementation_spec , implementation_def;
364 rule<T> object , object_ref_type , object_name , object_temp;
365
366 rule<T> name , null_str , boolean , string_literal;
367 rule<T> multiple_specifier , auto_specifier;
368 rule<T> number_range , number_list , number , float_range , default_number , default_float;
369 rule<T> attribute_name;
370 rule<T> default_string , default_bool , default_name;
371 rule<T> bool_values;
372 rule<T> enumerator , enumeration , enumerator_list;
373
374 rule<T> impl_parameter_list;
375
376 rule<T> uint32_impl_attr_def , int32_impl_attr_def , uint64_impl_attr_def , int64_impl_attr_def;
377 rule<T> float_impl_attr_def , string_impl_attr_def , bool_impl_attr_def , enum_impl_attr_def;
378 rule<T> reference_name;
379 rule<T> impl_attr_def , impl_ref_def;
380
381 rule<T> object_definition;
382 rule<T> parameter , attribute_value;
383
384 definition(oil_grammer const& self) :
385 assertion_open_brace(open_brace) ,
386 assertion_close_brace(close_brace) ,
387 assertion_semicolon(semicolon) ,
388 assertion_equal(equal) ,
389 assertion_keyword(keyword) ,
390 assertion_comma(comma)
391 {
392 // 記号関係
393 null_str = str_p("");
394 name = (alpha_p | ch_p('_')) >> +(alnum_p | ch_p('_'));
395 string_literal = ch_p('"') >> name >> ch_p('"');
396 multiple_specifier = !(ch_p('[') >> ch_p(']'));
397 auto_specifier = !str_p("WITH_AUTO");
398 number = (str_p("0x") >> +xdigit_p) | (str_p("0X") >> xdigit_p) | int_p | uint_p;
399 boolean = str_p("TRUE") | str_p("FALSE");
400
401 // レンジ、デフォルト値
402 number_list = ch_p('[') >> number >> *(ch_p(',') >> number) >> ch_p(']');
403 number_range = !((ch_p('[') >> number >> str_p("..") >> number >> ch_p(']'))
404 | number_list);
405 default_number = !((ch_p('=') >> number)
406 | (ch_p('=') >> str_p("NO_DEFAULT"))
407 | (ch_p('=') >> str_p("AUTO")));
408 float_range = !(ch_p('[') >> real_p >> str_p("..") >> real_p >> ch_p(']'));
409 default_float = !((ch_p('=') >> real_p)
410 | (ch_p('=') >> str_p("NO_DEFAULT"))
411 | (ch_p('=') >> str_p("AUTO")));
412
413 enumerator = name >> !(ch_p('{') >> implementation_def >> ch_p('}'));
414 enumerator_list = enumerator >> *(ch_p(',') >> enumerator);
415 enumeration = ch_p('[')[enum_start(self.m_container)] >>
416 enumerator_list >> ch_p(']')[enum_end(self.m_container)];
417
418 default_name = !((ch_p('=') >> name)
419 | (ch_p('=') >> str_p("NO_DEFAULT"))
420 | (ch_p('=') >> str_p("AUTO")));
421
422 attribute_name = name | object;
423 attribute_value = (boolean >> !(ch_p('{')[enum_start(self.m_container)] >>
424 *parameter >> (ch_p('}')[enum_end(self.m_container)])))
425 [find_attribute(self.m_container)]
426 | number[find_attribute(self.m_container)]
427 | real_p[find_attribute_float(self.m_container)]
428 | string_literal[find_attribute(self.m_container)]
429 /*
430 * modified by takuya 110823
431 * AUTOは下の定義で代用可能
432 */
433 | (name >> !(ch_p('{')[enum_start(self.m_container)] >>
434 *parameter >> ch_p('}')[enum_end(self.m_container)]))
435 [find_attribute(self.m_container)];
436
437 default_string = !((ch_p('=') >> ch_p('"') >> name >> ch_p('"'))
438 | (ch_p('=') >> str_p("NO_DEFAULT"))
439 | (ch_p('=') >> str_p("AUTO")));
440 default_bool = !((ch_p('=') >> boolean)
441 | (ch_p('=') >> str_p("NO_DEFAULT"))
442 | (ch_p('=') >> str_p("AUTO")));
443 bool_values = !(ch_p('[')[enum_start(self.m_container)] >>
444 str_p("TRUE") >> !(ch_p('{') >> implementation_def >> ch_p('}')) >>
445 ch_p(',') >>
446 str_p("FALSE") >> !(ch_p('{') >> implementation_def >> ch_p('}')) >>
447 ch_p(']')[enum_end(self.m_container)]);
448
449 std::vector<std::string>::iterator p;
450 std::string objtype = "(" , objref = "(";
451
452 // 正規表現のリストを作成
453 for(p = self.m_container->m_object_list.begin() ; p != self.m_container->m_object_list.end() ; p++)
454 {
455 objtype += (*p) + "|";
456 objref += (*p) + "_TYPE" + "|";
457 }
458
459 objtype[objtype.size() - 1] = ')';
460 objref[objref.size() - 1] = ')';
461
462 object = regex_p(objtype.c_str());
463 object_ref_type = regex_p(objref.c_str());
464
465 // オブジェクト定義
466 parameter = attribute_name[find_attrname(self.m_container)] >>
467 assertion_equal(ch_p("=")) >> attribute_value >>
468 assertion_semicolon(ch_p(";"));
469 object_name = (object >> name)[match_objdef_name(self.m_container)];
470 object_definition = guard_object(
471 object_name >> assertion_open_brace(ch_p('{')) >>
472 *parameter >> assertion_close_brace(ch_p('}')) >>
473 assertion_semicolon(ch_p(';'))[match_objdef_end(self.m_container)])
474 [error_handler(self.m_container)];
475
476 // 型別のパラメータ指定子
477 uint32_impl_attr_def = str_p("UINT32") >> auto_specifier >> number_range >>
478 attribute_name[find_implparam_name(self.m_container)] >>
479 multiple_specifier >> default_number >>
480 assertion_semicolon(ch_p(';'));
481 int32_impl_attr_def = str_p("INT32") >> auto_specifier >> number_range >>
482 attribute_name[find_implparam_name(self.m_container)] >>
483 multiple_specifier >> default_number >>
484 assertion_semicolon(ch_p(';'));
485 uint64_impl_attr_def = str_p("UINT64") >> auto_specifier >> number_range >>
486 attribute_name[find_implparam_name(self.m_container)] >>
487 multiple_specifier >> default_number >>
488 assertion_semicolon(ch_p(';'));
489 int64_impl_attr_def = str_p("INT64") >> auto_specifier >> number_range >>
490 attribute_name[find_implparam_name(self.m_container)] >>
491 multiple_specifier >> default_number >>
492 assertion_semicolon(ch_p(';'));
493 float_impl_attr_def = str_p("FLOAT") >> auto_specifier >> float_range >>
494 attribute_name[find_implparam_name(self.m_container)] >>
495 multiple_specifier >> default_float >>
496 assertion_semicolon(ch_p(';'));
497 string_impl_attr_def = str_p("STRING") >> auto_specifier >>
498 attribute_name[find_implparam_name(self.m_container)] >>
499 multiple_specifier >> default_string >>
500 assertion_semicolon(ch_p(';'));
501 bool_impl_attr_def = str_p("BOOLEAN") >>
502 auto_specifier >> bool_values >>
503 attribute_name[find_implparam_name(self.m_container)] >>
504 multiple_specifier >> default_bool >>
505 assertion_semicolon(ch_p(';'));
506 enum_impl_attr_def = str_p("ENUM") >>
507 auto_specifier >> enumeration >>
508 attribute_name[find_implparam_name(self.m_container)] >>
509 multiple_specifier >> default_name >>
510 assertion_semicolon(ch_p(';'));
511
512 // 属性値
513 impl_attr_def = uint32_impl_attr_def | int32_impl_attr_def
514 | uint64_impl_attr_def | int64_impl_attr_def
515 | float_impl_attr_def | string_impl_attr_def
516 | bool_impl_attr_def | enum_impl_attr_def;
517
518 reference_name = name | object;
519 impl_ref_def = object_ref_type >> reference_name[find_implparam_name(self.m_container)] >>
520 multiple_specifier >> assertion_semicolon(ch_p(';'));
521
522 // パラメータの形式
523 implementation_def = *((impl_attr_def | impl_ref_def)
524 [match_impl_parameter(self.m_container)]);
525
526 // 本体定義
527 application_definition =
528 str_p("CPU") >> name >> ch_p('{') >>
529 *object_definition >> ch_p('}') >> ch_p(';');
530
531 // 大きな単位の文法
532 implementation_spec =
533 guard_object(object[match_objimpl_name(self.m_container)] >>
534 assertion_open_brace(ch_p('{')) >>
535 implementation_def >>
536 assertion_close_brace(ch_p('}')) >>
537 assertion_semicolon(ch_p(';')[match_objimpl_end(self.m_container)]))
538 [error_handler(self.m_container)];
539 implementation_spec_list = *implementation_spec;
540
541 implementation_definition = "IMPLEMENTATION" >> name >> ch_p('{')
542 >> implementation_spec_list >> ch_p('}') >> ch_p(';');
543
544 oil_version = str_p("OIL_VERSION")
545 >> ch_p('=') >> ch_p('\"') >> real_p >> ch_p('\"') >> ch_p(';'); //
546 file = oil_version >> implementation_definition >> application_definition >> *space_p;
547 };
548 rule<T> const& start() const
549 {
550 return file; // 定義したルールを返す
551 }
552 };
553
554 };
555
556
557 }
558}
559
560#endif /* OIL_PARSER_H */
Note: See TracBrowser for help on using the repository browser.