⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.y

📁 GCC编译器源代码
💻 Y
📖 第 1 页 / 共 5 页
字号:
	| '(' expr_or_declarator ')'		{ $$ = $2; }	;notype_template_declarator:	  IDENTIFIER '<' template_arg_list template_close_bracket                { $$ = lookup_template_function ($1, $3); }	| NSNAME '<' template_arg_list template_close_bracket                { $$ = lookup_template_function ($1, $3); }	;		direct_notype_declarator:	  complex_direct_notype_declarator	| notype_unqualified_id	| notype_template_declarator	| '(' expr_or_declarator ')'		{ $$ = finish_decl_parsing ($2); }	;primary:	  notype_unqualified_id		{		  if (TREE_CODE ($$) == BIT_NOT_EXPR)		    $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($$, 0));		  else if (TREE_CODE ($$) != TEMPLATE_ID_EXPR)		    $$ = do_identifier ($$, 1);		}			| CONSTANT	| boolean.literal	| string		{		  if (processing_template_decl)		    push_obstacks (&permanent_obstack, &permanent_obstack);		  $$ = combine_strings ($$);		  if (processing_template_decl)		    pop_obstacks ();		}	| '(' expr ')'		{ char class;		  $$ = $2;		  class = TREE_CODE_CLASS (TREE_CODE ($$));		  if (class == 'e' || class == '1'		      || class == '2' || class == '<')                    /* This inhibits warnings in truthvalue_conversion.  */		    C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }	| '(' expr_or_declarator ')'		{ char class;		  $$ = reparse_decl_as_expr (NULL_TREE, $2);		  class = TREE_CODE_CLASS (TREE_CODE ($$));		  if (class == 'e' || class == '1'		      || class == '2' || class == '<')                    /* This inhibits warnings in truthvalue_conversion.  */		    C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }	| '(' error ')'		{ $$ = error_mark_node; }	| '('		{ if (current_function_decl == 0)		    {		      error ("braced-group within expression allowed only inside a function");		      YYERROR;		    }		  keep_next_level ();		  $<ttype>$ = expand_start_stmt_expr (); }	  compstmt ')'		{ tree rtl_exp;		  if (pedantic)		    pedwarn ("ANSI C++ forbids braced-groups within expressions");		  rtl_exp = expand_end_stmt_expr ($<ttype>2);		  /* The statements have side effects, so the group does.  */		  TREE_SIDE_EFFECTS (rtl_exp) = 1;		  if (TREE_CODE ($3) == BLOCK)		    {		      /* Make a BIND_EXPR for the BLOCK already made.  */		      $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),				  NULL_TREE, rtl_exp, $3);		      /* Remove the block from the tree at this point.			 It gets put back at the proper place			 when the BIND_EXPR is expanded.  */		      delete_block ($3);		    }		  else		    $$ = $3;		}	| primary '(' nonnull_exprlist ')'                {                  $$ = build_x_function_call ($1, $3, current_class_ref);                   if (TREE_CODE ($$) == CALL_EXPR                      && TREE_TYPE ($$) != void_type_node)	            $$ = require_complete_type ($$);                }	| primary LEFT_RIGHT                {		  $$ = build_x_function_call ($$, NULL_TREE, current_class_ref);		  if (TREE_CODE ($$) == CALL_EXPR		      && TREE_TYPE ($$) != void_type_node)		    $$ = require_complete_type ($$);                }	| primary '[' expr ']'		{ $$ = grok_array_decl ($$, $3); }	| primary PLUSPLUS		{ /* If we get an OFFSET_REF, turn it into what it really		     means (e.g., a COMPONENT_REF).  This way if we've got,		     say, a reference to a static member that's being operated		     on, we don't end up trying to find a member operator for		     the class it's in.  */		  if (TREE_CODE ($$) == OFFSET_REF)		    $$ = resolve_offset_ref ($$);		  $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }	| primary MINUSMINUS		{ if (TREE_CODE ($$) == OFFSET_REF)		    $$ = resolve_offset_ref ($$);		  $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }	/* C++ extensions */	| THIS		{ if (current_class_ptr)		    {#ifdef WARNING_ABOUT_CCD		      TREE_USED (current_class_ptr) = 1;#endif		      $$ = current_class_ptr;		    }		  else if (current_function_decl			   && DECL_STATIC_FUNCTION_P (current_function_decl))		    {		      error ("`this' is unavailable for static member functions");		      $$ = error_mark_node;		    }		  else		    {		      if (current_function_decl)			error ("invalid use of `this' in non-member function");		      else			error ("invalid use of `this' at top level");		      $$ = error_mark_node;		    }		}	| CV_QUALIFIER '(' nonnull_exprlist ')'		{		  tree type;		  tree id = $$;		  /* This is a C cast in C++'s `functional' notation.  */		  if ($3 == error_mark_node)		    {		      $$ = error_mark_node;		      break;		    }#if 0		  if ($3 == NULL_TREE)		    {		      error ("cannot cast null list to type `%s'",		             IDENTIFIER_POINTER (TYPE_NAME (id)));		      $$ = error_mark_node;		      break;		    }#endif#if 0		  /* type is not set! (mrs) */		  if (type == error_mark_node)		    $$ = error_mark_node;		  else#endif		    {		      if (id == ridpointers[(int) RID_CONST])		        type = build_type_variant (integer_type_node, 1, 0);		      else if (id == ridpointers[(int) RID_VOLATILE])		        type = build_type_variant (integer_type_node, 0, 1);#if 0		      /* should not be able to get here (mrs) */		      else if (id == ridpointers[(int) RID_FRIEND])		        {		          error ("cannot cast expression to `friend' type");		          $$ = error_mark_node;		          break;		        }#endif		      else my_friendly_abort (79);		      $$ = build_c_cast (type, build_compound_expr ($3));		    }		}	| functional_cast	| DYNAMIC_CAST '<' type_id '>' '(' expr ')'		{ tree type = groktypename ($3.t);		  check_for_new_type ("dynamic_cast", $3);		  $$ = build_dynamic_cast (type, $6); }	| STATIC_CAST '<' type_id '>' '(' expr ')'		{ tree type = groktypename ($3.t);		  check_for_new_type ("static_cast", $3);		  $$ = build_static_cast (type, $6); }	| REINTERPRET_CAST '<' type_id '>' '(' expr ')'		{ tree type = groktypename ($3.t);		  check_for_new_type ("reinterpret_cast", $3);		  $$ = build_reinterpret_cast (type, $6); }	| CONST_CAST '<' type_id '>' '(' expr ')'		{ tree type = groktypename ($3.t);		  check_for_new_type ("const_cast", $3);		  $$ = build_const_cast (type, $6); }	| TYPEID '(' expr ')'		{ $$ = build_x_typeid ($3); }	| TYPEID '(' type_id ')'		{ tree type = groktypename ($3.t);		  check_for_new_type ("typeid", $3);		  $$ = get_typeid (TYPE_MAIN_VARIANT (type)); }	| global_scope IDENTIFIER		{ $$ = do_scoped_id ($2, 1); }	| global_scope operator_name		{		  got_scope = NULL_TREE;		  if (TREE_CODE ($2) == IDENTIFIER_NODE)		    $$ = do_scoped_id ($2, 1);		  else		    $$ = $2;		}	| overqualified_id  %prec HYPERUNARY		{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }	| overqualified_id '(' nonnull_exprlist ')'		{ if (processing_template_decl)		    $$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1), $3, NULL_TREE);		  else		    $$ = build_member_call (OP0 ($$), OP1 ($$), $3); }	| overqualified_id LEFT_RIGHT		{ if (processing_template_decl)		    $$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1), 				       NULL_TREE, NULL_TREE);		  else		    $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }        | object object_template_id %prec UNARY                { 		  $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); 		}        | object object_template_id '(' nonnull_exprlist ')'                {		  $$ = build_method_call ($1, $2, $4, 					  NULL_TREE, LOOKUP_NORMAL);                 }	| object object_template_id LEFT_RIGHT                {		  $$ = build_method_call ($1, $2, NULL_TREE,					  NULL_TREE, LOOKUP_NORMAL);                 }	| object unqualified_id  %prec UNARY		{ $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); }	| object overqualified_id  %prec UNARY		{ if (processing_template_decl)		    $$ = build_min_nt (COMPONENT_REF, $1, copy_to_permanent ($2));		  else		    $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }	| object unqualified_id '(' nonnull_exprlist ')'		{#if 0		  /* This is a future direction of this code, but because		     build_x_function_call cannot always undo what is done		     in build_component_ref entirely yet, we cannot do this.  */		  $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, current_class_ref);		  if (TREE_CODE ($$) == CALL_EXPR		      && TREE_TYPE ($$) != void_type_node)		    $$ = require_complete_type ($$);#else		  $$ = build_method_call ($$, $2, $4, NULL_TREE,					  LOOKUP_NORMAL);#endif		}	| object unqualified_id LEFT_RIGHT		{#if 0		  /* This is a future direction of this code, but because		     build_x_function_call cannot always undo what is done		     in build_component_ref entirely yet, we cannot do this.  */		  $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, current_class_ref);		  if (TREE_CODE ($$) == CALL_EXPR		      && TREE_TYPE ($$) != void_type_node)		    $$ = require_complete_type ($$);#else		  $$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE,					  LOOKUP_NORMAL);#endif		}	| object overqualified_id '(' nonnull_exprlist ')'		{		  if (IS_SIGNATURE (OP0 ($2)))		    {		      warning ("signature name in scope resolution ignored");		      $$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,					      LOOKUP_NORMAL);		    }		  else		    $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);		}	| object overqualified_id LEFT_RIGHT		{		  if (IS_SIGNATURE (OP0 ($2)))		    {		      warning ("signature name in scope resolution ignored");		      $$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,					      LOOKUP_NORMAL);		    }		  else		    $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), NULL_TREE);		}	/* p->int::~int() is valid -- 12.4 */	| object '~' TYPESPEC LEFT_RIGHT		{		  if (IDENTIFIER_GLOBAL_VALUE ($3)		      && (TREE_CODE (TREE_TYPE ($1)) 			  != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))))		    cp_error ("`%E' is not of type `%T'", $1, $3);		  $$ = cp_convert (void_type_node, $1);		}	| object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT		{		  if ($2 != $5)		    cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5);		  if (TREE_CODE (TREE_TYPE ($1))		      != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2))))		    cp_error ("`%E' is not of type `%T'", $1, $2);		  $$ = cp_convert (void_type_node, $1);		}	| object error		{		  $$ = error_mark_node;		}	;/* Not needed for now.primary_no_id:	  '(' expr ')'		{ $$ = $2; }	| '(' error ')'		{ $$ = error_mark_node; }	| '('		{ if (current_function_decl == 0)		    {		      error ("braced-group within expression allowed only inside a function");		      YYERROR;		    }		  $<ttype>$ = expand_start_stmt_expr (); }	  compstmt ')'		{ if (pedantic)		    pedwarn ("ANSI C++ forbids braced-groups within expressions");		  $$ = expand_end_stmt_expr ($<ttype>2); }	| primary_no_id '(' nonnull_exprlist ')'		{ $$ = build_x_function_call ($$, $3, current_class_ref); }	| primary_no_id LEFT_RIGHT		{ $$ = build_x_function_call ($$, NULL_TREE, current_class_ref); }	| primary_no_id '[' expr ']'		{ goto do_array; }	| primary_no_id PLUSPLUS		{ $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }	| primary_no_id MINUSMINUS		{ $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }	| SCOPE IDENTIFIER		{ goto do_scoped_id; }	| SCOPE operator_name		{ if (TREE_CODE ($2) == IDENTIFIER_NODE)		    goto do_scoped_id;		  goto do_scoped_operator;		}	;*/new:	  NEW		{ $$ = 0; }	| global_scope NEW		{ got_scope = NULL_TREE; $$ = 1; }	;delete:	  DELETE		{ $$ = 0; }	| global_scope delete		{ got_scope = NULL_TREE; $$ = 1; }	;boolean.literal:	  CXX_TRUE		{ $$ = boolean_true_node; }	| CXX_FALSE		{ $$ = boolean_false_node; }	;/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */string:	  STRING	| string STRING		{ $$ = chainon ($$, $2); }	;nodecls:	  /* empty */		{		  if (! current_function_parms_stored)		    store_parm_decls ();		  setup_vtbl_ptr ();		  /* Always keep the BLOCK node associated with the outermost		     pair of curly braces of a function.  These are needed		     for correct operation of dwarfout.c.  */		  keep_next_level ();		}	;object:	  primary '.'		{ got_object = TREE_TYPE ($$); }	| primary POINTSAT		{		  $$ = build_x_arrow ($$); 		  got_object = TREE_TYPE ($$);		}	;decl:	  typespec initdecls ';'		{		  resume_momentary ($2);		  if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t)))		    note_got_semicolon ($1.t);		}	| typed_declspecs initdecls ';'		{		  resume_momentary ($2);		  note_list_got_semicolon ($1.t);		}	| declmods notype_initdecls ';'		{ resume_momentary ($2); }	| typed_declspecs ';'		{		  shadow_tag ($1.t);		  note_list_got_semicolon ($1.t);		}	| declmods ';'		{ warning ("empty declaration"); }	| extension decl		{ pedantic = $<itype>1; }	;/* Any kind of declarator (thus, all declarators allowed   after an explicit typespec).  */declarator:	  after_type_declarator  %prec EMPTY

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -