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