Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/spirit/symbols/symbols.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

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