]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/classic/symbols/symbols.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / classic / symbols / symbols.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2001-2003 Joel de Guzman
3 http://spirit.sourceforge.net/
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7=============================================================================*/
8#ifndef BOOST_SPIRIT_SYMBOLS_HPP
9#define BOOST_SPIRIT_SYMBOLS_HPP
10
11///////////////////////////////////////////////////////////////////////////////
12#include <string>
13
14#include <boost/ref.hpp>
15
16#include <boost/spirit/home/classic/namespace.hpp>
17#include <boost/spirit/home/classic/core/parser.hpp>
18#include <boost/spirit/home/classic/core/composite/directives.hpp>
19
20#include <boost/spirit/home/classic/symbols/symbols_fwd.hpp>
21
22
23///////////////////////////////////////////////////////////////////////////////
24namespace boost { namespace spirit {
25
26BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
27
28///////////////////////////////////////////////////////////////////////////////
29//
30// symbols class
31//
32// This class implements a symbol table. The symbol table holds a
33// dictionary of symbols where each symbol is a sequence of CharTs.
34// The template class can work efficiently with 8, 16 and 32 bit
35// characters. Mutable data of type T is associated with each
36// symbol.
37//
38// The class is a parser. The parse member function returns
39// additional information in the symbol_match class (see below).
40// The additional data is a pointer to some data associated with
41// the matching symbol.
42//
43// The actual set implementation is supplied by the SetT template
44// parameter. By default, this uses the tst class (see tst.ipp).
45//
46// Symbols are added into the symbol table statically using the
47// construct:
48//
49// sym = a, b, c, d ...;
50//
51// where sym is a symbol table and a..d are strings. Example:
52//
53// sym = "pineapple", "orange", "banana", "apple";
54//
55// Alternatively, symbols may be added dynamically through the
56// member functor 'add' (see symbol_inserter below). The member
57// functor 'add' may be attached to a parser as a semantic action
58// taking in a begin/end pair:
59//
60// p[sym.add]
61//
62// where p is a parser (and sym is a symbol table). On success,
63// the matching portion of the input is added to the symbol table.
64//
65// 'add' may also be used to directly initialize data. Examples:
66//
67// sym.add("hello", 1)("crazy", 2)("world", 3);
68//
69///////////////////////////////////////////////////////////////////////////////
70template <typename T, typename CharT, typename SetT>
71class symbols
72: private SetT
73, public parser<symbols<T, CharT, SetT> >
74{
75public:
76
77 typedef parser<symbols<T, CharT, SetT> > parser_base_t;
78 typedef symbols<T, CharT, SetT> self_t;
79 typedef self_t const& embed_t;
80 typedef T symbol_data_t;
81 typedef boost::reference_wrapper<T> symbol_ref_t;
82
83 symbols();
84 symbols(symbols const& other);
85 ~symbols();
86
87 symbols&
88 operator=(symbols const& other);
89
90 symbol_inserter<T, SetT> const&
91 operator=(CharT const* str);
92
93 template <typename ScannerT>
94 struct result
95 {
96 typedef typename match_result<ScannerT, symbol_ref_t>::type type;
97 };
98
99 template <typename ScannerT>
100 typename parser_result<self_t, ScannerT>::type
101 parse_main(ScannerT const& scan) const
102 {
103 typedef typename ScannerT::iterator_t iterator_t;
104 iterator_t first = scan.first;
105 typename SetT::search_info result = SetT::find(scan);
106
107 if (result.data)
108 return scan.
109 create_match(
110 result.length,
111 symbol_ref_t(*result.data),
112 first,
113 scan.first);
114 else
115 return scan.no_match();
116 }
117
118 template <typename ScannerT>
119 typename parser_result<self_t, ScannerT>::type
120 parse(ScannerT const& scan) const
121 {
122 typedef typename parser_result<self_t, ScannerT>::type result_t;
123 return impl::implicit_lexeme_parse<result_t>
124 (*this, scan, scan);
125 }
126
127 template < typename ScannerT >
128 T* find(ScannerT const& scan) const
129 { return SetT::find(scan).data; }
130
131 symbol_inserter<T, SetT> const add;
132};
133
134///////////////////////////////////////////////////////////////////////////////
135//
136// Symbol table utilities
137//
138// add
139//
140// adds a symbol 'sym' (string) to a symbol table 'table' plus an
141// optional data 'data' associated with the symbol. Returns a pointer to
142// the data associated with the symbol or NULL if add failed (e.g. when
143// the symbol is already added before).
144//
145// find
146//
147// finds a symbol 'sym' (string) from a symbol table 'table'. Returns a
148// pointer to the data associated with the symbol or NULL if not found
149//
150///////////////////////////////////////////////////////////////////////////////
151template <typename T, typename CharT, typename SetT>
152T* add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());
153
154template <typename T, typename CharT, typename SetT>
155T* find(symbols<T, CharT, SetT> const& table, CharT const* sym);
156
157///////////////////////////////////////////////////////////////////////////////
158//
159// symbol_inserter class
160//
161// The symbols class holds an instance of this class named 'add'.
162// This can be called directly just like a member function,
163// passing in a first/last iterator and optional data:
164//
165// sym.add(first, last, data);
166//
167// Or, passing in a C string and optional data:
168//
169// sym.add(c_string, data);
170//
171// where sym is a symbol table. The 'data' argument is optional.
172// This may also be used as a semantic action since it conforms
173// to the action interface (see action.hpp):
174//
175// p[sym.add]
176//
177///////////////////////////////////////////////////////////////////////////////
178template <typename T, typename SetT>
179class symbol_inserter
180{
181public:
182
183 symbol_inserter(SetT& set_)
184 : set(set_) {}
185
186 typedef symbol_inserter const & result_type;
187
188 template <typename IteratorT>
189 symbol_inserter const&
190 operator()(IteratorT first, IteratorT const& last, T const& data = T()) const
191 {
192 set.add(first, last, data);
193 return *this;
194 }
195
196 template <typename CharT>
197 symbol_inserter const&
198 operator()(CharT const* str, T const& data = T()) const
199 {
200 CharT const* last = str;
201 while (*last)
202 last++;
203 set.add(str, last, data);
204 return *this;
205 }
206
207 template <typename CharT>
208 symbol_inserter const&
209 operator,(CharT const* str) const
210 {
211 CharT const* last = str;
212 while (*last)
213 last++;
214 set.add(str, last, T());
215 return *this;
216 }
217
218private:
219
220 SetT& set;
221};
222
223///////////////////////////////////////////////////////////////////////////////
224BOOST_SPIRIT_CLASSIC_NAMESPACE_END
225
226}} // namespace BOOST_SPIRIT_CLASSIC_NS
227
228#include <boost/spirit/home/classic/symbols/impl/symbols.ipp>
229#endif