~ubuntu-branches/ubuntu/warty/aqsis/warty

« back to all changes in this revision

Viewing changes to boost/boost/spirit/symbols/symbols.hpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-08-24 07:25:04 UTC
  • Revision ID: james.westby@ubuntu.com-20040824072504-zf993vnevvisdsvb
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

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