grammar.hpp 11 KB

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