123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765 |
- /*=============================================================================
- Boost.Wave: A Standard compliant C++ preprocessor library
- http://www.boost.org/
- Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
- Software License, Version 1.0. (See accompanying file
- LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- #if !defined(BOOST_CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
- #define BOOST_CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED
- #include <boost/spirit/include/classic_core.hpp>
- #include <boost/spirit/include/classic_parse_tree.hpp>
- #include <boost/spirit/include/classic_parse_tree_utils.hpp>
- #include <boost/spirit/include/classic_confix.hpp>
- #include <boost/spirit/include/classic_lists.hpp>
- #include <boost/wave/wave_config.hpp>
- #include <boost/pool/pool_alloc.hpp>
- #if BOOST_WAVE_DUMP_PARSE_TREE != 0
- #include <map>
- #include <boost/spirit/include/classic_tree_to_xml.hpp>
- #endif
- #include <boost/wave/token_ids.hpp>
- #include <boost/wave/grammars/cpp_grammar_gen.hpp>
- #include <boost/wave/util/pattern_parser.hpp>
- #include <boost/wave/cpp_exceptions.hpp>
- // this must occur after all of the includes and before any code appears
- #ifdef BOOST_HAS_ABI_HEADERS
- #include BOOST_ABI_PREFIX
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost {
- namespace wave {
- namespace grammars {
- namespace impl {
- ///////////////////////////////////////////////////////////////////////////////
- //
- // store_found_eof
- //
- // The store_found_eof functor sets a given flag if the T_EOF token was
- // found during the parsing process
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct store_found_eof {
- store_found_eof(bool &found_eof_) : found_eof(found_eof_) {}
- template <typename TokenT>
- void operator()(TokenT const &/*token*/) const
- {
- found_eof = true;
- }
- bool &found_eof;
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // store_found_directive
- //
- // The store_found_directive functor stores the token_id of the recognized
- // pp directive
- //
- ///////////////////////////////////////////////////////////////////////////////
- template <typename TokenT>
- struct store_found_directive {
- store_found_directive(TokenT &found_directive_)
- : found_directive(found_directive_) {}
- void operator()(TokenT const &token) const
- {
- found_directive = token;
- }
- TokenT &found_directive;
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // store_found_eoltokens
- //
- // The store_found_eoltokens functor stores the token sequence of the
- // line ending for a particular pp directive
- //
- ///////////////////////////////////////////////////////////////////////////////
- template <typename ContainerT>
- struct store_found_eoltokens {
- store_found_eoltokens(ContainerT &found_eoltokens_)
- : found_eoltokens(found_eoltokens_) {}
- template <typename IteratorT>
- void operator()(IteratorT const &first, IteratorT const& last) const
- {
- std::copy(first, last,
- std::inserter(found_eoltokens, found_eoltokens.end()));
- }
- ContainerT &found_eoltokens;
- };
- ///////////////////////////////////////////////////////////////////////////////
- //
- // flush_underlying_parser
- //
- // The flush_underlying_parser flushes the underlying
- // multi_pass_iterator during the normal parsing process. This is
- // used at certain points during the parsing process, when it is
- // clear, that no backtracking is needed anymore and the input
- // gathered so far may be discarded.
- //
- ///////////////////////////////////////////////////////////////////////////////
- struct flush_underlying_parser
- : public boost::spirit::classic::parser<flush_underlying_parser>
- {
- typedef flush_underlying_parser this_t;
- template <typename ScannerT>
- typename boost::spirit::classic::parser_result<this_t, ScannerT>::type
- parse(ScannerT const& scan) const
- {
- scan.first.clear_queue();
- return scan.empty_match();
- }
- };
- flush_underlying_parser const
- flush_underlying_parser_p = flush_underlying_parser();
- } // anonymous namespace
- ///////////////////////////////////////////////////////////////////////////////
- // define, whether the rule's should generate some debug output
- #define TRACE_CPP_GRAMMAR \
- bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
- /**/
- ///////////////////////////////////////////////////////////////////////////////
- // Encapsulation of the C++ preprocessor grammar.
- template <typename TokenT, typename ContainerT>
- struct cpp_grammar :
- public boost::spirit::classic::grammar<cpp_grammar<TokenT, ContainerT> >
- {
- typedef typename TokenT::position_type position_type;
- typedef cpp_grammar<TokenT, ContainerT> grammar_type;
- typedef impl::store_found_eof store_found_eof_type;
- typedef impl::store_found_directive<TokenT> store_found_directive_type;
- typedef impl::store_found_eoltokens<ContainerT> store_found_eoltokens_type;
- template <typename ScannerT>
- struct definition
- {
- // non-parse_tree generating rule type
- typedef typename ScannerT::iteration_policy_t iteration_policy_t;
- typedef boost::spirit::classic::match_policy match_policy_t;
- typedef typename ScannerT::action_policy_t action_policy_t;
- typedef
- boost::spirit::classic::scanner_policies<
- iteration_policy_t, match_policy_t, action_policy_t>
- policies_t;
- typedef
- boost::spirit::classic::scanner<typename ScannerT::iterator_t, policies_t>
- non_tree_scanner_t;
- typedef
- boost::spirit::classic::rule<
- non_tree_scanner_t, boost::spirit::classic::dynamic_parser_tag>
- no_tree_rule_type;
- // 'normal' (parse_tree generating) rule type
- typedef
- boost::spirit::classic::rule<
- ScannerT, boost::spirit::classic::dynamic_parser_tag>
- rule_type;
- rule_type pp_statement, macro_include_file;
- // rule_type include_file, system_include_file;
- rule_type plain_define, macro_definition, macro_parameters;
- rule_type undefine;
- rule_type ppifdef, ppifndef, ppif, ppelif;
- // rule_type ppelse, ppendif;
- rule_type ppline;
- rule_type pperror;
- rule_type ppwarning;
- rule_type pppragma;
- rule_type illformed;
- rule_type ppqualifiedname;
- rule_type eol_tokens;
- no_tree_rule_type ppsp;
- #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
- rule_type ppregion;
- rule_type ppendregion;
- #endif
- definition(cpp_grammar const &self)
- {
- // import the spirit and cpplexer namespaces here
- using namespace boost::spirit::classic;
- using namespace boost::wave;
- using namespace boost::wave::util;
- // set the rule id's for later use
- pp_statement.set_id(BOOST_WAVE_PP_STATEMENT_ID);
- // include_file.set_id(BOOST_WAVE_INCLUDE_FILE_ID);
- // system_include_file.set_id(BOOST_WAVE_SYSINCLUDE_FILE_ID);
- macro_include_file.set_id(BOOST_WAVE_MACROINCLUDE_FILE_ID);
- plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
- macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
- macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
- undefine.set_id(BOOST_WAVE_UNDEFINE_ID);
- ppifdef.set_id(BOOST_WAVE_IFDEF_ID);
- ppifndef.set_id(BOOST_WAVE_IFNDEF_ID);
- ppif.set_id(BOOST_WAVE_IF_ID);
- ppelif.set_id(BOOST_WAVE_ELIF_ID);
- // ppelse.set_id(BOOST_WAVE_ELSE_ID);
- // ppendif.set_id(BOOST_WAVE_ENDIF_ID);
- ppline.set_id(BOOST_WAVE_LINE_ID);
- pperror.set_id(BOOST_WAVE_ERROR_ID);
- ppwarning.set_id(BOOST_WAVE_WARNING_ID);
- pppragma.set_id(BOOST_WAVE_PRAGMA_ID);
- illformed.set_id(BOOST_WAVE_ILLFORMED_ID);
- ppsp.set_id(BOOST_WAVE_PPSPACE_ID);
- ppqualifiedname.set_id(BOOST_WAVE_PPQUALIFIEDNAME_ID);
- #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
- ppregion.set_id(BOOST_WAVE_REGION_ID);
- ppendregion.set_id(BOOST_WAVE_ENDREGION_ID);
- #endif
- #if BOOST_WAVE_DUMP_PARSE_TREE != 0
- self.map_rule_id_to_name.init_rule_id_to_name_map(self);
- #endif
- // recognizes preprocessor directives only
- // C++ standard 16.1: A preprocessing directive consists of a sequence
- // of preprocessing tokens. The first token in the sequence is #
- // preprocessing token that is either the first character in the source
- // file (optionally after white space containing no new-line
- // characters) or that follows white space containing at least one
- // new-line character. The last token in the sequence is the first
- // new-line character that follows the first token in the sequence.
- pp_statement
- = ( plain_define
- // | include_file
- // | system_include_file
- | ppif
- | ppelif
- | ppifndef
- | ppifdef
- | undefine
- // | ppelse
- | macro_include_file
- | ppline
- | pppragma
- | pperror
- | ppwarning
- // | ppendif
- #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
- | ppregion
- | ppendregion
- #endif
- | illformed
- )
- >> eol_tokens
- [ store_found_eoltokens_type(self.found_eoltokens) ]
- // In parser debug mode it is useful not to flush the underlying stream
- // to allow its investigation in the debugger and to see the correct
- // output in the printed debug log..
- // Note: this may break the parser, though.
- #if !(defined(BOOST_SPIRIT_DEBUG) && \
- (BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
- )
- >> impl::flush_underlying_parser_p
- #endif // !(defined(BOOST_SPIRIT_DEBUG) &&
- ;
- // // #include ...
- // include_file // include "..."
- // = ch_p(T_PP_QHEADER)
- // [ store_found_directive_type(self.found_directive) ]
- // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
- // | ch_p(T_PP_QHEADER_NEXT)
- // [ store_found_directive_type(self.found_directive) ]
- // #endif
- // ;
- // system_include_file // include <...>
- // = ch_p(T_PP_HHEADER)
- // [ store_found_directive_type(self.found_directive) ]
- // #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
- // | ch_p(T_PP_HHEADER_NEXT)
- // [ store_found_directive_type(self.found_directive) ]
- // #endif
- // ;
- macro_include_file // include ...anything else...
- = no_node_d
- [
- ch_p(T_PP_INCLUDE)
- [ store_found_directive_type(self.found_directive) ]
- #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
- | ch_p(T_PP_INCLUDE_NEXT)
- [ store_found_directive_type(self.found_directive) ]
- #endif
- ]
- >> *( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- // #define FOO foo (with optional parameters)
- plain_define
- = no_node_d
- [
- ch_p(T_PP_DEFINE)
- [ store_found_directive_type(self.found_directive) ]
- >> +ppsp
- ]
- >> ( ch_p(T_IDENTIFIER)
- | pattern_p(KeywordTokenType,
- TokenTypeMask|PPTokenFlag)
- | pattern_p(OperatorTokenType|AltExtTokenType,
- ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
- | pattern_p(BoolLiteralTokenType,
- TokenTypeMask|PPTokenFlag) // true/false
- )
- >> ( ( no_node_d[eps_p(ch_p(T_LEFTPAREN))]
- >> macro_parameters
- >> !macro_definition
- )
- | !( no_node_d[+ppsp]
- >> macro_definition
- )
- )
- ;
- // parameter list
- // normal C++ mode
- macro_parameters
- = confix_p(
- no_node_d[ch_p(T_LEFTPAREN) >> *ppsp],
- !list_p(
- ( ch_p(T_IDENTIFIER)
- | pattern_p(KeywordTokenType,
- TokenTypeMask|PPTokenFlag)
- | pattern_p(OperatorTokenType|AltExtTokenType,
- ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
- | pattern_p(BoolLiteralTokenType,
- TokenTypeMask|PPTokenFlag) // true/false
- #if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
- | ch_p(T_ELLIPSIS)
- #endif
- ),
- no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp]
- ),
- no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)]
- )
- ;
- // macro body (anything left until eol)
- macro_definition
- = no_node_d[*ppsp]
- >> *( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- // #undef FOO
- undefine
- = no_node_d
- [
- ch_p(T_PP_UNDEF)
- [ store_found_directive_type(self.found_directive) ]
- >> +ppsp
- ]
- >> ( ch_p(T_IDENTIFIER)
- | pattern_p(KeywordTokenType,
- TokenTypeMask|PPTokenFlag)
- | pattern_p(OperatorTokenType|AltExtTokenType,
- ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
- | pattern_p(BoolLiteralTokenType,
- TokenTypeMask|PPTokenFlag) // true/false
- )
- ;
- // #ifdef et.al.
- ppifdef
- = no_node_d
- [
- ch_p(T_PP_IFDEF)
- [ store_found_directive_type(self.found_directive) ]
- >> +ppsp
- ]
- >> ppqualifiedname
- ;
- ppifndef
- = no_node_d
- [
- ch_p(T_PP_IFNDEF)
- [ store_found_directive_type(self.found_directive) ]
- >> +ppsp
- ]
- >> ppqualifiedname
- ;
- ppif
- = no_node_d
- [
- ch_p(T_PP_IF)
- [ store_found_directive_type(self.found_directive) ]
- // >> *ppsp
- ]
- >> +( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- // ppelse
- // = no_node_d
- // [
- // ch_p(T_PP_ELSE)
- // [ store_found_directive_type(self.found_directive) ]
- // ]
- // ;
- ppelif
- = no_node_d
- [
- ch_p(T_PP_ELIF)
- [ store_found_directive_type(self.found_directive) ]
- // >> *ppsp
- ]
- >> +( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- // ppendif
- // = no_node_d
- // [
- // ch_p(T_PP_ENDIF)
- // [ store_found_directive_type(self.found_directive) ]
- // ]
- // ;
- // #line ...
- ppline
- = no_node_d
- [
- ch_p(T_PP_LINE)
- [ store_found_directive_type(self.found_directive) ]
- >> *ppsp
- ]
- >> +( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
- // #region ...
- ppregion
- = no_node_d
- [
- ch_p(T_MSEXT_PP_REGION)
- [ store_found_directive_type(self.found_directive) ]
- >> +ppsp
- ]
- >> ppqualifiedname
- ;
- // #endregion
- ppendregion
- = no_node_d
- [
- ch_p(T_MSEXT_PP_ENDREGION)
- [ store_found_directive_type(self.found_directive) ]
- ]
- ;
- #endif
- // # something else (ill formed preprocessor directive)
- illformed // for error reporting
- = no_node_d
- [
- pattern_p(T_POUND, MainTokenMask)
- >> *ppsp
- ]
- >> ( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- >> no_node_d
- [
- *( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ]
- ;
- // #error
- pperror
- = no_node_d
- [
- ch_p(T_PP_ERROR)
- [ store_found_directive_type(self.found_directive) ]
- >> *ppsp
- ]
- >> *( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- // #warning
- ppwarning
- = no_node_d
- [
- ch_p(T_PP_WARNING)
- [ store_found_directive_type(self.found_directive) ]
- >> *ppsp
- ]
- >> *( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- // #pragma ...
- pppragma
- = no_node_d
- [
- ch_p(T_PP_PRAGMA)
- [ store_found_directive_type(self.found_directive) ]
- ]
- >> *( anychar_p -
- (ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
- )
- ;
- ppqualifiedname
- = no_node_d[*ppsp]
- >> ( ch_p(T_IDENTIFIER)
- | pattern_p(KeywordTokenType,
- TokenTypeMask|PPTokenFlag)
- | pattern_p(OperatorTokenType|AltExtTokenType,
- ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
- | pattern_p(BoolLiteralTokenType,
- TokenTypeMask|PPTokenFlag) // true/false
- )
- ;
- // auxiliary helper rules
- ppsp // valid space in a line with a preprocessor directive
- = ch_p(T_SPACE) | ch_p(T_CCOMMENT)
- ;
- // end of line tokens
- eol_tokens
- = no_node_d
- [
- *( ch_p(T_SPACE)
- | ch_p(T_CCOMMENT)
- )
- >> ( ch_p(T_NEWLINE)
- | ch_p(T_CPPCOMMENT)
- | ch_p(T_EOF)
- [ store_found_eof_type(self.found_eof) ]
- )
- ]
- ;
- BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR);
- // BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR);
- // BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR);
- // BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR);
- // BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR);
- #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppregion, TRACE_CPP_GRAMMAR);
- BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendregion, TRACE_CPP_GRAMMAR);
- #endif
- }
- // start rule of this grammar
- rule_type const& start() const
- { return pp_statement; }
- };
- bool &found_eof;
- TokenT &found_directive;
- ContainerT &found_eoltokens;
- cpp_grammar(bool &found_eof_, TokenT &found_directive_,
- ContainerT &found_eoltokens_)
- : found_eof(found_eof_),
- found_directive(found_directive_),
- found_eoltokens(found_eoltokens_)
- {
- BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar",
- TRACE_CPP_GRAMMAR);
- }
- #if BOOST_WAVE_DUMP_PARSE_TREE != 0
- // helper function and data to get readable names of the rules known to us
- struct map_ruleid_to_name :
- public std::map<boost::spirit::classic::parser_id, std::string>
- {
- typedef std::map<boost::spirit::classic::parser_id, std::string> base_type;
- void init_rule_id_to_name_map(cpp_grammar const &self)
- {
- struct {
- int parser_id;
- char const *rule_name;
- }
- init_ruleid_name_map[] = {
- { BOOST_WAVE_PP_STATEMENT_ID, "pp_statement" },
- // { BOOST_WAVE_INCLUDE_FILE_ID, "include_file" },
- // { BOOST_WAVE_SYSINCLUDE_FILE_ID, "system_include_file" },
- { BOOST_WAVE_MACROINCLUDE_FILE_ID, "macro_include_file" },
- { BOOST_WAVE_PLAIN_DEFINE_ID, "plain_define" },
- { BOOST_WAVE_MACRO_PARAMETERS_ID, "macro_parameters" },
- { BOOST_WAVE_MACRO_DEFINITION_ID, "macro_definition" },
- { BOOST_WAVE_UNDEFINE_ID, "undefine" },
- { BOOST_WAVE_IFDEF_ID, "ppifdef" },
- { BOOST_WAVE_IFNDEF_ID, "ppifndef" },
- { BOOST_WAVE_IF_ID, "ppif" },
- { BOOST_WAVE_ELIF_ID, "ppelif" },
- // { BOOST_WAVE_ELSE_ID, "ppelse" },
- // { BOOST_WAVE_ENDIF_ID, "ppendif" },
- { BOOST_WAVE_LINE_ID, "ppline" },
- { BOOST_WAVE_ERROR_ID, "pperror" },
- { BOOST_WAVE_WARNING_ID, "ppwarning" },
- { BOOST_WAVE_PRAGMA_ID, "pppragma" },
- { BOOST_WAVE_ILLFORMED_ID, "illformed" },
- { BOOST_WAVE_PPSPACE_ID, "ppspace" },
- { BOOST_WAVE_PPQUALIFIEDNAME_ID, "ppqualifiedname" },
- #if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
- { BOOST_WAVE_REGION_ID, "ppregion" },
- { BOOST_WAVE_ENDREGION_ID, "ppendregion" },
- #endif
- { 0 }
- };
- // initialize parser_id to rule_name map
- for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i)
- base_type::insert(base_type::value_type(
- boost::spirit::classic::parser_id(init_ruleid_name_map[i].parser_id),
- std::string(init_ruleid_name_map[i].rule_name))
- );
- }
- };
- mutable map_ruleid_to_name map_rule_id_to_name;
- #endif // WAVE_DUMP_PARSE_TREE != 0
- };
- ///////////////////////////////////////////////////////////////////////////////
- #undef TRACE_CPP_GRAMMAR
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Special parse function generating a parse tree using a given node_factory.
- //
- ///////////////////////////////////////////////////////////////////////////////
- template <typename NodeFactoryT, typename IteratorT, typename ParserT>
- inline boost::spirit::classic::tree_parse_info<IteratorT, NodeFactoryT>
- parsetree_parse(IteratorT const& first_, IteratorT const& last,
- boost::spirit::classic::parser<ParserT> const& p)
- {
- using namespace boost::spirit::classic;
- typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_type;
- typedef scanner_policies<iteration_policy, pt_match_policy_type>
- scanner_policies_type;
- typedef scanner<IteratorT, scanner_policies_type> scanner_type;
- scanner_policies_type policies;
- IteratorT first = first_;
- scanner_type scan(first, last, policies);
- tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan);
- return tree_parse_info<IteratorT, NodeFactoryT>(
- first, hit, hit && (first == last), hit.length(), hit.trees);
- }
- ///////////////////////////////////////////////////////////////////////////////
- //
- // The following parse function is defined here, to allow the separation of
- // the compilation of the cpp_grammar from the function using it.
- //
- ///////////////////////////////////////////////////////////////////////////////
- #if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
- #define BOOST_WAVE_GRAMMAR_GEN_INLINE
- #else
- #define BOOST_WAVE_GRAMMAR_GEN_INLINE inline
- #endif
- template <typename LexIteratorT, typename TokenContainerT>
- BOOST_WAVE_GRAMMAR_GEN_INLINE
- boost::spirit::classic::tree_parse_info<
- LexIteratorT,
- typename cpp_grammar_gen<LexIteratorT, TokenContainerT>::node_factory_type
- >
- cpp_grammar_gen<LexIteratorT, TokenContainerT>::parse_cpp_grammar (
- LexIteratorT const &first, LexIteratorT const &last,
- position_type const &act_pos, bool &found_eof,
- token_type &found_directive, token_container_type &found_eoltokens)
- {
- using namespace boost::spirit::classic;
- using namespace boost::wave;
- cpp_grammar<token_type, TokenContainerT> g(found_eof, found_directive, found_eoltokens);
- tree_parse_info<LexIteratorT, node_factory_type> hit =
- parsetree_parse<node_factory_type>(first, last, g);
- #if BOOST_WAVE_DUMP_PARSE_TREE != 0
- if (hit.match) {
- tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "",
- g.map_rule_id_to_name, &token_type::get_token_id,
- &token_type::get_token_value);
- }
- #endif
- return hit;
- }
- #undef BOOST_WAVE_GRAMMAR_GEN_INLINE
- ///////////////////////////////////////////////////////////////////////////////
- } // namespace grammars
- } // namespace wave
- } // namespace boost
- // the suffix header occurs after all of the code
- #ifdef BOOST_HAS_ABI_HEADERS
- #include BOOST_ABI_SUFFIX
- #endif
- #endif // !defined(BOOST_CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
|