Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/wave/grammars/cpp_grammar.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/wave/grammars/cpp_grammar.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,765 @@ +/*============================================================================= + 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(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED) +#define 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(CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)