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

📄 c-parse.y

📁 gcc库的原代码,对编程有很大帮助.
💻 Y
📖 第 1 页 / 共 5 页
字号:
	| component_decl_list2 ';'		{ if (pedantic)		    pedwarn ("extra semicolon in struct or union specified"); }	;/* There is a shift-reduce conflict here, because `components' may   start with a `typename'.  It happens that shifting (the default resolution)   does the right thing, because it treats the `typename' as part of   a `typed_typespecs'.   It is possible that this same technique would allow the distinction   between `notype_initdecls' and `initdecls' to be eliminated.   But I am being cautious and not trying it.  */component_decl:	  typed_typespecs setspecs components		{ $$ = $3;		  current_declspecs = TREE_VALUE (declspec_stack);		  prefix_attributes = TREE_PURPOSE (declspec_stack);		  declspec_stack = TREE_CHAIN (declspec_stack);		  resume_momentary ($2); }	| typed_typespecs		{ if (pedantic)		    pedwarn ("ANSI C forbids member declarations with no members");		  shadow_tag($1);		  $$ = NULL_TREE; }	| nonempty_type_quals setspecs components		{ $$ = $3;		  current_declspecs = TREE_VALUE (declspec_stack);		  prefix_attributes = TREE_PURPOSE (declspec_stack);		  declspec_stack = TREE_CHAIN (declspec_stack);		  resume_momentary ($2); }	| nonempty_type_quals		{ if (pedantic)		    pedwarn ("ANSI C forbids member declarations with no members");		  shadow_tag($1);		  $$ = NULL_TREE; }	| error		{ $$ = NULL_TREE; }	;components:	  component_declarator	| components ',' component_declarator		{ $$ = chainon ($1, $3); }	;component_declarator:	  save_filename save_lineno declarator maybe_attribute		{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);		  decl_attributes ($$, $4, prefix_attributes); }	| save_filename save_lineno	  declarator ':' expr_no_commas maybe_attribute		{ $$ = grokfield ($1, $2, $3, current_declspecs, $5);		  decl_attributes ($$, $6, prefix_attributes); }	| save_filename save_lineno ':' expr_no_commas maybe_attribute		{ $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);		  decl_attributes ($$, $5, prefix_attributes); }	;/* We chain the enumerators in reverse order.   They are put in forward order where enumlist is used.   (The order used to be significant, but no longer is so.   However, we still maintain the order, just to be clean.)  */enumlist:	  enumerator	| enumlist ',' enumerator		{ if ($1 == error_mark_node)		    $$ = $1;		  else		    $$ = chainon ($3, $1); }	| error		{ $$ = error_mark_node; }	;enumerator:	  identifier		{ $$ = build_enumerator ($1, NULL_TREE); }	| identifier '=' expr_no_commas		{ $$ = build_enumerator ($1, $3); }	;typename:	typed_typespecs absdcl		{ $$ = build_tree_list ($1, $2); }	| nonempty_type_quals absdcl		{ $$ = build_tree_list ($1, $2); }	;absdcl:   /* an absolute declarator */	/* empty */		{ $$ = NULL_TREE; }	| absdcl1	;nonempty_type_quals:	  TYPE_QUAL		{ $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }	| nonempty_type_quals TYPE_QUAL		{ $$ = tree_cons (NULL_TREE, $2, $1); }	;type_quals:	  /* empty */		{ $$ = NULL_TREE; }	| type_quals TYPE_QUAL		{ $$ = tree_cons (NULL_TREE, $2, $1); }	;absdcl1:  /* a nonempty absolute declarator */	  '(' absdcl1 ')'		{ $$ = $2; }	  /* `(typedef)1' is `int'.  */	| '*' type_quals absdcl1  %prec UNARY		{ $$ = make_pointer_declarator ($2, $3); }	| '*' type_quals  %prec UNARY		{ $$ = make_pointer_declarator ($2, NULL_TREE); }	| absdcl1 '(' parmlist  %prec '.'		{ $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }	| absdcl1 '[' expr ']'  %prec '.'		{ $$ = build_nt (ARRAY_REF, $1, $3); }	| absdcl1 '[' ']'  %prec '.'		{ $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }	| '(' parmlist  %prec '.'		{ $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }	| '[' expr ']'  %prec '.'		{ $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }	| '[' ']'  %prec '.'		{ $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }	| attributes setattrs absdcl1		{ $$ = $3; }	;/* at least one statement, the first of which parses without error.  *//* stmts is used only after decls, so an invalid first statement   is actually regarded as an invalid decl and part of the decls.  */stmts:	lineno_stmt_or_labels		{		  if (pedantic && $1)		    pedwarn ("ANSI C forbids label at end of compound statement");		}	;lineno_stmt_or_labels:	  lineno_stmt_or_label	| lineno_stmt_or_labels lineno_stmt_or_label		{ $$ = $2; }	| lineno_stmt_or_labels errstmt		{ $$ = 0; }	;xstmts:	/* empty */	| stmts	;errstmt:  error ';'	;pushlevel:  /* empty */		{ emit_line_note (input_filename, lineno);		  pushlevel (0);		  clear_last_expr ();		  push_momentary ();		  expand_start_bindings (0);		}	;/* Read zero or more forward-declarations for labels   that nested functions can jump to.  */maybe_label_decls:	  /* empty */	| label_decls		{ if (pedantic)		    pedwarn ("ANSI C forbids label declarations"); }	;label_decls:	  label_decl	| label_decls label_decl	;label_decl:	  LABEL identifiers_or_typenames ';'		{ tree link;		  for (link = $2; link; link = TREE_CHAIN (link))		    {		      tree label = shadow_label (TREE_VALUE (link));		      C_DECLARED_LABEL_FLAG (label) = 1;		      declare_nonlocal_label (label);		    }		}	;/* This is the body of a function definition.   It causes syntax errors to ignore to the next openbrace.  */compstmt_or_error:	  compstmt		{}	| error compstmt	;compstmt: '{' '}'		{ $$ = convert (void_type_node, integer_zero_node); }	| '{' pushlevel maybe_label_decls decls xstmts '}'		{ emit_line_note (input_filename, lineno);		  expand_end_bindings (getdecls (), 1, 0);		  $$ = poplevel (1, 1, 0);		  if (yychar == CONSTANT || yychar == STRING)		    pop_momentary_nofree ();		  else		    pop_momentary (); }	| '{' pushlevel maybe_label_decls error '}'		{ emit_line_note (input_filename, lineno);		  expand_end_bindings (getdecls (), kept_level_p (), 0);		  $$ = poplevel (kept_level_p (), 0, 0);		  if (yychar == CONSTANT || yychar == STRING)		    pop_momentary_nofree ();		  else		    pop_momentary (); }	| '{' pushlevel maybe_label_decls stmts '}'		{ emit_line_note (input_filename, lineno);		  expand_end_bindings (getdecls (), kept_level_p (), 0);		  $$ = poplevel (kept_level_p (), 0, 0);		  if (yychar == CONSTANT || yychar == STRING)		    pop_momentary_nofree ();		  else		    pop_momentary (); }	;/* Value is number of statements counted as of the closeparen.  */simple_if:	  if_prefix lineno_labeled_stmt/* Make sure expand_end_cond is run once   for each call to expand_start_cond.   Otherwise a crash is likely.  */	| if_prefix error	;if_prefix:	  IF '(' expr ')'		{ emit_line_note ($<filename>-1, $<lineno>0);		  expand_start_cond (truthvalue_conversion ($3), 0);		  $<itype>$ = stmt_count;		  if_stmt_file = $<filename>-1;		  if_stmt_line = $<lineno>0;		  position_after_white_space (); }	;/* This is a subroutine of stmt.   It is used twice, once for valid DO statements   and once for catching errors in parsing the end test.  */do_stmt_start:	  DO		{ stmt_count++;		  emit_line_note ($<filename>-1, $<lineno>0);		  /* See comment in `while' alternative, above.  */		  emit_nop ();		  expand_start_loop_continue_elsewhere (1);		  position_after_white_space (); }	  lineno_labeled_stmt WHILE		{ expand_loop_continue_here (); }	;save_filename:		{ $$ = input_filename; }	;save_lineno:		{ $$ = lineno; }	;lineno_labeled_stmt:	  save_filename save_lineno stmt		{ }/*	| save_filename save_lineno error		{ }*/	| save_filename save_lineno label lineno_labeled_stmt		{ }	;lineno_stmt_or_label:	  save_filename save_lineno stmt_or_label		{ $$ = $3; }	;stmt_or_label:	  stmt		{ $$ = 0; }	| label		{ $$ = 1; }	;/* Parse a single real statement, not including any labels.  */stmt:	  compstmt		{ stmt_count++; }        | all_iter_stmt 	| expr ';'		{ stmt_count++;		  emit_line_note ($<filename>-1, $<lineno>0);/* It appears that this should not be done--that a non-lvalue array   shouldn't get an error if the value isn't used.   Section 3.2.2.1 says that an array lvalue gets converted to a pointer   if it appears as a top-level expression,   but says nothing about non-lvalue arrays.  */#if 0		  /* Call default_conversion to get an error		     on referring to a register array if pedantic.  */		  if (TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE		      || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)		    $1 = default_conversion ($1);#endif		  iterator_expand ($1);		  clear_momentary (); }	| simple_if ELSE		{ expand_start_else ();		  $<itype>1 = stmt_count;		  position_after_white_space (); }	  lineno_labeled_stmt		{ expand_end_cond ();		  if (extra_warnings && stmt_count == $<itype>1)		    warning ("empty body in an else-statement"); }	| simple_if %prec IF		{ expand_end_cond ();		  /* This warning is here instead of in simple_if, because we		     do not want a warning if an empty if is followed by an		     else statement.  Increment stmt_count so we don't		     give a second error if this is a nested `if'.  */		  if (extra_warnings && stmt_count++ == $<itype>1)		    warning_with_file_and_line (if_stmt_file, if_stmt_line,						"empty body in an if-statement"); }/* Make sure expand_end_cond is run once   for each call to expand_start_cond.   Otherwise a crash is likely.  */	| simple_if ELSE error		{ expand_end_cond (); }	| WHILE		{ stmt_count++;		  emit_line_note ($<filename>-1, $<lineno>0);		  /* The emit_nop used to come before emit_line_note,		     but that made the nop seem like part of the preceding line.		     And that was confusing when the preceding line was		     inside of an if statement and was not really executed.		     I think it ought to work to put the nop after the line number.		     We will see.  --rms, July 15, 1991.  */		  emit_nop (); }	  '(' expr ')'		{ /* Don't start the loop till we have succeeded		     in parsing the end test.  This is to make sure		     that we end every loop we start.  */		  expand_start_loop (1);		  emit_line_note (input_filename, lineno);		  expand_exit_loop_if_false (NULL_PTR,					     truthvalue_conversion ($4));		  position_after_white_space (); }	  lineno_labeled_stmt		{ expand_end_loop (); }	| do_stmt_start	  '(' expr ')' ';'		{ emit_line_note (input_filename, lineno);		  expand_exit_loop_if_false (NULL_PTR,					     truthvalue_conversion ($3));		  expand_end_loop ();		  clear_momentary (); }/* This rule is needed to make sure we end every loop we start.  */	| do_stmt_start error		{ expand_end_loop ();		  clear_momentary (); }	| FOR	  '(' xexpr ';'		{ stmt_count++;		  emit_line_note ($<filename>-1, $<lineno>0);		  /* See comment in `while' alternative, above.  */		  emit_nop ();		  if ($3) c_expand_expr_stmt ($3);		  /* Next step is to call expand_start_loop_continue_elsewhere,		     but wait till after we parse the entire for (...).		     Otherwise, invalid input might cause us to call that		     fn without calling expand_end_loop.  */		}	  xexpr ';'		/* Can't emit now; wait till after expand_start_loop...  */		{ $<lineno>7 = lineno;		  $<filename>$ = input_filename; }	  xexpr ')'		{ 		  /* Start the loop.  Doing this after parsing		     all the expressions ensures we will end the loop.  */		  expand_start_loop_continue_elsewhere (1);		  /* Emit the end-test, with a line number.  */		  emit_line_note ($<filename>8, $<lineno>7);		  if ($6)		    expand_exit_loop_if_false (NULL_PTR,					       truthvalue_conversion ($6));		  /* Don't let the tree nodes for $9 be discarded by		     clear_momentary during the parsing of the next stmt.  */		  push_momentary ();		  $<lineno>7 = lineno;		  $<filename>8 = input_filename;		  position_after_white_space (); }	  lineno_labeled_stmt		{ /* Emit the increment expression, with a line number.  */		  emit_line_note ($<filename>8, $<lineno>7);		  expand_loop_continue_here ();		  if ($9)		    c_expand_expr_stmt ($9);		  if (yychar == CONSTANT || yychar == STRING)		    pop_momentary_nofree ();

⌨️ 快捷键说明

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