]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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(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/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 | ||
55 | 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 | |
127 | rule_type const& start() const | |
128 | { return plain_define; } | |
129 | }; | |
130 | ||
131 | 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> | |
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(CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED) |