1 #ifndef BOOST_METAPARSE_V1_GRAMMAR_HPP 2 #define BOOST_METAPARSE_V1_GRAMMAR_HPP 3 4 // Copyright Abel Sinkovics (abel@sinkovics.hu) 2012. 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 #include <boost/metaparse/v1/repeated.hpp> 10 #include <boost/metaparse/v1/repeated1.hpp> 11 #include <boost/metaparse/v1/sequence.hpp> 12 #include <boost/metaparse/v1/one_of.hpp> 13 #include <boost/metaparse/v1/transform.hpp> 14 #include <boost/metaparse/v1/lit.hpp> 15 #include <boost/metaparse/v1/lit_c.hpp> 16 #include <boost/metaparse/v1/token.hpp> 17 #include <boost/metaparse/v1/keyword.hpp> 18 #include <boost/metaparse/v1/middle_of.hpp> 19 #include <boost/metaparse/v1/last_of.hpp> 20 #include <boost/metaparse/v1/always.hpp> 21 #include <boost/metaparse/v1/one_char_except_c.hpp> 22 #include <boost/metaparse/v1/foldr1.hpp> 23 #include <boost/metaparse/v1/foldl_start_with_parser.hpp> 24 #include <boost/metaparse/v1/alphanum.hpp> 25 #include <boost/metaparse/v1/build_parser.hpp> 26 #include <boost/metaparse/v1/entire_input.hpp> 27 #include <boost/metaparse/v1/string.hpp> 28 #include <boost/metaparse/v1/impl/front_inserter.hpp> 29 30 #include <boost/mpl/at.hpp> 31 #include <boost/mpl/map.hpp> 32 #include <boost/mpl/eval_if.hpp> 33 #include <boost/mpl/has_key.hpp> 34 #include <boost/mpl/lambda.hpp> 35 #include <boost/mpl/front.hpp> 36 #include <boost/mpl/back.hpp> 37 #include <boost/mpl/pair.hpp> 38 #include <boost/mpl/insert.hpp> 39 40 /* 41 * The grammar 42 * 43 * rule_definition ::= name_token define_token expression 44 * expression ::= seq_expression (or_token seq_expression)* 45 * seq_expression ::= repeated_expression+ 46 * repeated_expression ::= name_expression (repeated_token | repeated1_token)* 47 * name_expression ::= char_token | name_token | bracket_expression 48 * bracket_expression ::= open_bracket_token expression close_bracket_token 49 */ 50 51 namespace boost 52 { 53 namespace metaparse 54 { 55 namespace v1 56 { 57 namespace grammar_util 58 { 59 template <char Op, class FState> 60 struct repeated_apply_impl 61 { 62 typedef repeated_apply_impl type; 63 64 template <class G> 65 struct apply : 66 repeated<typename FState::template apply<G>::type> 67 {}; 68 }; 69 70 template <class FState> 71 struct repeated_apply_impl<'+', FState> 72 { 73 typedef repeated_apply_impl type; 74 75 template <class G> 76 struct apply : 77 repeated1<typename FState::template apply<G>::type> 78 {}; 79 }; 80 81 struct build_repeated 82 { 83 typedef build_repeated type; 84 85 template <class FState, class T> 86 struct apply : repeated_apply_impl<T::type::value, FState> {}; 87 }; 88 89 struct build_sequence 90 { 91 typedef build_sequence type; 92 93 template <class FState, class FP> 94 struct apply_impl 95 { 96 typedef apply_impl type; 97 98 template <class G> 99 struct apply : 100 sequence< 101 typename FState::template apply<G>::type, 102 typename FP::template apply<G>::type 103 > 104 {}; 105 }; 106 107 template <class FState, class FP> 108 struct apply : apply_impl<FState, FP> {}; 109 }; 110 111 struct build_selection 112 { 113 typedef build_selection type; 114 115 template <class FState, class FP> 116 struct apply_impl 117 { 118 typedef apply_impl type; 119 120 template <class G> 121 struct apply : 122 one_of< 123 typename FState::template apply<G>::type, 124 typename FP::template apply<G>::type 125 > 126 {}; 127 }; 128 129 template <class FState, class FP> 130 struct apply : apply_impl<FState, FP> {}; 131 }; 132 133 template <class G, class Name> 134 struct get_parser 135 { 136 typedef 137 typename boost::mpl::at<typename G::rules, Name>::type 138 ::template apply<G> 139 p; 140 141 template <class Actions> 142 struct impl : transform<typename p::type, typename Actions::type> {}; 143 144 typedef 145 typename boost::mpl::eval_if< 146 typename boost::mpl::has_key<typename G::actions, Name>::type, 147 impl<boost::mpl::at<typename G::actions, Name> >, 148 p 149 >::type 150 type; 151 }; 152 153 struct build_name 154 { 155 typedef build_name type; 156 157 template <class Name> 158 struct apply_impl 159 { 160 typedef apply_impl type; 161 162 template <class G> 163 struct apply : get_parser<G, Name> {}; 164 }; 165 166 template <class Name> 167 struct apply : apply_impl<Name> {}; 168 }; 169 170 struct build_char 171 { 172 typedef build_char type; 173 174 template <class C> 175 struct apply_impl 176 { 177 typedef apply_impl type; 178 179 template <class G> 180 struct apply : lit<C> {}; 181 }; 182 183 template <class C> 184 struct apply : apply_impl<C> {}; 185 }; 186 187 typedef token<lit_c<'*'> > repeated_token; 188 typedef token<lit_c<'+'> > repeated1_token; 189 typedef token<lit_c<'|'> > or_token; 190 typedef token<lit_c<'('> > open_bracket_token; 191 typedef token<lit_c<')'> > close_bracket_token; 192 typedef token<keyword<string<':',':','='> > > define_token; 193 194 typedef 195 middle_of< 196 lit_c<'\''>, 197 one_of< 198 last_of< 199 lit_c<'\\'>, 200 one_of< 201 always<lit_c<'n'>, boost::mpl::char_<'\n'> >, 202 always<lit_c<'r'>, boost::mpl::char_<'\r'> >, 203 always<lit_c<'t'>, boost::mpl::char_<'\t'> >, 204 lit_c<'\\'>, 205 lit_c<'\''> 206 > 207 >, 208 one_char_except_c<'\''> 209 >, 210 token<lit_c<'\''> > 211 > 212 char_token; 213 214 typedef 215 token< 216 foldr1< 217 one_of<alphanum, lit_c<'_'> >, 218 string<>, 219 impl::front_inserter 220 > 221 > 222 name_token; 223 224 struct expression; 225 226 typedef 227 middle_of<open_bracket_token, expression, close_bracket_token> 228 bracket_expression; 229 230 typedef 231 one_of< 232 transform<char_token, build_char>, 233 transform<name_token, build_name>, 234 bracket_expression 235 > 236 name_expression; 237 238 typedef 239 foldl_start_with_parser< 240 one_of<repeated_token, repeated1_token>, 241 name_expression, 242 build_repeated 243 > 244 repeated_expression; 245 246 typedef 247 foldl_start_with_parser< 248 repeated_expression, 249 repeated_expression, 250 build_sequence 251 > 252 seq_expression; 253 254 struct expression : 255 foldl_start_with_parser< 256 last_of<or_token, seq_expression>, 257 seq_expression, 258 build_selection 259 > 260 {}; 261 262 typedef sequence<name_token, define_token, expression> rule_definition; 263 264 typedef build_parser<entire_input<rule_definition> > parser_parser; 265 266 template <class P> 267 struct build_native_parser 268 { 269 typedef build_native_parser type; 270 271 template <class G> 272 struct apply 273 { 274 typedef P type; 275 }; 276 }; 277 278 template <class S> 279 struct build_parsed_parser 280 { 281 typedef typename parser_parser::apply<S>::type p; 282 typedef typename boost::mpl::front<p>::type name; 283 typedef typename boost::mpl::back<p>::type exp; 284 285 struct the_parser 286 { 287 typedef the_parser type; 288 289 template <class G> 290 struct apply : exp::template apply<G> {}; 291 }; 292 293 typedef boost::mpl::pair<name, the_parser> type; 294 }; 295 296 typedef build_parser<name_token> name_parser; 297 298 template <class S> 299 struct rebuild : name_parser::template apply<S> {}; 300 301 struct no_action; 302 303 template <class G, class P, class F> 304 struct add_rule; 305 306 template <class G, class Name, class P> 307 struct add_import; 308 309 template <class Start, class Rules, class Actions> 310 struct grammar_builder 311 { 312 typedef grammar_builder type; 313 typedef Rules rules; 314 typedef Actions actions; 315 316 // Make it a parser 317 template <class S, class Pos> 318 struct apply : 319 get_parser< 320 grammar_builder, 321 typename rebuild<Start>::type 322 >::type::template apply<S, Pos> 323 {}; 324 325 template <class Name, class P> 326 struct import : 327 add_import<grammar_builder, typename rebuild<Name>::type, P> 328 {}; 329 330 template <class Def, class Action = no_action> 331 struct rule : 332 add_rule<grammar_builder, build_parsed_parser<Def>, Action> 333 {}; 334 }; 335 336 template <class Start, class Rules, class Actions, class P> 337 struct add_rule<grammar_builder<Start, Rules, Actions>, P, no_action> : 338 grammar_builder< 339 Start, 340 typename boost::mpl::insert<Rules, typename P::type>::type, 341 Actions 342 > 343 {}; 344 345 template <class Start, class Rules, class Actions, class P, class F> 346 struct add_rule<grammar_builder<Start, Rules, Actions>, P, F> : 347 grammar_builder< 348 Start, 349 typename boost::mpl::insert<Rules, typename P::type>::type, 350 typename boost::mpl::insert< 351 Actions, 352 boost::mpl::pair< 353 typename P::name, 354 typename boost::mpl::lambda<F>::type 355 > 356 > 357 ::type 358 > 359 {}; 360 361 template <class Start, class Rules, class Actions, class Name, class P> 362 struct add_import<grammar_builder<Start, Rules, Actions>, Name, P> : 363 grammar_builder< 364 Start, 365 typename boost::mpl::insert< 366 Rules, 367 boost::mpl::pair<Name, build_native_parser<P> > 368 >::type, 369 Actions 370 > 371 {}; 372 } 373 374 template <class Start = string<'S'> > 375 struct grammar : 376 grammar_util::grammar_builder< 377 Start, 378 boost::mpl::map<>, 379 boost::mpl::map<> 380 > 381 {}; 382 } 383 } 384 } 385 386 #endif 387