| /*============================================================================= |
| 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 |