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

📄 match.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* The abortive DO WHILE may have done something to the symbol     table, so we start over: */  gfc_undo_symbols ();  gfc_current_locus = old_loc;  gfc_match_label ();		/* This won't error */  gfc_match (" do ");		/* This will work */  gfc_match_st_label (&label);	/* Can't error out */  gfc_match_char (',');		/* Optional comma */  m = gfc_match_iterator (&iter, 0);  if (m == MATCH_NO)    return MATCH_NO;  if (m == MATCH_ERROR)    goto cleanup;  gfc_check_do_variable (iter.var->symtree);  if (gfc_match_eos () != MATCH_YES)    {      gfc_syntax_error (ST_DO);      goto cleanup;    }  new_st.op = EXEC_DO;done:  if (label != NULL      && gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)    goto cleanup;  new_st.label = label;  if (new_st.op == EXEC_DO_WHILE)    new_st.expr = iter.end;  else    {      new_st.ext.iterator = ip = gfc_get_iterator ();      *ip = iter;    }  return MATCH_YES;cleanup:  gfc_free_iterator (&iter, 0);  return MATCH_ERROR;}/* Match an EXIT or CYCLE statement.  */static matchmatch_exit_cycle (gfc_statement st, gfc_exec_op op){  gfc_state_data *p;  gfc_symbol *sym;  match m;  if (gfc_match_eos () == MATCH_YES)    sym = NULL;  else    {      m = gfc_match ("% %s%t", &sym);      if (m == MATCH_ERROR)	return MATCH_ERROR;      if (m == MATCH_NO)	{	  gfc_syntax_error (st);	  return MATCH_ERROR;	}      if (sym->attr.flavor != FL_LABEL)	{	  gfc_error ("Name '%s' in %s statement at %C is not a loop name",		     sym->name, gfc_ascii_statement (st));	  return MATCH_ERROR;	}    }  /* Find the loop mentioned specified by the label (or lack of a     label).  */  for (p = gfc_state_stack; p; p = p->previous)    if (p->state == COMP_DO && (sym == NULL || sym == p->sym))      break;  if (p == NULL)    {      if (sym == NULL)	gfc_error ("%s statement at %C is not within a loop",		   gfc_ascii_statement (st));      else	gfc_error ("%s statement at %C is not within loop '%s'",		   gfc_ascii_statement (st), sym->name);      return MATCH_ERROR;    }  /* Save the first statement in the loop - needed by the backend.  */  new_st.ext.whichloop = p->head;  new_st.op = op;/*  new_st.sym = sym;*/  return MATCH_YES;}/* Match the EXIT statement.  */matchgfc_match_exit (void){  return match_exit_cycle (ST_EXIT, EXEC_EXIT);}/* Match the CYCLE statement.  */matchgfc_match_cycle (void){  return match_exit_cycle (ST_CYCLE, EXEC_CYCLE);}/* Match a number or character constant after a STOP or PAUSE statement.  */static matchgfc_match_stopcode (gfc_statement st){  int stop_code;  gfc_expr *e;  match m;  int cnt;  stop_code = -1;  e = NULL;  if (gfc_match_eos () != MATCH_YES)    {      m = gfc_match_small_literal_int (&stop_code, &cnt);      if (m == MATCH_ERROR)        goto cleanup;      if (m == MATCH_YES && cnt > 5)        {          gfc_error ("Too many digits in STOP code at %C");          goto cleanup;        }      if (m == MATCH_NO)        {          /* Try a character constant.  */          m = gfc_match_expr (&e);          if (m == MATCH_ERROR)            goto cleanup;          if (m == MATCH_NO)            goto syntax;          if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)            goto syntax;        }      if (gfc_match_eos () != MATCH_YES)        goto syntax;    }  if (gfc_pure (NULL))    {      gfc_error ("%s statement not allowed in PURE procedure at %C",	         gfc_ascii_statement (st));      goto cleanup;    }  new_st.op = st == ST_STOP ? EXEC_STOP : EXEC_PAUSE;  new_st.expr = e;  new_st.ext.stop_code = stop_code;  return MATCH_YES;syntax:  gfc_syntax_error (st);cleanup:  gfc_free_expr (e);  return MATCH_ERROR;}/* Match the (deprecated) PAUSE statement.  */matchgfc_match_pause (void){  match m;  m = gfc_match_stopcode (ST_PAUSE);  if (m == MATCH_YES)    {      if (gfc_notify_std (GFC_STD_F95_DEL,	    "Obsolete: PAUSE statement at %C")	  == FAILURE)	m = MATCH_ERROR;    }  return m;}/* Match the STOP statement.  */matchgfc_match_stop (void){  return gfc_match_stopcode (ST_STOP);}/* Match a CONTINUE statement.  */matchgfc_match_continue (void){  if (gfc_match_eos () != MATCH_YES)    {      gfc_syntax_error (ST_CONTINUE);      return MATCH_ERROR;    }  new_st.op = EXEC_CONTINUE;  return MATCH_YES;}/* Match the (deprecated) ASSIGN statement.  */matchgfc_match_assign (void){  gfc_expr *expr;  gfc_st_label *label;  if (gfc_match (" %l", &label) == MATCH_YES)    {      if (gfc_reference_st_label (label, ST_LABEL_UNKNOWN) == FAILURE)        return MATCH_ERROR;      if (gfc_match (" to %v%t", &expr) == MATCH_YES)        {	  if (gfc_notify_std (GFC_STD_F95_DEL,		"Obsolete: ASSIGN statement at %C")	      == FAILURE)	    return MATCH_ERROR;          expr->symtree->n.sym->attr.assign = 1;          new_st.op = EXEC_LABEL_ASSIGN;          new_st.label = label;          new_st.expr = expr;          return MATCH_YES;        }    }  return MATCH_NO;}/* Match the GO TO statement.  As a computed GOTO statement is   matched, it is transformed into an equivalent SELECT block.  No   tree is necessary, and the resulting jumps-to-jumps are   specifically optimized away by the back end.  */matchgfc_match_goto (void){  gfc_code *head, *tail;  gfc_expr *expr;  gfc_case *cp;  gfc_st_label *label;  int i;  match m;  if (gfc_match (" %l%t", &label) == MATCH_YES)    {      if (gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)	return MATCH_ERROR;      new_st.op = EXEC_GOTO;      new_st.label = label;      return MATCH_YES;    }  /* The assigned GO TO statement.  */   if (gfc_match_variable (&expr, 0) == MATCH_YES)    {      if (gfc_notify_std (GFC_STD_F95_DEL,			  "Obsolete: Assigned GOTO statement at %C")	  == FAILURE)	return MATCH_ERROR;      new_st.op = EXEC_GOTO;      new_st.expr = expr;      if (gfc_match_eos () == MATCH_YES)	return MATCH_YES;      /* Match label list.  */      gfc_match_char (',');      if (gfc_match_char ('(') != MATCH_YES)	{	  gfc_syntax_error (ST_GOTO);	  return MATCH_ERROR;	}      head = tail = NULL;      do	{	  m = gfc_match_st_label (&label);	  if (m != MATCH_YES)	    goto syntax;	  if (gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)	    goto cleanup;	  if (head == NULL)	    head = tail = gfc_get_code ();	  else	    {	      tail->block = gfc_get_code ();	      tail = tail->block;	    }	  tail->label = label;	  tail->op = EXEC_GOTO;	}      while (gfc_match_char (',') == MATCH_YES);      if (gfc_match (")%t") != MATCH_YES)	goto syntax;      if (head == NULL)	{	   gfc_error (	       "Statement label list in GOTO at %C cannot be empty");	   goto syntax;	}      new_st.block = head;      return MATCH_YES;    }  /* Last chance is a computed GO TO statement.  */  if (gfc_match_char ('(') != MATCH_YES)    {      gfc_syntax_error (ST_GOTO);      return MATCH_ERROR;    }  head = tail = NULL;  i = 1;  do    {      m = gfc_match_st_label (&label);      if (m != MATCH_YES)	goto syntax;      if (gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)	goto cleanup;      if (head == NULL)	head = tail = gfc_get_code ();      else	{	  tail->block = gfc_get_code ();	  tail = tail->block;	}      cp = gfc_get_case ();      cp->low = cp->high = gfc_int_expr (i++);      tail->op = EXEC_SELECT;      tail->ext.case_list = cp;      tail->next = gfc_get_code ();      tail->next->op = EXEC_GOTO;      tail->next->label = label;    }  while (gfc_match_char (',') == MATCH_YES);  if (gfc_match_char (')') != MATCH_YES)    goto syntax;  if (head == NULL)    {      gfc_error ("Statement label list in GOTO at %C cannot be empty");      goto syntax;    }  /* Get the rest of the statement.  */  gfc_match_char (',');  if (gfc_match (" %e%t", &expr) != MATCH_YES)    goto syntax;  /* At this point, a computed GOTO has been fully matched and an     equivalent SELECT statement constructed.  */  new_st.op = EXEC_SELECT;  new_st.expr = NULL;  /* Hack: For a "real" SELECT, the expression is in expr. We put     it in expr2 so we can distinguish then and produce the correct     diagnostics.  */  new_st.expr2 = expr;  new_st.block = head;  return MATCH_YES;syntax:  gfc_syntax_error (ST_GOTO);cleanup:  gfc_free_statements (head);  return MATCH_ERROR;}/* Frees a list of gfc_alloc structures.  */voidgfc_free_alloc_list (gfc_alloc * p){  gfc_alloc *q;  for (; p; p = q)    {      q = p->next;      gfc_free_expr (p->expr);      gfc_free (p);    }}/* Match an ALLOCATE statement.  */matchgfc_match_allocate (void){  gfc_alloc *head, *tail;  gfc_expr *stat;  match m;  head = tail = NULL;  stat = NULL;  if (gfc_match_char ('(') != MATCH_YES)    goto syntax;  for (;;)    {      if (head == NULL)	head = tail = gfc_get_alloc ();      else	{	  tail->next = gfc_get_alloc ();	  tail = tail->next;	}      m = gfc_match_variable (&tail->expr, 0);      if (m == MATCH_NO)	goto syntax;      if (m == MATCH_ERROR)	goto cleanup;      if (gfc_check_do_variable (tail->expr->symtree))	goto cleanup;      if (gfc_pure (NULL)          && gfc_impure_variable (tail->expr->symtree->n.sym))	{	  gfc_error ("Bad allocate-object in ALLOCATE statement at %C for a "		     "PURE procedure");	  goto cleanup;	}      if (gfc_match_char (',') != MATCH_YES)	break;      m = gfc_match (" stat = %v", &stat);      if (m == MATCH_ERROR)	goto cleanup;      if (m == MATCH_YES)	break;    }  if (stat != NULL)    {      if (stat->symtree->n.sym->attr.intent == INTENT_IN)	{	  gfc_error	    ("STAT variable '%s' of ALLOCATE statement at %C cannot be "	     "INTENT(IN)", stat->symtree->n.sym->name);	  goto cleanup;	}      if (gfc_pure (NULL) && gfc_impure_variable (stat->symtree->n.sym))	{	  gfc_error	    ("Illegal STAT variable in ALLOCATE statement at %C for a PURE "	     "procedure");	  goto cleanup;	}      if (stat->symtree->n.sym->attr.flavor != FL_VARIABLE)	{	  gfc_error("STAT expression at %C must be a variable");	  goto cleanup;	}      gfc_check_do_variable(stat->symtree);    }  if (gfc_match (" )%t") != MATCH_YES)    goto syntax;  new_st.op = EXEC_ALLOCATE;  new_st.expr = stat;  new_st.ext.alloc_list = head;  return MATCH_YES;syntax:  gfc_syntax_error (ST_ALLOCATE);cleanup:  gfc_free_expr (stat);  gfc_free_alloc_list (head);  return MATCH_ERROR;}/* Match a NULLIFY statement. A NULLIFY statement is transformed into   a set of pointer assignments to intrinsic NULL().  */matchgfc_match_nullify (void){  gfc_code *tail;  gfc_expr *e, *p;  match m;  tail = NULL;  if (gfc_match_char ('(') != MATCH_YES)    goto syntax;  for (;;)    {      m = gfc_match_variable (&p, 0);      if (m == MATCH_ERROR)	goto cleanup;      if (m == MATCH_NO)	goto syntax;      if (gfc_check_do_variable(p->symtree))	goto cleanup;      if (gfc_pure (NULL) && gfc_impure_variable (p->symtree->n.sym))	{	  gfc_error	    ("Illegal variable in NULLIFY at %C for a PURE procedure");	  goto cleanup;	}      /* build ' => NULL() ' */      e = gfc_get_expr ();      e->where = gfc_current_locus;      e->expr_type = EXPR_NULL;      e->ts.type = BT_UNKNOWN;      /* Chain to list */      if (tail == NULL)	tail = &new_st;      else	{	  tail->next = gfc_get_code ();	  tail = tail->next;	}      tail->op = EXEC_POINTER_ASSIGN;      tail->expr = p;      tail->expr2 = e;      if (gfc_match (" )%t") == MATCH_YES)	break;      if (gfc_match_char (',') != MATCH_YES)	goto syntax;    }  return MATCH_YES;syntax:  gfc_syntax_error (ST_NULLIFY);cleanup:  gfc_free_statements (new_st.next);  return MATCH_ERROR;}/* Match a DEALLOCATE statement.  */matchgfc_match_deallocate (void){  gfc_alloc *head, *tail;  gfc_expr *stat;  match m;  head = tail = NULL;  stat = NULL;  if (gfc_match_char ('(') != MATCH_YES)    goto syntax;  for (;;)    {      if (head == NULL)	head = tail = gfc_get_alloc ();      else	{	  tail->next = gfc_get_alloc ();	  tail = tail->next;	}      m = gfc_match_variable (&tail->expr, 0);      if (m == MATCH_ERROR)	goto cleanup;      if (m == MATCH_NO)	goto syntax;

⌨️ 快捷键说明

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