directives.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /*=============================================================================
  2. Copyright (c) 1998-2003 Joel de Guzman
  3. Copyright (c) 2001 Daniel Nuffer
  4. http://spirit.sourceforge.net/
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(BOOST_SPIRIT_DIRECTIVES_HPP)
  9. #define BOOST_SPIRIT_DIRECTIVES_HPP
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include <algorithm>
  12. #include <boost/spirit/home/classic/namespace.hpp>
  13. #include <boost/spirit/home/classic/core/parser.hpp>
  14. #include <boost/spirit/home/classic/core/scanner/skipper.hpp>
  15. #include <boost/spirit/home/classic/core/primitives/primitives.hpp>
  16. #include <boost/spirit/home/classic/core/composite/composite.hpp>
  17. #include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
  18. namespace boost { namespace spirit {
  19. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  20. ///////////////////////////////////////////////////////////////////////////
  21. //
  22. // contiguous class
  23. //
  24. ///////////////////////////////////////////////////////////////////////////
  25. struct lexeme_parser_gen;
  26. template <typename ParserT>
  27. struct contiguous
  28. : public unary<ParserT, parser<contiguous<ParserT> > >
  29. {
  30. typedef contiguous<ParserT> self_t;
  31. typedef unary_parser_category parser_category_t;
  32. typedef lexeme_parser_gen parser_generator_t;
  33. typedef unary<ParserT, parser<self_t> > base_t;
  34. template <typename ScannerT>
  35. struct result
  36. {
  37. typedef typename parser_result<ParserT, ScannerT>::type type;
  38. };
  39. contiguous(ParserT const& p)
  40. : base_t(p) {}
  41. template <typename ScannerT>
  42. typename parser_result<self_t, ScannerT>::type
  43. parse(ScannerT const& scan) const
  44. {
  45. typedef typename parser_result<self_t, ScannerT>::type result_t;
  46. return impl::contiguous_parser_parse<result_t>
  47. (this->subject(), scan, scan);
  48. }
  49. };
  50. struct lexeme_parser_gen
  51. {
  52. template <typename ParserT>
  53. struct result {
  54. typedef contiguous<ParserT> type;
  55. };
  56. template <typename ParserT>
  57. static contiguous<ParserT>
  58. generate(parser<ParserT> const& subject)
  59. {
  60. return contiguous<ParserT>(subject.derived());
  61. }
  62. template <typename ParserT>
  63. contiguous<ParserT>
  64. operator[](parser<ParserT> const& subject) const
  65. {
  66. return contiguous<ParserT>(subject.derived());
  67. }
  68. };
  69. //////////////////////////////////
  70. const lexeme_parser_gen lexeme_d = lexeme_parser_gen();
  71. ///////////////////////////////////////////////////////////////////////////
  72. //
  73. // lexeme_scanner
  74. //
  75. // Given a Scanner, return the correct scanner type that
  76. // the lexeme_d uses. Scanner is assumed to be a phrase
  77. // level scanner (see skipper.hpp)
  78. //
  79. ///////////////////////////////////////////////////////////////////////////
  80. template <typename ScannerT>
  81. struct lexeme_scanner
  82. {
  83. typedef scanner_policies<
  84. no_skipper_iteration_policy<
  85. typename ScannerT::iteration_policy_t>,
  86. typename ScannerT::match_policy_t,
  87. typename ScannerT::action_policy_t
  88. > policies_t;
  89. typedef typename
  90. rebind_scanner_policies<ScannerT, policies_t>::type type;
  91. };
  92. ///////////////////////////////////////////////////////////////////////////
  93. //
  94. // inhibit_case_iteration_policy class
  95. //
  96. ///////////////////////////////////////////////////////////////////////////
  97. template <typename BaseT>
  98. struct inhibit_case_iteration_policy : public BaseT
  99. {
  100. typedef BaseT base_t;
  101. inhibit_case_iteration_policy()
  102. : BaseT() {}
  103. template <typename PolicyT>
  104. inhibit_case_iteration_policy(PolicyT const& other)
  105. : BaseT(other) {}
  106. template <typename CharT>
  107. CharT filter(CharT ch) const
  108. { return impl::tolower_(ch); }
  109. };
  110. ///////////////////////////////////////////////////////////////////////////
  111. //
  112. // inhibit_case class
  113. //
  114. ///////////////////////////////////////////////////////////////////////////
  115. struct inhibit_case_parser_gen;
  116. template <typename ParserT>
  117. struct inhibit_case
  118. : public unary<ParserT, parser<inhibit_case<ParserT> > >
  119. {
  120. typedef inhibit_case<ParserT> self_t;
  121. typedef unary_parser_category parser_category_t;
  122. typedef inhibit_case_parser_gen parser_generator_t;
  123. typedef unary<ParserT, parser<self_t> > base_t;
  124. template <typename ScannerT>
  125. struct result
  126. {
  127. typedef typename parser_result<ParserT, ScannerT>::type type;
  128. };
  129. inhibit_case(ParserT const& p)
  130. : base_t(p) {}
  131. template <typename ScannerT>
  132. typename parser_result<self_t, ScannerT>::type
  133. parse(ScannerT const& scan) const
  134. {
  135. typedef typename parser_result<self_t, ScannerT>::type result_t;
  136. return impl::inhibit_case_parser_parse<result_t>
  137. (this->subject(), scan, scan);
  138. }
  139. };
  140. template <int N>
  141. struct inhibit_case_parser_gen_base
  142. {
  143. // This hack is needed to make borland happy.
  144. // If these member operators were defined in the
  145. // inhibit_case_parser_gen class, or if this class
  146. // is non-templated, borland ICEs.
  147. static inhibit_case<strlit<char const*> >
  148. generate(char const* str)
  149. { return inhibit_case<strlit<char const*> >(str); }
  150. static inhibit_case<strlit<wchar_t const*> >
  151. generate(wchar_t const* str)
  152. { return inhibit_case<strlit<wchar_t const*> >(str); }
  153. static inhibit_case<chlit<char> >
  154. generate(char ch)
  155. { return inhibit_case<chlit<char> >(ch); }
  156. static inhibit_case<chlit<wchar_t> >
  157. generate(wchar_t ch)
  158. { return inhibit_case<chlit<wchar_t> >(ch); }
  159. template <typename ParserT>
  160. static inhibit_case<ParserT>
  161. generate(parser<ParserT> const& subject)
  162. { return inhibit_case<ParserT>(subject.derived()); }
  163. inhibit_case<strlit<char const*> >
  164. operator[](char const* str) const
  165. { return inhibit_case<strlit<char const*> >(str); }
  166. inhibit_case<strlit<wchar_t const*> >
  167. operator[](wchar_t const* str) const
  168. { return inhibit_case<strlit<wchar_t const*> >(str); }
  169. inhibit_case<chlit<char> >
  170. operator[](char ch) const
  171. { return inhibit_case<chlit<char> >(ch); }
  172. inhibit_case<chlit<wchar_t> >
  173. operator[](wchar_t ch) const
  174. { return inhibit_case<chlit<wchar_t> >(ch); }
  175. template <typename ParserT>
  176. inhibit_case<ParserT>
  177. operator[](parser<ParserT> const& subject) const
  178. { return inhibit_case<ParserT>(subject.derived()); }
  179. };
  180. //////////////////////////////////
  181. struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0>
  182. {
  183. inhibit_case_parser_gen() {}
  184. };
  185. //////////////////////////////////
  186. // Depracated
  187. const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen();
  188. // Preferred syntax
  189. const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen();
  190. ///////////////////////////////////////////////////////////////////////////
  191. //
  192. // as_lower_scanner
  193. //
  194. // Given a Scanner, return the correct scanner type that
  195. // the as_lower_d uses. Scanner is assumed to be a scanner
  196. // with an inhibit_case_iteration_policy.
  197. //
  198. ///////////////////////////////////////////////////////////////////////////
  199. template <typename ScannerT>
  200. struct as_lower_scanner
  201. {
  202. typedef scanner_policies<
  203. inhibit_case_iteration_policy<
  204. typename ScannerT::iteration_policy_t>,
  205. typename ScannerT::match_policy_t,
  206. typename ScannerT::action_policy_t
  207. > policies_t;
  208. typedef typename
  209. rebind_scanner_policies<ScannerT, policies_t>::type type;
  210. };
  211. ///////////////////////////////////////////////////////////////////////////
  212. //
  213. // longest_alternative class
  214. //
  215. ///////////////////////////////////////////////////////////////////////////
  216. struct longest_parser_gen;
  217. template <typename A, typename B>
  218. struct longest_alternative
  219. : public binary<A, B, parser<longest_alternative<A, B> > >
  220. {
  221. typedef longest_alternative<A, B> self_t;
  222. typedef binary_parser_category parser_category_t;
  223. typedef longest_parser_gen parser_generator_t;
  224. typedef binary<A, B, parser<self_t> > base_t;
  225. longest_alternative(A const& a, B const& b)
  226. : base_t(a, b) {}
  227. template <typename ScannerT>
  228. typename parser_result<self_t, ScannerT>::type
  229. parse(ScannerT const& scan) const
  230. {
  231. typedef typename parser_result<self_t, ScannerT>::type result_t;
  232. typename ScannerT::iterator_t save = scan.first;
  233. result_t l = this->left().parse(scan);
  234. std::swap(scan.first, save);
  235. result_t r = this->right().parse(scan);
  236. if (l || r)
  237. {
  238. if (l.length() > r.length())
  239. {
  240. scan.first = save;
  241. return l;
  242. }
  243. return r;
  244. }
  245. return scan.no_match();
  246. }
  247. };
  248. struct longest_parser_gen
  249. {
  250. template <typename A, typename B>
  251. struct result {
  252. typedef typename
  253. impl::to_longest_alternative<alternative<A, B> >::result_t
  254. type;
  255. };
  256. template <typename A, typename B>
  257. static typename
  258. impl::to_longest_alternative<alternative<A, B> >::result_t
  259. generate(alternative<A, B> const& alt)
  260. {
  261. return impl::to_longest_alternative<alternative<A, B> >::
  262. convert(alt);
  263. }
  264. //'generate' for binary composite
  265. template <typename A, typename B>
  266. static
  267. longest_alternative<A, B>
  268. generate(A const &left, B const &right)
  269. {
  270. return longest_alternative<A, B>(left, right);
  271. }
  272. template <typename A, typename B>
  273. typename impl::to_longest_alternative<alternative<A, B> >::result_t
  274. operator[](alternative<A, B> const& alt) const
  275. {
  276. return impl::to_longest_alternative<alternative<A, B> >::
  277. convert(alt);
  278. }
  279. };
  280. const longest_parser_gen longest_d = longest_parser_gen();
  281. ///////////////////////////////////////////////////////////////////////////
  282. //
  283. // shortest_alternative class
  284. //
  285. ///////////////////////////////////////////////////////////////////////////
  286. struct shortest_parser_gen;
  287. template <typename A, typename B>
  288. struct shortest_alternative
  289. : public binary<A, B, parser<shortest_alternative<A, B> > >
  290. {
  291. typedef shortest_alternative<A, B> self_t;
  292. typedef binary_parser_category parser_category_t;
  293. typedef shortest_parser_gen parser_generator_t;
  294. typedef binary<A, B, parser<self_t> > base_t;
  295. shortest_alternative(A const& a, B const& b)
  296. : base_t(a, b) {}
  297. template <typename ScannerT>
  298. typename parser_result<self_t, ScannerT>::type
  299. parse(ScannerT const& scan) const
  300. {
  301. typedef typename parser_result<self_t, ScannerT>::type result_t;
  302. typename ScannerT::iterator_t save = scan.first;
  303. result_t l = this->left().parse(scan);
  304. std::swap(scan.first, save);
  305. result_t r = this->right().parse(scan);
  306. if (l || r)
  307. {
  308. if ((l.length() < r.length() && l) || !r)
  309. {
  310. scan.first = save;
  311. return l;
  312. }
  313. return r;
  314. }
  315. return scan.no_match();
  316. }
  317. };
  318. struct shortest_parser_gen
  319. {
  320. template <typename A, typename B>
  321. struct result {
  322. typedef typename
  323. impl::to_shortest_alternative<alternative<A, B> >::result_t
  324. type;
  325. };
  326. template <typename A, typename B>
  327. static typename
  328. impl::to_shortest_alternative<alternative<A, B> >::result_t
  329. generate(alternative<A, B> const& alt)
  330. {
  331. return impl::to_shortest_alternative<alternative<A, B> >::
  332. convert(alt);
  333. }
  334. //'generate' for binary composite
  335. template <typename A, typename B>
  336. static
  337. shortest_alternative<A, B>
  338. generate(A const &left, B const &right)
  339. {
  340. return shortest_alternative<A, B>(left, right);
  341. }
  342. template <typename A, typename B>
  343. typename impl::to_shortest_alternative<alternative<A, B> >::result_t
  344. operator[](alternative<A, B> const& alt) const
  345. {
  346. return impl::to_shortest_alternative<alternative<A, B> >::
  347. convert(alt);
  348. }
  349. };
  350. const shortest_parser_gen shortest_d = shortest_parser_gen();
  351. ///////////////////////////////////////////////////////////////////////////
  352. //
  353. // min_bounded class
  354. //
  355. ///////////////////////////////////////////////////////////////////////////
  356. template <typename BoundsT>
  357. struct min_bounded_gen;
  358. template <typename ParserT, typename BoundsT>
  359. struct min_bounded
  360. : public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > >
  361. {
  362. typedef min_bounded<ParserT, BoundsT> self_t;
  363. typedef unary_parser_category parser_category_t;
  364. typedef min_bounded_gen<BoundsT> parser_generator_t;
  365. typedef unary<ParserT, parser<self_t> > base_t;
  366. template <typename ScannerT>
  367. struct result
  368. {
  369. typedef typename parser_result<ParserT, ScannerT>::type type;
  370. };
  371. min_bounded(ParserT const& p, BoundsT const& min__)
  372. : base_t(p)
  373. , min_(min__) {}
  374. template <typename ScannerT>
  375. typename parser_result<self_t, ScannerT>::type
  376. parse(ScannerT const& scan) const
  377. {
  378. typedef typename parser_result<self_t, ScannerT>::type result_t;
  379. result_t hit = this->subject().parse(scan);
  380. if (hit.has_valid_attribute() && hit.value() < min_)
  381. return scan.no_match();
  382. return hit;
  383. }
  384. BoundsT min_;
  385. };
  386. template <typename BoundsT>
  387. struct min_bounded_gen
  388. {
  389. min_bounded_gen(BoundsT const& min__)
  390. : min_(min__) {}
  391. template <typename DerivedT>
  392. min_bounded<DerivedT, BoundsT>
  393. operator[](parser<DerivedT> const& p) const
  394. { return min_bounded<DerivedT, BoundsT>(p.derived(), min_); }
  395. BoundsT min_;
  396. };
  397. template <typename BoundsT>
  398. inline min_bounded_gen<BoundsT>
  399. min_limit_d(BoundsT const& min_)
  400. { return min_bounded_gen<BoundsT>(min_); }
  401. ///////////////////////////////////////////////////////////////////////////
  402. //
  403. // max_bounded class
  404. //
  405. ///////////////////////////////////////////////////////////////////////////
  406. template <typename BoundsT>
  407. struct max_bounded_gen;
  408. template <typename ParserT, typename BoundsT>
  409. struct max_bounded
  410. : public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > >
  411. {
  412. typedef max_bounded<ParserT, BoundsT> self_t;
  413. typedef unary_parser_category parser_category_t;
  414. typedef max_bounded_gen<BoundsT> parser_generator_t;
  415. typedef unary<ParserT, parser<self_t> > base_t;
  416. template <typename ScannerT>
  417. struct result
  418. {
  419. typedef typename parser_result<ParserT, ScannerT>::type type;
  420. };
  421. max_bounded(ParserT const& p, BoundsT const& max__)
  422. : base_t(p)
  423. , max_(max__) {}
  424. template <typename ScannerT>
  425. typename parser_result<self_t, ScannerT>::type
  426. parse(ScannerT const& scan) const
  427. {
  428. typedef typename parser_result<self_t, ScannerT>::type result_t;
  429. result_t hit = this->subject().parse(scan);
  430. if (hit.has_valid_attribute() && hit.value() > max_)
  431. return scan.no_match();
  432. return hit;
  433. }
  434. BoundsT max_;
  435. };
  436. template <typename BoundsT>
  437. struct max_bounded_gen
  438. {
  439. max_bounded_gen(BoundsT const& max__)
  440. : max_(max__) {}
  441. template <typename DerivedT>
  442. max_bounded<DerivedT, BoundsT>
  443. operator[](parser<DerivedT> const& p) const
  444. { return max_bounded<DerivedT, BoundsT>(p.derived(), max_); }
  445. BoundsT max_;
  446. };
  447. //////////////////////////////////
  448. template <typename BoundsT>
  449. inline max_bounded_gen<BoundsT>
  450. max_limit_d(BoundsT const& max_)
  451. { return max_bounded_gen<BoundsT>(max_); }
  452. ///////////////////////////////////////////////////////////////////////////
  453. //
  454. // bounded class
  455. //
  456. ///////////////////////////////////////////////////////////////////////////
  457. template <typename BoundsT>
  458. struct bounded_gen;
  459. template <typename ParserT, typename BoundsT>
  460. struct bounded
  461. : public unary<ParserT, parser<bounded<ParserT, BoundsT> > >
  462. {
  463. typedef bounded<ParserT, BoundsT> self_t;
  464. typedef unary_parser_category parser_category_t;
  465. typedef bounded_gen<BoundsT> parser_generator_t;
  466. typedef unary<ParserT, parser<self_t> > base_t;
  467. template <typename ScannerT>
  468. struct result
  469. {
  470. typedef typename parser_result<ParserT, ScannerT>::type type;
  471. };
  472. bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__)
  473. : base_t(p)
  474. , min_(min__)
  475. , max_(max__) {}
  476. template <typename ScannerT>
  477. typename parser_result<self_t, ScannerT>::type
  478. parse(ScannerT const& scan) const
  479. {
  480. typedef typename parser_result<self_t, ScannerT>::type result_t;
  481. result_t hit = this->subject().parse(scan);
  482. if (hit.has_valid_attribute() &&
  483. (hit.value() < min_ || hit.value() > max_))
  484. return scan.no_match();
  485. return hit;
  486. }
  487. BoundsT min_, max_;
  488. };
  489. template <typename BoundsT>
  490. struct bounded_gen
  491. {
  492. bounded_gen(BoundsT const& min__, BoundsT const& max__)
  493. : min_(min__)
  494. , max_(max__) {}
  495. template <typename DerivedT>
  496. bounded<DerivedT, BoundsT>
  497. operator[](parser<DerivedT> const& p) const
  498. { return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); }
  499. BoundsT min_, max_;
  500. };
  501. template <typename BoundsT>
  502. inline bounded_gen<BoundsT>
  503. limit_d(BoundsT const& min_, BoundsT const& max_)
  504. { return bounded_gen<BoundsT>(min_, max_); }
  505. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  506. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  507. #endif