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

📄 parse.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    return NULL_TREE;  list_list = build_tree_list (NULL_TREE, list);  while (check_token (COMMA))    {      if (selectors != NULL_TREE)	selectors = TREE_CHAIN (selectors);      list = parse_case_label_list (selectors, 0);      if (list == NULL_TREE)	{	  error ("unrecognized case label list after ','");	  return list_list;	}      list_list = tree_cons (NULL_TREE, list, list_list);    }  return nreverse (list_list);}static voidparse_single_dimension_case_action (selector)     tree selector;{  int  no_completeness_check = 0;/* The case label/action toggle.  It is 0 initially, and when an action   was last seen.  It is 1 integer_zero_node when a label was last seen. */  int caseaction_flag = 0;  if (! ignoring)    {      expand_exit_needed = 0;      selector = check_case_selector (selector);      expand_start_case (1, selector, TREE_TYPE (selector), "CASE statement");      push_momentary ();    }  for (;;)    {      tree label_spec = parse_case_label_specification (selector);      if (label_spec != NULL_TREE)	{	  expect (COLON, "missing ':' in case alternative");	  if (! ignoring)	    {              no_completeness_check |= chill_handle_single_dimension_case_label (                selector, label_spec, &expand_exit_needed, &caseaction_flag);	    }	}      else if (parse_action ())	{	  expand_exit_needed = 1; 	  caseaction_flag = 0;	}      else	break;    }  if (! ignoring)    {      if (expand_exit_needed || caseaction_flag == 1)	expand_exit_something ();     }  if (check_token (ELSE))    {      if (! ignoring)	  chill_handle_case_default ();      parse_opt_actions ();      if (! ignoring)	{	  emit_line_note (input_filename, lineno); 	  expand_exit_something (); 	}    }  else if (! ignoring && TREE_CODE (selector) != ERROR_MARK &&	   ! no_completeness_check)    check_missing_cases (TREE_TYPE (selector));  expect (ESAC, "missing 'ESAC' after 'CASE'");  if (! ignoring)    {      expand_end_case (selector);      pop_momentary ();     }}static voidparse_multi_dimension_case_action (selector)     tree selector;{  struct rtx_def *begin_test_label = 0, *end_case_label = 0, *new_label;  tree action_labels = NULL_TREE;  tree tests = NULL_TREE;  int  save_lineno = lineno;  char *save_filename = input_filename;  /* We can't compute the range of an (ELSE) label until all of the CASE     label specifications have been seen, however, the code for the actions     between them is generated on the fly. We can still generate everything in     one pass is we use the following form:     Compile a CASE of the form       case S1,...,Sn of         (X11),...,(X1n): A1;               ...         (Xm1),...,(Xmn): Am;         else             Ae;       esac;     into:       goto L0;       L1:   A1;  goto L99;          ...       Lm:   Am;  goto L99;       Le:   Ae;  goto L99;       L0:       T1 := s1; ...; Tn := Sn;       if (T1 = X11 and ... and Tn = X1n) GOTO L1;          ...       if (T1 = Xm1 and ... and Tn = Xmn) GOTO Lm;       GOTO Le;       L99;   */  if (! ignoring)    {      selector = check_case_selector_list (selector);      begin_test_label = gen_label_rtx ();      end_case_label   = gen_label_rtx ();      emit_jump (begin_test_label);    }  for (;;)    {      tree label_spec = parse_case_label_specification (selector);      if (label_spec != NULL_TREE)	{	  expect (COLON, "missing ':' in case alternative");	  if (! ignoring)	    {	      tests = tree_cons (label_spec, NULL_TREE, tests);	      if (action_labels != NULL_TREE)		emit_jump (end_case_label);	      new_label = gen_label_rtx ();	      emit_label (new_label);	      emit_line_note (input_filename, lineno);	      action_labels = tree_cons (NULL_TREE, NULL_TREE, action_labels);              TREE_CST_RTL (action_labels) = new_label;	    }	}      else if (! parse_action ())	{	  if (action_labels != NULL_TREE)	    emit_jump (end_case_label);	  break;	}    }  if (check_token (ELSE))    {      if (! ignoring)	{	  new_label = gen_label_rtx ();	  emit_label (new_label);	  emit_line_note (input_filename, lineno);	  action_labels = tree_cons (NULL_TREE, NULL_TREE, action_labels);	  TREE_CST_RTL (action_labels) = new_label;	}      parse_opt_actions ();      if (! ignoring)	emit_jump (end_case_label);    }  expect (ESAC, "missing 'ESAC' after 'CASE'");  if (! ignoring)    {      emit_label (begin_test_label);      emit_line_note (save_filename, save_lineno);      if (tests != NULL_TREE)	{	  tree cond;	  tests = nreverse (tests);	  action_labels = nreverse (action_labels);	  compute_else_ranges (selector, tests);	  cond = build_multi_case_selector_expression (selector, TREE_PURPOSE (tests));	  expand_start_cond (truthvalue_conversion (cond), label ? 1 : 0);	  emit_jump (TREE_CST_RTL (action_labels));	  for (tests = TREE_CHAIN (tests), action_labels = TREE_CHAIN (action_labels);	       tests != NULL_TREE && action_labels != NULL_TREE;	       tests = TREE_CHAIN (tests), action_labels = TREE_CHAIN (action_labels))	    {	      cond =		build_multi_case_selector_expression (selector, TREE_PURPOSE (tests));	      expand_start_elseif (truthvalue_conversion (cond));	      emit_jump (TREE_CST_RTL (action_labels));	    }	  if (action_labels != NULL_TREE)	    {	      expand_start_else (); 	      emit_jump (TREE_CST_RTL (action_labels));	    }	  expand_end_cond (); 	}      emit_label (end_case_label);    }}static voidparse_case_action (label)     tree label;{  tree selector;  int  multi_dimension_case = 0;  require (CASE);  selector = parse_expr_list ();  selector = nreverse (selector);  expect (OF, "missing 'OF' after 'CASE'");  parse_range_list_clause ();  PUSH_ACTION;  if (label)    pushlevel (1);  if (! ignoring)    {      expand_exit_needed = 0;      if (TREE_CODE (selector) == TREE_LIST)	{	  if (TREE_CHAIN (selector) != NULL_TREE)            multi_dimension_case = 1;          else	    selector = TREE_VALUE (selector);	}    }  /* We want to use the regular CASE support for the single dimension case. The     multi dimension case requires different handling. Note that when "ignoring"     is true we parse using the single dimension code. This is OK since it will     still parse correctly. */  if (multi_dimension_case)    parse_multi_dimension_case_action (selector);  else    parse_single_dimension_case_action (selector);  if (label)    {      possibly_define_exit_label (label);      poplevel (0, 0, 0);    }}/* Matches: [ <asm_operand> { "," <asm_operand> }* ],   where <asm_operand> = STRING '(' <expression> ')'   These are the operands other than the first string and colon   in  asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x))  */static treeparse_asm_operands (){  tree list = NULL_TREE;  if (PEEK_TOKEN () != STRING)    return NULL_TREE;  for (;;)    {      tree string, expr;      if (PEEK_TOKEN () != STRING)	{	  error ("bad ASM operand");	  return list;	}      string = PEEK_TREE();      FORWARD_TOKEN ();      expect (LPRN, "missing '(' in ASM operand");      expr = parse_expression ();      expect (RPRN, "missing ')' in ASM operand");      list = tree_cons (string, expr, list);      if (! check_token (COMMA))	break;    }  return nreverse (list);}/* Matches:  STRING { ',' STRING }* */static treeparse_asm_clobbers (){  tree list = NULL_TREE;  for (;;)    {      tree string;      if (PEEK_TOKEN () != STRING)	{	  error ("bad ASM operand");	  return list;	}      string = PEEK_TREE();      FORWARD_TOKEN ();      list = tree_cons (NULL_TREE, string, list);      if (! check_token (COMMA))	break;    }  return list;}voidch_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)     tree string, outputs, inputs, clobbers;     int vol;     char *filename;     int line;{  int noutputs = list_length (outputs);  register int i;  /* o[I] is the place that output number I should be written.  */  register tree *o = (tree *) alloca (noutputs * sizeof (tree));  register tree tail;  if (TREE_CODE (string) == ADDR_EXPR)    string = TREE_OPERAND (string, 0);  if (TREE_CODE (string) != STRING_CST)    {      error ("asm template is not a string constant");      return;    }  /* Record the contents of OUTPUTS before it is modified.  */  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)    o[i] = TREE_VALUE (tail);#if 0  /* Perform default conversions on array and function inputs.  */  /* Don't do this for other types--     it would screw up operands expected to be in memory.  */  for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++)    if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE	|| TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE)      TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));#endif  /* Generate the ASM_OPERANDS insn;     store into the TREE_VALUEs of OUTPUTS some trees for     where the values were actually stored.  */  expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);  /* Copy all the intermediate outputs into the specified outputs.  */  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)    {      if (o[i] != TREE_VALUE (tail))	{	  expand_expr (build_chill_modify_expr (o[i], TREE_VALUE (tail)),		       0, VOIDmode, 0);	  free_temp_slots ();	}      /* Detect modification of read-only values.	 (Otherwise done by build_modify_expr.)  */      else	{	  tree type = TREE_TYPE (o[i]);	  if (TYPE_READONLY (type)	      || ((TREE_CODE (type) == RECORD_TYPE		   || TREE_CODE (type) == UNION_TYPE)		  && TYPE_FIELDS_READONLY (type)))	    warning ("readonly location modified by 'asm'");	}    }  /* Those MODIFY_EXPRs could do autoincrements.  */  emit_queue ();}static voidparse_asm_action (){  tree insn;  require (ASM_KEYWORD);  expect (LPRN, "missing '('");  PUSH_ACTION;  if (!ignoring)    emit_line_note (input_filename, lineno);  insn = parse_expression ();  if (check_token (COLON))    {      tree output_operand, input_operand, clobbered_regs;      output_operand = parse_asm_operands ();      if (check_token (COLON))	input_operand = parse_asm_operands ();      else	input_operand = NULL_TREE;      if (check_token (COLON))	clobbered_regs = parse_asm_clobbers ();      else	clobbered_regs = NULL_TREE;      expect (RPRN, "missing ')'");      if (!ignoring)	ch_expand_asm_operands (insn, output_operand, input_operand,				clobbered_regs, FALSE,				input_filename, lineno);    }  else    {      expect (RPRN, "missing ')'");      STRIP_NOPS (insn);      if (ignoring) { }      else if ((TREE_CODE (insn) == ADDR_EXPR	   && TREE_CODE (TREE_OPERAND (insn, 0)) == STRING_CST)	  || TREE_CODE (insn) == STRING_CST)	expand_asm (insn);      else	error ("argument of `asm' is not a constant string");    }}static voidparse_begin_end_block (label)     tree label;{  require (BEGINTOKEN);#if 0  /* don't make a linenote at BEGIN */  INIT_ACTION;#endif  pushlevel (1);  if (! ignoring)    {      clear_last_expr ();      push_momentary ();      expand_start_bindings (label ? 1 : 0);     }  push_handler ();  parse_body ();  expect (END, "missing 'END'");  /* Note that the opthandler comes before the poplevel     - hence a handler is in the scope of the block. */  parse_opt_handler ();  possibly_define_exit_label (label);  if (! ignoring)    {       emit_line_note (input_filename, lineno);      expand_end_bindings (getdecls (), kept_level_p (), 0);    }  poplevel (kept_level_p (), 0, 0);  if (! ignoring)    pop_momentary ();   parse_opt_end_label_semi_colon (label);}static voidparse_if_action (label)     tree label;{  tree cond;  require (IF);  PUSH_ACTION;  cond = parse_expression ();  if (label)    pushlevel (1);  if (! ignoring)    {       expand_start_cond (truthvalue_conversion (cond),			 label ? 1 : 0);     }  parse_then_clause ();  parse_opt_else_clause ();  expect (FI, "expected 'FI' after 'IF'");  if (! ignoring)    {       emit_line_note (input_filename, lineno);      expand_end_cond ();     }  if (label)    {      possibly_define_exit_label  (label);      poplevel (0, 0, 0);    }}/* Matches:  <iteration>  (as in a <for control>). */static voidparse_iteration (){  tree loop_counter = parse_defining_occurrence ();  if (check_token (ASGN))    {      tree start_value = parse_expression ();      tree step_value	= check_token (BY) ? parse_expression () : NULL_TREE;      int going_down = check_token (DOWN);      tree end_value;      if (check_token (TO))	end_value = parse_expression ();      else	{	  error ("expected 'TO' in step enumeration");	  end_value = error_mark_node;	}      if (!ignoring)	build_loop_iterator (loop_counter, start_value, step_value,			     end_value, going_down, 0, 0);    }  else    {      int going_down = check_token (DOWN);      tree expr;      if (check_token (IN))	expr = parse_expression ();      else	{	  error ("expected 'IN' in FOR control here");	  expr = error_mark_node;	}      if (!ignoring)	{	  tree low_bound, high_bound;	  if (expr && TREE_CODE (expr) == TYPE_DECL)	    {	      expr = TREE_TYPE (expr);	      /* FIXME: expr must be an array or powerset */	      low_bound = convert (expr, TYPE_MIN_VALUE (expr));	      high_bound = convert (expr, TYPE_MAX_VALUE (expr));	    }	  else	    {

⌨️ 快捷键说明

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