1 | /*============================================================================= |
---|
2 | Boost.Wave: A Standard compliant C++ preprocessor library |
---|
3 | |
---|
4 | http://www.boost.org/ |
---|
5 | |
---|
6 | Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost |
---|
7 | Software License, Version 1.0. (See accompanying file |
---|
8 | LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
---|
9 | =============================================================================*/ |
---|
10 | |
---|
11 | #if !defined(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED) |
---|
12 | #define CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED |
---|
13 | |
---|
14 | #include <boost/spirit/core.hpp> |
---|
15 | #include <boost/spirit/attribute/closure.hpp> |
---|
16 | #if SPIRIT_VERSION >= 0x1700 |
---|
17 | #include <boost/spirit/actor/assign_actor.hpp> |
---|
18 | #include <boost/spirit/actor/push_back_actor.hpp> |
---|
19 | #endif // SPIRIT_VERSION >= 0x1700 |
---|
20 | |
---|
21 | #include <boost/spirit/phoenix/operators.hpp> |
---|
22 | #include <boost/spirit/phoenix/primitives.hpp> |
---|
23 | #include <boost/spirit/phoenix/statements.hpp> |
---|
24 | |
---|
25 | #include <boost/wave/wave_config.hpp> |
---|
26 | #include <boost/wave/cpp_exceptions.hpp> |
---|
27 | #include <boost/wave/grammars/cpp_literal_grammar_gen.hpp> |
---|
28 | |
---|
29 | #if !defined(spirit_append_actor) |
---|
30 | #if SPIRIT_VERSION >= 0x1700 |
---|
31 | #define spirit_append_actor(actor) boost::spirit::push_back_a(actor) |
---|
32 | #define spirit_assign_actor(actor) boost::spirit::assign_a(actor) |
---|
33 | #else |
---|
34 | #define spirit_append_actor(actor) boost::spirit::append(actor) |
---|
35 | #define spirit_assign_actor(actor) boost::spirit::assign(actor) |
---|
36 | #endif // SPIRIT_VERSION >= 0x1700 |
---|
37 | #endif // !defined(spirit_append_actor) |
---|
38 | |
---|
39 | /////////////////////////////////////////////////////////////////////////////// |
---|
40 | // |
---|
41 | // Reusable grammar for parsing of C++ style integer literals |
---|
42 | // |
---|
43 | /////////////////////////////////////////////////////////////////////////////// |
---|
44 | namespace boost { |
---|
45 | namespace wave { |
---|
46 | namespace grammars { |
---|
47 | |
---|
48 | namespace closures { |
---|
49 | |
---|
50 | struct intlit_closure |
---|
51 | : boost::spirit::closure<intlit_closure, unsigned long> |
---|
52 | { |
---|
53 | member1 val; |
---|
54 | }; |
---|
55 | } |
---|
56 | |
---|
57 | /////////////////////////////////////////////////////////////////////////////// |
---|
58 | // define, whether the rule's should generate some debug output |
---|
59 | #define TRACE_INTLIT_GRAMMAR \ |
---|
60 | bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR) \ |
---|
61 | /**/ |
---|
62 | |
---|
63 | struct intlit_grammar : |
---|
64 | boost::spirit::grammar<intlit_grammar, closures::intlit_closure::context_t> |
---|
65 | { |
---|
66 | intlit_grammar(bool &is_unsigned_) : is_unsigned(is_unsigned_) |
---|
67 | { |
---|
68 | BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "intlit_grammar", |
---|
69 | TRACE_INTLIT_GRAMMAR); |
---|
70 | } |
---|
71 | |
---|
72 | template <typename ScannerT> |
---|
73 | struct definition |
---|
74 | { |
---|
75 | typedef boost::spirit::rule<ScannerT> rule_t; |
---|
76 | |
---|
77 | rule_t int_lit; |
---|
78 | boost::spirit::subrule<0> sub_int_lit; |
---|
79 | boost::spirit::subrule<1> oct_lit; |
---|
80 | boost::spirit::subrule<2> hex_lit; |
---|
81 | boost::spirit::subrule<3> dec_lit; |
---|
82 | |
---|
83 | definition(intlit_grammar const &self) |
---|
84 | { |
---|
85 | using namespace boost::spirit; |
---|
86 | using namespace phoenix; |
---|
87 | |
---|
88 | int_lit = ( |
---|
89 | sub_int_lit = |
---|
90 | ( ch_p('0')[self.val = 0] >> (hex_lit | oct_lit) |
---|
91 | | dec_lit |
---|
92 | ) |
---|
93 | >> !as_lower_d[ |
---|
94 | (ch_p('u')[var(self.is_unsigned) = true] || ch_p('l')) |
---|
95 | | (ch_p('l') || ch_p('u')[var(self.is_unsigned) = true]) |
---|
96 | ] |
---|
97 | , |
---|
98 | |
---|
99 | hex_lit = |
---|
100 | (ch_p('X') | ch_p('x')) |
---|
101 | >> uint_parser<unsigned long, 16>() |
---|
102 | [ |
---|
103 | self.val = arg1, |
---|
104 | var(self.is_unsigned) = true |
---|
105 | ] |
---|
106 | , |
---|
107 | |
---|
108 | oct_lit = |
---|
109 | !uint_parser<unsigned long, 8>() |
---|
110 | [ |
---|
111 | self.val = arg1, |
---|
112 | var(self.is_unsigned) = true |
---|
113 | ] |
---|
114 | , |
---|
115 | |
---|
116 | dec_lit = |
---|
117 | int_parser<long, 10>() |
---|
118 | [ |
---|
119 | self.val = arg1 |
---|
120 | ] |
---|
121 | ) |
---|
122 | ; |
---|
123 | |
---|
124 | BOOST_SPIRIT_DEBUG_TRACE_RULE(int_lit, TRACE_INTLIT_GRAMMAR); |
---|
125 | BOOST_SPIRIT_DEBUG_TRACE_RULE(sub_int_lit, TRACE_INTLIT_GRAMMAR); |
---|
126 | BOOST_SPIRIT_DEBUG_TRACE_RULE(hex_lit, TRACE_INTLIT_GRAMMAR); |
---|
127 | BOOST_SPIRIT_DEBUG_TRACE_RULE(oct_lit, TRACE_INTLIT_GRAMMAR); |
---|
128 | BOOST_SPIRIT_DEBUG_TRACE_RULE(dec_lit, TRACE_INTLIT_GRAMMAR); |
---|
129 | } |
---|
130 | |
---|
131 | // start rule of this grammar |
---|
132 | rule_t const& start() const |
---|
133 | { return int_lit; } |
---|
134 | }; |
---|
135 | |
---|
136 | bool &is_unsigned; |
---|
137 | }; |
---|
138 | |
---|
139 | #undef TRACE_INTLIT_GRAMMAR |
---|
140 | |
---|
141 | /////////////////////////////////////////////////////////////////////////////// |
---|
142 | // |
---|
143 | // The following function is defined here, to allow the separation of |
---|
144 | // the compilation of the intlit_grammar from the function using it. |
---|
145 | // |
---|
146 | /////////////////////////////////////////////////////////////////////////////// |
---|
147 | |
---|
148 | #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0 |
---|
149 | #define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE |
---|
150 | #else |
---|
151 | #define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE inline |
---|
152 | #endif |
---|
153 | |
---|
154 | template <typename TokenT> |
---|
155 | BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE |
---|
156 | unsigned long |
---|
157 | intlit_grammar_gen<TokenT>::evaluate(TokenT const &token, |
---|
158 | bool &is_unsigned) |
---|
159 | { |
---|
160 | using namespace boost::spirit; |
---|
161 | |
---|
162 | intlit_grammar g(is_unsigned); |
---|
163 | unsigned long result = 0; |
---|
164 | typename TokenT::string_type const &token_val = token.get_value(); |
---|
165 | parse_info<typename TokenT::string_type::const_iterator> hit = |
---|
166 | parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]); |
---|
167 | |
---|
168 | if (!hit.hit) { |
---|
169 | BOOST_WAVE_THROW(preprocess_exception, ill_formed_integer_literal, |
---|
170 | token_val.c_str(), token.get_position()); |
---|
171 | } |
---|
172 | return result; |
---|
173 | } |
---|
174 | |
---|
175 | #undef BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE |
---|
176 | |
---|
177 | /////////////////////////////////////////////////////////////////////////////// |
---|
178 | } // namespace grammars |
---|
179 | } // namespace wave |
---|
180 | } // namespace boost |
---|
181 | |
---|
182 | #endif // !defined(CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED) |
---|