/Src/Dependencies/Boost/boost/spirit/home/qi/operator/list.hpp

http://hadesmem.googlecode.com/ · C++ Header · 135 lines · 96 code · 19 blank · 20 comment · 4 complexity · 2300b8fa52ef12bbf7c36017136aa219 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
  8. #define SPIRIT_LIST_MARCH_24_2007_1031AM
  9. #if defined(_MSC_VER)
  10. #pragma once
  11. #endif
  12. #include <boost/spirit/home/qi/meta_compiler.hpp>
  13. #include <boost/spirit/home/qi/parser.hpp>
  14. #include <boost/spirit/home/support/container.hpp>
  15. #include <boost/spirit/home/qi/detail/attributes.hpp>
  16. #include <boost/spirit/home/qi/detail/fail_function.hpp>
  17. #include <boost/spirit/home/qi/detail/pass_container.hpp>
  18. #include <boost/spirit/home/support/has_semantic_action.hpp>
  19. #include <boost/spirit/home/support/handles_container.hpp>
  20. #include <boost/spirit/home/support/info.hpp>
  21. #include <vector>
  22. namespace boost { namespace spirit
  23. {
  24. ///////////////////////////////////////////////////////////////////////////
  25. // Enablers
  26. ///////////////////////////////////////////////////////////////////////////
  27. template <>
  28. struct use_operator<qi::domain, proto::tag::modulus> // enables p % d
  29. : mpl::true_ {};
  30. }}
  31. namespace boost { namespace spirit { namespace qi
  32. {
  33. template <typename Left, typename Right>
  34. struct list : binary_parser<list<Left, Right> >
  35. {
  36. typedef Left left_type;
  37. typedef Right right_type;
  38. template <typename Context, typename Iterator>
  39. struct attribute
  40. {
  41. // Build a std::vector from the LHS's attribute. Note
  42. // that build_std_vector may return unused_type if the
  43. // subject's attribute is an unused_type.
  44. typedef typename
  45. traits::build_std_vector<
  46. typename traits::
  47. attribute_of<Left, Context, Iterator>::type
  48. >::type
  49. type;
  50. };
  51. list(Left const& left, Right const& right)
  52. : left(left), right(right) {}
  53. template <typename F>
  54. bool parse_container(F f) const
  55. {
  56. // in order to succeed we need to match at least one element
  57. if (f (left))
  58. return false;
  59. typename F::iterator_type save = f.f.first;
  60. while (right.parse(f.f.first, f.f.last, f.f.context, f.f.skipper, unused)
  61. && !f (left))
  62. {
  63. save = f.f.first;
  64. }
  65. f.f.first = save;
  66. return true;
  67. }
  68. template <typename Iterator, typename Context
  69. , typename Skipper, typename Attribute>
  70. bool parse(Iterator& first, Iterator const& last
  71. , Context& context, Skipper const& skipper
  72. , Attribute& attr) const
  73. {
  74. typedef detail::fail_function<Iterator, Context, Skipper>
  75. fail_function;
  76. // ensure the attribute is actually a container type
  77. traits::make_container(attr);
  78. Iterator iter = first;
  79. fail_function f(iter, last, context, skipper);
  80. if (!parse_container(detail::make_pass_container(f, attr)))
  81. return false;
  82. first = f.first;
  83. return true;
  84. }
  85. template <typename Context>
  86. info what(Context& context) const
  87. {
  88. return info("list",
  89. std::make_pair(left.what(context), right.what(context)));
  90. }
  91. Left left;
  92. Right right;
  93. };
  94. ///////////////////////////////////////////////////////////////////////////
  95. // Parser generators: make_xxx function (objects)
  96. ///////////////////////////////////////////////////////////////////////////
  97. template <typename Elements, typename Modifiers>
  98. struct make_composite<proto::tag::modulus, Elements, Modifiers>
  99. : make_binary_composite<Elements, list>
  100. {};
  101. }}}
  102. namespace boost { namespace spirit { namespace traits
  103. {
  104. ///////////////////////////////////////////////////////////////////////////
  105. template <typename Left, typename Right>
  106. struct has_semantic_action<qi::list<Left, Right> >
  107. : binary_has_semantic_action<Left, Right> {};
  108. ///////////////////////////////////////////////////////////////////////////
  109. template <typename Left, typename Right, typename Attribute
  110. , typename Context, typename Iterator>
  111. struct handles_container<qi::list<Left, Right>, Attribute, Context
  112. , Iterator>
  113. : mpl::true_ {};
  114. }}}
  115. #endif