annotate DEPENDENCIES/generic/include/boost/wave/grammars/cpp_grammar.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
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_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
Chris@16 12 #define CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_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_parse_tree_utils.hpp>
Chris@16 17 #include <boost/spirit/include/classic_confix.hpp>
Chris@16 18 #include <boost/spirit/include/classic_lists.hpp>
Chris@16 19
Chris@16 20 #include <boost/wave/wave_config.hpp>
Chris@16 21 #include <boost/pool/pool_alloc.hpp>
Chris@16 22
Chris@16 23 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
Chris@16 24 #include <map>
Chris@16 25 #include <boost/spirit/include/classic_tree_to_xml.hpp>
Chris@16 26 #endif
Chris@16 27
Chris@16 28 #include <boost/wave/token_ids.hpp>
Chris@16 29 #include <boost/wave/grammars/cpp_grammar_gen.hpp>
Chris@16 30 #include <boost/wave/util/pattern_parser.hpp>
Chris@16 31
Chris@16 32 #include <boost/wave/cpp_exceptions.hpp>
Chris@16 33
Chris@16 34 // this must occur after all of the includes and before any code appears
Chris@16 35 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 36 #include BOOST_ABI_PREFIX
Chris@16 37 #endif
Chris@16 38
Chris@16 39 ///////////////////////////////////////////////////////////////////////////////
Chris@16 40 namespace boost {
Chris@16 41 namespace wave {
Chris@16 42 namespace grammars {
Chris@16 43
Chris@16 44 namespace impl {
Chris@16 45
Chris@16 46 ///////////////////////////////////////////////////////////////////////////////
Chris@16 47 //
Chris@16 48 // store_found_eof
Chris@16 49 //
Chris@16 50 // The store_found_eof functor sets a given flag if the T_EOF token was
Chris@16 51 // found during the parsing process
Chris@16 52 //
Chris@16 53 ///////////////////////////////////////////////////////////////////////////////
Chris@16 54
Chris@16 55 struct store_found_eof {
Chris@16 56
Chris@16 57 store_found_eof(bool &found_eof_) : found_eof(found_eof_) {}
Chris@16 58
Chris@16 59 template <typename TokenT>
Chris@16 60 void operator()(TokenT const &/*token*/) const
Chris@16 61 {
Chris@16 62 found_eof = true;
Chris@16 63 }
Chris@16 64
Chris@16 65 bool &found_eof;
Chris@16 66 };
Chris@16 67
Chris@16 68 ///////////////////////////////////////////////////////////////////////////////
Chris@16 69 //
Chris@16 70 // store_found_directive
Chris@16 71 //
Chris@16 72 // The store_found_directive functor stores the token_id of the recognized
Chris@16 73 // pp directive
Chris@16 74 //
Chris@16 75 ///////////////////////////////////////////////////////////////////////////////
Chris@16 76
Chris@16 77 template <typename TokenT>
Chris@16 78 struct store_found_directive {
Chris@16 79
Chris@16 80 store_found_directive(TokenT &found_directive_)
Chris@16 81 : found_directive(found_directive_) {}
Chris@16 82
Chris@16 83 void operator()(TokenT const &token) const
Chris@16 84 {
Chris@16 85 found_directive = token;
Chris@16 86 }
Chris@16 87
Chris@16 88 TokenT &found_directive;
Chris@16 89 };
Chris@16 90
Chris@16 91 ///////////////////////////////////////////////////////////////////////////////
Chris@16 92 //
Chris@16 93 // store_found_eoltokens
Chris@16 94 //
Chris@16 95 // The store_found_eoltokens functor stores the token sequence of the
Chris@16 96 // line ending for a particular pp directive
Chris@16 97 //
Chris@16 98 ///////////////////////////////////////////////////////////////////////////////
Chris@16 99
Chris@16 100 template <typename ContainerT>
Chris@16 101 struct store_found_eoltokens {
Chris@16 102
Chris@16 103 store_found_eoltokens(ContainerT &found_eoltokens_)
Chris@16 104 : found_eoltokens(found_eoltokens_) {}
Chris@16 105
Chris@16 106 template <typename IteratorT>
Chris@16 107 void operator()(IteratorT const &first, IteratorT const& last) const
Chris@16 108 {
Chris@16 109 std::copy(first, last,
Chris@16 110 std::inserter(found_eoltokens, found_eoltokens.end()));
Chris@16 111 }
Chris@16 112
Chris@16 113 ContainerT &found_eoltokens;
Chris@16 114 };
Chris@16 115
Chris@16 116 ///////////////////////////////////////////////////////////////////////////////
Chris@16 117 //
Chris@16 118 // flush_underlying_parser
Chris@16 119 //
Chris@16 120 // The flush_underlying_parser flushes the underlying
Chris@16 121 // multi_pass_iterator during the normal parsing process. This is
Chris@16 122 // used at certain points during the parsing process, when it is
Chris@16 123 // clear, that no backtracking is needed anymore and the input
Chris@16 124 // gathered so far may be discarded.
Chris@16 125 //
Chris@16 126 ///////////////////////////////////////////////////////////////////////////////
Chris@16 127 struct flush_underlying_parser
Chris@16 128 : public boost::spirit::classic::parser<flush_underlying_parser>
Chris@16 129 {
Chris@16 130 typedef flush_underlying_parser this_t;
Chris@16 131
Chris@16 132 template <typename ScannerT>
Chris@16 133 typename boost::spirit::classic::parser_result<this_t, ScannerT>::type
Chris@16 134 parse(ScannerT const& scan) const
Chris@16 135 {
Chris@16 136 scan.first.clear_queue();
Chris@16 137 return scan.empty_match();
Chris@16 138 }
Chris@16 139 };
Chris@16 140
Chris@16 141 flush_underlying_parser const
Chris@16 142 flush_underlying_parser_p = flush_underlying_parser();
Chris@16 143
Chris@16 144 } // anonymous namespace
Chris@16 145
Chris@16 146 ///////////////////////////////////////////////////////////////////////////////
Chris@16 147 // define, whether the rule's should generate some debug output
Chris@16 148 #define TRACE_CPP_GRAMMAR \
Chris@16 149 bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
Chris@16 150 /**/
Chris@16 151
Chris@16 152 ///////////////////////////////////////////////////////////////////////////////
Chris@16 153 // Encapsulation of the C++ preprocessor grammar.
Chris@16 154 template <typename TokenT, typename ContainerT>
Chris@16 155 struct cpp_grammar :
Chris@16 156 public boost::spirit::classic::grammar<cpp_grammar<TokenT, ContainerT> >
Chris@16 157 {
Chris@16 158 typedef typename TokenT::position_type position_type;
Chris@16 159 typedef cpp_grammar<TokenT, ContainerT> grammar_type;
Chris@16 160 typedef impl::store_found_eof store_found_eof_type;
Chris@16 161 typedef impl::store_found_directive<TokenT> store_found_directive_type;
Chris@16 162 typedef impl::store_found_eoltokens<ContainerT> store_found_eoltokens_type;
Chris@16 163
Chris@16 164 template <typename ScannerT>
Chris@16 165 struct definition
Chris@16 166 {
Chris@16 167 // non-parse_tree generating rule type
Chris@16 168 typedef typename ScannerT::iteration_policy_t iteration_policy_t;
Chris@16 169 typedef boost::spirit::classic::match_policy match_policy_t;
Chris@16 170 typedef typename ScannerT::action_policy_t action_policy_t;
Chris@16 171 typedef
Chris@16 172 boost::spirit::classic::scanner_policies<
Chris@16 173 iteration_policy_t, match_policy_t, action_policy_t>
Chris@16 174 policies_t;
Chris@16 175 typedef
Chris@16 176 boost::spirit::classic::scanner<typename ScannerT::iterator_t, policies_t>
Chris@16 177 non_tree_scanner_t;
Chris@16 178 typedef
Chris@16 179 boost::spirit::classic::rule<
Chris@16 180 non_tree_scanner_t, boost::spirit::classic::dynamic_parser_tag>
Chris@16 181 no_tree_rule_type;
Chris@16 182
Chris@16 183 // 'normal' (parse_tree generating) rule type
Chris@16 184 typedef
Chris@16 185 boost::spirit::classic::rule<
Chris@16 186 ScannerT, boost::spirit::classic::dynamic_parser_tag>
Chris@16 187 rule_type;
Chris@16 188
Chris@16 189 rule_type pp_statement, macro_include_file;
Chris@16 190 // rule_type include_file, system_include_file;
Chris@16 191 rule_type plain_define, macro_definition, macro_parameters;
Chris@16 192 rule_type undefine;
Chris@16 193 rule_type ppifdef, ppifndef, ppif, ppelif;
Chris@16 194 // rule_type ppelse, ppendif;
Chris@16 195 rule_type ppline;
Chris@16 196 rule_type pperror;
Chris@16 197 rule_type ppwarning;
Chris@16 198 rule_type pppragma;
Chris@16 199 rule_type illformed;
Chris@16 200 rule_type ppqualifiedname;
Chris@16 201 rule_type eol_tokens;
Chris@16 202 no_tree_rule_type ppsp;
Chris@16 203 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
Chris@16 204 rule_type ppregion;
Chris@16 205 rule_type ppendregion;
Chris@16 206 #endif
Chris@16 207
Chris@16 208 definition(cpp_grammar const &self)
Chris@16 209 {
Chris@16 210 // import the spirit and cpplexer namespaces here
Chris@16 211 using namespace boost::spirit::classic;
Chris@16 212 using namespace boost::wave;
Chris@16 213 using namespace boost::wave::util;
Chris@16 214
Chris@16 215 // set the rule id's for later use
Chris@16 216 pp_statement.set_id(BOOST_WAVE_PP_STATEMENT_ID);
Chris@16 217 // include_file.set_id(BOOST_WAVE_INCLUDE_FILE_ID);
Chris@16 218 // system_include_file.set_id(BOOST_WAVE_SYSINCLUDE_FILE_ID);
Chris@16 219 macro_include_file.set_id(BOOST_WAVE_MACROINCLUDE_FILE_ID);
Chris@16 220 plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
Chris@16 221 macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
Chris@16 222 macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
Chris@16 223 undefine.set_id(BOOST_WAVE_UNDEFINE_ID);
Chris@16 224 ppifdef.set_id(BOOST_WAVE_IFDEF_ID);
Chris@16 225 ppifndef.set_id(BOOST_WAVE_IFNDEF_ID);
Chris@16 226 ppif.set_id(BOOST_WAVE_IF_ID);
Chris@16 227 ppelif.set_id(BOOST_WAVE_ELIF_ID);
Chris@16 228 // ppelse.set_id(BOOST_WAVE_ELSE_ID);
Chris@16 229 // ppendif.set_id(BOOST_WAVE_ENDIF_ID);
Chris@16 230 ppline.set_id(BOOST_WAVE_LINE_ID);
Chris@16 231 pperror.set_id(BOOST_WAVE_ERROR_ID);
Chris@16 232 ppwarning.set_id(BOOST_WAVE_WARNING_ID);
Chris@16 233 pppragma.set_id(BOOST_WAVE_PRAGMA_ID);
Chris@16 234 illformed.set_id(BOOST_WAVE_ILLFORMED_ID);
Chris@16 235 ppsp.set_id(BOOST_WAVE_PPSPACE_ID);
Chris@16 236 ppqualifiedname.set_id(BOOST_WAVE_PPQUALIFIEDNAME_ID);
Chris@16 237 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
Chris@16 238 ppregion.set_id(BOOST_WAVE_REGION_ID);
Chris@16 239 ppendregion.set_id(BOOST_WAVE_ENDREGION_ID);
Chris@16 240 #endif
Chris@16 241
Chris@16 242 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
Chris@16 243 self.map_rule_id_to_name.init_rule_id_to_name_map(self);
Chris@16 244 #endif
Chris@16 245
Chris@16 246 // recognizes preprocessor directives only
Chris@16 247
Chris@16 248 // C++ standard 16.1: A preprocessing directive consists of a sequence
Chris@16 249 // of preprocessing tokens. The first token in the sequence is #
Chris@16 250 // preprocessing token that is either the first character in the source
Chris@16 251 // file (optionally after white space containing no new-line
Chris@16 252 // characters) or that follows white space containing at least one
Chris@16 253 // new-line character. The last token in the sequence is the first
Chris@16 254 // new-line character that follows the first token in the sequence.
Chris@16 255
Chris@16 256 pp_statement
Chris@16 257 = ( plain_define
Chris@16 258 // | include_file
Chris@16 259 // | system_include_file
Chris@16 260 | ppif
Chris@16 261 | ppelif
Chris@16 262 | ppifndef
Chris@16 263 | ppifdef
Chris@16 264 | undefine
Chris@16 265 // | ppelse
Chris@16 266 | macro_include_file
Chris@16 267 | ppline
Chris@16 268 | pppragma
Chris@16 269 | pperror
Chris@16 270 | ppwarning
Chris@16 271 // | ppendif
Chris@16 272 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
Chris@16 273 | ppregion
Chris@16 274 | ppendregion
Chris@16 275 #endif
Chris@16 276 | illformed
Chris@16 277 )
Chris@16 278 >> eol_tokens
Chris@16 279 [ store_found_eoltokens_type(self.found_eoltokens) ]
Chris@16 280 // In parser debug mode it is useful not to flush the underlying stream
Chris@16 281 // to allow its investigation in the debugger and to see the correct
Chris@16 282 // output in the printed debug log..
Chris@16 283 // Note: this may break the parser, though.
Chris@16 284 #if !(defined(BOOST_SPIRIT_DEBUG) && \
Chris@16 285 (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
Chris@16 286 )
Chris@16 287 >> impl::flush_underlying_parser_p
Chris@16 288 #endif // !(defined(BOOST_SPIRIT_DEBUG) &&
Chris@16 289 ;
Chris@16 290
Chris@16 291 // // #include ...
Chris@16 292 // include_file // include "..."
Chris@16 293 // = ch_p(T_PP_QHEADER)
Chris@16 294 // [ store_found_directive_type(self.found_directive) ]
Chris@16 295 // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
Chris@16 296 // | ch_p(T_PP_QHEADER_NEXT)
Chris@16 297 // [ store_found_directive_type(self.found_directive) ]
Chris@16 298 // #endif
Chris@16 299 // ;
Chris@16 300
Chris@16 301 // system_include_file // include <...>
Chris@16 302 // = ch_p(T_PP_HHEADER)
Chris@16 303 // [ store_found_directive_type(self.found_directive) ]
Chris@16 304 // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
Chris@16 305 // | ch_p(T_PP_HHEADER_NEXT)
Chris@16 306 // [ store_found_directive_type(self.found_directive) ]
Chris@16 307 // #endif
Chris@16 308 // ;
Chris@16 309
Chris@16 310 macro_include_file // include ...anything else...
Chris@16 311 = no_node_d
Chris@16 312 [
Chris@16 313 ch_p(T_PP_INCLUDE)
Chris@16 314 [ store_found_directive_type(self.found_directive) ]
Chris@16 315 #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
Chris@16 316 | ch_p(T_PP_INCLUDE_NEXT)
Chris@16 317 [ store_found_directive_type(self.found_directive) ]
Chris@16 318 #endif
Chris@16 319 ]
Chris@16 320 >> *( anychar_p -
Chris@16 321 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 322 )
Chris@16 323 ;
Chris@16 324
Chris@16 325 // #define FOO foo (with optional parameters)
Chris@16 326 plain_define
Chris@16 327 = no_node_d
Chris@16 328 [
Chris@16 329 ch_p(T_PP_DEFINE)
Chris@16 330 [ store_found_directive_type(self.found_directive) ]
Chris@16 331 >> +ppsp
Chris@16 332 ]
Chris@16 333 >> ( ch_p(T_IDENTIFIER)
Chris@16 334 | pattern_p(KeywordTokenType,
Chris@16 335 TokenTypeMask|PPTokenFlag)
Chris@16 336 | pattern_p(OperatorTokenType|AltExtTokenType,
Chris@16 337 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
Chris@16 338 | pattern_p(BoolLiteralTokenType,
Chris@16 339 TokenTypeMask|PPTokenFlag) // true/false
Chris@16 340 )
Chris@16 341 >> ( ( no_node_d[eps_p(ch_p(T_LEFTPAREN))]
Chris@16 342 >> macro_parameters
Chris@16 343 >> !macro_definition
Chris@16 344 )
Chris@16 345 | !( no_node_d[+ppsp]
Chris@16 346 >> macro_definition
Chris@16 347 )
Chris@16 348 )
Chris@16 349 ;
Chris@16 350
Chris@16 351 // parameter list
Chris@16 352 // normal C++ mode
Chris@16 353 macro_parameters
Chris@16 354 = confix_p(
Chris@16 355 no_node_d[ch_p(T_LEFTPAREN) >> *ppsp],
Chris@16 356 !list_p(
Chris@16 357 ( ch_p(T_IDENTIFIER)
Chris@16 358 | pattern_p(KeywordTokenType,
Chris@16 359 TokenTypeMask|PPTokenFlag)
Chris@16 360 | pattern_p(OperatorTokenType|AltExtTokenType,
Chris@16 361 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
Chris@16 362 | pattern_p(BoolLiteralTokenType,
Chris@16 363 TokenTypeMask|PPTokenFlag) // true/false
Chris@16 364 #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
Chris@16 365 | ch_p(T_ELLIPSIS)
Chris@16 366 #endif
Chris@16 367 ),
Chris@16 368 no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp]
Chris@16 369 ),
Chris@16 370 no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)]
Chris@16 371 )
Chris@16 372 ;
Chris@16 373
Chris@16 374 // macro body (anything left until eol)
Chris@16 375 macro_definition
Chris@16 376 = no_node_d[*ppsp]
Chris@16 377 >> *( anychar_p -
Chris@16 378 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 379 )
Chris@16 380 ;
Chris@16 381
Chris@16 382 // #undef FOO
Chris@16 383 undefine
Chris@16 384 = no_node_d
Chris@16 385 [
Chris@16 386 ch_p(T_PP_UNDEF)
Chris@16 387 [ store_found_directive_type(self.found_directive) ]
Chris@16 388 >> +ppsp
Chris@16 389 ]
Chris@16 390 >> ( ch_p(T_IDENTIFIER)
Chris@16 391 | pattern_p(KeywordTokenType,
Chris@16 392 TokenTypeMask|PPTokenFlag)
Chris@16 393 | pattern_p(OperatorTokenType|AltExtTokenType,
Chris@16 394 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
Chris@16 395 | pattern_p(BoolLiteralTokenType,
Chris@16 396 TokenTypeMask|PPTokenFlag) // true/false
Chris@16 397 )
Chris@16 398 ;
Chris@16 399
Chris@16 400 // #ifdef et.al.
Chris@16 401 ppifdef
Chris@16 402 = no_node_d
Chris@16 403 [
Chris@16 404 ch_p(T_PP_IFDEF)
Chris@16 405 [ store_found_directive_type(self.found_directive) ]
Chris@16 406 >> +ppsp
Chris@16 407 ]
Chris@16 408 >> ppqualifiedname
Chris@16 409 ;
Chris@16 410
Chris@16 411 ppifndef
Chris@16 412 = no_node_d
Chris@16 413 [
Chris@16 414 ch_p(T_PP_IFNDEF)
Chris@16 415 [ store_found_directive_type(self.found_directive) ]
Chris@16 416 >> +ppsp
Chris@16 417 ]
Chris@16 418 >> ppqualifiedname
Chris@16 419 ;
Chris@16 420
Chris@16 421 ppif
Chris@16 422 = no_node_d
Chris@16 423 [
Chris@16 424 ch_p(T_PP_IF)
Chris@16 425 [ store_found_directive_type(self.found_directive) ]
Chris@16 426 // >> *ppsp
Chris@16 427 ]
Chris@16 428 >> +( anychar_p -
Chris@16 429 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 430 )
Chris@16 431 ;
Chris@16 432
Chris@16 433 // ppelse
Chris@16 434 // = no_node_d
Chris@16 435 // [
Chris@16 436 // ch_p(T_PP_ELSE)
Chris@16 437 // [ store_found_directive_type(self.found_directive) ]
Chris@16 438 // ]
Chris@16 439 // ;
Chris@16 440
Chris@16 441 ppelif
Chris@16 442 = no_node_d
Chris@16 443 [
Chris@16 444 ch_p(T_PP_ELIF)
Chris@16 445 [ store_found_directive_type(self.found_directive) ]
Chris@16 446 // >> *ppsp
Chris@16 447 ]
Chris@16 448 >> +( anychar_p -
Chris@16 449 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 450 )
Chris@16 451 ;
Chris@16 452
Chris@16 453 // ppendif
Chris@16 454 // = no_node_d
Chris@16 455 // [
Chris@16 456 // ch_p(T_PP_ENDIF)
Chris@16 457 // [ store_found_directive_type(self.found_directive) ]
Chris@16 458 // ]
Chris@16 459 // ;
Chris@16 460
Chris@16 461 // #line ...
Chris@16 462 ppline
Chris@16 463 = no_node_d
Chris@16 464 [
Chris@16 465 ch_p(T_PP_LINE)
Chris@16 466 [ store_found_directive_type(self.found_directive) ]
Chris@16 467 >> *ppsp
Chris@16 468 ]
Chris@16 469 >> +( anychar_p -
Chris@16 470 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 471 )
Chris@16 472 ;
Chris@16 473
Chris@16 474 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
Chris@16 475 // #region ...
Chris@16 476 ppregion
Chris@16 477 = no_node_d
Chris@16 478 [
Chris@16 479 ch_p(T_MSEXT_PP_REGION)
Chris@16 480 [ store_found_directive_type(self.found_directive) ]
Chris@16 481 >> +ppsp
Chris@16 482 ]
Chris@16 483 >> ppqualifiedname
Chris@16 484 ;
Chris@16 485
Chris@16 486 // #endregion
Chris@16 487 ppendregion
Chris@16 488 = no_node_d
Chris@16 489 [
Chris@16 490 ch_p(T_MSEXT_PP_ENDREGION)
Chris@16 491 [ store_found_directive_type(self.found_directive) ]
Chris@16 492 ]
Chris@16 493 ;
Chris@16 494 #endif
Chris@16 495
Chris@16 496 // # something else (ill formed preprocessor directive)
Chris@16 497 illformed // for error reporting
Chris@16 498 = no_node_d
Chris@16 499 [
Chris@16 500 pattern_p(T_POUND, MainTokenMask)
Chris@16 501 >> *ppsp
Chris@16 502 ]
Chris@16 503 >> ( anychar_p -
Chris@16 504 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 505 )
Chris@16 506 >> no_node_d
Chris@16 507 [
Chris@16 508 *( anychar_p -
Chris@16 509 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 510 )
Chris@16 511 ]
Chris@16 512 ;
Chris@16 513
Chris@16 514 // #error
Chris@16 515 pperror
Chris@16 516 = no_node_d
Chris@16 517 [
Chris@16 518 ch_p(T_PP_ERROR)
Chris@16 519 [ store_found_directive_type(self.found_directive) ]
Chris@16 520 >> *ppsp
Chris@16 521 ]
Chris@16 522 >> *( anychar_p -
Chris@16 523 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 524 )
Chris@16 525 ;
Chris@16 526
Chris@16 527 // #warning
Chris@16 528 ppwarning
Chris@16 529 = no_node_d
Chris@16 530 [
Chris@16 531 ch_p(T_PP_WARNING)
Chris@16 532 [ store_found_directive_type(self.found_directive) ]
Chris@16 533 >> *ppsp
Chris@16 534 ]
Chris@16 535 >> *( anychar_p -
Chris@16 536 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 537 )
Chris@16 538 ;
Chris@16 539
Chris@16 540 // #pragma ...
Chris@16 541 pppragma
Chris@16 542 = no_node_d
Chris@16 543 [
Chris@16 544 ch_p(T_PP_PRAGMA)
Chris@16 545 [ store_found_directive_type(self.found_directive) ]
Chris@16 546 ]
Chris@16 547 >> *( anychar_p -
Chris@16 548 (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
Chris@16 549 )
Chris@16 550 ;
Chris@16 551
Chris@16 552 ppqualifiedname
Chris@16 553 = no_node_d[*ppsp]
Chris@16 554 >> ( ch_p(T_IDENTIFIER)
Chris@16 555 | pattern_p(KeywordTokenType,
Chris@16 556 TokenTypeMask|PPTokenFlag)
Chris@16 557 | pattern_p(OperatorTokenType|AltExtTokenType,
Chris@16 558 ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
Chris@16 559 | pattern_p(BoolLiteralTokenType,
Chris@16 560 TokenTypeMask|PPTokenFlag) // true/false
Chris@16 561 )
Chris@16 562 ;
Chris@16 563
Chris@16 564 // auxiliary helper rules
Chris@16 565 ppsp // valid space in a line with a preprocessor directive
Chris@16 566 = ch_p(T_SPACE) | ch_p(T_CCOMMENT)
Chris@16 567 ;
Chris@16 568
Chris@16 569 // end of line tokens
Chris@16 570 eol_tokens
Chris@16 571 = no_node_d
Chris@16 572 [
Chris@16 573 *( ch_p(T_SPACE)
Chris@16 574 | ch_p(T_CCOMMENT)
Chris@16 575 )
Chris@16 576 >> ( ch_p(T_NEWLINE)
Chris@16 577 | ch_p(T_CPPCOMMENT)
Chris@16 578 | ch_p(T_EOF)
Chris@16 579 [ store_found_eof_type(self.found_eof) ]
Chris@16 580 )
Chris@16 581 ]
Chris@16 582 ;
Chris@16 583
Chris@16 584 BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR);
Chris@16 585 // BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR);
Chris@16 586 // BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR);
Chris@16 587 BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR);
Chris@16 588 BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR);
Chris@16 589 BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR);
Chris@16 590 BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR);
Chris@16 591 BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR);
Chris@16 592 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR);
Chris@16 593 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR);
Chris@16 594 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR);
Chris@16 595 // BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR);
Chris@16 596 // BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR);
Chris@16 597 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR);
Chris@16 598 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR);
Chris@16 599 BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR);
Chris@16 600 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR);
Chris@16 601 BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR);
Chris@16 602 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR);
Chris@16 603 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR);
Chris@16 604 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
Chris@16 605 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppregion, TRACE_CPP_GRAMMAR);
Chris@16 606 BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendregion, TRACE_CPP_GRAMMAR);
Chris@16 607 #endif
Chris@16 608 }
Chris@16 609
Chris@16 610 // start rule of this grammar
Chris@16 611 rule_type const& start() const
Chris@16 612 { return pp_statement; }
Chris@16 613 };
Chris@16 614
Chris@16 615 bool &found_eof;
Chris@16 616 TokenT &found_directive;
Chris@16 617 ContainerT &found_eoltokens;
Chris@16 618
Chris@16 619 cpp_grammar(bool &found_eof_, TokenT &found_directive_,
Chris@16 620 ContainerT &found_eoltokens_)
Chris@16 621 : found_eof(found_eof_),
Chris@16 622 found_directive(found_directive_),
Chris@16 623 found_eoltokens(found_eoltokens_)
Chris@16 624 {
Chris@16 625 BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar",
Chris@16 626 TRACE_CPP_GRAMMAR);
Chris@16 627 }
Chris@16 628
Chris@16 629 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
Chris@16 630 // helper function and data to get readable names of the rules known to us
Chris@16 631 struct map_ruleid_to_name :
Chris@16 632 public std::map<boost::spirit::classic::parser_id, std::string>
Chris@16 633 {
Chris@16 634 typedef std::map<boost::spirit::classic::parser_id, std::string> base_type;
Chris@16 635
Chris@16 636 void init_rule_id_to_name_map(cpp_grammar const &self)
Chris@16 637 {
Chris@16 638 struct {
Chris@16 639 int parser_id;
Chris@16 640 char const *rule_name;
Chris@16 641 }
Chris@16 642 init_ruleid_name_map[] = {
Chris@16 643 { BOOST_WAVE_PP_STATEMENT_ID, "pp_statement" },
Chris@16 644 // { BOOST_WAVE_INCLUDE_FILE_ID, "include_file" },
Chris@16 645 // { BOOST_WAVE_SYSINCLUDE_FILE_ID, "system_include_file" },
Chris@16 646 { BOOST_WAVE_MACROINCLUDE_FILE_ID, "macro_include_file" },
Chris@16 647 { BOOST_WAVE_PLAIN_DEFINE_ID, "plain_define" },
Chris@16 648 { BOOST_WAVE_MACRO_PARAMETERS_ID, "macro_parameters" },
Chris@16 649 { BOOST_WAVE_MACRO_DEFINITION_ID, "macro_definition" },
Chris@16 650 { BOOST_WAVE_UNDEFINE_ID, "undefine" },
Chris@16 651 { BOOST_WAVE_IFDEF_ID, "ppifdef" },
Chris@16 652 { BOOST_WAVE_IFNDEF_ID, "ppifndef" },
Chris@16 653 { BOOST_WAVE_IF_ID, "ppif" },
Chris@16 654 { BOOST_WAVE_ELIF_ID, "ppelif" },
Chris@16 655 // { BOOST_WAVE_ELSE_ID, "ppelse" },
Chris@16 656 // { BOOST_WAVE_ENDIF_ID, "ppendif" },
Chris@16 657 { BOOST_WAVE_LINE_ID, "ppline" },
Chris@16 658 { BOOST_WAVE_ERROR_ID, "pperror" },
Chris@16 659 { BOOST_WAVE_WARNING_ID, "ppwarning" },
Chris@16 660 { BOOST_WAVE_PRAGMA_ID, "pppragma" },
Chris@16 661 { BOOST_WAVE_ILLFORMED_ID, "illformed" },
Chris@16 662 { BOOST_WAVE_PPSPACE_ID, "ppspace" },
Chris@16 663 { BOOST_WAVE_PPQUALIFIEDNAME_ID, "ppqualifiedname" },
Chris@16 664 #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
Chris@16 665 { BOOST_WAVE_REGION_ID, "ppregion" },
Chris@16 666 { BOOST_WAVE_ENDREGION_ID, "ppendregion" },
Chris@16 667 #endif
Chris@16 668 { 0 }
Chris@16 669 };
Chris@16 670
Chris@16 671 // initialize parser_id to rule_name map
Chris@16 672 for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i)
Chris@16 673 base_type::insert(base_type::value_type(
Chris@16 674 boost::spirit::classic::parser_id(init_ruleid_name_map[i].parser_id),
Chris@16 675 std::string(init_ruleid_name_map[i].rule_name))
Chris@16 676 );
Chris@16 677 }
Chris@16 678 };
Chris@16 679 mutable map_ruleid_to_name map_rule_id_to_name;
Chris@16 680 #endif // WAVE_DUMP_PARSE_TREE != 0
Chris@16 681 };
Chris@16 682
Chris@16 683 ///////////////////////////////////////////////////////////////////////////////
Chris@16 684 #undef TRACE_CPP_GRAMMAR
Chris@16 685
Chris@16 686 ///////////////////////////////////////////////////////////////////////////////
Chris@16 687 //
Chris@16 688 // Special parse function generating a parse tree using a given node_factory.
Chris@16 689 //
Chris@16 690 ///////////////////////////////////////////////////////////////////////////////
Chris@16 691 template <typename NodeFactoryT, typename IteratorT, typename ParserT>
Chris@16 692 inline boost::spirit::classic::tree_parse_info<IteratorT, NodeFactoryT>
Chris@16 693 parsetree_parse(IteratorT const& first_, IteratorT const& last,
Chris@16 694 boost::spirit::classic::parser<ParserT> const& p)
Chris@16 695 {
Chris@16 696 using namespace boost::spirit::classic;
Chris@16 697
Chris@16 698 typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_type;
Chris@16 699 typedef scanner_policies<iteration_policy, pt_match_policy_type>
Chris@16 700 scanner_policies_type;
Chris@16 701 typedef scanner<IteratorT, scanner_policies_type> scanner_type;
Chris@16 702
Chris@16 703 scanner_policies_type policies;
Chris@16 704 IteratorT first = first_;
Chris@16 705 scanner_type scan(first, last, policies);
Chris@16 706 tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan);
Chris@16 707 return tree_parse_info<IteratorT, NodeFactoryT>(
Chris@16 708 first, hit, hit && (first == last), hit.length(), hit.trees);
Chris@16 709 }
Chris@16 710
Chris@16 711 ///////////////////////////////////////////////////////////////////////////////
Chris@16 712 //
Chris@16 713 // The following parse function is defined here, to allow the separation of
Chris@16 714 // the compilation of the cpp_grammar from the function using it.
Chris@16 715 //
Chris@16 716 ///////////////////////////////////////////////////////////////////////////////
Chris@16 717
Chris@16 718 #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
Chris@16 719 #define BOOST_WAVE_GRAMMAR_GEN_INLINE
Chris@16 720 #else
Chris@16 721 #define BOOST_WAVE_GRAMMAR_GEN_INLINE inline
Chris@16 722 #endif
Chris@16 723
Chris@16 724 template <typename LexIteratorT, typename TokenContainerT>
Chris@16 725 BOOST_WAVE_GRAMMAR_GEN_INLINE
Chris@16 726 boost::spirit::classic::tree_parse_info<
Chris@16 727 LexIteratorT,
Chris@16 728 typename cpp_grammar_gen<LexIteratorT, TokenContainerT>::node_factory_type
Chris@16 729 >
Chris@16 730 cpp_grammar_gen<LexIteratorT, TokenContainerT>::parse_cpp_grammar (
Chris@16 731 LexIteratorT const &first, LexIteratorT const &last,
Chris@16 732 position_type const &act_pos, bool &found_eof,
Chris@16 733 token_type &found_directive, token_container_type &found_eoltokens)
Chris@16 734 {
Chris@16 735 using namespace boost::spirit::classic;
Chris@16 736 using namespace boost::wave;
Chris@16 737
Chris@16 738 cpp_grammar<token_type, TokenContainerT> g(found_eof, found_directive, found_eoltokens);
Chris@16 739 tree_parse_info<LexIteratorT, node_factory_type> hit =
Chris@16 740 parsetree_parse<node_factory_type>(first, last, g);
Chris@16 741
Chris@16 742 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
Chris@16 743 if (hit.match) {
Chris@16 744 tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "",
Chris@16 745 g.map_rule_id_to_name, &token_type::get_token_id,
Chris@16 746 &token_type::get_token_value);
Chris@16 747 }
Chris@16 748 #endif
Chris@16 749
Chris@16 750 return hit;
Chris@16 751 }
Chris@16 752
Chris@16 753 #undef BOOST_WAVE_GRAMMAR_GEN_INLINE
Chris@16 754
Chris@16 755 ///////////////////////////////////////////////////////////////////////////////
Chris@16 756 } // namespace grammars
Chris@16 757 } // namespace wave
Chris@16 758 } // namespace boost
Chris@16 759
Chris@16 760 // the suffix header occurs after all of the code
Chris@16 761 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 762 #include BOOST_ABI_SUFFIX
Chris@16 763 #endif
Chris@16 764
Chris@16 765 #endif // !defined(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)