]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/lex/lexer/support_functions.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / spirit / home / lex / lexer / support_functions.hpp
1 // Copyright (c) 2001-2011 Hartmut Kaiser
2 //
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(SPIRIT_LEX_SUPPORT_FUNCTIONS_JUN_08_2009_0211PM)
7 #define SPIRIT_LEX_SUPPORT_FUNCTIONS_JUN_08_2009_0211PM
8
9 #if defined(_MSC_VER)
10 #pragma once
11 #endif
12
13 #include <boost/spirit/include/phoenix_core.hpp>
14 #include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
15 #include <boost/spirit/home/lex/lexer/pass_flags.hpp>
16
17 #include <boost/spirit/home/lex/lexer/support_functions_expression.hpp>
18
19 ///////////////////////////////////////////////////////////////////////////////
20 namespace boost { namespace spirit { namespace lex
21 {
22 ///////////////////////////////////////////////////////////////////////////
23 // The function object less_type is used by the implementation of the
24 // support function lex::less(). Its functionality is equivalent to flex'
25 // function yyless(): it returns an iterator positioned to the nth input
26 // character beyond the current start iterator (i.e. by assigning the
27 // return value to the placeholder '_end' it is possible to return all but
28 // the first n characters of the current token back to the input stream.
29 //
30 // This Phoenix actor is invoked whenever the function lex::less(n) is
31 // used inside a lexer semantic action:
32 //
33 // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
34 // this->self = identifier [ _end = lex::less(4) ];
35 //
36 // The example shows how to limit the length of the matched identifier to
37 // four characters.
38 //
39 // Note: the function lex::less() has no effect if used on it's own, you
40 // need to use the returned result in order to make use of its
41 // functionality.
42 template <typename Actor>
43 struct less_type
44 {
45 typedef mpl::true_ no_nullary;
46
47 template <typename Env>
48 struct result
49 {
50 typedef typename remove_reference<
51 typename remove_const<
52 typename mpl::at_c<typename Env::args_type, 4>::type
53 >::type
54 >::type context_type;
55 typedef typename context_type::base_iterator_type type;
56 };
57
58 template <typename Env>
59 typename result<Env>::type
60 eval(Env const& env) const
61 {
62 typename result<Env>::type it;
63 return fusion::at_c<4>(env.args()).less(it, actor_());
64 }
65
66 less_type(Actor const& actor)
67 : actor_(actor) {}
68
69 Actor actor_;
70 };
71
72 // The function lex::less() is used to create a Phoenix actor allowing to
73 // implement functionality similar to flex' function yyless().
74 template <typename T>
75 inline typename expression::less<
76 typename phoenix::as_actor<T>::type
77 >::type const
78 less(T const& v)
79 {
80 return expression::less<T>::make(phoenix::as_actor<T>::convert(v));
81 }
82
83 ///////////////////////////////////////////////////////////////////////////
84 // The function object more_type is used by the implementation of the
85 // support function lex::more(). Its functionality is equivalent to flex'
86 // function yymore(): it tells the lexer that the next time it matches a
87 // rule, the corresponding token should be appended onto the current token
88 // value rather than replacing it.
89 //
90 // This Phoenix actor is invoked whenever the function lex::more(n) is
91 // used inside a lexer semantic action:
92 //
93 // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
94 // this->self = identifier [ lex::more() ];
95 //
96 // The example shows how prefix the next matched token with the matched
97 // identifier.
98 struct more_type
99 {
100 typedef mpl::true_ no_nullary;
101
102 template <typename Env>
103 struct result
104 {
105 typedef void type;
106 };
107
108 template <typename Env>
109 void eval(Env const& env) const
110 {
111 fusion::at_c<4>(env.args()).more();
112 }
113 };
114
115 // The function lex::more() is used to create a Phoenix actor allowing to
116 // implement functionality similar to flex' function yymore().
117 //inline expression::more<mpl::void_>::type const
118 inline phoenix::actor<more_type> more()
119 {
120 return phoenix::actor<more_type>();
121 }
122
123 ///////////////////////////////////////////////////////////////////////////
124 // The function object lookahead_type is used by the implementation of the
125 // support function lex::lookahead(). Its functionality is needed to
126 // emulate the flex' lookahead operator a/b. Use lex::lookahead() inside
127 // of lexer semantic actions to test whether the argument to this function
128 // matches the current look ahead input. lex::lookahead() can be used with
129 // either a token id or a token_def instance as its argument. It returns
130 // a bool indicating whether the look ahead has been matched.
131 template <typename IdActor, typename StateActor>
132 struct lookahead_type
133 {
134 typedef mpl::true_ no_nullary;
135
136 template <typename Env>
137 struct result
138 {
139 typedef bool type;
140 };
141
142 template <typename Env>
143 bool eval(Env const& env) const
144 {
145 return fusion::at_c<4>(env.args()).
146 lookahead(id_actor_(), state_actor_());
147 }
148
149 lookahead_type(IdActor const& id_actor, StateActor const& state_actor)
150 : id_actor_(id_actor), state_actor_(state_actor) {}
151
152 IdActor id_actor_;
153 StateActor state_actor_;
154 };
155
156 // The function lex::lookahead() is used to create a Phoenix actor
157 // allowing to implement functionality similar to flex' lookahead operator
158 // a/b.
159 template <typename T>
160 inline typename expression::lookahead<
161 typename phoenix::as_actor<T>::type
162 , typename phoenix::as_actor<std::size_t>::type
163 >::type const
164 lookahead(T const& id)
165 {
166 typedef typename phoenix::as_actor<T>::type id_actor_type;
167 typedef typename phoenix::as_actor<std::size_t>::type state_actor_type;
168
169 return expression::lookahead<id_actor_type, state_actor_type>::make(
170 phoenix::as_actor<T>::convert(id),
171 phoenix::as_actor<std::size_t>::convert(std::size_t(~0)));
172 }
173
174 template <typename Attribute, typename Char, typename Idtype>
175 inline typename expression::lookahead<
176 typename phoenix::as_actor<Idtype>::type
177 , typename phoenix::as_actor<std::size_t>::type
178 >::type const
179 lookahead(token_def<Attribute, Char, Idtype> const& tok)
180 {
181 typedef typename phoenix::as_actor<Idtype>::type id_actor_type;
182 typedef typename phoenix::as_actor<std::size_t>::type state_actor_type;
183
184 std::size_t state = tok.state();
185
186 // The following assertion fires if you pass a token_def instance to
187 // lex::lookahead without first associating this instance with the
188 // lexer.
189 BOOST_ASSERT(std::size_t(~0) != state &&
190 "token_def instance not associated with lexer yet");
191
192 return expression::lookahead<id_actor_type, state_actor_type>::make(
193 phoenix::as_actor<Idtype>::convert(tok.id()),
194 phoenix::as_actor<std::size_t>::convert(state));
195 }
196
197 ///////////////////////////////////////////////////////////////////////////
198 inline BOOST_SCOPED_ENUM(pass_flags) ignore()
199 {
200 return pass_flags::pass_ignore;
201 }
202
203 }}}
204
205 #endif