📄 gcc2.9.txt
字号:
{ $$.t = decl_tree_cons (NULL_TREE, $1.t, chainon ($2, $3)); $$.new_type_flag = $1.new_type_flag; } | declmods typespec reserved_declspecs { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); $$.new_type_flag = $2.new_type_flag; } | declmods typespec reserved_typespecquals { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); $$.new_type_flag = $2.new_type_flag; } | declmods typespec reserved_typespecquals reserved_declspecs { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, chainon ($4, $1))); $$.new_type_flag = $2.new_type_flag; } ;reserved_declspecs: SCSPEC { if (extra_warnings) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($$)); $$ = build_decl_list (NULL_TREE, $$); } | reserved_declspecs typespecqual_reserved { $$ = decl_tree_cons (NULL_TREE, $2.t, $$); } | reserved_declspecs SCSPEC { if (extra_warnings) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); $$ = decl_tree_cons (NULL_TREE, $2, $$); } | reserved_declspecs attributes { $$ = decl_tree_cons ($2, NULL_TREE, $1); } | attributes { $$ = decl_tree_cons ($1, NULL_TREE, NULL_TREE); } ;/* List of just storage classes and type modifiers. A declaration can start with just this, but then it cannot be used to redeclare a typedef-name. In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. *//* We use hash_tree_cons for lists of typeless declspecs so that they end up on a persistent obstack. Otherwise, they could appear at the beginning of something like static const struct { int foo () { } } b; and would be discarded after we finish compiling foo. We don't need to worry once we see a type. */declmods: nonempty_cv_qualifiers %prec EMPTY { $$ = $1.t; TREE_STATIC ($$) = 1; } | SCSPEC { $$ = hash_tree_cons (NULL_TREE, $$, NULL_TREE); } | declmods CV_QUALIFIER { $$ = hash_tree_cons (NULL_TREE, $2, $$); TREE_STATIC ($$) = 1; } | declmods SCSPEC { if (extra_warnings && TREE_STATIC ($$)) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); $$ = hash_tree_cons (NULL_TREE, $2, $$); TREE_STATIC ($$) = TREE_STATIC ($1); } | declmods attributes { $$ = hash_tree_cons ($2, NULL_TREE, $1); } | attributes %prec EMPTY { $$ = hash_tree_cons ($1, NULL_TREE, NULL_TREE); } ;/* Used instead of declspecs where storage classes are not allowed (that is, for typenames and structure components). C++ can takes storage classes for structure components. Don't accept a typedef-name if anything but a modifier precedes it. */typed_typespecs: typespec %prec EMPTY { $$.t = build_decl_list (NULL_TREE, $1.t); $$.new_type_flag = $1.new_type_flag; } | nonempty_cv_qualifiers typespec { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1.t); $$.new_type_flag = $2.new_type_flag; } | typespec reserved_typespecquals { $$.t = decl_tree_cons (NULL_TREE, $1.t, $2); $$.new_type_flag = $1.new_type_flag; } | nonempty_cv_qualifiers typespec reserved_typespecquals { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); $$.new_type_flag = $1.new_type_flag; } ;reserved_typespecquals: typespecqual_reserved { $$ = build_decl_list (NULL_TREE, $1.t); } | reserved_typespecquals typespecqual_reserved { $$ = decl_tree_cons (NULL_TREE, $2.t, $1); } ;/* A typespec (but not a type qualifier). Once we have seen one of these in a declaration, if a typedef name appears then it is being redeclared. */typespec: structsp | TYPESPEC %prec EMPTY { $$.t = $1; $$.new_type_flag = 0; } | complete_type_name { $$.t = $1; $$.new_type_flag = 0; } | TYPEOF '(' expr ')' { $$.t = finish_typeof ($3); $$.new_type_flag = 0; } | TYPEOF '(' type_id ')' { $$.t = groktypename ($3.t); $$.new_type_flag = 0; } | SIGOF '(' expr ')' { tree type = TREE_TYPE ($3); $$.new_type_flag = 0; if (IS_AGGR_TYPE (type)) { sorry ("sigof type specifier"); $$.t = type; } else { error ("`sigof' applied to non-aggregate expression"); $$.t = error_mark_node; } } | SIGOF '(' type_id ')' { tree type = groktypename ($3.t); $$.new_type_flag = 0; if (IS_AGGR_TYPE (type)) { sorry ("sigof type specifier"); $$.t = type; } else { error("`sigof' applied to non-aggregate type"); $$.t = error_mark_node; } } ;/* A typespec that is a reserved word, or a type qualifier. */typespecqual_reserved: TYPESPEC { $$.t = $1; $$.new_type_flag = 0; } | CV_QUALIFIER { $$.t = $1; $$.new_type_flag = 0; } | structsp ;initdecls: initdcl0 | initdecls ',' initdcl { check_multiple_declarators (); } ;notype_initdecls: notype_initdcl0 | notype_initdecls ',' initdcl { check_multiple_declarators (); } ;nomods_initdecls: nomods_initdcl0 | nomods_initdecls ',' initdcl { check_multiple_declarators (); } ;maybeasm: /* empty */ { $$ = NULL_TREE; } | asm_keyword '(' string ')' { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; } ;initdcl: declarator maybeasm maybe_attribute '=' { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $3, prefix_attributes); } init/* Note how the declaration of the variable is in effect while its init is parsed! */ { cp_finish_decl ($<ttype>5, $6, $2, 1, LOOKUP_ONLYCONVERTING); } | declarator maybeasm maybe_attribute { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $3, prefix_attributes); cp_finish_decl ($<ttype>$, NULL_TREE, $2, 1, 0); } ; /* This rule assumes a certain configuration of the parser stack. In particular, $0, the element directly before the beginning of this rule on the stack, must be a maybeasm. $-1 must be a declarator or notype_declarator. And $-2 must be some declmods or declspecs. We can't move the maybeasm into this rule because we need that reduce so we prefer fn.def1 when appropriate. */initdcl0_innards: maybe_attribute '=' { $<itype>2 = parse_decl ($<ttype>-1, $<ttype>-2, $1, 1, &$<ttype>$); } /* Note how the declaration of the variable is in effect while its init is parsed! */ init { cp_finish_decl ($<ttype>3, $4, $<ttype>0, 1, LOOKUP_ONLYCONVERTING); $$ = $<itype>2; } | maybe_attribute { tree d; $$ = parse_decl ($<ttype>-1, $<ttype>-2, $1, 0, &d); cp_finish_decl (d, NULL_TREE, $<ttype>0, 1, 0); } ; initdcl0: declarator maybeasm initdcl0_innards { $$ = $3; } ; notype_initdcl0: notype_declarator maybeasm initdcl0_innards { $$ = $3; } ; nomods_initdcl0: notype_declarator maybeasm { /* Set things up as initdcl0_innards expects. */ $<ttype>2 = $1; $1 = NULL_TREE; } initdcl0_innards {} | constructor_declarator maybeasm maybe_attribute { tree d; parse_decl($1, NULL_TREE, $3, 0, &d); cp_finish_decl (d, NULL_TREE, $2, 1, 0); } ;/* the * rules are dummies to accept the Apollo extended syntax so that the header files compile. */maybe_attribute: /* empty */ { $$ = NULL_TREE; } | attributes { $$ = $1; } ; attributes: attribute { $$ = $1; } | attributes attribute { $$ = chainon ($1, $2); } ;attribute: ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; } ;attribute_list: attrib { $$ = $1; } | attribute_list ',' attrib { $$ = chainon ($1, $3); } ; attrib: /* empty */ { $$ = NULL_TREE; } | any_word { $$ = build_tree_list ($1, NULL_TREE); } | any_word '(' IDENTIFIER ')' { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } | any_word '(' nonnull_exprlist ')' { $$ = build_tree_list ($1, $3); } ;/* This still leaves out most reserved keywords, shouldn't we include them? */any_word: identifier | SCSPEC | TYPESPEC | CV_QUALIFIER ;/* A nonempty list of identifiers, including typenames. */identifiers_or_typenames: identifier { $$ = build_tree_list (NULL_TREE, $1); } | identifiers_or_typenames ',' identifier { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ;maybe_init: /* empty */ %prec EMPTY { $$ = NULL_TREE; } | '=' init { $$ = $2; } ; /* If we are processing a template, we don't want to expand this initializer yet. */init: expr_no_commas %prec '=' | '{' '}' { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); TREE_HAS_CONSTRUCTOR ($$) = 1; } | '{' initlist '}' { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); TREE_HAS_CONSTRUCTOR ($$) = 1; } | '{' initlist ',' '}' { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); TREE_HAS_CONSTRUCTOR ($$) = 1; } | error { $$ = NULL_TREE; } ;/* This chain is built in reverse order, and put in forward order where initlist is used. */initlist: init { $$ = build_tree_list (NULL_TREE, $$); } | initlist ',' init { $$ = expr_tree_cons (NULL_TREE, $3, $$); } /* These are for labeled elements. */ | '[' expr_no_commas ']' init { $$ = build_expr_list ($2, $4); } | identifier ':' init { $$ = build_expr_list ($$, $3); } | initlist ',' identifier ':' init { $$ = expr_tree_cons ($3, $5, $$); } ;fn.defpen: PRE_PARSED_FUNCTION_DECL { start_function (NULL_TREE, TREE_VALUE ($1), NULL_TREE, 2); reinit_parse_for_function (); } ; pending_inline: fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error { int nested = (hack_decl_function_context (current_function_decl) != NULL_TREE); finish_function (lineno, (int)$3 | 2, nested); process_next_inline ($1); } | fn.defpen maybe_return_init function_try_block { int nested = (hack_decl_function_context (current_function_decl) != NULL_TREE); finish_function (lineno, (int)$3 | 2, nested); process_next_inline ($1); } | fn.defpen maybe_return_init error { process_next_inline ($1); } ;pending_inlines: /* empty */ | pending_inlines pending_inline eat_saved_input ;/* A regurgitated default argument. The value of DEFARG_MARKER will be the TREE_LIST node for the parameter in question. */defarg_again: DEFARG_MARKER expr_no_commas END_OF_SAVED_INPUT { replace_defarg ($1, $2); } | DEFARG_MARKER error END_OF_SAVED_INPUT { replace_defarg ($1, error_mark_node); } ;pending_defargs: /* empty */ %prec EMPTY | pending_defargs defarg_again { do_pending_defargs (); } | pending_defargs error { do_pending_defargs (); } ;structsp: ENUM identifier '{' { $<itype>3 = suspend_momentary (); $<ttype>$ = current_enum_type; current_enum_type = start_enum ($2); } enumlist maybecomma_warn '}' { TYPE_VALUES (current_enum_type) = $5; $$.t = finish_enum (current_enum_type); $$.new_type_flag = 1; current_enum_type = $<ttype>4; resume_momentary ((int) $<itype>3); check_for_missing_semicolon ($$.t); } | ENUM identifier '{' '}' { $$.t = finish_enum (start_enum ($2)); $$.new_type_flag = 1; check_for_missing_semicolon ($$.t); } | ENUM '{' { $<itype>2 = suspend_momentary (); $<ttype>$ = current_enum_type; current_enum_type = start_enum (make_anon_name ()); } enumlist maybecomma_warn '}' { TYPE_VALUES (current_enum_type) = $4; $$.t = finish_enum (current_enum_type); $$.new_type_flag = 1; current_enum_type = $<ttype>3; resume_momentary ((int) $<itype>1); check_for_missing_semicolon ($$.t); } | ENUM '{' '}' { $$.t = finish_enum (start_enum (make_anon_name())); $$.new_type_flag = 1; check_for_missing_semicolon ($$.t); } | ENUM identifier { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | ENUM complex_type_name { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | TYPENAME_KEYWORD typename_sub { $$.t = $2; $$.new_type_flag = 0; if (!processing_template_decl) cp_pedwarn ("using `typename' outside of template"); } /* C++ extensions, merged with C to avoid shift/reduce conflicts */ | class_head '{' { $1.t = begin_class_definition ($1.t); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -