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 | ///////////////////////////////////////////////////////////////////////////////
|
---|
25 | namespace boost {
|
---|
26 | namespace wave {
|
---|
27 | namespace 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.
|
---|
37 | struct 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 |
|
---|
146 | template <typename LexIteratorT>
|
---|
147 | BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
|
---|
148 | boost::spirit::tree_parse_info<LexIteratorT>
|
---|
149 | predefined_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)
|
---|