Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2001-2003 Daniel Nuffer
|
Chris@16
|
3 http://spirit.sourceforge.net/
|
Chris@16
|
4
|
Chris@16
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 =============================================================================*/
|
Chris@16
|
8 #ifndef BOOST_SPIRIT_ESCAPE_CHAR_HPP
|
Chris@16
|
9 #define BOOST_SPIRIT_ESCAPE_CHAR_HPP
|
Chris@16
|
10
|
Chris@16
|
11 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
12 #include <string>
|
Chris@16
|
13 #include <iterator>
|
Chris@16
|
14 #include <cctype>
|
Chris@16
|
15 #include <boost/limits.hpp>
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/spirit/home/classic/namespace.hpp>
|
Chris@16
|
18 #include <boost/spirit/home/classic/debug.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/spirit/home/classic/utility/escape_char_fwd.hpp>
|
Chris@16
|
21 #include <boost/spirit/home/classic/utility/impl/escape_char.ipp>
|
Chris@16
|
22
|
Chris@16
|
23 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
24 namespace boost { namespace spirit {
|
Chris@16
|
25
|
Chris@16
|
26 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
Chris@16
|
27
|
Chris@16
|
28 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
29 //
|
Chris@16
|
30 // escape_char_action class
|
Chris@16
|
31 //
|
Chris@16
|
32 // Links an escape char parser with a user defined semantic action.
|
Chris@16
|
33 // The semantic action may be a function or a functor. A function
|
Chris@16
|
34 // should be compatible with the interface:
|
Chris@16
|
35 //
|
Chris@16
|
36 // void f(CharT ch);
|
Chris@16
|
37 //
|
Chris@16
|
38 // A functor should have a member operator() with a compatible signature
|
Chris@16
|
39 // as above. The matching character is passed into the function/functor.
|
Chris@16
|
40 // This is the default class that character parsers use when dealing with
|
Chris@16
|
41 // the construct:
|
Chris@16
|
42 //
|
Chris@16
|
43 // p[f]
|
Chris@16
|
44 //
|
Chris@16
|
45 // where p is a parser and f is a function or functor.
|
Chris@16
|
46 //
|
Chris@16
|
47 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
48 template <
|
Chris@16
|
49 typename ParserT, typename ActionT,
|
Chris@16
|
50 unsigned long Flags, typename CharT
|
Chris@16
|
51 >
|
Chris@16
|
52 struct escape_char_action
|
Chris@16
|
53 : public unary<ParserT,
|
Chris@16
|
54 parser<escape_char_action<ParserT, ActionT, Flags, CharT> > >
|
Chris@16
|
55 {
|
Chris@16
|
56 typedef escape_char_action
|
Chris@16
|
57 <ParserT, ActionT, Flags, CharT> self_t;
|
Chris@16
|
58 typedef action_parser_category parser_category_t;
|
Chris@16
|
59 typedef unary<ParserT, parser<self_t> > base_t;
|
Chris@16
|
60
|
Chris@16
|
61 template <typename ScannerT>
|
Chris@16
|
62 struct result
|
Chris@16
|
63 {
|
Chris@16
|
64 typedef typename match_result<ScannerT, CharT>::type type;
|
Chris@16
|
65 };
|
Chris@16
|
66
|
Chris@16
|
67 escape_char_action(ParserT const& p, ActionT const& a)
|
Chris@16
|
68 : base_t(p), actor(a) {}
|
Chris@16
|
69
|
Chris@16
|
70 template <typename ScannerT>
|
Chris@16
|
71 typename parser_result<self_t, ScannerT>::type
|
Chris@16
|
72 parse(ScannerT const& scan) const
|
Chris@16
|
73 {
|
Chris@16
|
74 return impl::escape_char_action_parse<Flags, CharT>::
|
Chris@16
|
75 parse(scan, *this);
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 ActionT const& predicate() const { return actor; }
|
Chris@16
|
79
|
Chris@16
|
80 private:
|
Chris@16
|
81
|
Chris@16
|
82 ActionT actor;
|
Chris@16
|
83 };
|
Chris@16
|
84
|
Chris@16
|
85 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
86 //
|
Chris@16
|
87 // escape_char_parser class
|
Chris@16
|
88 //
|
Chris@16
|
89 // The escape_char_parser helps in conjunction with the escape_char_action
|
Chris@16
|
90 // template class (see above) in parsing escaped characters. There are two
|
Chris@16
|
91 // different variants of this parser: one for parsing C style escaped
|
Chris@16
|
92 // characters and one for parsing LEX style escaped characters.
|
Chris@16
|
93 //
|
Chris@16
|
94 // The C style escaped character parser is generated, when the template
|
Chris@16
|
95 // parameter 'Flags' is equal to 'c_escapes' (a constant defined in the
|
Chris@16
|
96 // file impl/escape_char.ipp). This parser recognizes all valid C escape
|
Chris@16
|
97 // character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\'
|
Chris@16
|
98 // and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal)
|
Chris@16
|
99 // and converts these to their character equivalent, for instance the
|
Chris@16
|
100 // sequence of a backslash and a 'b' is parsed as the character '\b'.
|
Chris@16
|
101 // All other escaped characters are rejected by this parser.
|
Chris@16
|
102 //
|
Chris@16
|
103 // The LEX style escaped character parser is generated, when the template
|
Chris@16
|
104 // parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the
|
Chris@16
|
105 // file impl/escape_char.ipp). This parser recognizes all the C style
|
Chris@16
|
106 // escaped character sequences (as described above) and additionally
|
Chris@16
|
107 // does not reject all other escape sequences. All not mentioned escape
|
Chris@16
|
108 // sequences are converted by the parser to the plain character, for
|
Chris@16
|
109 // instance '\a' will be parsed as 'a'.
|
Chris@16
|
110 //
|
Chris@16
|
111 // All not escaped characters are parsed without modification.
|
Chris@16
|
112 //
|
Chris@16
|
113 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
114
|
Chris@16
|
115 template <unsigned long Flags, typename CharT>
|
Chris@16
|
116 struct escape_char_action_parser_gen;
|
Chris@16
|
117
|
Chris@16
|
118 template <unsigned long Flags, typename CharT>
|
Chris@16
|
119 struct escape_char_parser :
|
Chris@16
|
120 public parser<escape_char_parser<Flags, CharT> > {
|
Chris@16
|
121
|
Chris@16
|
122 // only the values c_escapes and lex_escapes are valid for Flags
|
Chris@16
|
123 BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes);
|
Chris@16
|
124
|
Chris@16
|
125 typedef escape_char_parser<Flags, CharT> self_t;
|
Chris@16
|
126 typedef
|
Chris@16
|
127 escape_char_action_parser_gen<Flags, CharT>
|
Chris@16
|
128 action_parser_generator_t;
|
Chris@16
|
129
|
Chris@16
|
130 template <typename ScannerT>
|
Chris@16
|
131 struct result {
|
Chris@16
|
132
|
Chris@16
|
133 typedef typename match_result<ScannerT, CharT>::type type;
|
Chris@16
|
134 };
|
Chris@16
|
135
|
Chris@16
|
136 template <typename ActionT>
|
Chris@16
|
137 escape_char_action<self_t, ActionT, Flags, CharT>
|
Chris@16
|
138 operator[](ActionT const& actor) const
|
Chris@16
|
139 {
|
Chris@16
|
140 return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor);
|
Chris@16
|
141 }
|
Chris@16
|
142
|
Chris@16
|
143 template <typename ScannerT>
|
Chris@16
|
144 typename parser_result<self_t, ScannerT>::type
|
Chris@16
|
145 parse(ScannerT const &scan) const
|
Chris@16
|
146 {
|
Chris@16
|
147 return impl::escape_char_parse<CharT>::parse(scan, *this);
|
Chris@16
|
148 }
|
Chris@16
|
149 };
|
Chris@16
|
150
|
Chris@16
|
151 template <unsigned long Flags, typename CharT>
|
Chris@16
|
152 struct escape_char_action_parser_gen {
|
Chris@16
|
153
|
Chris@16
|
154 template <typename ParserT, typename ActionT>
|
Chris@16
|
155 static escape_char_action<ParserT, ActionT, Flags, CharT>
|
Chris@16
|
156 generate (ParserT const &p, ActionT const &actor)
|
Chris@16
|
157 {
|
Chris@16
|
158 typedef
|
Chris@16
|
159 escape_char_action<ParserT, ActionT, Flags, CharT>
|
Chris@16
|
160 action_parser_t;
|
Chris@16
|
161 return action_parser_t(p, actor);
|
Chris@16
|
162 }
|
Chris@16
|
163 };
|
Chris@16
|
164
|
Chris@16
|
165 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
166 //
|
Chris@16
|
167 // predefined escape_char_parser objects
|
Chris@16
|
168 //
|
Chris@16
|
169 // These objects should be used for generating correct escaped character
|
Chris@16
|
170 // parsers.
|
Chris@16
|
171 //
|
Chris@16
|
172 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
173 const escape_char_parser<lex_escapes> lex_escape_ch_p =
|
Chris@16
|
174 escape_char_parser<lex_escapes>();
|
Chris@16
|
175
|
Chris@16
|
176 const escape_char_parser<c_escapes> c_escape_ch_p =
|
Chris@16
|
177 escape_char_parser<c_escapes>();
|
Chris@16
|
178
|
Chris@16
|
179 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
180 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
Chris@16
|
181
|
Chris@16
|
182 }} // namespace BOOST_SPIRIT_CLASSIC_NS
|
Chris@16
|
183
|
Chris@16
|
184 #endif
|