translation_unit_parser.h
来自「Boost provides free peer-reviewed portab」· C头文件 代码 · 共 1,346 行 · 第 1/4 页
H
1,346 行
// Hannibal: partial C++ grammar to parse C++ type information// Copyright (c) 2005-2006 Danny Havenith// // Boost.Wave: A Standard compliant C++ preprocessor// Copyright (c) 2001-2008 Hartmut Kaiser// // http://www.boost.org///// 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(HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED)#define HANNIBAL_TRANSLATION_UNIT_GRAMMAR_H_INCLUDED#include <map>#include <boost/assert.hpp>#include <boost/spirit/include/classic_core.hpp>#include <boost/spirit/include/classic_confix.hpp>#include <boost/wave/wave_config.hpp>#include <boost/wave/token_ids.hpp>#include <boost/wave/util/pattern_parser.hpp>//// If so required, trace every declaration and member-declaration. // This can be a much faster alternative to BOOST_SPIRIT_DEBUG-type of// debugging.//#ifdef HANNIBAL_TRACE_DECLARATIONSstruct trace_actor{ trace_actor( const char rule_type[], std::ostream &strm ) : strm_( strm), rule_type_( rule_type) { // nop } template<typename PositionIterator> void operator()(PositionIterator begin, PositionIterator end) const { typedef const boost::wave::cpplexer::lex_token<>::position_type position_type; //typedef pos_iterator_type::token_type::position_type position_type; position_type &begin_pos(begin->get_position()); strm_ << "Parsed " << rule_type_ << std::endl; strm_ << " from: " << begin_pos.get_file() << "(" << begin_pos.get_line() << ")" << std::endl; };private: std::ostream &strm_; char const* const rule_type_;};#define HANNIBAL_TRACE_ACTION( type) [trace_actor( (type), std::cout)]#else#define HANNIBAL_TRACE_ACTION( type) #endif///////////////////////////////////////////////////////////////////////////////#define HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR \ bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \ /**////////////////////////////////////////////////////////////////////////////////// Helper macro to register rules for debugging#if HANNIBAL_DUMP_PARSE_TREE != 0#define HANNIBAL_REGISTER_RULE(r) \ BOOST_SPIRIT_DEBUG_NODE(r); \ self.declare_rule(r, #r) \ /**/#else#define HANNIBAL_REGISTER_RULE(r) \ BOOST_SPIRIT_DEBUG_NODE(r) \ /**/#endif///////////////////////////////////////////////////////////////////////////////struct dump_actor { template<typename ForwardIterator> void operator()(ForwardIterator begin, ForwardIterator end) { std::cerr << "*** COULD NOT PARSE THE FOLLOWING ***" << std::endl; while (begin != end) { std::cerr << begin->get_value(); ++begin; } }} dump_a;///////////////////////////////////////////////////////////////////////////////struct translation_unit_grammar : public boost::spirit::classic::grammar<translation_unit_grammar>{#if HANNIBAL_DUMP_PARSE_TREE != 0//// allow an external map with rule-id -> rule-name mappings.// this map is external so it can be altered by the definition constructor,// which receives a const grammar object.//// Please Note: the lifetime of the rule map should at least extend beyond the // call of the definition constructor...// typedef std::map<boost::spirit::classic::parser_id, std::string> rule_map_type; translation_unit_grammar(rule_map_type *rule_map_ptr_ = 0) : rule_map_ptr(rule_map_ptr_)#else translation_unit_grammar()#endif { BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "translation_unit_grammar", HANNIBAL_TRACE_TRANSLATION_UNIT_GRAMMAR); } template <typename ScannerT> struct definition { // declare non-terminals typedef boost::spirit::classic::rule<ScannerT> rule_type; rule_type constant_expression; rule_type logical_or_exp, logical_and_exp; rule_type inclusive_or_exp, exclusive_or_exp, and_exp; rule_type cmp_equality, cmp_relational; rule_type shift_exp; rule_type add_exp, multiply_exp; rule_type unary_exp, primary_exp, constant; boost::spirit::classic::subrule<0> const_exp_subrule; boost::spirit::classic::subrule<1> shift_exp_clos; rule_type simple_type_name, class_keywords; rule_type storage_class_specifier, cv_qualifier, function_specifier; rule_type access_specifier; rule_type extension_type_decorator; rule_type operator_sym; rule_type class_key; rule_type enumerator; rule_type enumerator_list; rule_type enumerator_definition; rule_type member_declarator; rule_type member_declarator_list; rule_type member_declaration; rule_type constant_initializer; rule_type pure_specifier; rule_type namespace_body; rule_type type_id; rule_type unnamed_namespace_definition; rule_type extension_namespace_definition; rule_type original_namespace_definition; rule_type named_namespace_definition; rule_type namespace_definition; rule_type linkage_specification; rule_type explicit_specialization; rule_type using_directive; rule_type using_declaration; rule_type type_parameter; rule_type template_parameter; rule_type template_parameter_list; rule_type template_declaration; rule_type explicit_instantiation; rule_type qualified_namespace_specifier; rule_type namespace_alias_definition; rule_type expression_list; rule_type initializer_list; rule_type initializer_clause; rule_type initializer; rule_type init_declarator; rule_type init_declarator_list; rule_type asm_definition; rule_type simple_declaration; rule_type block_declaration; rule_type declaration; rule_type declaration_seq; rule_type translation_unit; rule_type function_definition, function_definition_helper, declarator; rule_type direct_declarator, parameters_or_array_spec; rule_type abstract_declarator, direct_abstract_declarator; rule_type direct_abstract_declarator_helper; rule_type parameter_declaration_clause, parameter_declaration_list; rule_type parameter_declaration, assignment_expression, decimal_literal; rule_type octal_literal, hexadecimal_literal; rule_type declarator_id, id_expression, qualified_id, unqualified_id; rule_type operator_function_id, conversion_function_id, conversion_type_id; rule_type conversion_declarator, function_body; rule_type compound_statement, ctor_initializer, ptr_operator; rule_type decl_specifier, type_specifier; rule_type type_specifier_seq, cv_qualifier_seq, enum_specifier; rule_type enum_keyword, simple_type_specifier; rule_type class_specifier, member_specification, class_head; rule_type type_name, elaborated_type_specifier, template_argument_list; rule_type template_argument, nested_name_specifier; rule_type class_or_namespace_name, class_name, enum_name, typedef_name; rule_type namespace_name, template_id; rule_type decl_specifier_seq, no_type_decl_specifier; rule_type function_try_block, handler_seq, handler; rule_type exception_specification, template_name; rule_type original_namespace_name, base_specifier; rule_type base_specifier_list, base_clause; rule_type odd_language_extension, mem_initializer_id; rule_type mem_initializer, mem_initializer_list; rule_type ta_expression_operator; rule_type ta_logical_or_expression; rule_type ta_expression; rule_type ta_conditional_expression; rule_type ta_throw_expression; rule_type ta_assignment_expression; rule_type postfix_expression_helper; rule_type simple_postfix_expression; rule_type pseudo_destructor_name; rule_type direct_new_declarator; rule_type new_declarator; rule_type new_initializer; rule_type new_type_id; rule_type new_placement; rule_type delete_expression; rule_type new_expression; rule_type unary_operator; rule_type postfix_expression; rule_type unary_expression; rule_type expression_operator; rule_type cast_expression; rule_type throw_expression; rule_type assignment_operator; rule_type logical_or_expression; rule_type conditional_expression; rule_type boolean_literal; rule_type string_literal; rule_type floating_literal; rule_type character_literal; rule_type integer_literal; rule_type expression; rule_type literal; rule_type primary_expression; // // grammar definition. definition(translation_unit_grammar const& self) { using namespace boost::spirit::classic; using namespace boost::wave; using boost::wave::util::pattern_p; // // First, a long list of expression rules. // HANNIBAL_REGISTER_RULE( primary_expression); primary_expression = literal | ch_p(T_THIS) | ch_p(T_COLON_COLON) >> ch_p(T_IDENTIFIER) | ch_p(T_COLON_COLON) >> operator_function_id | ch_p(T_COLON_COLON) >> qualified_id | ch_p(T_LEFTPAREN) >> expression >> ch_p(T_RIGHTPAREN) | id_expression ; HANNIBAL_REGISTER_RULE( literal); literal = integer_literal | character_literal | floating_literal | string_literal | boolean_literal ; HANNIBAL_REGISTER_RULE( integer_literal); integer_literal = pattern_p( IntegerLiteralTokenType, TokenTypeMask) ; HANNIBAL_REGISTER_RULE( character_literal); character_literal = pattern_p( CharacterLiteralTokenType, TokenTypeMask) ; HANNIBAL_REGISTER_RULE( floating_literal); floating_literal = pattern_p( FloatingLiteralTokenType, TokenTypeMask) ; HANNIBAL_REGISTER_RULE( string_literal); string_literal = pattern_p( StringLiteralTokenType, TokenTypeMask) ; HANNIBAL_REGISTER_RULE( boolean_literal); boolean_literal = pattern_p( BoolLiteralTokenType, TokenTypeMask) ; // // TODO: separate assignment expression into a grammar of it's own // HANNIBAL_REGISTER_RULE( assignment_expression); assignment_expression = conditional_expression | logical_or_expression >> assignment_operator >> assignment_expression | throw_expression ; // // Have a separate assignment expression for template arguments. // This is needed, because without it, an expression of the form // template < a, b, c > x; // would not parse, since the 'c > x' part would be taken by the // assignment expression. // // Note that this ta_xxxxx duplication cascades all the way down to // logical_or_expression. // Both the previous example and a declaration of the form // template < a, b, (c > d) > x; // should parse fine now. // // HANNIBAL_REGISTER_RULE( ta_assignment_expression); ta_assignment_expression = ta_conditional_expression | ta_logical_or_expression >> assignment_operator >> ta_assignment_expression | ta_throw_expression ; HANNIBAL_REGISTER_RULE( throw_expression);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?