1 /*=============================================================================
2 Copyright (c) 2001-2003 Daniel Nuffer
3 http://spirit.sourceforge.net/
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #ifndef BOOST_SPIRIT_ESCAPE_CHAR_HPP
9 #define BOOST_SPIRIT_ESCAPE_CHAR_HPP
11 ///////////////////////////////////////////////////////////////////////////////
15 #include <boost/limits.hpp>
17 #include <boost/spirit/home/classic/namespace.hpp>
18 #include <boost/spirit/home/classic/debug.hpp>
20 #include <boost/spirit/home/classic/utility/escape_char_fwd.hpp>
21 #include <boost/spirit/home/classic/utility/impl/escape_char.ipp>
23 ///////////////////////////////////////////////////////////////////////////////
24 namespace boost { namespace spirit {
26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
28 ///////////////////////////////////////////////////////////////////////////////
30 // escape_char_action class
32 // Links an escape char parser with a user defined semantic action.
33 // The semantic action may be a function or a functor. A function
34 // should be compatible with the interface:
38 // A functor should have a member operator() with a compatible signature
39 // as above. The matching character is passed into the function/functor.
40 // This is the default class that character parsers use when dealing with
45 // where p is a parser and f is a function or functor.
47 ///////////////////////////////////////////////////////////////////////////////
49 typename ParserT, typename ActionT,
50 unsigned long Flags, typename CharT
52 struct escape_char_action
53 : public unary<ParserT,
54 parser<escape_char_action<ParserT, ActionT, Flags, CharT> > >
56 typedef escape_char_action
57 <ParserT, ActionT, Flags, CharT> self_t;
58 typedef action_parser_category parser_category_t;
59 typedef unary<ParserT, parser<self_t> > base_t;
61 template <typename ScannerT>
64 typedef typename match_result<ScannerT, CharT>::type type;
67 escape_char_action(ParserT const& p, ActionT const& a)
68 : base_t(p), actor(a) {}
70 template <typename ScannerT>
71 typename parser_result<self_t, ScannerT>::type
72 parse(ScannerT const& scan) const
74 return impl::escape_char_action_parse<Flags, CharT>::
78 ActionT const& predicate() const { return actor; }
85 ///////////////////////////////////////////////////////////////////////////////
87 // escape_char_parser class
89 // The escape_char_parser helps in conjunction with the escape_char_action
90 // template class (see above) in parsing escaped characters. There are two
91 // different variants of this parser: one for parsing C style escaped
92 // characters and one for parsing LEX style escaped characters.
94 // The C style escaped character parser is generated, when the template
95 // parameter 'Flags' is equal to 'c_escapes' (a constant defined in the
96 // file impl/escape_char.ipp). This parser recognizes all valid C escape
97 // character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\'
98 // and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal)
99 // and converts these to their character equivalent, for instance the
100 // sequence of a backslash and a 'b' is parsed as the character '\b'.
101 // All other escaped characters are rejected by this parser.
103 // The LEX style escaped character parser is generated, when the template
104 // parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the
105 // file impl/escape_char.ipp). This parser recognizes all the C style
106 // escaped character sequences (as described above) and additionally
107 // does not reject all other escape sequences. All not mentioned escape
108 // sequences are converted by the parser to the plain character, for
109 // instance '\a' will be parsed as 'a'.
111 // All not escaped characters are parsed without modification.
113 ///////////////////////////////////////////////////////////////////////////////
115 template <unsigned long Flags, typename CharT>
116 struct escape_char_action_parser_gen;
118 template <unsigned long Flags, typename CharT>
119 struct escape_char_parser :
120 public parser<escape_char_parser<Flags, CharT> > {
122 // only the values c_escapes and lex_escapes are valid for Flags
123 BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes);
125 typedef escape_char_parser<Flags, CharT> self_t;
127 escape_char_action_parser_gen<Flags, CharT>
128 action_parser_generator_t;
130 template <typename ScannerT>
133 typedef typename match_result<ScannerT, CharT>::type type;
136 template <typename ActionT>
137 escape_char_action<self_t, ActionT, Flags, CharT>
138 operator[](ActionT const& actor) const
140 return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor);
143 template <typename ScannerT>
144 typename parser_result<self_t, ScannerT>::type
145 parse(ScannerT const &scan) const
147 return impl::escape_char_parse<CharT>::parse(scan, *this);
151 template <unsigned long Flags, typename CharT>
152 struct escape_char_action_parser_gen {
154 template <typename ParserT, typename ActionT>
155 static escape_char_action<ParserT, ActionT, Flags, CharT>
156 generate (ParserT const &p, ActionT const &actor)
159 escape_char_action<ParserT, ActionT, Flags, CharT>
161 return action_parser_t(p, actor);
165 ///////////////////////////////////////////////////////////////////////////////
167 // predefined escape_char_parser objects
169 // These objects should be used for generating correct escaped character
172 ///////////////////////////////////////////////////////////////////////////////
173 const escape_char_parser<lex_escapes> lex_escape_ch_p =
174 escape_char_parser<lex_escapes>();
176 const escape_char_parser<c_escapes> c_escape_ch_p =
177 escape_char_parser<c_escapes>();
179 ///////////////////////////////////////////////////////////////////////////////
180 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
182 }} // namespace BOOST_SPIRIT_CLASSIC_NS