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