Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:08

0001 /*=============================================================================
0002     Copyright (c) 2001-2003 Daniel Nuffer
0003     http://spirit.sourceforge.net/
0004 
0005   Distributed under the Boost Software License, Version 1.0. (See accompanying
0006   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #ifndef BOOST_SPIRIT_ESCAPE_CHAR_HPP
0009 #define BOOST_SPIRIT_ESCAPE_CHAR_HPP
0010 
0011 ///////////////////////////////////////////////////////////////////////////////
0012 #include <string>
0013 #include <iterator>
0014 #include <cctype>
0015 #include <boost/limits.hpp>
0016 
0017 #include <boost/spirit/home/classic/namespace.hpp>
0018 #include <boost/spirit/home/classic/debug.hpp>
0019 
0020 #include <boost/spirit/home/classic/utility/escape_char_fwd.hpp>
0021 #include <boost/spirit/home/classic/utility/impl/escape_char.ipp>
0022 
0023 ///////////////////////////////////////////////////////////////////////////////
0024 namespace boost { namespace spirit {
0025 
0026 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0027 
0028 ///////////////////////////////////////////////////////////////////////////////
0029 //
0030 //  escape_char_action class
0031 //
0032 //      Links an escape char parser with a user defined semantic action.
0033 //      The semantic action may be a function or a functor. A function
0034 //      should be compatible with the interface:
0035 //
0036 //          void f(CharT ch);
0037 //
0038 //      A functor should have a member operator() with a compatible signature
0039 //      as above. The matching character is passed into the function/functor.
0040 //      This is the default class that character parsers use when dealing with
0041 //      the construct:
0042 //
0043 //          p[f]
0044 //
0045 //      where p is a parser and f is a function or functor.
0046 //
0047 ///////////////////////////////////////////////////////////////////////////////
0048 template <
0049     typename ParserT, typename ActionT,
0050     unsigned long Flags, typename CharT
0051 >
0052 struct escape_char_action
0053 :   public unary<ParserT,
0054         parser<escape_char_action<ParserT, ActionT, Flags, CharT> > >
0055 {
0056     typedef escape_char_action
0057         <ParserT, ActionT, Flags, CharT>        self_t;
0058     typedef action_parser_category              parser_category_t;
0059     typedef unary<ParserT, parser<self_t> >     base_t;
0060 
0061     template <typename ScannerT>
0062     struct result
0063     {
0064         typedef typename match_result<ScannerT, CharT>::type type;
0065     };
0066 
0067     escape_char_action(ParserT const& p, ActionT const& a)
0068     : base_t(p), actor(a) {}
0069 
0070     template <typename ScannerT>
0071     typename parser_result<self_t, ScannerT>::type
0072     parse(ScannerT const& scan) const
0073     {
0074         return impl::escape_char_action_parse<Flags, CharT>::
0075             parse(scan, *this);
0076     }
0077 
0078     ActionT const& predicate() const { return actor; }
0079 
0080 private:
0081 
0082     ActionT actor;
0083 };
0084 
0085 ///////////////////////////////////////////////////////////////////////////////
0086 //
0087 //  escape_char_parser class
0088 //
0089 //      The escape_char_parser helps in conjunction with the escape_char_action
0090 //      template class (see above) in parsing escaped characters. There are two
0091 //      different variants of this parser: one for parsing C style escaped
0092 //      characters and one for parsing LEX style escaped characters.
0093 //
0094 //      The C style escaped character parser is generated, when the template
0095 //      parameter 'Flags' is equal to 'c_escapes' (a constant defined in the
0096 //      file impl/escape_char.ipp). This parser recognizes all valid C escape
0097 //      character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\'
0098 //      and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal)
0099 //      and converts these to their character equivalent, for instance the
0100 //      sequence of a backslash and a 'b' is parsed as the character '\b'.
0101 //      All other escaped characters are rejected by this parser.
0102 //
0103 //      The LEX style escaped character parser is generated, when the template
0104 //      parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the
0105 //      file impl/escape_char.ipp). This parser recognizes all the C style
0106 //      escaped character sequences (as described above) and additionally
0107 //      does not reject all other escape sequences. All not mentioned escape
0108 //      sequences are converted by the parser to the plain character, for
0109 //      instance '\a' will be parsed as 'a'.
0110 //
0111 //      All not escaped characters are parsed without modification.
0112 //
0113 ///////////////////////////////////////////////////////////////////////////////
0114 
0115 template <unsigned long Flags, typename CharT>
0116 struct escape_char_action_parser_gen;
0117 
0118 template <unsigned long Flags, typename CharT>
0119 struct escape_char_parser :
0120     public parser<escape_char_parser<Flags, CharT> > {
0121 
0122     // only the values c_escapes and lex_escapes are valid for Flags
0123     BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes);
0124 
0125     typedef escape_char_parser<Flags, CharT> self_t;
0126     typedef
0127         escape_char_action_parser_gen<Flags, CharT>
0128         action_parser_generator_t;
0129 
0130     template <typename ScannerT>
0131     struct result {
0132 
0133         typedef typename match_result<ScannerT, CharT>::type type;
0134     };
0135 
0136     template <typename ActionT>
0137     escape_char_action<self_t, ActionT, Flags, CharT>
0138     operator[](ActionT const& actor) const
0139     {
0140         return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor);
0141     }
0142 
0143     template <typename ScannerT>
0144     typename parser_result<self_t, ScannerT>::type
0145     parse(ScannerT const &scan) const
0146     {
0147         return impl::escape_char_parse<CharT>::parse(scan, *this);
0148     }
0149 };
0150 
0151 template <unsigned long Flags, typename CharT>
0152 struct escape_char_action_parser_gen {
0153 
0154     template <typename ParserT, typename ActionT>
0155     static escape_char_action<ParserT, ActionT, Flags, CharT>
0156     generate (ParserT const &p, ActionT const &actor)
0157     {
0158         typedef
0159             escape_char_action<ParserT, ActionT, Flags, CharT>
0160             action_parser_t;
0161         return action_parser_t(p, actor);
0162     }
0163 };
0164 
0165 ///////////////////////////////////////////////////////////////////////////////
0166 //
0167 //  predefined escape_char_parser objects
0168 //
0169 //      These objects should be used for generating correct escaped character
0170 //      parsers.
0171 //
0172 ///////////////////////////////////////////////////////////////////////////////
0173 const escape_char_parser<lex_escapes> lex_escape_ch_p =
0174     escape_char_parser<lex_escapes>();
0175 
0176 const escape_char_parser<c_escapes> c_escape_ch_p =
0177     escape_char_parser<c_escapes>();
0178 
0179 ///////////////////////////////////////////////////////////////////////////////
0180 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0181 
0182 }} // namespace BOOST_SPIRIT_CLASSIC_NS
0183 
0184 #endif