00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef JDL_GRAMMAR_HPP_
00019 #define JDL_GRAMMAR_HPP_
00020
00021 #include "defs.hpp"
00022
00023 #define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
00024 #define BOOST_SPIRIT_ASSERT_EXCEPTION
00025
00026
00027
00028 #ifdef DEBUG
00029 #define BOOST_SPIRIT_DEBUG
00030 #endif
00031
00032 #include <boost/spirit/core.hpp>
00033 #include <boost/spirit/attribute.hpp>
00034 #include <boost/spirit/actor/push_back_actor.hpp>
00035 #include <boost/spirit/error_handling/exceptions.hpp>
00036 #include <boost/spirit/utility/confix.hpp>
00037
00038
00039 #include <jdl_parser/tree.hpp>
00040 #include <jdl_parser/utils.hpp>
00041
00042 using namespace boost::spirit;
00043
00044 namespace jdl{
00046
00047
00048
00050 enum Errors{
00051 attribute_expected,
00052 expr_expected,
00053 attrname_expected,
00054 semicolon_expected,
00055 colon_expected,
00056 right_quad_par_expected,
00057 right_round_par_expected,
00058 right_graph_par_expected,
00059 question_mark_expected,
00060 left_round_par_expected
00061 };
00062
00063 assertion<Errors> expect_attribute(attribute_expected);
00064 assertion<Errors> expect_expr(expr_expected);
00065 assertion<Errors> expect_attrname(expect_attrname);
00066 assertion<Errors> expect_semicolon(semicolon_expected);
00067 assertion<Errors> expect_colon(colon_expected);
00068 assertion<Errors> expect_right_quad_par(right_quad_par_expected);
00069 assertion<Errors> expect_right_round_par(right_round_par_expected);
00070 assertion<Errors> expect_right_graph_par(right_graph_par_expected);
00071 assertion<Errors> expect_question_mark(question_mark_expected);
00072 assertion<Errors> expect_left_round_par(left_round_par_expected);
00073
00074 guard<Errors> expr_guard;
00076
00077
00078
00080
00081 void create(attribute_definition_node &node, parser_stack<boost::shared_ptr<component> >& stack);
00082
00083 void create(conditional_expr& node, parser_stack<boost::shared_ptr<component> >& stack);
00084
00085 void create(binary_expr_node& node, parser_stack<boost::shared_ptr<component> >& stack);
00086
00087 void create(bracket_node& node, parser_stack<boost::shared_ptr<component> >& stack);
00088
00089 void create(dot_node& node, parser_stack<boost::shared_ptr<component> >& stack);
00090
00091 void create(term_node& node, parser_stack<boost::shared_ptr<component> >& stack);
00092
00093 void create(list_node& node, parser_stack<boost::shared_ptr<component> >& stack);
00094
00095 void create(func_call_node& node, parser_stack<boost::shared_ptr<component> >& stack);
00096
00097 void create(unary_expr_node& node, parser_stack<boost::shared_ptr<component> >& stack);
00098
00099 template <typename node_type>
00100 struct push
00101 {
00102 push(parser_stack<boost::shared_ptr<component> >& node_stack)
00103 : _node_stack(node_stack) {}
00104
00105 void operator()(char const*, char const*) const
00106 {
00107 #ifdef DEBUG
00108 Logger::getInstance().debug().out << "Pushing new NODE into stack: " << typeid(node_type).name() << endl;
00109 #endif
00110 boost::shared_ptr<node_type> node(new node_type());
00111 create(*node, _node_stack);
00112 _node_stack.push(node);
00113 #ifdef DEBUG
00114 _node_stack.print(cout);
00115 #endif
00116 }
00117 parser_stack<boost::shared_ptr<component> >& _node_stack;
00118 };
00119
00120 template <typename node_type>
00121 struct push_leaf
00122 {
00123 push_leaf(parser_stack<boost::shared_ptr<component> >& node_stack)
00124 : _node_stack(node_stack) {}
00125
00126 void operator()(char const* begin, char const* end) const
00127 {
00128 #ifdef DEBUG
00129 Logger::getInstance().debug().out << "Pushing new LEAF into stack: " << typeid(node_type).name() << endl;
00130 #endif
00131 boost::shared_ptr<component> node(new node_type(begin,end));
00132 _node_stack.push(node);
00133 #ifdef DEBUG
00134 _node_stack.print(cout);
00135 #endif
00136 }
00137 parser_stack<boost::shared_ptr<component> >& _node_stack;
00138 };
00139
00140 void create_activation_record(parser_stack<boost::shared_ptr<component> >& node_stack);
00141
00142 struct new_ar
00143 {
00144 new_ar(parser_stack<boost::shared_ptr<component> >& node_stack)
00145 : _node_stack(node_stack) {}
00146
00147 void operator()(char const c) const
00148 {
00149 create_activation_record(_node_stack);
00150 }
00151
00152 void operator()(char const* begin, char const* end) const
00153 {
00154 create_activation_record(_node_stack);
00155 }
00156
00157 parser_stack<boost::shared_ptr<component> >& _node_stack;
00158 };
00159
00160 void reduce_stack(parser_stack<boost::shared_ptr<component> >& node_stack);
00161
00162 struct reduce
00163 {
00164 reduce(parser_stack<boost::shared_ptr<component> >& node_stack)
00165 : _node_stack(node_stack) {}
00166
00167 void operator()(char const c) const
00168 {
00169 reduce_stack(_node_stack);
00170 }
00171
00172 void operator()(char const* begin, char const* end) const
00173 {
00174 reduce_stack(_node_stack);
00175 }
00176
00177 parser_stack<boost::shared_ptr<component> >& _node_stack;
00178 };
00179
00180 void discard_activation_record(parser_stack<boost::shared_ptr<component> >& node_stack);
00181
00182 struct discard
00183 {
00184 discard(parser_stack<boost::shared_ptr<component> >& node_stack)
00185 : _node_stack(node_stack) {}
00186
00187 void operator()(char const c) const
00188 {
00189 #ifdef DEBUG
00190 Logger::getInstance().debug().out << "Discarding activation record." << endl;
00191 #endif
00192 discard_activation_record(_node_stack);
00193 }
00194
00195 void operator()(char const* begin, char const* end) const
00196 {
00197 #ifdef DEBUG
00198 Logger::getInstance().debug().out << "Discarding activation record." << endl;
00199 #endif
00200 discard_activation_record(_node_stack);
00201 }
00202
00203 parser_stack<boost::shared_ptr<component> >& _node_stack;
00204 };
00205
00207
00208
00209
00211 struct discard_ar
00212 {
00213 discard_ar(parser_stack<boost::shared_ptr<component> >& node_stack)
00214 : _node_stack(node_stack) {}
00215
00216 template <typename ScannerT, typename ErrorT>
00217 error_status<>
00218 operator()(ScannerT const& , ErrorT const& error) const
00219 {
00220 #ifdef DEBUG
00221 cout << "Discarding activation record." << endl;
00222 #endif
00223 if(error.descriptor == question_mark_expected ||
00224 error.descriptor == left_round_par_expected){
00225 discard_activation_record(_node_stack);
00226 _node_stack.new_ar();
00227 #ifdef DEBUG
00228 _node_stack.print(cout);
00229 #endif
00230 return error_status<>(error_status<>::fail);
00231 }else{
00232 #ifdef BOOST_SPIRIT_DEBUG
00233 cout << "Rethrowing error!" << endl;
00234 cout << "Error type: " << error.descriptor << endl;
00235 #endif
00236 return error_status<>(error_status<>::rethrow);
00237 }
00238 }
00239 parser_stack<boost::shared_ptr<component> >& _node_stack;
00240 };
00241
00243
00244
00245
00247 struct jdl_grammar : public grammar<jdl_grammar>
00248 {
00249 jdl_grammar(parser_stack<boost::shared_ptr<component> >& stack): node_stack(stack){}
00250
00251 template <typename ScannerT>
00252 struct definition
00253 {
00254
00255 definition(jdl_grammar const& self)
00256 {
00257
00258
00259
00260
00261 def_list =
00262
00263 ( +( attribute_definition >>
00264 expect_semicolon(ch_p(';')[new_ar(self.node_stack)])
00265 | comment
00266 )
00267 )[discard(self.node_stack)][push<term_node>(self.node_stack)]
00268
00269 | record_expression >> !ch_p(';')
00270 ;
00271
00272 comment =
00273 comment_p("//")
00274 | comment_p("#")
00275 ;
00276
00277
00278
00279
00280
00281 expression =
00282 expr_guard( (simple_expression >>
00283 expect_question_mark(ch_p('?')[new_ar(self.node_stack)]) >>
00284 expect_expr(expression)[reduce(self.node_stack)] >>
00285 expect_colon(ch_p(':')[new_ar(self.node_stack)]) >>
00286 expect_expr(expression)[reduce(self.node_stack)])[push<conditional_expr>(self.node_stack)])[discard_ar(self.node_stack)]
00287 | simple_expression
00288 ;
00289
00290
00291
00292
00293 simple_expression =
00294 term1 >>
00295 *( (level1_op[push_leaf<string_node>(self.node_stack)][new_ar(self.node_stack)] >>
00296 term1[reduce(self.node_stack)])[push<binary_expr_node>(self.node_stack)]
00297 )
00298 ;
00299
00300
00301
00302
00303 term1 =
00304 term2 >>
00305 *( (level2_op[push_leaf<string_node>(self.node_stack)][new_ar(self.node_stack)] >>
00306 term2[reduce(self.node_stack)])[push<binary_expr_node>(self.node_stack)]
00307 )
00308 ;
00309
00310
00311
00312
00313
00314 term2 =
00315 term3 >>
00316 *( (level3_op[push_leaf<string_node>(self.node_stack)][new_ar(self.node_stack)] >>
00317 term3[reduce(self.node_stack)])[push<binary_expr_node>(self.node_stack)]
00318 )
00319 ;
00320
00321
00322
00323
00324 term3 =
00325 term4 >>
00326 *( (level4_op[push_leaf<string_node>(self.node_stack)][new_ar(self.node_stack)] >>
00327 term4[reduce(self.node_stack)])[push<binary_expr_node>(self.node_stack)]
00328 )
00329 ;
00330
00331
00332
00333
00334 term4 =
00335 term5 >>
00336 *( (level5_op[push_leaf<string_node>(self.node_stack)][new_ar(self.node_stack)] >>
00337 term5[reduce(self.node_stack)])[push<binary_expr_node>(self.node_stack)]
00338 )
00339 ;
00340
00341
00342
00343
00344 term5 =
00345 factor >>
00346 *( (level6_op[push_leaf<string_node>(self.node_stack)][new_ar(self.node_stack)] >>
00347 factor[reduce(self.node_stack)])[push<binary_expr_node>(self.node_stack)]
00348 )
00349 ;
00350
00351
00352
00353
00354
00355 factor =
00356 (unary_op[push_leaf<string_node>(self.node_stack)][new_ar(self.node_stack)] >>
00357 suffix_expr[reduce(self.node_stack)])[push<unary_expr_node>(self.node_stack)]
00358 | suffix_expr
00359 ;
00360
00361 level1_op =
00362 lexeme_d[
00363 longest_d[chseq_p("||") | "&&"]]
00364 ;
00365
00366 level2_op =
00367 lexeme_d[
00368 longest_d[chseq_p("|") | '&' | '^'] ] - "&&" - "||"
00369 ;
00370
00371 level3_op =
00372 lexeme_d[
00373 longest_d[chseq_p("==") | "!=" | "is" | "isnt"
00374 | '<' | '>' | "<=" | ">="]] - "<<" - ">>" - ">>>"
00375 ;
00376
00377 level4_op =
00378 lexeme_d[
00379 longest_d[chseq_p("<<") | ">>" | ">>>"]]
00380 ;
00381
00382 level5_op =
00383 lexeme_d[
00384 longest_d[chseq_p("+") | '-']]
00385 ;
00386
00387 level6_op =
00388 lexeme_d[
00389 longest_d[chseq_p("*") | '/' | '%']]
00390 ;
00391
00392 unary_op =
00393 lexeme_d[ch_p('+') | '-' | '~' | '!' ]
00394 ;
00395
00396
00397
00398
00399 suffix_expr =
00400 (atom >>
00401 *( (ch_p('.')[new_ar(self.node_stack)] >>
00402 expect_attrname(attribute_name))[reduce(self.node_stack)][push<dot_node>(self.node_stack)]
00403 |
00404 (ch_p('[')[new_ar(self.node_stack)] >>
00405 expect_expr(expression) >> expect_right_quad_par(ch_p(']')))[reduce(self.node_stack)][push<bracket_node>(self.node_stack)] )
00406 )
00407 ;
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 atom =
00419 ( '(' >> expect_expr(expression) >> expect_right_round_par(ch_p(')')) )
00420 | list_expression[push<list_node>(self.node_stack)]
00421 | record_expression
00422 | function_call[push<func_call_node>(self.node_stack)]
00423 | literal
00424 | attribute_name
00425 | keywords
00426 ;
00427
00428 keywords =
00429 lexeme_d[(chseq_p("error") | "false" | "true" | "undefined" | "parent")[push_leaf<string_node>(self.node_stack)]]
00430 ;
00431
00432
00433
00434
00435 list_expression =
00436 ch_p('{')[new_ar(self.node_stack)] >>
00437 (ch_p('}')[discard(self.node_stack)]
00438 | list_expr_list)
00439 ;
00440
00441
00442
00443
00444 list_expr_list =
00445 expect_expr(expression)[reduce(self.node_stack)] >>
00446 (ch_p(',')[new_ar(self.node_stack)] >> list_expr_list
00447 | expect_right_graph_par(ch_p('}')) )
00448 ;
00449
00450
00451
00452
00453 record_expression =
00454 (ch_p('[')[new_ar(self.node_stack)] >>
00455 attribute_def_list
00456 | ch_p(']'))[push<term_node>(self.node_stack)]
00457 ;
00458
00459
00460
00461
00462
00463 attribute_def_list =
00464 (comment >> (ch_p(']') | attribute_def_list))
00465 | expect_attribute(attribute_definition) >>
00466 ( !ch_p(';') >> *comment >> ch_p(']')
00467 | expect_semicolon(ch_p(';'))[new_ar(self.node_stack)] >> attribute_def_list)
00468 ;
00469
00470
00471
00472
00473 attribute_definition =
00474 (attribute_name >>
00475 ch_p('=')[new_ar(self.node_stack)] >>
00476 expect_expr(expression)[reduce(self.node_stack)])[push<attribute_definition_node>(self.node_stack)]
00477 ;
00478
00479
00480
00481
00482 function_call =
00483 expr_guard(unquoted_name[push_leaf<string_node>(self.node_stack)] >>
00484 ( expect_left_round_par(ch_p('('))[new_ar(self.node_stack)] >>
00485 !( expect_expr(expression) >>
00486 *( (ch_p(',')[new_ar(self.node_stack)] >> expect_expr(expression) )[reduce(self.node_stack)])
00487 ) >> expect_right_round_par(ch_p(')'))
00488 )[push<term_node>(self.node_stack)][reduce(self.node_stack)])[discard_ar(self.node_stack)]
00489 ;
00490
00491
00492
00493
00494 attribute_name =
00495 (unquoted_name
00496 | quoted_name)[push_leaf<string_node>(self.node_stack)]
00497 ;
00498
00499
00500
00501
00502 literal =
00503 floating_point_literal[push_leaf<float_node>(self.node_stack)]
00504 | integer_literal[push_leaf<int_node>(self.node_stack)]
00505 | string_literal
00506 ;
00507
00508
00509
00510
00511
00512
00513 floating_point_literal =
00514 +uint_p >> '.' >> *uint_p >> !exponent
00515 | '.' >> +uint_p >> !exponent
00516 | +uint_p >> exponent
00517 ;
00518
00519
00520
00521
00522 exponent =
00523 lexeme_d[( ch_p('e') | 'E' ) >> !( ch_p('+') | '-' ) >> +uint_p ]
00524 ;
00525
00526 nonzero_digit =
00527 range_p('1','9')
00528 ;
00529
00530 integer_literal =
00531 nonzero_digit >> *uint_p
00532 | lexeme_d[ ('0' >> *oct_p) ]
00533 | lexeme_d[ ('0' >> ( ch_p('x') | 'X' ) >> +hex_p) ]
00534 ;
00535
00536 string_literal =
00537 ch_p('\"') >> ( *( non_quote | '\'' ) )[push_leaf<string_literal_node>(self.node_stack)] >> '\"'
00538 ;
00539
00540 escaped_char =
00541 lexeme_d[ch_p('n') | 't' | 'b' | 'r' | 'f' | '\\' | '\"' | '\'']
00542 ;
00543
00544 non_quote =
00545 ('\\' >> escaped_char
00546 | lexeme_d['\\' >> oct_p >> !oct_p]
00547 | lexeme_d['\\' >> range_p('0','3') >> oct_p >> oct_p]
00548 | ~ch_p('\"'))
00549 ;
00550
00551 quoted_name =
00552 ch_p('\'') >> (+( non_quote | '\"' )) >> '\''
00553 ;
00554
00555 unquoted_name =
00556 (lexeme_d[( alpha_p | '_' ) >> *( alpha_p | uint_p | '_' )])
00557 - "error" - "true" - "false" - "undefined" - "parent"
00558 ;
00559
00560 BOOST_SPIRIT_DEBUG_NODE(attribute_definition);
00561 BOOST_SPIRIT_DEBUG_NODE(attribute_def_list);
00562 BOOST_SPIRIT_DEBUG_NODE(function_call);
00563 BOOST_SPIRIT_DEBUG_NODE(list_expression);
00564 BOOST_SPIRIT_DEBUG_NODE(atom);
00565 BOOST_SPIRIT_DEBUG_NODE(suffix_expr);
00566 BOOST_SPIRIT_DEBUG_NODE(unary_op);
00567 BOOST_SPIRIT_DEBUG_NODE(factor);
00568 BOOST_SPIRIT_DEBUG_NODE(binary_op);
00569 BOOST_SPIRIT_DEBUG_NODE(simple_expression);
00570 BOOST_SPIRIT_DEBUG_NODE(expression);
00571 BOOST_SPIRIT_DEBUG_NODE(record_expression);
00572 BOOST_SPIRIT_DEBUG_NODE(comment);
00573 BOOST_SPIRIT_DEBUG_NODE(def_list);
00574 BOOST_SPIRIT_DEBUG_NODE(escaped_char);
00575 BOOST_SPIRIT_DEBUG_NODE(string_literal);
00576 BOOST_SPIRIT_DEBUG_NODE(letter);
00577 BOOST_SPIRIT_DEBUG_NODE(exponent);
00578 BOOST_SPIRIT_DEBUG_NODE(floating_point_literal);
00579 BOOST_SPIRIT_DEBUG_NODE(integer_literal);
00580 BOOST_SPIRIT_DEBUG_NODE(non_quote);
00581 BOOST_SPIRIT_DEBUG_NODE(quoted_name);
00582 BOOST_SPIRIT_DEBUG_NODE(unquoted_name);
00583 BOOST_SPIRIT_DEBUG_NODE(literal);
00584 BOOST_SPIRIT_DEBUG_NODE(term1);
00585 BOOST_SPIRIT_DEBUG_NODE(term2);
00586 BOOST_SPIRIT_DEBUG_NODE(term3);
00587 BOOST_SPIRIT_DEBUG_NODE(term4);
00588 BOOST_SPIRIT_DEBUG_NODE(term5);
00589 BOOST_SPIRIT_DEBUG_NODE(level1_op);
00590 BOOST_SPIRIT_DEBUG_NODE(level2_op);
00591 BOOST_SPIRIT_DEBUG_NODE(level3_op);
00592 BOOST_SPIRIT_DEBUG_NODE(level4_op);
00593 BOOST_SPIRIT_DEBUG_NODE(level5_op);
00594 BOOST_SPIRIT_DEBUG_NODE(level6_op);
00595 BOOST_SPIRIT_DEBUG_NODE(attribute_name);
00596 }
00597
00598 rule<ScannerT> def_list, expression, simple_expression, binary_op, factor,
00599 atom, unary_op, suffix_expr, list_expr_list, list_expression,
00600 record_expression, attribute_definition, function_call,
00601 attribute_def_list, comment, term, level1_op, level2_op, level3_op,
00602 level4_op, level5_op, level6_op, term1, term2, term3, term4, term5,
00603 keywords;
00604
00605 rule<ScannerT> attribute_name, literal, unquoted_name,
00606 quoted_name, integer_literal, floating_point_literal, exponent,
00607 string_literal, letter, escaped_char, non_quote, nonzero_digit;
00608
00609 rule<ScannerT> const&
00610 start() const { return def_list; }
00611
00612 };
00613
00614 parser_stack<boost::shared_ptr<component> > &node_stack;
00615 };
00616
00617 }
00618 #endif