Line data Source code
1 : /*=============================================================================
2 : Copyright (c) 1998-2003 Joel de Guzman
3 : Copyright (c) 2001 Daniel Nuffer
4 : Copyright (c) 2002 Hartmut Kaiser
5 : http://spirit.sourceforge.net/
6 :
7 : Distributed under the Boost Software License, Version 1.0. (See accompanying
8 : file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 : =============================================================================*/
10 : #if !defined(BOOST_SPIRIT_DIFFERENCE_HPP)
11 : #define BOOST_SPIRIT_DIFFERENCE_HPP
12 :
13 : #include <boost/spirit/home/classic/namespace.hpp>
14 : #include <boost/spirit/home/classic/core/parser.hpp>
15 : #include <boost/spirit/home/classic/core/primitives/primitives.hpp>
16 : #include <boost/spirit/home/classic/core/composite/composite.hpp>
17 : #include <boost/spirit/home/classic/meta/as_parser.hpp>
18 :
19 : namespace boost { namespace spirit {
20 :
21 : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
22 :
23 : ///////////////////////////////////////////////////////////////////////////
24 : //
25 : // difference: a - b; Matches a but not b
26 : //
27 : // Handles expressions of the form:
28 : //
29 : // a - b
30 : //
31 : // where a and b are parsers. The expression returns a composite
32 : // parser that matches a but not b. One (not both) of the operands
33 : // may be a literal char, wchar_t or a primitive string char const*,
34 : // wchar_t const*.
35 : //
36 : ///////////////////////////////////////////////////////////////////////////
37 : struct difference_parser_gen;
38 :
39 : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
40 : #pragma warning(push)
41 : #pragma warning(disable:4512) //assignment operator could not be generated
42 : #endif
43 :
44 : template <typename A, typename B>
45 : struct difference
46 : : public binary<A, B, parser<difference<A, B> > >
47 : {
48 : typedef difference<A, B> self_t;
49 : typedef binary_parser_category parser_category_t;
50 : typedef difference_parser_gen parser_generator_t;
51 : typedef binary<A, B, parser<self_t> > base_t;
52 :
53 0 : difference(A const& a, B const& b)
54 0 : : base_t(a, b) {}
55 :
56 : template <typename ScannerT>
57 : typename parser_result<self_t, ScannerT>::type
58 0 : parse(ScannerT const& scan) const
59 : {
60 : typedef typename parser_result<self_t, ScannerT>::type result_t;
61 : typedef typename ScannerT::iterator_t iterator_t;
62 0 : iterator_t save = scan.first;
63 0 : if (result_t hl = this->left().parse(scan))
64 : {
65 0 : std::swap(save, scan.first);
66 0 : result_t hr = this->right().parse(scan);
67 0 : if (!hr || (hr.length() < hl.length()))
68 : {
69 0 : scan.first = save;
70 0 : return hl;
71 : }
72 : }
73 :
74 0 : return scan.no_match();
75 : }
76 : };
77 :
78 : #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
79 : #pragma warning(pop)
80 : #endif
81 :
82 : struct difference_parser_gen
83 : {
84 : template <typename A, typename B>
85 : struct result
86 : {
87 : typedef
88 : difference<
89 : typename as_parser<A>::type
90 : , typename as_parser<B>::type
91 : >
92 : type;
93 : };
94 :
95 : template <typename A, typename B>
96 : static difference<
97 : typename as_parser<A>::type
98 : , typename as_parser<B>::type
99 : >
100 : generate(A const& a, B const& b)
101 : {
102 : return difference<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
103 : BOOST_DEDUCED_TYPENAME as_parser<B>::type>
104 : (as_parser<A>::convert(a), as_parser<B>::convert(b));
105 : }
106 : };
107 :
108 : template <typename A, typename B>
109 : difference<A, B>
110 : operator-(parser<A> const& a, parser<B> const& b);
111 :
112 : template <typename A>
113 : difference<A, chlit<char> >
114 : operator-(parser<A> const& a, char b);
115 :
116 : template <typename B>
117 : difference<chlit<char>, B>
118 : operator-(char a, parser<B> const& b);
119 :
120 : template <typename A>
121 : difference<A, strlit<char const*> >
122 : operator-(parser<A> const& a, char const* b);
123 :
124 : template <typename B>
125 : difference<strlit<char const*>, B>
126 : operator-(char const* a, parser<B> const& b);
127 :
128 : template <typename A>
129 : difference<A, chlit<wchar_t> >
130 : operator-(parser<A> const& a, wchar_t b);
131 :
132 : template <typename B>
133 : difference<chlit<wchar_t>, B>
134 : operator-(wchar_t a, parser<B> const& b);
135 :
136 : template <typename A>
137 : difference<A, strlit<wchar_t const*> >
138 : operator-(parser<A> const& a, wchar_t const* b);
139 :
140 : template <typename B>
141 : difference<strlit<wchar_t const*>, B>
142 : operator-(wchar_t const* a, parser<B> const& b);
143 :
144 : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
145 :
146 : }} // namespace BOOST_SPIRIT_CLASSIC_NS
147 :
148 : #endif
149 :
150 : #include <boost/spirit/home/classic/core/composite/impl/difference.ipp>
|