• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Boost.Wave: A Standard compliant C++ preprocessor library
3 
4     http://www.boost.org/
5 
6     Copyright (c) 2001-2012 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(BOOST_CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
12 #define BOOST_CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED
13 
14 #include <boost/spirit/include/classic_core.hpp>
15 #include <boost/spirit/include/classic_parse_tree.hpp>
16 #include <boost/spirit/include/classic_confix.hpp>
17 #include <boost/spirit/include/classic_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 // this must occur after all of the includes and before any code appears
25 #ifdef BOOST_HAS_ABI_HEADERS
26 #include BOOST_ABI_PREFIX
27 #endif
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 namespace boost {
31 namespace wave {
32 namespace grammars {
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 //  define, whether the rule's should generate some debug output
36 #define TRACE_PREDEF_MACROS_GRAMMAR \
37     bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \
38     /**/
39 
40 ///////////////////////////////////////////////////////////////////////////////
41 // Encapsulation of the grammar for command line driven predefined macros.
42 struct predefined_macros_grammar :
43     public boost::spirit::classic::grammar<predefined_macros_grammar>
44 {
45     template <typename ScannerT>
46     struct definition
47     {
48     // 'normal' (parse_tree generating) rule type
49         typedef boost::spirit::classic::rule<
50                 ScannerT, boost::spirit::classic::dynamic_parser_tag>
51             rule_type;
52 
53         rule_type plain_define, macro_definition, macro_parameters;
54 
definitionboost::wave::grammars::predefined_macros_grammar::definition55         definition(predefined_macros_grammar const &/*self*/)
56         {
57         // import the spirit and cpplexer namespaces here
58             using namespace boost::spirit::classic;
59             using namespace boost::wave;
60             using namespace boost::wave::util;
61 
62         // set the rule id's for later use
63             plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
64             macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
65             macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
66 
67         // recognizes command line defined macro syntax, i.e.
68         //  -DMACRO
69         //  -DMACRO=
70         //  -DMACRO=value
71         //  -DMACRO(x)
72         //  -DMACRO(x)=
73         //  -DMACRO(x)=value
74 
75         // This grammar resembles the overall structure of the cpp_grammar to
76         // make it possible to reuse the parse tree traversal code
77             plain_define
78                 =   (   ch_p(T_IDENTIFIER)
79                     |   pattern_p(KeywordTokenType,
80                             TokenTypeMask|PPTokenFlag)
81                     |   pattern_p(OperatorTokenType|AltExtTokenType,
82                             ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
83                     |   pattern_p(BoolLiteralTokenType,
84                             TokenTypeMask|PPTokenFlag)  // true/false
85                     )
86                     >>  !macro_parameters
87                     >>  !macro_definition
88                 ;
89 
90         // parameter list
91             macro_parameters
92                 =   confix_p(
93                         no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)],
94                        !list_p(
95                             (   ch_p(T_IDENTIFIER)
96                             |   pattern_p(KeywordTokenType,
97                                     TokenTypeMask|PPTokenFlag)
98                             |   pattern_p(OperatorTokenType|AltExtTokenType,
99                                     ExtTokenTypeMask|PPTokenFlag)   // and, bit_and etc.
100                             |   pattern_p(BoolLiteralTokenType,
101                                     TokenTypeMask|PPTokenFlag)  // true/false
102 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
103                             |   ch_p(T_ELLIPSIS)
104 #endif
105                             ),
106                             no_node_d
107                             [
108                                 *ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE)
109                             ]
110                         ),
111                         no_node_d[*ch_p(T_SPACE) >> ch_p(T_RIGHTPAREN)]
112                     )
113                 ;
114 
115         // macro body (anything left until eol)
116             macro_definition
117                 =   no_node_d[ch_p(T_ASSIGN)]
118                     >> *anychar_p
119                 ;
120 
121             BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR);
122             BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR);
123             BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR);
124         }
125 
126     // start rule of this grammar
startboost::wave::grammars::predefined_macros_grammar::definition127         rule_type const& start() const
128         { return plain_define; }
129     };
130 
predefined_macros_grammarboost::wave::grammars::predefined_macros_grammar131     predefined_macros_grammar()
132     {
133         BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
134             "predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR);
135     }
136 
137 };
138 
139 ///////////////////////////////////////////////////////////////////////////////
140 #undef TRACE_PREDEF_MACROS_GRAMMAR
141 
142 ///////////////////////////////////////////////////////////////////////////////
143 //
144 //  The following parse function is defined here, to allow the separation of
145 //  the compilation of the cpp_predefined_macros_grammar from the function
146 //  using it.
147 //
148 ///////////////////////////////////////////////////////////////////////////////
149 
150 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
151 #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
152 #else
153 #define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline
154 #endif
155 
156 template <typename LexIteratorT>
157 BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
158 boost::spirit::classic::tree_parse_info<LexIteratorT>
parse_predefined_macro(LexIteratorT const & first,LexIteratorT const & last)159 predefined_macros_grammar_gen<LexIteratorT>::parse_predefined_macro (
160     LexIteratorT const &first, LexIteratorT const &last)
161 {
162     predefined_macros_grammar g;
163     return boost::spirit::classic::pt_parse (first, last, g);
164 }
165 
166 #undef BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
167 
168 ///////////////////////////////////////////////////////////////////////////////
169 }   // namespace grammars
170 }   // namespace wave
171 }   // namespace boost
172 
173 // the suffix header occurs after all of the code
174 #ifdef BOOST_HAS_ABI_HEADERS
175 #include BOOST_ABI_SUFFIX
176 #endif
177 
178 #endif // !defined(BOOST_CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
179