grammar.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(BOOST_SPIRIT_GRAMMAR_FEBRUARY_19_2007_0236PM)
  7. #define BOOST_SPIRIT_GRAMMAR_FEBRUARY_19_2007_0236PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/support/unused.hpp>
  12. #include <boost/spirit/home/support/info.hpp>
  13. #include <boost/spirit/home/support/assert_msg.hpp>
  14. #include <boost/spirit/home/qi/domain.hpp>
  15. #include <boost/spirit/home/qi/nonterminal/rule.hpp>
  16. #include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
  17. #include <boost/spirit/home/qi/reference.hpp>
  18. #include <boost/noncopyable.hpp>
  19. #include <boost/proto/extends.hpp>
  20. #include <boost/proto/traits.hpp>
  21. #include <boost/type_traits/is_same.hpp>
  22. namespace boost { namespace spirit { namespace qi
  23. {
  24. template <
  25. typename Iterator, typename T1, typename T2, typename T3
  26. , typename T4>
  27. struct grammar
  28. : proto::extends<
  29. typename proto::terminal<
  30. reference<rule<Iterator, T1, T2, T3, T4> const>
  31. >::type
  32. , grammar<Iterator, T1, T2, T3, T4>
  33. >
  34. , parser<grammar<Iterator, T1, T2, T3, T4> >
  35. , noncopyable
  36. {
  37. typedef Iterator iterator_type;
  38. typedef rule<Iterator, T1, T2, T3, T4> start_type;
  39. typedef typename start_type::sig_type sig_type;
  40. typedef typename start_type::locals_type locals_type;
  41. typedef typename start_type::skipper_type skipper_type;
  42. typedef typename start_type::encoding_type encoding_type;
  43. typedef grammar<Iterator, T1, T2, T3, T4> base_type;
  44. typedef reference<start_type const> reference_;
  45. typedef typename proto::terminal<reference_>::type terminal;
  46. static size_t const params_size = start_type::params_size;
  47. template <typename Context, typename Iterator_>
  48. struct attribute
  49. {
  50. typedef typename start_type::attr_type type;
  51. };
  52. grammar(
  53. start_type const& start
  54. , std::string const& name = "unnamed-grammar")
  55. : proto::extends<terminal, base_type>(terminal::make(reference_(start)))
  56. , name_(name)
  57. {}
  58. // This constructor is used to catch if the start rule is not
  59. // compatible with the grammar.
  60. template <typename Iterator_,
  61. typename T1_, typename T2_, typename T3_, typename T4_>
  62. grammar(
  63. rule<Iterator_, T1_, T2_, T3_, T4_> const&
  64. , std::string const& = "unnamed-grammar")
  65. {
  66. // If you see the assertion below failing then the start rule
  67. // passed to the constructor of the grammar is not compatible with
  68. // the grammar (i.e. it uses different template parameters).
  69. BOOST_SPIRIT_ASSERT_MSG(
  70. (is_same<start_type, rule<Iterator_, T1_, T2_, T3_, T4_> >::value)
  71. , incompatible_start_rule, (rule<Iterator_, T1_, T2_, T3_, T4_>));
  72. }
  73. std::string name() const
  74. {
  75. return name_;
  76. }
  77. void name(std::string const& str)
  78. {
  79. name_ = str;
  80. }
  81. template <typename Context, typename Skipper, typename Attribute>
  82. bool parse(Iterator& first, Iterator const& last
  83. , Context& context, Skipper const& skipper
  84. , Attribute& attr_) const
  85. {
  86. return this->proto_base().child0.parse(
  87. first, last, context, skipper, attr_);
  88. }
  89. template <typename Context>
  90. info what(Context&) const
  91. {
  92. return info(name_);
  93. }
  94. // bring in the operator() overloads
  95. start_type const& get_parameterized_subject() const
  96. { return this->proto_base().child0.ref.get(); }
  97. typedef start_type parameterized_subject_type;
  98. #include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
  99. std::string name_;
  100. };
  101. }}}
  102. namespace boost { namespace spirit { namespace traits
  103. {
  104. ///////////////////////////////////////////////////////////////////////////
  105. template <
  106. typename IteratorA, typename IteratorB, typename Attribute
  107. , typename Context, typename T1, typename T2, typename T3, typename T4>
  108. struct handles_container<
  109. qi::grammar<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
  110. : traits::is_container<
  111. typename attribute_of<
  112. qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  113. >::type
  114. >
  115. {};
  116. }}}
  117. #endif