grammar.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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/type_traits/is_same.hpp>
  20. namespace boost { namespace spirit { namespace qi
  21. {
  22. template <
  23. typename Iterator, typename T1, typename T2, typename T3
  24. , typename T4>
  25. struct grammar
  26. : proto::extends<
  27. typename proto::terminal<
  28. reference<rule<Iterator, T1, T2, T3, T4> const>
  29. >::type
  30. , grammar<Iterator, T1, T2, T3, T4>
  31. >
  32. , parser<grammar<Iterator, T1, T2, T3, T4> >
  33. , noncopyable
  34. {
  35. typedef Iterator iterator_type;
  36. typedef rule<Iterator, T1, T2, T3, T4> start_type;
  37. typedef typename start_type::sig_type sig_type;
  38. typedef typename start_type::locals_type locals_type;
  39. typedef typename start_type::skipper_type skipper_type;
  40. typedef typename start_type::encoding_type encoding_type;
  41. typedef grammar<Iterator, T1, T2, T3, T4> base_type;
  42. typedef reference<start_type const> reference_;
  43. typedef typename proto::terminal<reference_>::type terminal;
  44. static size_t const params_size = start_type::params_size;
  45. template <typename Context, typename Iterator_>
  46. struct attribute
  47. {
  48. typedef typename start_type::attr_type type;
  49. };
  50. grammar(
  51. start_type const& start
  52. , std::string const& name = "unnamed-grammar")
  53. : proto::extends<terminal, base_type>(terminal::make(reference_(start)))
  54. , name_(name)
  55. {}
  56. // This constructor is used to catch if the start rule is not
  57. // compatible with the grammar.
  58. template <typename Iterator_,
  59. typename T1_, typename T2_, typename T3_, typename T4_>
  60. grammar(
  61. rule<Iterator_, T1_, T2_, T3_, T4_> const&
  62. , std::string const& = "unnamed-grammar")
  63. {
  64. // If you see the assertion below failing then the start rule
  65. // passed to the constructor of the grammar is not compatible with
  66. // the grammar (i.e. it uses different template parameters).
  67. BOOST_SPIRIT_ASSERT_MSG(
  68. (is_same<start_type, rule<Iterator_, T1_, T2_, T3_, T4_> >::value)
  69. , incompatible_start_rule, (rule<Iterator_, T1_, T2_, T3_, T4_>));
  70. }
  71. std::string name() const
  72. {
  73. return name_;
  74. }
  75. void name(std::string const& str)
  76. {
  77. name_ = str;
  78. }
  79. template <typename Context, typename Skipper, typename Attribute>
  80. bool parse(Iterator& first, Iterator const& last
  81. , Context& context, Skipper const& skipper
  82. , Attribute& attr_) const
  83. {
  84. return this->proto_base().child0.parse(
  85. first, last, context, skipper, attr_);
  86. }
  87. template <typename Context>
  88. info what(Context&) const
  89. {
  90. return info(name_);
  91. }
  92. // bring in the operator() overloads
  93. start_type const& get_parameterized_subject() const
  94. { return this->proto_base().child0.ref.get(); }
  95. typedef start_type parameterized_subject_type;
  96. #include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
  97. std::string name_;
  98. };
  99. }}}
  100. namespace boost { namespace spirit { namespace traits
  101. {
  102. ///////////////////////////////////////////////////////////////////////////
  103. template <
  104. typename IteratorA, typename IteratorB, typename Attribute
  105. , typename Context, typename T1, typename T2, typename T3, typename T4>
  106. struct handles_container<
  107. qi::grammar<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
  108. : traits::is_container<
  109. typename attribute_of<
  110. qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
  111. >::type
  112. >
  113. {};
  114. }}}
  115. #endif