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

📄 parse.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 4 页
字号:
     SEQUENCE.  */  if (error_flag == 0 && gfc_current_block ()->attr.sequence)    for (c = gfc_current_block ()->components; c; c = c->next)      {	if (c->ts.type == BT_DERIVED && c->ts.derived->attr.sequence == 0)	  {	    gfc_error	      ("Component %s of SEQUENCE type declared at %C does not "	       "have the SEQUENCE attribute", c->ts.derived->name);	  }      }  pop_state ();}/* Parse an ENUM.  */ static voidparse_enum (void){  int error_flag;  gfc_statement st;  int compiling_enum;  gfc_state_data s;  int seen_enumerator = 0;  error_flag = 0;  push_state (&s, COMP_ENUM, gfc_new_block);  compiling_enum = 1;  while (compiling_enum)    {      st = next_statement ();      switch (st)        {        case ST_NONE:          unexpected_eof ();          break;        case ST_ENUMERATOR:	  seen_enumerator = 1;          accept_statement (st);          break;        case ST_END_ENUM:          compiling_enum = 0;	  if (!seen_enumerator)            {              gfc_error ("ENUM declaration at %C has no ENUMERATORS");	      error_flag = 1;            }          accept_statement (st);          break;        default:          gfc_free_enum_history ();          unexpected_statement (st);          break;        }    }  pop_state ();}/* Parse an interface.  We must be able to deal with the possibility   of recursive interfaces.  The parse_spec() subroutine is mutually   recursive with parse_interface().  */static gfc_statement parse_spec (gfc_statement);static voidparse_interface (void){  gfc_compile_state new_state, current_state;  gfc_symbol *prog_unit, *sym;  gfc_interface_info save;  gfc_state_data s1, s2;  gfc_statement st;  accept_statement (ST_INTERFACE);  current_interface.ns = gfc_current_ns;  save = current_interface;  sym = (current_interface.type == INTERFACE_GENERIC	 || current_interface.type == INTERFACE_USER_OP) ? gfc_new_block : NULL;  push_state (&s1, COMP_INTERFACE, sym);  current_state = COMP_NONE;loop:  gfc_current_ns = gfc_get_namespace (current_interface.ns, 0);  st = next_statement ();  switch (st)    {    case ST_NONE:      unexpected_eof ();    case ST_SUBROUTINE:      new_state = COMP_SUBROUTINE;      gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,				  gfc_new_block->formal, NULL);      break;    case ST_FUNCTION:      new_state = COMP_FUNCTION;      gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,				  gfc_new_block->formal, NULL);      break;    case ST_MODULE_PROC:	/* The module procedure matcher makes				   sure the context is correct.  */      accept_statement (st);      gfc_free_namespace (gfc_current_ns);      goto loop;    case ST_END_INTERFACE:      gfc_free_namespace (gfc_current_ns);      gfc_current_ns = current_interface.ns;      goto done;    default:      gfc_error ("Unexpected %s statement in INTERFACE block at %C",		 gfc_ascii_statement (st));      reject_statement ();      gfc_free_namespace (gfc_current_ns);      goto loop;    }  /* Make sure that a generic interface has only subroutines or     functions and that the generic name has the right attribute.  */  if (current_interface.type == INTERFACE_GENERIC)    {      if (current_state == COMP_NONE)	{	  if (new_state == COMP_FUNCTION)	    gfc_add_function (&sym->attr, sym->name, NULL);	  else if (new_state == COMP_SUBROUTINE)	    gfc_add_subroutine (&sym->attr, sym->name, NULL);	  current_state = new_state;	}      else	{	  if (new_state != current_state)	    {	      if (new_state == COMP_SUBROUTINE)		gfc_error		  ("SUBROUTINE at %C does not belong in a generic function "		   "interface");	      if (new_state == COMP_FUNCTION)		gfc_error		  ("FUNCTION at %C does not belong in a generic subroutine "		   "interface");	    }	}    }  push_state (&s2, new_state, gfc_new_block);  accept_statement (st);  prog_unit = gfc_new_block;  prog_unit->formal_ns = gfc_current_ns;decl:  /* Read data declaration statements.  */  st = parse_spec (ST_NONE);  if (st != ST_END_SUBROUTINE && st != ST_END_FUNCTION)    {      gfc_error ("Unexpected %s statement at %C in INTERFACE body",		 gfc_ascii_statement (st));      reject_statement ();      goto decl;    }  current_interface = save;  gfc_add_interface (prog_unit);  pop_state ();  goto loop;done:  pop_state ();}/* Parse a set of specification statements.  Returns the statement   that doesn't fit.  */static gfc_statementparse_spec (gfc_statement st){  st_state ss;  verify_st_order (&ss, ST_NONE);  if (st == ST_NONE)    st = next_statement ();loop:  switch (st)    {    case ST_NONE:      unexpected_eof ();    case ST_FORMAT:    case ST_ENTRY:    case ST_DATA:	/* Not allowed in interfaces */      if (gfc_current_state () == COMP_INTERFACE)	break;      /* Fall through */    case ST_USE:    case ST_IMPLICIT_NONE:    case ST_IMPLICIT:    case ST_PARAMETER:    case ST_PUBLIC:    case ST_PRIVATE:    case ST_DERIVED_DECL:    case_decl:      if (verify_st_order (&ss, st) == FAILURE)	{	  reject_statement ();	  st = next_statement ();	  goto loop;	}      switch (st)	{	case ST_INTERFACE:	  parse_interface ();	  break;	case ST_DERIVED_DECL:	  parse_derived ();	  break;	case ST_PUBLIC:	case ST_PRIVATE:	  if (gfc_current_state () != COMP_MODULE)	    {	      gfc_error ("%s statement must appear in a MODULE",			 gfc_ascii_statement (st));	      break;	    }	  if (gfc_current_ns->default_access != ACCESS_UNKNOWN)	    {	      gfc_error ("%s statement at %C follows another accessibility "			 "specification", gfc_ascii_statement (st));	      break;	    }	  gfc_current_ns->default_access = (st == ST_PUBLIC)	    ? ACCESS_PUBLIC : ACCESS_PRIVATE;	  break;	default:	  break;	}      accept_statement (st);      st = next_statement ();      goto loop;    case ST_ENUM:      accept_statement (st);      parse_enum();      st = next_statement ();      goto loop;    default:      break;    }  return st;}/* Parse a WHERE block, (not a simple WHERE statement).  */static voidparse_where_block (void){  int seen_empty_else;  gfc_code *top, *d;  gfc_state_data s;  gfc_statement st;  accept_statement (ST_WHERE_BLOCK);  top = gfc_state_stack->tail;  push_state (&s, COMP_WHERE, gfc_new_block);  d = add_statement ();  d->expr = top->expr;  d->op = EXEC_WHERE;  top->expr = NULL;  top->block = d;  seen_empty_else = 0;  do    {      st = next_statement ();      switch (st)	{	case ST_NONE:	  unexpected_eof ();	case ST_WHERE_BLOCK:	  parse_where_block ();          break;	case ST_ASSIGNMENT:	case ST_WHERE:	  accept_statement (st);	  break;	case ST_ELSEWHERE:	  if (seen_empty_else)	    {	      gfc_error		("ELSEWHERE statement at %C follows previous unmasked "		 "ELSEWHERE");	      break;	    }	  if (new_st.expr == NULL)	    seen_empty_else = 1;	  d = new_level (gfc_state_stack->head);	  d->op = EXEC_WHERE;	  d->expr = new_st.expr;	  accept_statement (st);	  break;	case ST_END_WHERE:	  accept_statement (st);	  break;	default:	  gfc_error ("Unexpected %s statement in WHERE block at %C",		     gfc_ascii_statement (st));	  reject_statement ();	  break;	}    }  while (st != ST_END_WHERE);  pop_state ();}/* Parse a FORALL block (not a simple FORALL statement).  */static voidparse_forall_block (void){  gfc_code *top, *d;  gfc_state_data s;  gfc_statement st;  accept_statement (ST_FORALL_BLOCK);  top = gfc_state_stack->tail;  push_state (&s, COMP_FORALL, gfc_new_block);  d = add_statement ();  d->op = EXEC_FORALL;  top->block = d;  do    {      st = next_statement ();      switch (st)	{	case ST_ASSIGNMENT:	case ST_POINTER_ASSIGNMENT:	case ST_WHERE:	case ST_FORALL:	  accept_statement (st);	  break;	case ST_WHERE_BLOCK:	  parse_where_block ();	  break;	case ST_FORALL_BLOCK:	  parse_forall_block ();	  break;	case ST_END_FORALL:	  accept_statement (st);	  break;	case ST_NONE:	  unexpected_eof ();	default:	  gfc_error ("Unexpected %s statement in FORALL block at %C",		     gfc_ascii_statement (st));	  reject_statement ();	  break;	}    }  while (st != ST_END_FORALL);  pop_state ();}static gfc_statement parse_executable (gfc_statement);/* parse the statements of an IF-THEN-ELSEIF-ELSE-ENDIF block.  */static voidparse_if_block (void){  gfc_code *top, *d;  gfc_statement st;  locus else_locus;  gfc_state_data s;  int seen_else;  seen_else = 0;  accept_statement (ST_IF_BLOCK);  top = gfc_state_stack->tail;  push_state (&s, COMP_IF, gfc_new_block);  new_st.op = EXEC_IF;  d = add_statement ();  d->expr = top->expr;  top->expr = NULL;  top->block = d;  do    {      st = parse_executable (ST_NONE);      switch (st)	{	case ST_NONE:	  unexpected_eof ();	case ST_ELSEIF:	  if (seen_else)	    {	      gfc_error		("ELSE IF statement at %C cannot follow ELSE statement at %L",		 &else_locus);	      reject_statement ();	      break;	    }	  d = new_level (gfc_state_stack->head);	  d->op = EXEC_IF;	  d->expr = new_st.expr;	  accept_statement (st);	  break;	case ST_ELSE:	  if (seen_else)	    {	      gfc_error ("Duplicate ELSE statements at %L and %C",			 &else_locus);	      reject_statement ();	      break;	    }	  seen_else = 1;	  else_locus = gfc_current_locus;	  d = new_level (gfc_state_stack->head);	  d->op = EXEC_IF;	  accept_statement (st);	  break;	case ST_ENDIF:	  break;	default:	  unexpected_statement (st);	  break;	}    }  while (st != ST_ENDIF);  pop_state ();  accept_statement (st);}/* Parse a SELECT block.  */static voidparse_select_block (void){  gfc_statement st;  gfc_code *cp;  gfc_state_data s;  accept_statement (ST_SELECT_CASE);  cp = gfc_state_stack->tail;  push_state (&s, COMP_SELECT, gfc_new_block);  /* Make sure that the next statement is a CASE or END SELECT.  */  for (;;)    {      st = next_statement ();      if (st == ST_NONE)	unexpected_eof ();      if (st == ST_END_SELECT)	{	  /* Empty SELECT CASE is OK.  */	  accept_statement (st);	  pop_state ();	  return;	}      if (st == ST_CASE)	break;      gfc_error	("Expected a CASE or END SELECT statement following SELECT CASE "	 "at %C");      reject_statement ();    }  /* At this point, we're got a nonempty select block.  */  cp = new_level (cp);  *cp = new_st;  accept_statement (st);  do    {      st = parse_executable (ST_NONE);      switch (st)	{	case ST_NONE:	  unexpected_eof ();	case ST_CASE:	  cp = new_level (gfc_state_stack->head);	  *cp = new_st;	  gfc_clear_new_st ();	  accept_statement (st);	  /* Fall through */	case ST_END_SELECT:	  break;        /* Can't have an executable statement because of           parse_executable().  */	default:	  unexpected_statement (st);	  break;	}    }  while (st != ST_END_SELECT);  pop_state ();  accept_statement (st);}/* Given a symbol, make sure it is not an iteration variable for a DO   statement.  This subroutine is called when the symbol is seen in a   context that causes it to become redefined.  If the symbol is an   iterator, we generate an error message and return nonzero.  */int gfc_check_do_variable (gfc_symtree *st){  gfc_state_data *s;  for (s=gfc_state_stack; s; s = s->previous)    if (s->do_variable == st)      {	gfc_error_now("Variable '%s' at %C cannot be redefined inside "		      "loop beginning at %L", st->name, &s->head->loc);	return 1;      }  return 0;}  /* Checks to see if the current statement label closes an enddo.   Returns 0 if not, 1 if closes an ENDDO correctly, or 2 (and issues   an error) if it incorrectly closes an ENDDO.  */static intcheck_do_closure (void){  gfc_state_data *p;  if (gfc_statement_label == NULL)    return 0;  for (p = gfc_state_stack; p; p = p->previous)    if (p->state == COMP_DO)      break;  if (p == NULL)    return 0;		/* No loops to close */  if (p->ext.end_do_label == gfc_statement_label)    {      if (p == gfc_state_stack)	return 1;      gfc_error	("End of nonblock DO statement at %C is within another block");      return 2;    }  /* At this point, the label doesn't terminate the innermost loop.     Make sure it doesn't terminate another one.  */  for (; p; p = p->previous)    if (p->state == COMP_DO && p->ext.end_do_label == gfc_statement_label)      {	gfc_error ("End of nonblock DO statement at %C is interwoven "		   "with another DO loop");	return 2;      }  return 0;}/* Parse a DO loop.  Note that the ST_CYCLE and ST_EXIT statements are   handled inside of parse_executable(), because they aren't really   loop statements.  */static voidparse_do_block (void){  gfc_statement st;  gfc_code *top;  gfc_state_data s;  gfc_symtree *stree;  s.ext.end_do_label = new_st.label;  if (new_st.ext.iterator != NULL)    stree = new_st.ext.iterator->var->symtree;  else    stree = NULL;  accept_statement (ST_DO);  top = gfc_state_stack->tail;

⌨️ 快捷键说明

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