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)
|
---|