185 lines
6.4 KiB
C++
185 lines
6.4 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2001-2003 Daniel Nuffer
|
|
http://spirit.sourceforge.net/
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
=============================================================================*/
|
|
#ifndef BOOST_SPIRIT_ESCAPE_CHAR_HPP
|
|
#define BOOST_SPIRIT_ESCAPE_CHAR_HPP
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include <string>
|
|
#include <iterator>
|
|
#include <cctype>
|
|
#include <boost/limits.hpp>
|
|
|
|
#include <boost/spirit/home/classic/namespace.hpp>
|
|
#include <boost/spirit/home/classic/debug.hpp>
|
|
|
|
#include <boost/spirit/home/classic/utility/escape_char_fwd.hpp>
|
|
#include <boost/spirit/home/classic/utility/impl/escape_char.ipp>
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace boost { namespace spirit {
|
|
|
|
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// escape_char_action class
|
|
//
|
|
// Links an escape char parser 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(CharT ch);
|
|
//
|
|
// A functor should have a member operator() with a compatible signature
|
|
// as above. The matching character is passed into the function/functor.
|
|
// This is the default class that character parsers 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,
|
|
unsigned long Flags, typename CharT
|
|
>
|
|
struct escape_char_action
|
|
: public unary<ParserT,
|
|
parser<escape_char_action<ParserT, ActionT, Flags, CharT> > >
|
|
{
|
|
typedef escape_char_action
|
|
<ParserT, ActionT, Flags, CharT> self_t;
|
|
typedef action_parser_category parser_category_t;
|
|
typedef unary<ParserT, parser<self_t> > base_t;
|
|
|
|
template <typename ScannerT>
|
|
struct result
|
|
{
|
|
typedef typename match_result<ScannerT, CharT>::type type;
|
|
};
|
|
|
|
escape_char_action(ParserT const& p, ActionT const& a)
|
|
: base_t(p), actor(a) {}
|
|
|
|
template <typename ScannerT>
|
|
typename parser_result<self_t, ScannerT>::type
|
|
parse(ScannerT const& scan) const
|
|
{
|
|
return impl::escape_char_action_parse<Flags, CharT>::
|
|
parse(scan, *this);
|
|
}
|
|
|
|
ActionT const& predicate() const { return actor; }
|
|
|
|
private:
|
|
|
|
ActionT actor;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// escape_char_parser class
|
|
//
|
|
// The escape_char_parser helps in conjunction with the escape_char_action
|
|
// template class (see above) in parsing escaped characters. There are two
|
|
// different variants of this parser: one for parsing C style escaped
|
|
// characters and one for parsing LEX style escaped characters.
|
|
//
|
|
// The C style escaped character parser is generated, when the template
|
|
// parameter 'Flags' is equal to 'c_escapes' (a constant defined in the
|
|
// file impl/escape_char.ipp). This parser recognizes all valid C escape
|
|
// character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\'
|
|
// and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal)
|
|
// and converts these to their character equivalent, for instance the
|
|
// sequence of a backslash and a 'b' is parsed as the character '\b'.
|
|
// All other escaped characters are rejected by this parser.
|
|
//
|
|
// The LEX style escaped character parser is generated, when the template
|
|
// parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the
|
|
// file impl/escape_char.ipp). This parser recognizes all the C style
|
|
// escaped character sequences (as described above) and additionally
|
|
// does not reject all other escape sequences. All not mentioned escape
|
|
// sequences are converted by the parser to the plain character, for
|
|
// instance '\a' will be parsed as 'a'.
|
|
//
|
|
// All not escaped characters are parsed without modification.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
template <unsigned long Flags, typename CharT>
|
|
struct escape_char_action_parser_gen;
|
|
|
|
template <unsigned long Flags, typename CharT>
|
|
struct escape_char_parser :
|
|
public parser<escape_char_parser<Flags, CharT> > {
|
|
|
|
// only the values c_escapes and lex_escapes are valid for Flags
|
|
BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes);
|
|
|
|
typedef escape_char_parser<Flags, CharT> self_t;
|
|
typedef
|
|
escape_char_action_parser_gen<Flags, CharT>
|
|
action_parser_generator_t;
|
|
|
|
template <typename ScannerT>
|
|
struct result {
|
|
|
|
typedef typename match_result<ScannerT, CharT>::type type;
|
|
};
|
|
|
|
template <typename ActionT>
|
|
escape_char_action<self_t, ActionT, Flags, CharT>
|
|
operator[](ActionT const& actor) const
|
|
{
|
|
return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor);
|
|
}
|
|
|
|
template <typename ScannerT>
|
|
typename parser_result<self_t, ScannerT>::type
|
|
parse(ScannerT const &scan) const
|
|
{
|
|
return impl::escape_char_parse<CharT>::parse(scan, *this);
|
|
}
|
|
};
|
|
|
|
template <unsigned long Flags, typename CharT>
|
|
struct escape_char_action_parser_gen {
|
|
|
|
template <typename ParserT, typename ActionT>
|
|
static escape_char_action<ParserT, ActionT, Flags, CharT>
|
|
generate (ParserT const &p, ActionT const &actor)
|
|
{
|
|
typedef
|
|
escape_char_action<ParserT, ActionT, Flags, CharT>
|
|
action_parser_t;
|
|
return action_parser_t(p, actor);
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// predefined escape_char_parser objects
|
|
//
|
|
// These objects should be used for generating correct escaped character
|
|
// parsers.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
const escape_char_parser<lex_escapes> lex_escape_ch_p =
|
|
escape_char_parser<lex_escapes>();
|
|
|
|
const escape_char_parser<c_escapes> c_escape_ch_p =
|
|
escape_char_parser<c_escapes>();
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
|
|
|
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
|
|
|
#endif
|