source: NonGTP/Boost/boost/wave/grammars/cpp_defined_grammar.hpp @ 857

Revision 857, 6.3 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3
4    http://www.boost.org/
5
6    Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost
7    Software License, Version 1.0. (See accompanying file
8    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9=============================================================================*/
10
11#if !defined(CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
12#define CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED
13
14#include <boost/assert.hpp>
15#include <boost/spirit/core.hpp>
16#include <boost/spirit/attribute/closure.hpp>
17#if SPIRIT_VERSION >= 0x1700
18#include <boost/spirit/actor/assign_actor.hpp>
19#include <boost/spirit/actor/push_back_actor.hpp>
20#endif // SPIRIT_VERSION >= 0x1700
21
22#include <boost/wave/wave_config.hpp>
23#include <boost/wave/token_ids.hpp>
24#include <boost/wave/util/pattern_parser.hpp>
25#include <boost/wave/grammars/cpp_defined_grammar_gen.hpp>
26
27#if !defined(spirit_append_actor)
28#if SPIRIT_VERSION >= 0x1700
29#define spirit_append_actor(actor) boost::spirit::push_back_a(actor)
30#define spirit_assign_actor(actor) boost::spirit::assign_a(actor)
31#else
32#define spirit_append_actor(actor) boost::spirit::append(actor)
33#define spirit_assign_actor(actor) boost::spirit::assign(actor)
34#endif // SPIRIT_VERSION >= 0x1700
35#endif // !defined(spirit_append_actor)
36
37///////////////////////////////////////////////////////////////////////////////
38namespace boost {
39namespace wave {
40namespace grammars {
41
42///////////////////////////////////////////////////////////////////////////////
43//  define, whether the rule's should generate some debug output
44#define TRACE_CPP_DEFINED_GRAMMAR \
45    bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR) \
46    /**/
47
48template <typename ContainerT>
49struct defined_grammar :
50    public boost::spirit::grammar<defined_grammar<ContainerT> >
51{
52    defined_grammar(ContainerT &result_seq_)
53    :   result_seq(result_seq_)
54    {
55        BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "defined_grammar",
56            TRACE_CPP_DEFINED_GRAMMAR);
57    }
58
59    template <typename ScannerT>
60    struct definition
61    {
62        typedef boost::spirit::rule<ScannerT> rule_t;
63
64        rule_t defined_op;
65        rule_t identifier;
66
67        definition(defined_grammar const &self)
68        {
69            using namespace boost::spirit;
70            using namespace boost::wave;
71            using namespace boost::wave::util;
72
73            defined_op      // parens not required, see C++ standard 16.1.1
74                =   ch_p(T_IDENTIFIER)      // token contains 'defined'
75                    >>  (
76                            (   ch_p(T_LEFTPAREN)
77                                >>  identifier
78                                >>  ch_p(T_RIGHTPAREN)
79                            )
80                            |   identifier
81                        )
82                ;
83
84            identifier
85                =   ch_p(T_IDENTIFIER)
86                    [
87                        spirit_append_actor(self.result_seq)
88                    ]
89                |   pattern_p(KeywordTokenType, TokenTypeMask)
90                    [
91                        spirit_append_actor(self.result_seq)
92                    ]
93                |   pattern_p(OperatorTokenType|AltExtTokenType, ExtTokenTypeMask)
94                    [
95                        spirit_append_actor(self.result_seq)
96                    ]
97                ;
98
99            BOOST_SPIRIT_DEBUG_TRACE_RULE(defined_op, TRACE_CPP_DEFINED_GRAMMAR);
100            BOOST_SPIRIT_DEBUG_TRACE_RULE(identifier, TRACE_CPP_DEFINED_GRAMMAR);
101        }
102
103    // start rule of this grammar
104        rule_t const& start() const
105        { return defined_op; }
106    };
107
108    ContainerT &result_seq;
109};
110
111///////////////////////////////////////////////////////////////////////////////
112#undef TRACE_CPP_DEFINED_GRAMMAR
113
114///////////////////////////////////////////////////////////////////////////////
115// 
116//  The following parse function is defined here, to allow the separation of
117//  the compilation of the defined_grammar from the function
118//  using it.
119// 
120///////////////////////////////////////////////////////////////////////////////
121
122#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
123#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
124#else
125#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE inline
126#endif
127
128//  The parse_operator_define function is instantiated manually twice to
129//  simplify the explicit specialization of this template. This way the user
130//  has only to specify one template parameter (the lexer type) to correctly
131//  formulate the required explicit specialization.
132//  This results in no code overhead, because otherwise the function would be
133//  generated by the compiler twice anyway.
134
135template <typename LexIteratorT>
136BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
137boost::spirit::parse_info<
138    typename defined_grammar_gen<LexIteratorT>::iterator1_t
139>
140defined_grammar_gen<LexIteratorT>::parse_operator_defined (
141    iterator1_t const &first, iterator1_t const &last,
142    token_sequence_type &found_qualified_name)
143{
144    using namespace boost::spirit;
145    using namespace boost::wave;
146   
147    defined_grammar<token_sequence_type> g(found_qualified_name);
148    return boost::spirit::parse (
149        first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
150}
151
152template <typename LexIteratorT>
153BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
154boost::spirit::parse_info<
155    typename defined_grammar_gen<LexIteratorT>::iterator2_t
156>
157defined_grammar_gen<LexIteratorT>::parse_operator_defined (
158    iterator2_t const &first, iterator2_t const &last,
159    token_sequence_type &found_qualified_name)
160{
161    using namespace boost::spirit;
162    using namespace boost::wave;
163   
164    defined_grammar<token_sequence_type> g(found_qualified_name);
165    return boost::spirit::parse (
166        first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
167}
168
169#undef BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
170
171///////////////////////////////////////////////////////////////////////////////
172}   // namespace grammars
173}   // namespace wave
174}   // namespace boost
175
176#endif // !defined(CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
Note: See TracBrowser for help on using the repository browser.