1
/*=============================================================================
3
Copyright (c) 2001-2003 Joel de Guzman
4
http://spirit.sourceforge.net/
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
14
///////////////////////////////////////////////////////////////////////////////
17
#include "boost/ref.hpp"
19
#include "boost/spirit/core/parser.hpp"
20
#include "boost/spirit/core/composite/directives.hpp"
22
///////////////////////////////////////////////////////////////////////////////
23
namespace boost { namespace spirit {
25
///////////////////////////////////////////////////////////////////////////////
26
// Forward Declarations
30
template <typename CharT, typename T>
34
template <typename T, typename SetT>
35
class symbol_inserter;
37
///////////////////////////////////////////////////////////////////////////////
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
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.
52
// The actual set implementation is supplied by the SetT template
53
// parameter. By default, this uses the tst class (see tst.ipp).
55
// Symbols are added into the symbol table statically using the
58
// sym = a, b, c, d ...;
60
// where sym is a symbol table and a..d are strings. Example:
62
// sym = "pineapple", "orange", "banana", "apple";
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:
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.
74
// 'add' may also be used to directly initialize data. Examples:
76
// sym.add("hello", 1)("crazy", 2)("world", 3);
78
///////////////////////////////////////////////////////////////////////////////
82
typename CharT = char,
83
typename SetT = impl::tst<T, CharT>
87
, public parser<symbols<T, CharT, SetT> >
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;
98
symbols(symbols const& other);
102
operator=(symbols const& other);
104
symbol_inserter<T, SetT> const&
105
operator=(CharT const* str);
107
template <typename ScannerT>
110
typedef typename match_result<ScannerT, symbol_ref_t>::type type;
113
template <typename ScannerT>
114
typename parser_result<self_t, ScannerT>::type
115
parse_main(ScannerT const& scan) const
117
typedef typename ScannerT::iterator_t iterator_t;
118
iterator_t first = scan.first;
119
typename SetT::search_info result = SetT::find(scan);
125
symbol_ref_t(*result.data),
129
return scan.no_match();
132
template <typename ScannerT>
133
typename parser_result<self_t, ScannerT>::type
134
parse(ScannerT const& scan) const
136
typedef typename parser_result<self_t, ScannerT>::type result_t;
137
return impl::implicit_lexeme_parse<result_t>
141
template < typename ScannerT >
142
T* find(ScannerT const& scan) const
143
{ return SetT::find(scan).data; }
145
symbol_inserter<T, SetT> const add;
148
///////////////////////////////////////////////////////////////////////////////
150
// Symbol table utilities
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).
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
164
///////////////////////////////////////////////////////////////////////////////
165
template <typename T, typename CharT, typename SetT>
166
T* add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());
168
template <typename T, typename CharT, typename SetT>
169
T* find(symbols<T, CharT, SetT> const& table, CharT const* sym);
171
///////////////////////////////////////////////////////////////////////////////
173
// symbol_inserter class
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:
179
// sym.add(first, last, data);
181
// Or, passing in a C string and optional data:
183
// sym.add(c_string, data);
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):
191
///////////////////////////////////////////////////////////////////////////////
192
template <typename T, typename SetT>
193
class symbol_inserter
197
symbol_inserter(SetT& set_)
200
template <typename IteratorT>
201
symbol_inserter const&
202
operator()(IteratorT first, IteratorT const& last, T const& data = T()) const
204
set.add(first, last, data);
208
template <typename CharT>
209
symbol_inserter const&
210
operator()(CharT const* str, T const& data = T()) const
212
CharT const* last = str;
215
set.add(str, last, data);
219
template <typename CharT>
220
symbol_inserter const&
221
operator,(CharT const* str) const
223
CharT const* last = str;
226
set.add(str, last, T());
235
///////////////////////////////////////////////////////////////////////////////
236
}} // namespace boost::spirit
238
#include "boost/spirit/symbols/impl/symbols.ipp"