Update contrib.
1 /*=============================================================================
2 Copyright (c) 2001-2003 Joel de Guzman
3 http://spirit.sourceforge.net/
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
12 ///////////////////////////////////////////////////////////////////////////////
15 #include <boost/ref.hpp>
17 #include <boost/spirit/core/parser.hpp>
18 #include <boost/spirit/core/composite/directives.hpp>
20 #include <boost/spirit/symbols/symbols_fwd.hpp>
23 ///////////////////////////////////////////////////////////////////////////////
24 namespace boost { namespace spirit {
26 ///////////////////////////////////////////////////////////////////////////////
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
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.
41 // The actual set implementation is supplied by the SetT template
42 // parameter. By default, this uses the tst class (see tst.ipp).
44 // Symbols are added into the symbol table statically using the
47 // sym = a, b, c, d ...;
49 // where sym is a symbol table and a..d are strings. Example:
51 // sym = "pineapple", "orange", "banana", "apple";
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:
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.
63 // 'add' may also be used to directly initialize data. Examples:
65 // sym.add("hello", 1)("crazy", 2)("world", 3);
67 ///////////////////////////////////////////////////////////////////////////////
68 template <typename T, typename CharT, typename SetT>
71 , public parser<symbols<T, CharT, SetT> >
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;
82 symbols(symbols const& other);
86 operator=(symbols const& other);
88 symbol_inserter<T, SetT> const&
89 operator=(CharT const* str);
91 template <typename ScannerT>
94 typedef typename match_result<ScannerT, symbol_ref_t>::type type;
97 template <typename ScannerT>
98 typename parser_result<self_t, ScannerT>::type
99 parse_main(ScannerT const& scan) const
101 typedef typename ScannerT::iterator_t iterator_t;
102 iterator_t first = scan.first;
103 typename SetT::search_info result = SetT::find(scan);
109 symbol_ref_t(*result.data),
113 return scan.no_match();
116 template <typename ScannerT>
117 typename parser_result<self_t, ScannerT>::type
118 parse(ScannerT const& scan) const
120 typedef typename parser_result<self_t, ScannerT>::type result_t;
121 return impl::implicit_lexeme_parse<result_t>
125 template < typename ScannerT >
126 T* find(ScannerT const& scan) const
127 { return SetT::find(scan).data; }
129 symbol_inserter<T, SetT> const add;
132 ///////////////////////////////////////////////////////////////////////////////
134 // Symbol table utilities
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).
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
148 ///////////////////////////////////////////////////////////////////////////////
149 template <typename T, typename CharT, typename SetT>
150 T* add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());
152 template <typename T, typename CharT, typename SetT>
153 T* find(symbols<T, CharT, SetT> const& table, CharT const* sym);
155 ///////////////////////////////////////////////////////////////////////////////
157 // symbol_inserter class
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:
163 // sym.add(first, last, data);
165 // Or, passing in a C string and optional data:
167 // sym.add(c_string, data);
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):
175 ///////////////////////////////////////////////////////////////////////////////
176 template <typename T, typename SetT>
177 class symbol_inserter
181 symbol_inserter(SetT& set_)
184 typedef symbol_inserter const & result_type;
186 template <typename IteratorT>
187 symbol_inserter const&
188 operator()(IteratorT first, IteratorT const& last, T const& data = T()) const
190 set.add(first, last, data);
194 template <typename CharT>
195 symbol_inserter const&
196 operator()(CharT const* str, T const& data = T()) const
198 CharT const* last = str;
201 set.add(str, last, data);
205 template <typename CharT>
206 symbol_inserter const&
207 operator,(CharT const* str) const
209 CharT const* last = str;
212 set.add(str, last, T());
221 ///////////////////////////////////////////////////////////////////////////////
222 }} // namespace boost::spirit
224 #include <boost/spirit/symbols/impl/symbols.ipp>