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