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

📄 cp-parse.y

📁 早期freebsd实现
💻 Y
📖 第 1 页 / 共 5 页
字号:
		  interface_unknown = 1;		  $$ = finish_struct ($<ttype>3, $5, 0, 0);		  pop_obstacks ();		  end_template_instantiation ($1, $<ttype>3);                  /* Now go after the methods & class data.  */		  old_interface = interface_unknown;		  interface_unknown = 1;                  instantiate_member_templates ($1);		  interface_unknown = old_interface;		  CLASSTYPE_GOT_SEMICOLON ($$) = 1;		}	;template_instantiation:          /* empty */                { $$ = NULL_TREE; }        | template_instantiate_once                { $$ = $1; }        ;template_instantiate_some:          /* empty */                { $$ = NULL_TREE; /* never used from here... */}        | template_instantiate_once template_instantiate_some                { $$ = $1; /*???*/ }        ;unop:     '-'		{ $$ = NEGATE_EXPR; }	| '+'		{ $$ = CONVERT_EXPR; }	| PLUSPLUS		{ $$ = PREINCREMENT_EXPR; }	| MINUSMINUS		{ $$ = PREDECREMENT_EXPR; }	| '!'		{ $$ = TRUTH_NOT_EXPR; }	;expr:	  nonnull_exprlist		{ $$ = build_x_compound_expr ($$); }	/* Ugly, but faster.  */	| expr_no_commas	;nonnull_exprlist:	  expr_no_commas		{ $$ = build_tree_list (NULL_TREE, $$); }	| nonnull_exprlist ',' expr_no_commas		{ chainon ($$, build_tree_list (NULL_TREE, $3)); }	| nonnull_exprlist ',' error		{ chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); }	;unary_expr:	  primary %prec UNARY		{		  if (TREE_CODE ($$) == TYPE_EXPR)		    $$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1);		}	/* __extension__ turns off -pedantic for following primary.  */	| EXTENSION		{ $<itype>1 = pedantic;		  pedantic = 0; }	  cast_expr	  %prec UNARY		{ $$ = $3;		  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   %prec UNARY		{ $$ = build_x_unary_op (BIT_NOT_EXPR, $2); }	| unop cast_expr  %prec UNARY		{ $$ = build_x_unary_op ($$, $2);		  if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST)		    TREE_NEGATED_INT ($$) = 1;		}	/* Refer to the address of a label as a pointer.  */	| ANDAND identifier		{ tree label = lookup_label ($2);		  TREE_USED (label) = 1;		  $$ = build1 (ADDR_EXPR, ptr_type_node, label);		  TREE_CONSTANT ($$) = 1; }	| SIZEOF unary_expr  %prec UNARY		{ if (TREE_CODE ($2) == COMPONENT_REF		      && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))		    error ("sizeof applied to a bit-field");		  /* ANSI says arrays and functions are converted inside comma.		     But we can't really convert them in build_compound_expr		     because that would break commas in lvalues.		     So do the conversion here if operand was a comma.  */		  if (TREE_CODE ($2) == COMPOUND_EXPR		      && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE			  || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))		    $2 = default_conversion ($2);		  $$ = c_sizeof (TREE_TYPE ($2)); }	| SIZEOF '(' typename ')'  %prec HYPERUNARY		{ $$ = c_sizeof (groktypename ($3)); }	| ALIGNOF unary_expr  %prec UNARY		{ if (TREE_CODE ($2) == COMPONENT_REF		      && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))		    error ("`__alignof' applied to a bit-field");		  if (TREE_CODE ($2) == INDIRECT_REF)		    {		      tree t = TREE_OPERAND ($2, 0);		      tree best = t;		      int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));		      while (TREE_CODE (t) == NOP_EXPR			     && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)			{			  int thisalign;			  t = TREE_OPERAND (t, 0);			  thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));			  if (thisalign > bestalign)			    best = t, bestalign = thisalign;			}		      $$ = c_alignof (TREE_TYPE (TREE_TYPE (best)));		    }		  else		    {		      /* ANSI says arrays and fns are converted inside comma.			 But we can't convert them in build_compound_expr			 because that would break commas in lvalues.			 So do the conversion here if operand was a comma.  */		      if (TREE_CODE ($2) == COMPOUND_EXPR			  && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE			      || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))			$2 = default_conversion ($2);		      $$ = c_alignof (TREE_TYPE ($2));		    }		}	| ALIGNOF '(' typename ')'  %prec HYPERUNARY		{ $$ = c_alignof (groktypename ($3)); }	| .scope new typename %prec '='		{ $$ = build_new ($2, $3, NULL_TREE, $$); }	| .scope new '(' nonnull_exprlist ')' typename %prec '='		{ $$ = build_new ($4, $6, NULL_TREE, $$); }	| .scope new typespec '(' nonnull_exprlist ')'		{ $$ = build_new ($2, $3, $5, $$); }	| .scope new '(' nonnull_exprlist ')' typespec '(' nonnull_exprlist ')'		{ $$ = build_new ($4, $6, $8, $$); }	| .scope new typespec LEFT_RIGHT		{ $$ = build_new ($2, $3, NULL_TREE, $$); }	| .scope new '(' nonnull_exprlist ')' typespec LEFT_RIGHT		{ $$ = build_new ($4, $6, NULL_TREE, $$); }	| .scope new typename '=' init %prec '='		{ $$ = build_new ($2, $3, $5, $$); }	| .scope new '(' nonnull_exprlist ')' typename '=' init %prec '='		{ $$ = build_new ($4, $6, $8, $$); }	/* I am not going to add placement syntax to the below complex rules	   because Ken says the syntax is illegal. (mrs) */	/* I'm not sure why this is disallowed.  But since it is, and it	   doesn't seem difficult to catch it, let's give a message, so	   the programmer can fix it.  --Ken Raeburn  */	| .scope new '(' typed_typespecs absdcl ')' '[' nonmomentary_expr ']'		{		  tree absdcl, typename;		illegal_new_array:		  absdcl = build_parse_node (ARRAY_REF, $5, $8);		  typename = build_decl_list ($4, absdcl);		  pedwarn ("ANSI C++ forbids array dimensions with parenthesized type");		  $$ = build_new ($2, typename, NULL_TREE, $$);		}	| .scope new '(' nonempty_type_quals absdcl ')' '[' nonmomentary_expr ']'		{ goto illegal_new_array; }	| .scope new '(' typed_typespecs absdcl ')'		{ $$ = build_new ($2, build_decl_list ($4, $5), NULL_TREE, $$); }	| .scope new '(' nonnull_exprlist ')' '(' typed_typespecs absdcl ')'		{ $$ = build_new ($4, build_decl_list ($7, $8), NULL_TREE, $$); }	| .scope new '(' nonempty_type_quals absdcl ')'		{ $$ = build_new ($2, build_decl_list ($4, $5), NULL_TREE, $$); }	| .scope new '(' nonnull_exprlist ')' '(' nonempty_type_quals absdcl ')'		{ $$ = build_new ($4, build_decl_list ($7, $8), NULL_TREE, $$); }	/* Unswallow a ':' which is probably meant for ?: expression.  */	| .scope new TYPENAME_COLON		{ yyungetc (':', 1); $$ = build_new ($2, $3, NULL_TREE, $$); }	| .scope new '(' nonnull_exprlist ')' TYPENAME_COLON		{ yyungetc (':', 1); $$ = build_new ($4, $6, NULL_TREE, $$); }	| delete cast_expr  %prec UNARY		{ tree expr = stabilize_reference (convert_from_reference ($2));		  tree type = TREE_TYPE (expr);		  if (TREE_CODE (type) != POINTER_TYPE)		    {		      error ("non-pointer type to `delete'");		      $$ = error_mark_node;		      break;		    }		  else if (integer_zerop (expr))		    {		      /* ANSI C++ June 5 1992 WP 5.3.4.  Deleting a pointer			 with the value zero is legal and has no effect.  */		      $$ = build1 (NOP_EXPR, void_type_node, expr);		      break;		    }		  else if (TREE_READONLY (TREE_TYPE (type)))		    {		      error ("`const *' cannot be deleted");		      $$ = error_mark_node;		      break;		    }		  $$ = build_delete (type, expr, integer_three_node,				     LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE,				     TYPE_HAS_DESTRUCTOR (TREE_TYPE (type)),				     0);		}	| delete '[' ']' cast_expr  %prec UNARY		{		  tree exp = stabilize_reference (convert_from_reference ($4));		  tree type = TREE_TYPE (exp);		  tree elt_size = c_sizeof (type);		  if (yychar == YYEMPTY)		    yychar = YYLEX;		  if (TREE_CODE (type) == POINTER_TYPE		      && TREE_READONLY (TREE_TYPE (type)))		    {		      error ("`const *' cannot be deleted");		      $$ = error_mark_node;		      break;		    }		  $$ = build_vec_delete (exp, NULL_TREE, elt_size, NULL_TREE,					 integer_one_node, integer_two_node);		}	| delete '[' expr ']' cast_expr %prec UNARY		{		  tree maxindex = build_binary_op (MINUS_EXPR, $3,						   integer_one_node);		  tree exp = stabilize_reference (convert_from_reference ($5));		  tree type = TREE_TYPE (exp);		  tree elt_size = c_sizeof (type);		  if (yychar == YYEMPTY)		    yychar = YYLEX;		  if (! flag_traditional)		    pedwarn ("ANSI C++ forbids array size in vector delete");		  if (TREE_CODE (type) == POINTER_TYPE		      && TREE_READONLY (TREE_TYPE (type)))		    {		      error ("`const *' cannot be deleted");		      $$ = error_mark_node;		      break;		    }		  $$ = build_vec_delete (exp, maxindex, elt_size, NULL_TREE,					 integer_one_node, integer_two_node);		}	;cast_expr:	  unary_expr	| '(' typename ')' expr_no_commas  %prec UNARY		{ tree type = groktypename ($2);		  $$ = build_c_cast (type, $4); }	| '(' typename ')' '{' initlist maybecomma '}'  %prec UNARY		{ tree type = groktypename ($2);		  tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5));		  if (pedantic)		    pedwarn ("ANSI C++ forbids constructor-expressions");		  /* Indicate that this was a GNU C constructor expression.  */		  TREE_HAS_CONSTRUCTOR (init) = 1;		  $$ = digest_init (type, init, 0);		  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)		    {		      int failure = complete_array_type (type, $$, 1);		      if (failure)			my_friendly_abort (78);		    }		}	| HEADOF '(' expr ')'		{ $$ = build_headof ($3); }	| CLASSOF '(' expr ')'		{ $$ = build_classof ($3); }	| CLASSOF '(' TYPENAME ')'		{ if (is_aggr_typedef ($3, 1))		    {		      tree type = IDENTIFIER_TYPE_VALUE ($3);		      $$ = CLASSTYPE_DOSSIER (type);		    }		  else		    $$ = error_mark_node;		}	;expr_no_commas:	  cast_expr	| 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_modify_expr ($$, NOP_EXPR, $3); }	| expr_no_commas ASSIGN expr_no_commas		{ register tree rval;		  if (rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3,			make_node ($2)))		    $$ = rval;		  else		    $$ = build_modify_expr ($$, $2, $3); }	| primary DOT_STAR expr_no_commas %prec UNARY		{ $$ = build_m_component_ref ($$, build_indirect_ref ($3, 0)); }	/* Handle general members.  */	| object_star expr_no_commas   %prec UNARY		{ $$ = build_x_binary_op (MEMBER_REF, $$, $2); }/* These extensions are not defined.	| object '&' expr_no_commas   %prec UNARY		{ $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); }	| object unop expr_no_commas  %prec UNARY		{ $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); }	| object '(' typename ')' expr_no_commas  %prec UNARY		{ tree type = groktypename ($3);		  $$ = build_m_component_ref ($$, build_c_cast (type, $5)); }	| object primary_no_id  %prec UNARY		{ $$ = build_m_component_ref ($$, $2); }*/	;primary:	IDENTIFIER		{ $$ = do_identifier ($$); }	| operator_name		{		  tree op = $$;		  if (TREE_CODE (op) != IDENTIFIER_NODE)		    $$ = op;		  else		    {		      $$ = lookup_name (op, 0);		      if ($$ == NULL_TREE)			{			  error ("operator %s not defined", operator_name_string (op));			  $$ = error_mark_node;			}		    }		}	| CONSTANT	| string		{ $$ = combine_strings ($$); }	| '(' expr ')'		{ $$ = $2; }	| '(' 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;		  /* 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);		}	| primary '(' nonnull_exprlist ')'                { /* [eichin:19911016.1902EST] */                  $<ttype>$ = build_x_function_call ($1, $3, current_class_decl);                   /* here we instantiate_class_template as needed... */                  do_pending_templates ();                } template_instantiate_some {                  if (TREE_CODE ($<ttype>5) == CALL_EXPR                      && TREE_TYPE ($<ttype>5) != void_type_node)	            $$ = require_complete_type ($<ttype>5);                  else                    $$ = $<ttype>5;                }	| primary LEFT_RIGHT                { 		if ($$ != error_mark_node)		  {		    $$ = build_x_function_call ($$, NULL_TREE,						current_class_decl);		    if (TREE_CODE ($$) == CALL_EXPR			&& TREE_TYPE ($$) != void_type_node)		      $$ = require_complete_type ($$);		  }                }	| primary '[' expr ']'		{		do_array:		  {		    tree array_expr = $$;		    tree index_exp = $3;		    tree type = TREE_TYPE (array_expr);		    if (type == error_mark_node || index_exp == error_mark_node)		      $$ = error_mark_node;		    else if (type == NULL_TREE)		      {			/* Something has gone very wrong.  Assume we			   are mistakenly reducing an expression			   instead of a declaration.  */			error ("parser may be lost: is there a '{' missing somewhere?");

⌨️ 快捷键说明

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