📄 symbols.hpp
字号:
//
// This class implements a symbol table. The symbol table holds a
// dictionary of symbols where each symbol is a sequence of CharTs.
// The template class can work efficiently with 8, 16 and 32 bit
// characters. Mutable data of type T is associated with each
// symbol.
//
// The class is a parser. The parse member function returns
// additional information in the symbol_match class (see below).
// The additional data is a pointer to some data associated with
// the matching symbol.
//
// The actual set implementation is supplied by the SetT template
// parameter. By default, this uses the tst class (see set.ipp).
//
// Symbols are added into the symbol table statically using the
// construct:
//
// sym = a, b, c, d ...;
//
// where sym is a symbol table and a..d are strings. Example:
//
// sym = "pineapple", "orange", "banana", "apple";
//
// Alternatively, symbols may be added dynamically through the
// member functor 'add' (see symbol_inserter below). The member
// functor 'add' may be attached to a parser as a semantic action:
//
// p[sym.add]
//
// where p is a parser (and sym is a symbol table). On success,
// the matching portion of the input is added to the symbol table.
//
///////////////////////////////////////////////////////////////////////////////
template <
typename T = int,
typename CharT = char,
typename SetT = tst<T, CharT> >
class symbols
: private SetT,
public parser<symbols<T, CharT, SetT> > {
public:
typedef symbol_match<T> symbol_match;
typedef T symbol_data_t;
symbols();
symbols(symbols const& other);
~symbols();
symbol_inserter<T, SetT> const&
operator=(CharT const* str);
symbols&
operator=(symbols const& other);
template <typename IteratorT>
symbol_match
parse(IteratorT& first, IteratorT const& last) const
{
typename SetT::search_info result = tst<T, CharT>::find(first, last);
if (result.data)
return symbol_match(result.length, result.data);
else
return symbol_match();
}
template <typename ActionT>
symbol_action<symbols<T, CharT, SetT>, ActionT>
operator[](ActionT const& actor) const
{
// Borland 5.5 complains if this is not defined here
return symbol_action<symbols<T, CharT, SetT>, ActionT>(*this, actor);
}
symbol_inserter<T, SetT> const add;
};
///////////////////////////////////////////////////////////////////////////////
//
// Symbol table utilities
//
// add
//
// adds a symbol 'sym' (string) to a symbol table 'table' plus an
// optional data 'data' associated with the symbol. Returns a pointer to
// the data associated with the symbol or NULL if add failed (e.g. when
// the symbol is already added before).
//
// find
//
// finds a symbol 'sym' (string) from a symbol table 'table'. Returns a
// pointer to the data associated with the symbol or NULL if not found
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename CharT, typename SetT>
T* add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());
template <typename T, typename CharT, typename SetT>
T* find(symbols<T, CharT, SetT>& table, CharT const* sym);
///////////////////////////////////////////////////////////////////////////////
//
// symbol_action class
//
// Links a symbol table with a user defined semantic action.
// The semantic action may be a function or a functor. A function
// should be compatible with the interface:
//
// void f(IteratorT first, IteratorT last, T& data);
//
// Where first points to the current input, last points to one
// after the end of the input (same as STL algorithms) and data
// is any information associated with the matching symbol in the
// symbol table (see symbols class above).
//
// A functor should have a member operator() with a compatible
// signature as above. The matching portion is passed to the
// function/functor. This is the default class that symbol
// tables use when dealing with the construct:
//
// p[f]
//
// where p is a parser and f is a function or functor.
//
///////////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename ActionT>
class symbol_action
: public unary<ParserT>,
public parser<symbol_action<ParserT, ActionT> > {
public:
typedef action_parser_category parser_category;
symbol_action(ParserT const& parser, ActionT const& actor);
template <typename IteratorT>
match
parse(IteratorT& first, IteratorT const& last) const
{
typedef impl::strip_scanner<IteratorT> strip_scanner;
typename strip_scanner::iterator_type
begin = strip_scanner::get(first);
typename ParserT::symbol_match hit = this->subject().parse(first, last);
if (hit)
actor(begin, strip_scanner::get(first), *hit.data());
return hit;
}
ActionT const &predicate() const { return actor; }
private:
typename embed_trait<ActionT>::type actor;
};
///////////////////////////////////////////////////////////////////////////////
//
// symbol_match class
//
// An instance of this class is returned by the symbols::parse
// member function. symbol_match is a subclass of match with the
// added T* data() member function. This is the data associated
// with each entry in the symbol table (see symbols above). The
// data is null on unsuccessful matches.
//
///////////////////////////////////////////////////////////////////////////////
template <typename T = int>
class symbol_match : public match {
public:
symbol_match();
symbol_match(unsigned length, T* info);
T* data() const;
private:
T* info;
};
///////////////////////////////////////////////////////////////////////////////
//
// ast_symbol_match class
//
// An instance of this class is returned by the symbols::parse
// member function. ast_symbol_match is a subclass of match with the
// added T* data() member function. This is the data associated
// with each entry in the symbol table (see symbols above). The
// data is null on unsuccessful matches.
//
///////////////////////////////////////////////////////////////////////////////
template <typename MatchTraitsT, typename T = int>
class ast_symbol_match : public MatchTraitsT::match_t {
public:
ast_symbol_match();
ast_symbol_match(unsigned length, T* info);
T* data() const;
private:
T* info;
};
///////////////////////////////////////////////////////////////////////////////
//
// symbol_inserter class
//
// The symbols class holds an instance of this class named 'add'.
// This can be called directly just like a member function:
//
// sym.add(first, last, data);
//
// where sym is a symbol table. The third argument is optional.
// This may also be used as a semantic action since it conforms
// to the action interface (see action.hpp):
//
// p[sym.add]
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename SetT>
class symbol_inserter {
public:
symbol_inserter(SetT& set);
template <typename IteratorT>
T*
operator()(
IteratorT first,
IteratorT const& last,
T const& data = T()) const
{
return set.add(first, last, data);
}
template <typename CharT>
symbol_inserter const&
operator,(CharT const* str) const
{
CharT const* last = str;
while (*last)
last++;
set.add(str, last, T());
return *this;
}
private:
SetT& set;
};
///////////////////////////////////////////////////////////////////////////////
} // namespace Spirit
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -