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

Revision 857, 6.3 KB checked in by igarcia, 19 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_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
12#define CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED
13
14#include <boost/spirit/core.hpp>
15#include <boost/spirit/tree/parse_tree.hpp>
16#include <boost/spirit/utility/confix.hpp>
17#include <boost/spirit/utility/lists.hpp>
18
19#include <boost/wave/wave_config.hpp>
20#include <boost/wave/token_ids.hpp>
21#include <boost/wave/grammars/cpp_predef_macros_gen.hpp>
22#include <boost/wave/util/pattern_parser.hpp>
23
24///////////////////////////////////////////////////////////////////////////////
25namespace boost {
26namespace wave {
27namespace grammars {
28
29///////////////////////////////////////////////////////////////////////////////
30//  define, whether the rule's should generate some debug output
31#define TRACE_PREDEF_MACROS_GRAMMAR \
32    bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \
33    /**/
34
35///////////////////////////////////////////////////////////////////////////////
36// Encapsulation of the grammar for command line driven predefined macros.
37struct predefined_macros_grammar :
38    public boost::spirit::grammar<predefined_macros_grammar>
39{
40    template <typename ScannerT>
41    struct definition
42    {
43    // 'normal' (parse_tree generating) rule type
44        typedef boost::spirit::rule<ScannerT> rule_t;
45
46        rule_t plain_define, macro_definition, macro_parameters;
47
48        definition(predefined_macros_grammar const &self)
49        {
50        // import the spirit and cpplexer namespaces here
51            using namespace boost::spirit;
52            using namespace boost::wave;
53            using namespace boost::wave::util;
54           
55        // save the rule id's for later use
56            self.rule_ids.plain_define_id = plain_define.id().to_long();
57            self.rule_ids.macro_parameters_id = macro_parameters.id().to_long();
58            self.rule_ids.macro_definition_id = macro_definition.id().to_long();
59
60        // recognizes command line defined macro syntax, i.e.
61        //  -DMACRO
62        //  -DMACRO=
63        //  -DMACRO=value
64        //  -DMACRO(x)
65        //  -DMACRO(x)=
66        //  -DMACRO(x)=value
67
68        // This grammar resembles the overall structure of the cpp_grammar to
69        // make it possible to reuse the parse tree traversal code
70            plain_define
71                =   (   ch_p(T_IDENTIFIER)
72                    |   pattern_p(KeywordTokenType, TokenTypeMask)
73                    |   pattern_p(OperatorTokenType|AltExtTokenType,
74                            ExtTokenTypeMask)   // and, bit_and etc.
75                    )
76                    >>  !macro_parameters
77                    >>  !macro_definition
78                ;
79
80        // parameter list
81            macro_parameters
82                =   confix_p(
83                        no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)],
84                       !list_p(
85                            (   ch_p(T_IDENTIFIER)
86                            |   pattern_p(KeywordTokenType, TokenTypeMask)
87                            |   pattern_p(OperatorTokenType|AltExtTokenType,
88                                    ExtTokenTypeMask)   // and, bit_and etc.
89#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
90                            |   ch_p(T_ELLIPSIS)
91#endif
92                            ),
93                            no_node_d
94                            [
95                                *ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE)
96                            ]
97                        ),
98                        no_node_d[*ch_p(T_SPACE) >> ch_p(T_RIGHTPAREN)]
99                    )
100                ;
101
102        // macro body (anything left until eol)
103            macro_definition
104                =   no_node_d[ch_p(T_ASSIGN)]
105                    >> *anychar_p
106                ;
107
108            BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR);
109            BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR);
110            BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR);
111        }
112
113    // start rule of this grammar
114        rule_t const& start() const
115        { return plain_define; }
116    };
117
118    predefined_macros_grammar_rule_ids &rule_ids;
119   
120    predefined_macros_grammar(predefined_macros_grammar_rule_ids &rule_ids_)
121    :   rule_ids(rule_ids_)
122    {
123        BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
124            "predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR);
125    }
126
127};
128
129///////////////////////////////////////////////////////////////////////////////
130#undef TRACE_PREDEF_MACROS_GRAMMAR
131
132///////////////////////////////////////////////////////////////////////////////
133// 
134//  The following parse function is defined here, to allow the separation of
135//  the compilation of the cpp_predefined_macros_grammar from the function
136//  using it.
137// 
138///////////////////////////////////////////////////////////////////////////////
139
140#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
141#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
142#else
143#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline
144#endif
145
146template <typename LexIteratorT>
147BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
148boost::spirit::tree_parse_info<LexIteratorT>
149predefined_macros_grammar_gen<LexIteratorT>::parse_predefined_macro (
150    LexIteratorT const &first, LexIteratorT const &last)
151{
152    predefined_macros_grammar g(rule_ids);
153    return boost::spirit::pt_parse (first, last, g);
154}
155
156#undef BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
157
158///////////////////////////////////////////////////////////////////////////////
159}   // namespace grammars
160}   // namespace wave
161}   // namespace boost
162
163#endif // !defined(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
Note: See TracBrowser for help on using the repository browser.