📄 gcc2.9.txt
字号:
;identifier_defn: IDENTIFIER_DEFN | TYPENAME_DEFN | PTYPENAME_DEFN ;explicit_instantiation: TEMPLATE begin_explicit_instantiation typespec ';' { do_type_instantiation ($3.t, NULL_TREE); yyungetc (';', 1); } end_explicit_instantiation | TEMPLATE begin_explicit_instantiation typed_declspecs declarator { tree specs = strip_attrs ($3.t); do_decl_instantiation (specs, $4, NULL_TREE); } end_explicit_instantiation | TEMPLATE begin_explicit_instantiation notype_declarator { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); } end_explicit_instantiation | TEMPLATE begin_explicit_instantiation constructor_declarator { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); } end_explicit_instantiation | SCSPEC TEMPLATE begin_explicit_instantiation typespec ';' { do_type_instantiation ($4.t, $1); yyungetc (';', 1); } end_explicit_instantiation | SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs declarator { tree specs = strip_attrs ($4.t); do_decl_instantiation (specs, $5, $1); } end_explicit_instantiation | SCSPEC TEMPLATE begin_explicit_instantiation notype_declarator { do_decl_instantiation (NULL_TREE, $4, $1); } end_explicit_instantiation | SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator { do_decl_instantiation (NULL_TREE, $4, $1); } end_explicit_instantiation ;begin_explicit_instantiation: { begin_explicit_instantiation(); } ; end_explicit_instantiation: { end_explicit_instantiation(); } ;/* The TYPENAME expansions are to deal with use of a template class name as a template within the class itself, where the template decl is hidden by a type decl. Got all that? */template_type: PTYPENAME '<' template_arg_list_opt template_close_bracket .finish_template_type { $$ = $5; } | TYPENAME '<' template_arg_list_opt template_close_bracket .finish_template_type { $$ = $5; } | self_template_type ;apparent_template_type: template_type | identifier '<' template_arg_list_opt '>' .finish_template_type { $$ = $5; } ; self_template_type: SELFNAME '<' template_arg_list_opt template_close_bracket .finish_template_type { $$ = $5; } ;.finish_template_type: { if (yychar == YYEMPTY) yychar = YYLEX; $$ = finish_template_type ($<ttype>-3, $<ttype>-1, yychar == SCOPE); } ;template_close_bracket: '>' | RSHIFT { /* Handle `Class<Class<Type>>' without space in the `>>' */ pedwarn ("`>>' should be `> >' in template class name"); yyungetc ('>', 1); } ;template_arg_list_opt: /* empty */ { $$ = NULL_TREE; } | template_arg_list ;template_arg_list: template_arg { $$ = build_tree_list (NULL_TREE, $$); } | template_arg_list ',' template_arg { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } ;template_arg: type_id { $$ = groktypename ($1.t); } | PTYPENAME { $$ = lastiddecl; } | expr_no_commas %prec ARITHCOMPARE ;unop: '-' { $$ = NEGATE_EXPR; } | '+' { $$ = CONVERT_EXPR; } | PLUSPLUS { $$ = PREINCREMENT_EXPR; } | MINUSMINUS { $$ = PREDECREMENT_EXPR; } | '!' { $$ = TRUTH_NOT_EXPR; } ;expr: nontrivial_exprlist { $$ = build_x_compound_expr ($$); } | expr_no_commas ;paren_expr_or_null: LEFT_RIGHT { error ("ANSI C++ forbids an empty condition for `%s'", cond_stmt_keyword); $$ = integer_zero_node; } | '(' expr ')' { $$ = $2; } ;paren_cond_or_null: LEFT_RIGHT { error ("ANSI C++ forbids an empty condition for `%s'", cond_stmt_keyword); $$ = integer_zero_node; } | '(' condition ')' { $$ = $2; } ;xcond: /* empty */ { $$ = NULL_TREE; } | condition | error { $$ = NULL_TREE; } ;condition: type_specifier_seq declarator maybeasm maybe_attribute '=' { { tree d; for (d = getdecls (); d; d = TREE_CHAIN (d)) if (TREE_CODE (d) == TYPE_DECL) { tree s = TREE_TYPE (d); if (TREE_CODE (s) == RECORD_TYPE) cp_error ("definition of class `%T' in condition", s); else if (TREE_CODE (s) == ENUMERAL_TYPE) cp_error ("definition of enum `%T' in condition", s); } } current_declspecs = $1.t; $<itype>5 = suspend_momentary (); $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, $4, /*prefix_attributes*/ NULL_TREE); } init { cp_finish_decl ($<ttype>6, $7, $4, 1, LOOKUP_ONLYCONVERTING); resume_momentary ($<itype>5); $$ = convert_from_reference ($<ttype>6); if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) cp_error ("definition of array `%#D' in condition", $$); } | expr ;compstmtend: '}' | maybe_label_decls stmts '}' | maybe_label_decls stmts error '}' | maybe_label_decls error '}' ;already_scoped_stmt: '{' { $<ttype>$ = begin_compound_stmt (1); } compstmtend { finish_compound_stmt (1, $<ttype>2); } | simple_stmt ;nontrivial_exprlist: expr_no_commas ',' expr_no_commas { $$ = expr_tree_cons (NULL_TREE, $$, build_expr_list (NULL_TREE, $3)); } | expr_no_commas ',' error { $$ = expr_tree_cons (NULL_TREE, $$, build_expr_list (NULL_TREE, error_mark_node)); } | nontrivial_exprlist ',' expr_no_commas { chainon ($$, build_expr_list (NULL_TREE, $3)); } | nontrivial_exprlist ',' error { chainon ($$, build_expr_list (NULL_TREE, error_mark_node)); } ;nonnull_exprlist: expr_no_commas { $$ = build_expr_list (NULL_TREE, $$); } | nontrivial_exprlist ;unary_expr: primary %prec UNARY { $$ = $1; } /* __extension__ turns off -pedantic for following primary. */ | extension cast_expr %prec UNARY { $$ = $2; pedantic = $<itype>1; } | '*' cast_expr %prec UNARY { $$ = build_x_indirect_ref ($2, "unary *"); } | '&' cast_expr %prec UNARY { $$ = build_x_unary_op (ADDR_EXPR, $2); } | '~' cast_expr { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); } | unop cast_expr %prec UNARY { $$ = finish_unary_op_expr ($1, $2); } /* Refer to the address of a label as a pointer. */ | ANDAND identifier { if (pedantic) pedwarn ("ANSI C++ forbids `&&'"); $$ = finish_label_address_expr ($2); } | SIZEOF unary_expr %prec UNARY { $$ = expr_sizeof ($2); } | SIZEOF '(' type_id ')' %prec HYPERUNARY { $$ = c_sizeof (groktypename ($3.t)); check_for_new_type ("sizeof", $3); } | ALIGNOF unary_expr %prec UNARY { $$ = grok_alignof ($2); } | ALIGNOF '(' type_id ')' %prec HYPERUNARY { $$ = c_alignof (groktypename ($3.t)); check_for_new_type ("alignof", $3); } /* The %prec EMPTY's here are required by the = init initializer syntax extension; see below. */ | new new_type_id %prec EMPTY { $$ = build_new (NULL_TREE, $2.t, NULL_TREE, $1); check_for_new_type ("new", $2); } | new new_type_id new_initializer { $$ = build_new (NULL_TREE, $2.t, $3, $1); check_for_new_type ("new", $2); } | new new_placement new_type_id %prec EMPTY { $$ = build_new ($2, $3.t, NULL_TREE, $1); check_for_new_type ("new", $3); } | new new_placement new_type_id new_initializer { $$ = build_new ($2, $3.t, $4, $1); check_for_new_type ("new", $3); } /* The .begin_new_placement in the following rules is necessary to avoid shift/reduce conflicts that lead to mis-parsing some expressions. Of course, these constructs are not really new-placement and it is bogus to call begin_new_placement. But, the parser cannot always tell at this point whether the next thing is an expression or a type-id, so there is nothing we can do. Fortunately, begin_new_placement does nothing harmful. When we rewrite the parser, this lossage should be removed, of course. */ | new '(' .begin_new_placement type_id .finish_new_placement %prec EMPTY { $$ = build_new (NULL_TREE, groktypename($4.t), NULL_TREE, $1); check_for_new_type ("new", $4); } | new '(' .begin_new_placement type_id .finish_new_placement new_initializer { $$ = build_new (NULL_TREE, groktypename($4.t), $6, $1); check_for_new_type ("new", $4); } | new new_placement '(' .begin_new_placement type_id .finish_new_placement %prec EMPTY { $$ = build_new ($2, groktypename($5.t), NULL_TREE, $1); check_for_new_type ("new", $5); } | new new_placement '(' .begin_new_placement type_id .finish_new_placement new_initializer { $$ = build_new ($2, groktypename($5.t), $7, $1); check_for_new_type ("new", $5); } | delete cast_expr %prec UNARY { $$ = delete_sanity ($2, NULL_TREE, 0, $1); } | delete '[' ']' cast_expr %prec UNARY { $$ = delete_sanity ($4, NULL_TREE, 1, $1); if (yychar == YYEMPTY) yychar = YYLEX; } | delete '[' expr ']' cast_expr %prec UNARY { $$ = delete_sanity ($5, $3, 2, $1); if (yychar == YYEMPTY) yychar = YYLEX; } | REALPART cast_expr %prec UNARY { $$ = build_x_unary_op (REALPART_EXPR, $2); } | IMAGPART cast_expr %prec UNARY { $$ = build_x_unary_op (IMAGPART_EXPR, $2); } ; /* Note this rule is not suitable for use in new_placement since it uses NULL_TREE as the argument to finish_new_placement. This rule serves only to avoid reduce/reduce conflicts in unary_expr. See the comments there on the use of begin/finish_new_placement. */.finish_new_placement: ')' { finish_new_placement (NULL_TREE, $<itype>-1); } ; .begin_new_placement: { $$ = begin_new_placement (); } ; new_placement: '(' .begin_new_placement nonnull_exprlist ')' { $$ = finish_new_placement ($3, $2); } | '{' .begin_new_placement nonnull_exprlist '}' { cp_pedwarn ("old style placement syntax, use () instead"); $$ = finish_new_placement ($3, $2); } ;new_initializer: '(' nonnull_exprlist ')' { $$ = $2; } | LEFT_RIGHT { $$ = NULL_TREE; } | '(' typespec ')' { cp_error ("`%T' is not a valid expression", $2.t); $$ = error_mark_node; } /* GNU extension so people can use initializer lists. Note that this alters the meaning of `new int = 1', which was previously syntactically valid but semantically invalid. */ | '=' init { if (pedantic) pedwarn ("ANSI C++ forbids initialization of new expression with `='"); if (TREE_CODE ($2) != TREE_LIST && TREE_CODE ($2) != CONSTRUCTOR) $$ = build_expr_list (NULL_TREE, $2); else $$ = $2; } ;/* This is necessary to postpone reduction of `int ((int)(int)(int))'. */regcast_or_absdcl: '(' type_id ')' %prec EMPTY { $2.t = finish_parmlist (build_tree_list (NULL_TREE, $2.t), 0); $$ = make_call_declarator (NULL_TREE, $2.t, NULL_TREE, NULL_TREE); check_for_new_type ("cast", $2); } | regcast_or_absdcl '(' type_id ')' %prec EMPTY { $3.t = finish_parmlist (build_tree_list (NULL_TREE, $3.t), 0); $$ = make_call_declarator ($$, $3.t, NULL_TREE, NULL_TREE); check_for_new_type ("cast", $3); } ;cast_expr: unary_expr | regcast_or_absdcl unary_expr %prec UNARY { $$ = reparse_absdcl_as_casts ($$, $2); } | regcast_or_absdcl '{' initlist maybecomma '}' %prec UNARY { tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($3)); if (pedantic) pedwarn ("ANSI C++ forbids constructor-expressions"); /* Indicate that this was a GNU C constructor expression. */ TREE_HAS_CONSTRUCTOR (init) = 1; $$ = reparse_absdcl_as_casts ($$, init); } ;expr_no_commas: cast_expr /* Handle general members. */ | expr_no_commas POINTSAT_STAR expr_no_commas { $$ = build_x_binary_op (MEMBER_REF, $$, $3); } | expr_no_commas DOT_STAR expr_no_commas { $$ = build_m_component_ref ($$, $3); } | expr_no_commas '+' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '-' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '*' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '/' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '%' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas LSHIFT expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas RSHIFT expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas ARITHCOMPARE expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '<' expr_no_commas { $$ = build_x_binary_op (LT_EXPR, $$, $3); } | expr_no_commas '>' expr_no_commas { $$ = build_x_binary_op (GT_EXPR, $$, $3); } | expr_no_commas EQCOMPARE expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas MIN_MAX expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '&' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '|' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas '^' expr_no_commas { $$ = build_x_binary_op ($2, $$, $3); } | expr_no_commas ANDAND expr_no_commas { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); } | expr_no_commas OROR expr_no_commas { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); } | expr_no_commas '?' xexpr ':' expr_no_commas { $$ = build_x_conditional_expr ($$, $3, $5); } | expr_no_commas '=' expr_no_commas { $$ = build_x_modify_expr ($$, NOP_EXPR, $3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -