/* sta.c -- Implementation File (module.c template V1.0)
   Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
   Contributed by James Craig Burley.

This file is part of GNU Fortran.

GNU Fortran is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Fortran is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Fortran; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.

   Related Modules:
      None

   Description:
      Analyzes the first two tokens, figures out what statements are
      possible, tries parsing the possible statements by calling on
      the ffestb functions.

   Modifications:
*/

/* Include files. */

#include "proj.h"
#include "sta.h"
#include "bad.h"
#include "implic.h"
#include "lex.h"
#include "malloc.h"
#include "stb.h"
#include "stc.h"
#include "std.h"
#include "str.h"
#include "storag.h"
#include "symbol.h"

/* Externals defined here. */

ffelexToken ffesta_tokens[FFESTA_tokensMAX];	/* For use by a possible. */
ffestrFirst ffesta_first_kw;	/* First NAME(S) looked up. */
ffestrSecond ffesta_second_kw;	/* Second NAME(S) looked up. */
mallocPool ffesta_output_pool;	/* Pool for results of stmt handling. */
mallocPool ffesta_scratch_pool;	/* Pool for stmt scratch handling. */
ffelexToken ffesta_construct_name;
ffelexToken ffesta_label_token;	/* Pending label stuff. */
bool ffesta_seen_first_exec;
bool ffesta_is_entry_valid = FALSE;	/* TRUE only in SUBROUTINE/FUNCTION. */
bool ffesta_line_has_semicolons = FALSE;

/* Simple definitions and enumerations. */

#define FFESTA_ABORT_ON_CONFIRM_ 1	/* 0=slow, tested way; 1=faster way
					   that might not always work. Here's
					   the old description of what used
					   to not work with ==1: (try
					   "CONTINUE\10
					   FORMAT('hi',I11)\END").  Problem
					   is that the "topology" of the
					   confirmed stmt's tokens with
					   regard to CHARACTER, HOLLERITH,
					   NAME/NAMES/NUMBER tokens (like hex
					   numbers), isn't traced if we abort
					   early, then other stmts might get
					   their grubby hands on those
					   unprocessed tokens and commit them
					   improperly.	Ideal fix is to rerun
					   the confirmed stmt and forget the
					   rest.  */

#define FFESTA_maxPOSSIBLES_ 8/* Never more than this # of possibles. */

/* Internal typedefs. */

typedef struct _ffesta_possible_ *ffestaPossible_;

/* Private include files. */


/* Internal structure definitions. */

struct _ffesta_possible_
  {
    ffestaPossible_ next;
    ffestaPossible_ previous;
    ffelexHandler handler;
    bool named;
  };

struct _ffesta_possible_root_
  {
    ffestaPossible_ first;
    ffestaPossible_ last;
    ffelexHandler nil;
  };

/* Static objects accessed by functions in this module. */

static bool ffesta_is_inhibited_ = FALSE;
static ffelexToken ffesta_token_0_;	/* For use by ffest possibility
					   handling. */
static ffestaPossible_ ffesta_possibles_[FFESTA_maxPOSSIBLES_];
static int ffesta_num_possibles_ = 0;	/* Number of possibilities. */
static struct _ffesta_possible_root_ ffesta_possible_nonexecs_;
static struct _ffesta_possible_root_ ffesta_possible_execs_;
static ffestaPossible_ ffesta_current_possible_;
static ffelexHandler ffesta_current_handler_;
static bool ffesta_confirmed_current_ = FALSE;
static bool ffesta_confirmed_other_ = FALSE;
static ffestaPossible_ ffesta_confirmed_possible_;
static bool ffesta_current_shutdown_ = FALSE;
#if !FFESTA_ABORT_ON_CONFIRM_
static bool ffesta_is_two_into_statement_ = FALSE;	/* For IF, WHERE stmts. */
static ffelexToken ffesta_twotokens_1_;	/* For IF, WHERE stmts. */
static ffelexToken ffesta_twotokens_2_;	/* For IF, WHERE stmts. */
#endif
static ffestaPooldisp ffesta_outpooldisp_;	/* After statement dealt
						   with. */
static bool ffesta_inhibit_confirmation_ = FALSE;

/* Static functions (internal). */

static void ffesta_add_possible_ (ffelexHandler fn, bool exec, bool named);
static bool ffesta_inhibited_exec_transition_ (void);
static void ffesta_reset_possibles_ (void);
static ffelexHandler ffesta_save_ (ffelexToken t);
static ffelexHandler ffesta_second_ (ffelexToken t);
#if !FFESTA_ABORT_ON_CONFIRM_
static ffelexHandler ffesta_send_two_ (ffelexToken t);
#endif

/* Internal macros. */

#define ffesta_add_possible_exec_(fn) (ffesta_add_possible_ (fn, TRUE, TRUE))
#define ffesta_add_possible_nonexec_(fn) (ffesta_add_possible_ (fn, FALSE, TRUE))
#define ffesta_add_possible_unnamed_exec_(fn) (ffesta_add_possible_ (fn, TRUE, FALSE))
#define ffesta_add_possible_unnamed_nonexec_(fn) (ffesta_add_possible_ (fn, FALSE, FALSE))

/* Add possible statement to appropriate list.  */

static void
ffesta_add_possible_ (ffelexHandler fn, bool exec, bool named)
{
  ffestaPossible_ p;

  assert (ffesta_num_possibles_ < FFESTA_maxPOSSIBLES_);

  p = ffesta_possibles_[ffesta_num_possibles_++];

  if (exec)
    {
      p->next = (ffestaPossible_) &ffesta_possible_execs_.first;
      p->previous = ffesta_possible_execs_.last;
    }
  else
    {
      p->next = (ffestaPossible_) &ffesta_possible_nonexecs_.first;
      p->previous = ffesta_possible_nonexecs_.last;
    }
  p->next->previous = p;
  p->previous->next = p;

  p->handler = fn;
  p->named = named;
}

/* ffesta_inhibited_exec_transition_ -- Do exec transition while inhibited

   if (!ffesta_inhibited_exec_transition_())  // couldn't transition...

   Invokes ffestc_exec_transition, but first enables ffebad and ffesta and
   afterwards disables them again.  Then returns the result of the
   invocation of ffestc_exec_transition.  */

static bool
ffesta_inhibited_exec_transition_ (void)
{
  bool result;

  assert (ffebad_inhibit ());
  assert (ffesta_is_inhibited_);

  ffebad_set_inhibit (FALSE);
  ffesta_is_inhibited_ = FALSE;

  result = ffestc_exec_transition ();

  ffebad_set_inhibit (TRUE);
  ffesta_is_inhibited_ = TRUE;

  return result;
}

/* ffesta_reset_possibles_ -- Reset (clear) lists of possible statements

   ffesta_reset_possibles_();

   Clears the lists of executable and nonexecutable statements.	 */

static void
ffesta_reset_possibles_ (void)
{
  ffesta_num_possibles_ = 0;

  ffesta_possible_execs_.first = ffesta_possible_execs_.last
    = (ffestaPossible_) &ffesta_possible_execs_.first;
  ffesta_possible_nonexecs_.first = ffesta_possible_nonexecs_.last
    = (ffestaPossible_) &ffesta_possible_nonexecs_.first;
}

/* ffesta_save_ -- Save token on list, pass thru to current handler

   return ffesta_save_;	 // to lexer.

   Receives a token from the lexer.  Saves it in the list of tokens.  Calls
   the current handler with the token.

   If no shutdown error occurred (via
   ffest_ffebad_start), then if the token was EOS or SEMICOLON, mark the
   current possible as successful and confirmed but try the next possible
   anyway until ambiguities in the form handling are ironed out.  */

static ffelexHandler
ffesta_save_ (ffelexToken t)
{
  static ffelexToken *saved_tokens = NULL;	/* A variable-sized array. */
  static unsigned int num_saved_tokens = 0;	/* Number currently saved. */
  static unsigned int max_saved_tokens = 0;	/* Maximum to be saved. */
  unsigned int toknum;		/* Index into saved_tokens array. */
  ffelexToken eos;		/* EOS created on-the-fly for shutdown
				   purposes. */
  ffelexToken t2;		/* Another temporary token (no intersect with
				   eos, btw). */

  /* Save the current token. */

  if (saved_tokens == NULL)
    {
      saved_tokens
	= malloc_new_ksr (malloc_pool_image (), "FFEST Saved Tokens",
			  (max_saved_tokens = 8) * sizeof (ffelexToken));
      /* Start off with 8. */
    }
  else if (num_saved_tokens >= max_saved_tokens)
    {
      toknum = max_saved_tokens;
      max_saved_tokens <<= 1;	/* Multiply by two. */
      assert (max_saved_tokens > toknum);
      saved_tokens
	= malloc_resize_ksr (malloc_pool_image (), saved_tokens,
			     max_saved_tokens * sizeof (ffelexToken),
			     toknum * sizeof (ffelexToken));
    }

  *(saved_tokens + num_saved_tokens++) = ffelex_token_use (t);

  /* Transmit the current token to the current handler. */

  ffesta_current_handler_ = (ffelexHandler) (*ffesta_current_handler_) (t);

  /* See if this possible has been shut down, or confirmed in which case we
     might as well shut it down anyway to save time. */

  if ((ffesta_current_shutdown_ || (FFESTA_ABORT_ON_CONFIRM_
				    && ffesta_confirmed_current_))
      && !ffelex_expecting_character ())
    {
      switch (ffelex_token_type (t))
	{
	case FFELEX_typeEOS:
	case FFELEX_typeSEMICOLON:
	  break;

	default:
	  eos = ffelex_token_new_eos (ffelex_token_where_line (t),
				      ffelex_token_where_column (t));
	  ffesta_inhibit_confirmation_ = ffesta_current_shutdown_;
	  (*ffesta_current_handler_) (eos);
	  ffesta_inhibit_confirmation_ = FALSE;
	  ffelex_token_kill (eos);
	  break;
	}
    }
  else
    {

      /* If this is an EOS or SEMICOLON token, switch to next handler, else
	 return self as next handler for lexer. */

      switch (ffelex_token_type (t))
	{
	case FFELEX_typeEOS:
	case FFELEX_typeSEMICOLON:
	  break;

	default:
	  return (ffelexHandler) ffesta_save_;
	}
    }

 next_handler:			/* :::::::::::::::::::: */

  /* Note that a shutdown also happens after seeing the first two tokens
     after "IF (expr)" or "WHERE (expr)" where a statement follows, even
     though there is no error.	This causes the IF or WHERE form to be
     implemented first before ffest_first is called for the first token in
     the following statement. */

  if (ffesta_current_shutdown_)
    ffesta_current_shutdown_ = FALSE;	/* Only after sending EOS! */
  else
    assert (ffesta_confirmed_current_);

  if (ffesta_confirmed_current_)
    {
      ffesta_confirmed_current_ = FALSE;
      ffesta_confirmed_other_ = TRUE;
    }

  /* Pick next handler. */

  ffesta_current_possible_ = ffesta_current_possible_->next;
  ffesta_current_handler_ = ffesta_current_possible_->handler;
  if (ffesta_current_handler_ == NULL)
    {				/* No handler in this list, try exec list if
				   not tried yet. */
      if (ffesta_current_possible_
	  == (ffestaPossible_) &ffesta_possible_nonexecs_.first)
	{
	  ffesta_current_possible_ = ffesta_possible_execs_.first;
	  ffesta_current_handler_ = ffesta_current_possible_->handler;
	}
      if ((ffesta_current_handler_ == NULL)
	  || (!ffesta_seen_first_exec
	      && ((ffesta_confirmed_possible_ != NULL)
		  || !ffesta_inhibited_exec_transition_ ())))
	/* Don't run execs if:	  (decoding the "if" ^^^ up here ^^^) - we
	   have no exec handler available, or - we haven't seen the first
	   executable statement yet, and - we've confirmed a nonexec
	   (otherwise even a nonexec would cause a transition), or - a
	   nonexec-to-exec transition can't be made at the statement context
	   level (as in an executable statement in the middle of a STRUCTURE
	   definition); if it can be made, ffestc_exec_transition makes the
	   corresponding transition at the statement state level so
	   specification statements are no longer accepted following an
	   unrecognized statement.  (Note: it is valid for f_e_t_ to decide
	   to always return TRUE by "shrieking" away the statement state
	   stack until a transitionable state is reached.  Or it can leave
	   the stack as is and return FALSE.)

	   If we decide not to run execs, enter this block to rerun the
	   confirmed statement, if any. */
	{			/* At end of both lists!  Pick confirmed or
				   first possible. */
	  ffebad_set_inhibit (FALSE);
	  ffesta_is_inhibited_ = FALSE;
	  ffesta_confirmed_other_ = FALSE;
	  ffesta_tokens[0] = ffesta_token_0_;
	  if (ffesta_confirmed_possible_ == NULL)
	    {			/* No confirmed success, just use first
				   named possible, or first possible if
				   no named possibles. */
	      ffestaPossible_ possible = ffesta_possible_nonexecs_.first;
	      ffestaPossible_ first = NULL;
	      ffestaPossible_ first_named = NULL;
	      ffestaPossible_ first_exec = NULL;

	      for (;;)
		{
		  if (possible->handler == NULL)
		    {
		      if (possible == (ffestaPossible_) &ffesta_possible_nonexecs_.first)
			{
			  possible = first_exec = ffesta_possible_execs_.first;
			  continue;
			}
		      else
			break;
		    }
		  if (first == NULL)
		    first = possible;
		  if (possible->named
		      && (first_named == NULL))
		    first_named = possible;

		  possible = possible->next;
		}

	      if (first_named != NULL)
		ffesta_current_possible_ = first_named;
	      else if (ffesta_seen_first_exec
		       && (first_exec != NULL))
		ffesta_current_possible_ = first_exec;
	      else
		ffesta_current_possible_ = first;

	      ffesta_current_handler_ = ffesta_current_possible_->handler;
	      assert (ffesta_current_handler_ != NULL);
	    }
	  else
	    {			/* Confirmed success, use it. */
	      ffesta_current_possible_ = ffesta_confirmed_possible_;
	      ffesta_current_handler_ = ffesta_confirmed_possible_->handler;
	    }
	  ffesta_reset_possibles_ ();
	}
      else
	{			/* Switching from [empty?] list of nonexecs
				   to nonempty list of execs at this point. */
	  ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_);
	  ffesymbol_set_retractable (ffesta_scratch_pool);
	}
    }
  else
    {
      ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_);
      ffesymbol_set_retractable (ffesta_scratch_pool);
    }

  /* Send saved tokens to current handler until either shut down or all
     tokens sent. */

  for (toknum = 0; toknum < num_saved_tokens; ++toknum)
    {
      t = *(saved_tokens + toknum);
      switch (ffelex_token_type (t))
	{
	case FFELEX_typeCHARACTER:
	  ffelex_set_expecting_hollerith (0, '\0',
					  ffewhere_line_unknown (),
					  ffewhere_column_unknown ());
	  ffesta_current_handler_
	    = (ffelexHandler) (*ffesta_current_handler_) (t);
	  break;

	case FFELEX_typeNAMES:
	  if (ffelex_is_names_expected ())
	    ffesta_current_handler_
	      = (ffelexHandler) (*ffesta_current_handler_) (t);
	  else
	    {
	      t2 = ffelex_token_name_from_names (t, 0, 0);
	      ffesta_current_handler_
		= (ffelexHandler) (*ffesta_current_handler_) (t2);
	      ffelex_token_kill (t2);
	    }
	  break;

	default:
	  ffesta_current_handler_
	    = (ffelexHandler) (*ffesta_current_handler_) (t);
	  break;
	}

      if (!ffesta_is_inhibited_)
	ffelex_token_kill (t);	/* Won't need this any more. */

      /* See if this possible has been shut down. */

      else if ((ffesta_current_shutdown_ || (FFESTA_ABORT_ON_CONFIRM_
					     && ffesta_confirmed_current_))
	       && !ffelex_expecting_character ())
	{
	  switch (ffelex_token_type (t))
	    {
	    case FFELEX_typeEOS:
	    case FFELEX_typeSEMICOLON:
	      break;

	    default:
	      eos = ffelex_token_new_eos (ffelex_token_where_line (t),
					  ffelex_token_where_column (t));
	      ffesta_inhibit_confirmation_ = ffesta_current_shutdown_;
	      (*ffesta_current_handler_) (eos);
	      ffesta_inhibit_confirmation_ = FALSE;
	      ffelex_token_kill (eos);
	      break;
	    }
	  goto next_handler;	/* :::::::::::::::::::: */
	}
    }

  /* Finished sending all the tokens so far.  If still trying possibilities,
     then if we've just sent an EOS or SEMICOLON token through, go to the
     next handler.  Otherwise, return self so we can gather and process more
     tokens. */

  if (ffesta_is_inhibited_)
    {
      switch (ffelex_token_type (t))
	{
	case FFELEX_typeEOS:
	case FFELEX_typeSEMICOLON:
	  goto next_handler;	/* :::::::::::::::::::: */

	default:
#if FFESTA_ABORT_ON_CONFIRM_
	  assert (!ffesta_confirmed_other_);	/* Catch ambiguities. */
#endif
	  return (ffelexHandler) ffesta_save_;
	}
    }

  /* This was the one final possibility, uninhibited, so send the final
     handler it sent. */

  num_saved_tokens = 0;
#if !FFESTA_ABORT_ON_CONFIRM_
  if (ffesta_is_two_into_statement_)
    {				/* End of the line for the previous two
				   tokens, resurrect them. */
      ffelexHandler next;

      ffesta_is_two_into_statement_ = FALSE;
      next = (ffelexHandler) ffesta_first (ffesta_twotokens_1_);
      ffelex_token_kill (ffesta_twotokens_1_);
      next = (ffelexHandler) (*next) (ffesta_twotokens_2_);
      ffelex_token_kill (ffesta_twotokens_2_);
      return (ffelexHandler) next;
    }
#endif

  assert (ffesta_current_handler_ != NULL);
  return (ffelexHandler) ffesta_current_handler_;
}

/* ffesta_second_ -- Parse the token after a NAME/NAMES in a statement

   return ffesta_second_;  // to lexer.

   The second token cannot be a NAMES, since the first token is a NAME or
   NAMES.  If the second token is a NAME, look up its name in the list of
   second names for use by whoever needs it.

   Then make a list of all the possible statements this could be, based on
   looking at the first two tokens.  Two lists of possible statements are
   created, one consisting of nonexecutable statements, the other consisting
   of executable statements.

   If the total number of possibilities is one, just fire up that
   possibility by calling its handler function, passing the first two
   tokens through it and so on.

   Otherwise, start up a process whereby tokens are passed to the first
   possibility on the list until EOS or SEMICOLON is reached or an error
   is detected.	 But inhibit any actual reporting of errors; just record
   their existence in the list.	 If EOS or SEMICOLON is reached with no
   errors (other than non-form errors happening downstream, such as an
   overflowing value for an integer or a GOTO statement identifying a label
   on a FORMAT statement), then that is the only possible statement.  Rerun
   the statement with error-reporting turned on if any non-form errors were
   generated, otherwise just use its results, then erase the list of tokens
   memorized during the search process.	 If a form error occurs, immediately
   cancel that possibility by sending EOS as the next token, remember the
   error code for that possibility, and try the next possibility on the list,
   first sending it the list of tokens memorized while handling the first
   possibility, then continuing on as before.

   Ultimately, either the end of the list of possibilities will be reached
   without any successful forms being detected, in which case we pick one
   based on hueristics (usually the first possibility) and rerun it with
   error reporting turned on using the list of memorized tokens so the user
   sees the error, or one of the possibilities will effectively succeed.  */

static ffelexHandler
ffesta_second_ (ffelexToken t)
{
  ffelexHandler next;
  ffesymbol s;

  assert (ffelex_token_type (t) != FFELEX_typeNAMES);

  if (ffelex_token_type (t) == FFELEX_typeNAME)
    ffesta_second_kw = ffestr_second (t);

  /* Here we use switch on the first keyword name and handle each possible
     recognizable name by looking at the second token, and building the list
     of possible names accordingly.  For now, just put every possible
     statement on the list for ambiguity checking. */

  switch (ffesta_first_kw)
    {
    case FFESTR_firstASSIGN:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R838);
      break;

    case FFESTR_firstBACKSPACE:
      ffestb_args.beru.len = FFESTR_firstlBACKSPACE;
      ffestb_args.beru.badname = "BACKSPACE";
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru);
      break;

    case FFESTR_firstBLOCK:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_block);
      break;

    case FFESTR_firstBLOCKDATA:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_blockdata);
      break;

    case FFESTR_firstBYTE:
      ffestb_args.decl.len = FFESTR_firstlBYTE;
      ffestb_args.decl.type = FFESTP_typeBYTE;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
      break;

    case FFESTR_firstCALL:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1212);
      break;

    case FFESTR_firstCASE:
    case FFESTR_firstCASEDEFAULT:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R810);
      break;

    case FFESTR_firstCHRCTR:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_chartype);
      break;

    case FFESTR_firstCLOSE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R907);
      break;

    case FFESTR_firstCOMMON:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R547);
      break;

    case FFESTR_firstCMPLX:
      ffestb_args.decl.len = FFESTR_firstlCMPLX;
      ffestb_args.decl.type = FFESTP_typeCOMPLEX;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
      break;

    case FFESTR_firstCONTINUE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R841);
      break;

    case FFESTR_firstCYCLE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R834);
      break;

    case FFESTR_firstDATA:
      if (ffe_is_pedantic_not_90 ())
	ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R528);
      else
	ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R528);
      break;

    case FFESTR_firstDIMENSION:
      ffestb_args.R524.len = FFESTR_firstlDIMENSION;
      ffestb_args.R524.badname = "DIMENSION";
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R524);
      break;

    case FFESTR_firstDO:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_do);
      break;

    case FFESTR_firstDBL:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_double);
      break;

    case FFESTR_firstDBLCMPLX:
      ffestb_args.decl.len = FFESTR_firstlDBLCMPLX;
      ffestb_args.decl.type = FFESTP_typeDBLCMPLX;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_dbltype);
      break;

    case FFESTR_firstDBLPRCSN:
      ffestb_args.decl.len = FFESTR_firstlDBLPRCSN;
      ffestb_args.decl.type = FFESTP_typeDBLPRCSN;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_dbltype);
      break;

    case FFESTR_firstDOWHILE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_dowhile);
      break;

    case FFESTR_firstELSE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_else);
      break;

    case FFESTR_firstELSEIF:
      ffestb_args.elsexyz.second = FFESTR_secondIF;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz);
      break;

    case FFESTR_firstEND:
      if ((ffelex_token_type (ffesta_token_0_) == FFELEX_typeNAMES)
	  || (ffelex_token_type (t) != FFELEX_typeNAME))
	ffesta_add_possible_exec_ ((ffelexHandler) ffestb_end);
      else
	{
	  switch (ffesta_second_kw)
	    {
	    case FFESTR_secondBLOCK:
	    case FFESTR_secondBLOCKDATA:
	    case FFESTR_secondDO:
	    case FFESTR_secondFILE:
	    case FFESTR_secondFUNCTION:
	    case FFESTR_secondIF:
	    case FFESTR_secondPROGRAM:
	    case FFESTR_secondSELECT:
	    case FFESTR_secondSUBROUTINE:
	      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_end);
	      break;

	    default:
	      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_end);
	      break;
	    }
	}
      break;

    case FFESTR_firstENDBLOCK:
      ffestb_args.endxyz.len = FFESTR_firstlENDBLOCK;
      ffestb_args.endxyz.second = FFESTR_secondBLOCK;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENDBLOCKDATA:
      ffestb_args.endxyz.len = FFESTR_firstlENDBLOCKDATA;
      ffestb_args.endxyz.second = FFESTR_secondBLOCKDATA;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENDDO:
      ffestb_args.endxyz.len = FFESTR_firstlENDDO;
      ffestb_args.endxyz.second = FFESTR_secondDO;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENDFILE:
      ffestb_args.beru.len = FFESTR_firstlENDFILE;
      ffestb_args.beru.badname = "ENDFILE";
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru);
      break;

    case FFESTR_firstENDFUNCTION:
      ffestb_args.endxyz.len = FFESTR_firstlENDFUNCTION;
      ffestb_args.endxyz.second = FFESTR_secondFUNCTION;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENDIF:
      ffestb_args.endxyz.len = FFESTR_firstlENDIF;
      ffestb_args.endxyz.second = FFESTR_secondIF;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENDPROGRAM:
      ffestb_args.endxyz.len = FFESTR_firstlENDPROGRAM;
      ffestb_args.endxyz.second = FFESTR_secondPROGRAM;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENDSELECT:
      ffestb_args.endxyz.len = FFESTR_firstlENDSELECT;
      ffestb_args.endxyz.second = FFESTR_secondSELECT;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENDSUBROUTINE:
      ffestb_args.endxyz.len = FFESTR_firstlENDSUBROUTINE;
      ffestb_args.endxyz.second = FFESTR_secondSUBROUTINE;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
      break;

    case FFESTR_firstENTRY:
      ffestb_args.dummy.len = FFESTR_firstlENTRY;
      ffestb_args.dummy.badname = "ENTRY";
      ffestb_args.dummy.is_subr = ffestc_is_entry_in_subr ();
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy);
      break;

    case FFESTR_firstEQUIVALENCE:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R544);
      break;

    case FFESTR_firstEXIT:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R835);
      break;

    case FFESTR_firstEXTERNAL:
      ffestb_args.varlist.len = FFESTR_firstlEXTERNAL;
      ffestb_args.varlist.badname = "EXTERNAL";
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist);
      break;

      /* WARNING: don't put anything that might cause an item to precede
	 FORMAT in the list of possible statements (it's added below) without
	 making sure FORMAT still is first.  It has to run with
	 ffelex_set_names_pure(TRUE), to make sure the lexer delivers NAMES
	 tokens. */

    case FFESTR_firstFORMAT:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1001);
      break;

    case FFESTR_firstFUNCTION:
      ffestb_args.dummy.len = FFESTR_firstlFUNCTION;
      ffestb_args.dummy.badname = "FUNCTION";
      ffestb_args.dummy.is_subr = FALSE;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy);
      break;

    case FFESTR_firstGO:
      if ((ffelex_token_type (ffesta_token_0_) == FFELEX_typeNAMES)
	|| (ffelex_token_type (t) != FFELEX_typeNAME))
	ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
      else
	switch (ffesta_second_kw)
	  {
	    case FFESTR_secondTO:
	      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
              break;
	    default:
	      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
              break;
	  }
      break;

    case FFESTR_firstGOTO:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
      break;

    case FFESTR_firstIF:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_if);
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R840);
      break;

    case FFESTR_firstIMPLICIT:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_R539);
      break;

    case FFESTR_firstINCLUDE:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_S3P4);
      switch (ffelex_token_type (t))
	{
	case FFELEX_typeNUMBER:
	case FFELEX_typeNAME:
	case FFELEX_typeAPOSTROPHE:
	case FFELEX_typeQUOTE:
	  break;

	default:
	  break;
	}
      break;

    case FFESTR_firstINQUIRE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R923);
      break;

    case FFESTR_firstINTGR:
      ffestb_args.decl.len = FFESTR_firstlINTGR;
      ffestb_args.decl.type = FFESTP_typeINTEGER;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
      break;

    case FFESTR_firstINTRINSIC:
      ffestb_args.varlist.len = FFESTR_firstlINTRINSIC;
      ffestb_args.varlist.badname = "INTRINSIC";
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist);
      break;

    case FFESTR_firstLGCL:
      ffestb_args.decl.len = FFESTR_firstlLGCL;
      ffestb_args.decl.type = FFESTP_typeLOGICAL;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
      break;

    case FFESTR_firstNAMELIST:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R542);
      break;

    case FFESTR_firstOPEN:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R904);
      break;

    case FFESTR_firstPARAMETER:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R537);
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V027);
      break;

    case FFESTR_firstPAUSE:
      ffestb_args.halt.len = FFESTR_firstlPAUSE;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt);
      break;

    case FFESTR_firstPRINT:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R911);
      break;

    case FFESTR_firstPROGRAM:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1102);
      break;

    case FFESTR_firstREAD:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R909);
      break;

    case FFESTR_firstREAL:
      ffestb_args.decl.len = FFESTR_firstlREAL;
      ffestb_args.decl.type = FFESTP_typeREAL;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
      break;

    case FFESTR_firstRETURN:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1227);
      break;

    case FFESTR_firstREWIND:
      ffestb_args.beru.len = FFESTR_firstlREWIND;
      ffestb_args.beru.badname = "REWIND";
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru);
      break;

    case FFESTR_firstSAVE:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R522);
      break;

    case FFESTR_firstSELECT:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809);
      break;

    case FFESTR_firstSELECTCASE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809);
      break;

    case FFESTR_firstSTOP:
      ffestb_args.halt.len = FFESTR_firstlSTOP;
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt);
      break;

    case FFESTR_firstSUBROUTINE:
      ffestb_args.dummy.len = FFESTR_firstlSUBROUTINE;
      ffestb_args.dummy.badname = "SUBROUTINE";
      ffestb_args.dummy.is_subr = TRUE;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy);
      break;

    case FFESTR_firstTYPE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V020);
      break;

    case FFESTR_firstVIRTUAL:
      ffestb_args.R524.len = FFESTR_firstlVIRTUAL;
      ffestb_args.R524.badname = "VIRTUAL";
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R524);
      break;

    case FFESTR_firstVOLATILE:
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V014);
      break;

    case FFESTR_firstWORD:
      ffestb_args.decl.len = FFESTR_firstlWORD;
      ffestb_args.decl.type = FFESTP_typeWORD;
      ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
      break;

    case FFESTR_firstWRITE:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R910);
      break;

    default:
      break;
    }

  /* Now check the default cases, which are always "live" (meaning that no
     other possibility can override them).  These are where the second token
     is OPEN_PAREN, PERCENT, EQUALS, POINTS, or COLON. */

  switch (ffelex_token_type (t))
    {
    case FFELEX_typeOPEN_PAREN:
      s = ffesymbol_lookup_local (ffesta_token_0_);
      if (((s == NULL) || (ffesymbol_dims (s) == NULL))
	  && !ffesta_seen_first_exec)
	{			/* Not known as array; may be stmt function. */
	  ffesta_add_possible_unnamed_nonexec_ ((ffelexHandler) ffestb_R1229);

	  /* If the symbol is (or will be due to implicit typing) of
	     CHARACTER type, then the statement might be an assignment
	     statement.	 If so, since it can't be a function invocation nor
	     an array element reference, the open paren following the symbol
	     name must be followed by an expression and a colon.  Without the
	     colon (which cannot appear in a stmt function definition), the
	     let stmt rejects.	So CHARACTER_NAME(...)=expr, unlike any other
	     type, is not ambiguous alone. */

	  if (ffeimplic_peek_symbol_type (s,
					ffelex_token_text (ffesta_token_0_))
	      == FFEINFO_basictypeCHARACTER)
	    ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let);
	}
      else			/* Not statement function if known as an
				   array. */
	ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let);
      break;

    case FFELEX_typeEQUALS:
      ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let);
      break;

    case FFELEX_typeCOLON:
      ffesta_add_possible_exec_ ((ffelexHandler) ffestb_construct);
      break;

    default:
      ;
    }

  /* Now see how many possibilities are on the list. */

  switch (ffesta_num_possibles_)
    {
    case 0:			/* None, so invalid statement. */
    no_stmts:			/* :::::::::::::::::::: */
      ffesta_tokens[0] = ffesta_token_0_;
      ffesta_ffebad_2t (FFEBAD_UNREC_STMT, ffesta_token_0_, t);
      next = (ffelexHandler) ffelex_swallow_tokens (NULL,
					       (ffelexHandler) ffesta_zero);
      break;

    case 1:			/* One, so just do it! */
      ffesta_tokens[0] = ffesta_token_0_;
      next = ffesta_possible_execs_.first->handler;
      if (next == NULL)
	{			/* Have a nonexec stmt. */
	  next = ffesta_possible_nonexecs_.first->handler;
	  assert (next != NULL);
	}
      else if (ffesta_seen_first_exec)
	;			/* Have an exec stmt after exec transition. */
      else if (!ffestc_exec_transition ())
	/* 1 exec stmt only, but not valid in context, so pretend as though
	   statement is unrecognized. */
	goto no_stmts;		/* :::::::::::::::::::: */
      break;

    default:			/* More than one, so try them in order. */
      ffesta_confirmed_possible_ = NULL;
      ffesta_current_possible_ = ffesta_possible_nonexecs_.first;
      ffesta_current_handler_ = ffesta_current_possible_->handler;
      if (ffesta_current_handler_ == NULL)
	{
	  ffesta_current_possible_ = ffesta_possible_execs_.first;
	  ffesta_current_handler_ = ffesta_current_possible_->handler;
	  assert (ffesta_current_handler_ != NULL);
	  if (!ffesta_seen_first_exec)
	    {			/* Need to do exec transition now. */
	      ffesta_tokens[0] = ffesta_token_0_;
	      if (!ffestc_exec_transition ())
		goto no_stmts;	/* :::::::::::::::::::: */
	    }
	}
      ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_);
      next = (ffelexHandler) ffesta_save_;
      ffebad_set_inhibit (TRUE);
      ffesta_is_inhibited_ = TRUE;
      break;
    }

  ffesta_output_pool
    = malloc_pool_new ("Statement Output", ffe_pool_program_unit (), 1024);
  ffesta_scratch_pool
    = malloc_pool_new ("Statement Scratch", ffe_pool_program_unit (), 1024);
  ffesta_outpooldisp_ = FFESTA_pooldispDISCARD;

  if (ffesta_is_inhibited_)
    ffesymbol_set_retractable (ffesta_scratch_pool);

  ffelex_set_names (FALSE);	/* Most handlers will want this.  If not,
				   they have to set it TRUE again (its value
				   at the beginning of a statement). */

  return (ffelexHandler) (*next) (t);
}

/* ffesta_send_two_ -- Send the two tokens saved by ffesta_two after all

   return ffesta_send_two_;  // to lexer.

   Currently, if this function gets called, it means that the two tokens
   saved by ffesta_two did not have their handlers derailed by
   ffesta_save_, which probably means they weren't sent by ffesta_save_
   but directly by the lexer, which probably means the original statement
   (which should be IF (expr) or WHERE (expr)) somehow evaluated to only
   one possibility in ffesta_second_ or somebody optimized FFEST to
   immediately revert to one possibility upon confirmation but forgot to
   change this function (and thus perhaps the entire resubmission
   mechanism).	*/

#if !FFESTA_ABORT_ON_CONFIRM_
static ffelexHandler
ffesta_send_two_ (ffelexToken t)
{
  assert ("what am I doing here?" == NULL);
  return NULL;
}

#endif
/* ffesta_confirmed -- Confirm current possibility as only one

   ffesta_confirmed();

   Sets the confirmation flag.	During debugging for ambiguous constructs,
   asserts that the confirmation flag for a previous possibility has not
   yet been set.  */

void
ffesta_confirmed (void)
{
  if (ffesta_inhibit_confirmation_)
    return;
  ffesta_confirmed_current_ = TRUE;
  assert (!ffesta_confirmed_other_
	  || (ffesta_confirmed_possible_ == ffesta_current_possible_));
  ffesta_confirmed_possible_ = ffesta_current_possible_;
}

/* ffesta_eof -- End of (non-INCLUDEd) source file

   ffesta_eof();

   Call after piping tokens through ffest_first, where the most recent
   token sent through must be EOS.

   20-Feb-91  JCB  1.1
      Put new EOF token in ffesta_tokens[0], not NULL, because too much
      code expects something there for error reporting and the like.  Also,
      do basically the same things ffest_second and ffesta_zero do for
      processing a statement (make and destroy pools, et cetera).  */

void
ffesta_eof (void)
{
  ffesta_tokens[0] = ffelex_token_new_eof ();

  ffesta_output_pool
    = malloc_pool_new ("Statement Output", ffe_pool_program_unit (), 1024);
  ffesta_scratch_pool
    = malloc_pool_new ("Statement Scratch", ffe_pool_program_unit (), 1024);
  ffesta_outpooldisp_ = FFESTA_pooldispDISCARD;

  ffestc_eof ();

  if (ffesta_tokens[0] != NULL)
    ffelex_token_kill (ffesta_tokens[0]);

  if (ffesta_output_pool != NULL)
    {
      if (ffesta_outpooldisp_ == FFESTA_pooldispDISCARD)
	malloc_pool_kill (ffesta_output_pool);
      ffesta_output_pool = NULL;
    }

  if (ffesta_scratch_pool != NULL)
    {
      malloc_pool_kill (ffesta_scratch_pool);
      ffesta_scratch_pool = NULL;
    }

  if (ffesta_label_token != NULL)
    {
      ffelex_token_kill (ffesta_label_token);
      ffesta_label_token = NULL;
    }

  if (ffe_is_ffedebug ())
    {
      ffestorag_report ();
    }
}

/* ffesta_ffebad_here_current_stmt -- ffebad_here with ptr to current stmt

   ffesta_ffebad_here_current_stmt(0);

   Outsiders can call this fn if they have no more convenient place to
   point to (via a token or pair of ffewhere objects) and they know a
   current, useful statement is being evaluted by ffest (i.e. they are
   being called from ffestb, ffestc, ffestd, ... functions).  */

void
ffesta_ffebad_here_current_stmt (ffebadIndex i)
{
  assert (ffesta_tokens[0] != NULL);
  ffebad_here (i, ffelex_token_where_line (ffesta_tokens[0]),
	       ffelex_token_where_column (ffesta_tokens[0]));
}

/* ffesta_ffebad_start -- Start a possibly inhibited error report

   if (ffesta_ffebad_start(FFEBAD_SOME_ERROR))
       {
       ffebad_here, ffebad_string ...;
       ffebad_finish();
       }

   Call if the error might indicate that ffest is evaluating the wrong
   statement form, instead of calling ffebad_start directly.  If ffest
   is choosing between forms, it will return FALSE, send an EOS/SEMICOLON
   token through as the next token (if the current one isn't already one
   of those), and try another possible form.  Otherwise, ffebad_start is
   called with the argument and TRUE returned.	*/

bool
ffesta_ffebad_start (ffebad errnum)
{
  if (!ffesta_is_inhibited_)
    {
      ffebad_start (errnum);
      return TRUE;
    }

  if (!ffesta_confirmed_current_)
    ffesta_current_shutdown_ = TRUE;

  return FALSE;
}

/* ffesta_first -- Parse the first token in a statement

   return ffesta_first;	 // to lexer.  */

ffelexHandler
ffesta_first (ffelexToken t)
{
  switch (ffelex_token_type (t))
    {
    case FFELEX_typeSEMICOLON:
    case FFELEX_typeEOS:
      ffesta_tokens[0] = ffelex_token_use (t);
      if (ffesta_label_token != NULL)
	{
	  ffebad_start (FFEBAD_LABEL_WITHOUT_STMT);
	  ffebad_here (0, ffelex_token_where_line (ffesta_label_token),
		       ffelex_token_where_column (ffesta_label_token));
	  ffebad_string (ffelex_token_text (ffesta_label_token));
	  ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t));
	  ffebad_finish ();
	}
      return (ffelexHandler) ffesta_zero (t);

    case FFELEX_typeNAME:
    case FFELEX_typeNAMES:
      ffesta_token_0_ = ffelex_token_use (t);
      ffesta_first_kw = ffestr_first (t);
      return (ffelexHandler) ffesta_second_;

    case FFELEX_typeNUMBER:
      if (ffesta_line_has_semicolons
	  && !ffe_is_free_form ()
	  && ffe_is_pedantic ())
	{
	  ffebad_start (FFEBAD_LABEL_WRONG_PLACE);
	  ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
	  ffebad_string (ffelex_token_text (t));
	  ffebad_finish ();
	}
      if (ffesta_label_token == NULL)
	{
	  ffesta_label_token = ffelex_token_use (t);
	  return (ffelexHandler) ffesta_first;
	}
      else
	{
	  ffebad_start (FFEBAD_EXTRA_LABEL_DEF);
	  ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
	  ffebad_string (ffelex_token_text (t));
	  ffebad_here (1, ffelex_token_where_line (ffesta_label_token),
		       ffelex_token_where_column (ffesta_label_token));
	  ffebad_string (ffelex_token_text (ffesta_label_token));
	  ffebad_finish ();

	  return (ffelexHandler) ffesta_first;
	}

    default:			/* Invalid first token. */
      ffesta_tokens[0] = ffelex_token_use (t);
      ffebad_start (FFEBAD_STMT_BEGINS_BAD);
      ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
      ffebad_finish ();
      return (ffelexHandler) ffelex_swallow_tokens (t,
					       (ffelexHandler) ffesta_zero);
    }
}

/* ffesta_init_0 -- Initialize for entire image invocation

   ffesta_init_0();

   Call just once per invocation of the compiler (not once per invocation
   of the front end).

   Gets memory for the list of possibles once and for all, since this
   list never gets larger than a certain size (FFESTA_maxPOSSIBLES_)
   and is not particularly large.  Initializes the array of pointers to
   this list.  Initializes the executable and nonexecutable lists.  */

void
ffesta_init_0 (void)
{
  ffestaPossible_ ptr;
  int i;

  ptr = malloc_new_kp (malloc_pool_image (), "FFEST possibles",
		       FFESTA_maxPOSSIBLES_ * sizeof (*ptr));

  for (i = 0; i < FFESTA_maxPOSSIBLES_; ++i)
    ffesta_possibles_[i] = ptr++;

  ffesta_possible_execs_.first = ffesta_possible_execs_.last
    = (ffestaPossible_) &ffesta_possible_execs_.first;
  ffesta_possible_nonexecs_.first = ffesta_possible_nonexecs_.last
    = (ffestaPossible_) &ffesta_possible_nonexecs_.first;
  ffesta_possible_execs_.nil = ffesta_possible_nonexecs_.nil = NULL;
}

/* ffesta_init_3 -- Initialize for any program unit

   ffesta_init_3();  */

void
ffesta_init_3 (void)
{
  ffesta_output_pool = NULL;	/* May be doing this just before reaching */
  ffesta_scratch_pool = NULL;	/* ffesta_zero or ffesta_two. */
  /* NOTE: we let the ffe_terminate_2 action of killing the program_unit pool
     handle the killing of the output and scratch pools for us, which is why
     we don't have a terminate_3 action to do so. */
  ffesta_construct_name = NULL;
  ffesta_label_token = NULL;
  ffesta_seen_first_exec = FALSE;
}

/* ffesta_is_inhibited -- Test whether the current possibility is inhibited

   if (!ffesta_is_inhibited())
       // implement the statement.

   Just make sure the current possibility has been confirmed.  If anyone
   really needs to test whether the current possibility is inhibited prior
   to confirming it, that indicates a need to begin statement processing
   before it is certain that the given possibility is indeed the statement
   to be processed.  As of this writing, there does not appear to be such
   a need.  If there is, then when confirming a statement would normally
   immediately disable the inhibition (whereas currently we leave the
   confirmed statement disabled until we've tried the other possibilities,
   to check for ambiguities), we must check to see if the possibility has
   already tested for inhibition prior to confirmation and, if so, maintain
   inhibition until the end of the statement (which may be forced right
   away) and then rerun the entire statement from the beginning.  Otherwise,
   initial calls to ffestb functions won't have been made, but subsequent
   calls (after confirmation) will, which is wrong.  Of course, this all
   applies only to those statements implemented via multiple calls to
   ffestb, although if a statement requiring only a single ffestb call
   tested for inhibition prior to confirmation, it would likely mean that
   the ffestb call would be completely dropped without this mechanism.	*/

bool
ffesta_is_inhibited (void)
{
  assert (ffesta_confirmed_current_ || ffesta_inhibit_confirmation_);
  return ffesta_is_inhibited_;
}

/* ffesta_ffebad_1p -- Issue diagnostic with one source character

   ffelexToken names_token;
   ffeTokenLength index;
   ffelexToken next_token;
   ffesta_ffebad_1p(FFEBAD_SOME_ERROR,names_token,index,next_token);

   Equivalent to "if (ffest_ffebad_start(FFEBAD_SOME_ERROR))" followed by
   sending one argument, the location of index with names_token, if TRUE is
   returned.  If index is equal to the length of names_token, meaning it
   points to the end of the token, then uses the location in next_token
   (which should be the token sent by the lexer after it sent names_token)
   instead.  */

void
ffesta_ffebad_1p (ffebad errnum, ffelexToken names_token, ffeTokenLength index,
		  ffelexToken next_token)
{
  ffewhereLine line;
  ffewhereColumn col;

  assert (index <= ffelex_token_length (names_token));

  if (ffesta_ffebad_start (errnum))
    {
      if (index == ffelex_token_length (names_token))
	{
	  assert (next_token != NULL);
	  line = ffelex_token_where_line (next_token);
	  col = ffelex_token_where_column (next_token);
	  ffebad_here (0, line, col);
	}
      else
	{
	  ffewhere_set_from_track (&line, &col,
				   ffelex_token_where_line (names_token),
				   ffelex_token_where_column (names_token),
				   ffelex_token_wheretrack (names_token),
				   index);
	  ffebad_here (0, line, col);
	  ffewhere_line_kill (line);
	  ffewhere_column_kill (col);
	}
      ffebad_finish ();
    }
}

void
ffesta_ffebad_1sp (ffebad errnum, const char *s, ffelexToken names_token,
		   ffeTokenLength index, ffelexToken next_token)
{
  ffewhereLine line;
  ffewhereColumn col;

  assert (index <= ffelex_token_length (names_token));

  if (ffesta_ffebad_start (errnum))
    {
      ffebad_string (s);
      if (index == ffelex_token_length (names_token))
	{
	  assert (next_token != NULL);
	  line = ffelex_token_where_line (next_token);
	  col = ffelex_token_where_column (next_token);
	  ffebad_here (0, line, col);
	}
      else
	{
	  ffewhere_set_from_track (&line, &col,
				   ffelex_token_where_line (names_token),
				   ffelex_token_where_column (names_token),
				   ffelex_token_wheretrack (names_token),
				   index);
	  ffebad_here (0, line, col);
	  ffewhere_line_kill (line);
	  ffewhere_column_kill (col);
	}
      ffebad_finish ();
    }
}

void
ffesta_ffebad_1st (ffebad errnum, const char *s, ffelexToken t)
{
  if (ffesta_ffebad_start (errnum))
    {
      ffebad_string (s);
      ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
      ffebad_finish ();
    }
}

/* ffesta_ffebad_1t -- Issue diagnostic with one source token

   ffelexToken t;
   ffesta_ffebad_1t(FFEBAD_SOME_ERROR,t);

   Equivalent to "if (ffesta_ffebad_start(FFEBAD_SOME_ERROR))" followed by
   sending one argument, the location of the token t, if TRUE is returned.  */

void
ffesta_ffebad_1t (ffebad errnum, ffelexToken t)
{
  if (ffesta_ffebad_start (errnum))
    {
      ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
      ffebad_finish ();
    }
}

void
ffesta_ffebad_2st (ffebad errnum, const char *s, ffelexToken t1, ffelexToken t2)
{
  if (ffesta_ffebad_start (errnum))
    {
      ffebad_string (s);
      ffebad_here (0, ffelex_token_where_line (t1), ffelex_token_where_column (t1));
      ffebad_here (1, ffelex_token_where_line (t2), ffelex_token_where_column (t2));
      ffebad_finish ();
    }
}

/* ffesta_ffebad_2t -- Issue diagnostic with two source tokens

   ffelexToken t1, t2;
   ffesta_ffebad_2t(FFEBAD_SOME_ERROR,t1,t2);

   Equivalent to "if (ffesta_ffebad_start(FFEBAD_SOME_ERROR))" followed by
   sending two argument, the locations of the tokens t1 and t2, if TRUE is
   returned.  */

void
ffesta_ffebad_2t (ffebad errnum, ffelexToken t1, ffelexToken t2)
{
  if (ffesta_ffebad_start (errnum))
    {
      ffebad_here (0, ffelex_token_where_line (t1), ffelex_token_where_column (t1));
      ffebad_here (1, ffelex_token_where_line (t2), ffelex_token_where_column (t2));
      ffebad_finish ();
    }
}

ffestaPooldisp
ffesta_outpooldisp (void)
{
  return ffesta_outpooldisp_;
}

void
ffesta_set_outpooldisp (ffestaPooldisp d)
{
  ffesta_outpooldisp_ = d;
}

/* Shut down current parsing possibility, but without bothering the
   user with a diagnostic if we're not inhibited.  */

void
ffesta_shutdown (void)
{
  if (ffesta_is_inhibited_)
    ffesta_current_shutdown_ = TRUE;
}

/* ffesta_two -- Deal with the first two tokens after a swallowed statement

   return ffesta_two(first_token,second_token);	 // to lexer.

   Like ffesta_zero, except instead of expecting an EOS or SEMICOLON, it
   expects the first two tokens of a statement that is part of another
   statement: the first two tokens of statement in "IF (expr) statement" or
   "WHERE (expr) statement", in particular.  The first token must be a NAME
   or NAMES, the second can be basically anything.  The statement type MUST
   be confirmed by now.

   If we're not inhibited, just handle things as if we were ffesta_zero
   and saw an EOS just before the two tokens.

   If we're inhibited, set ffesta_current_shutdown_ to shut down the current
   statement and continue with other possibilities, then (presumably) come
   back to this one for real when not inhibited.  */

ffelexHandler
ffesta_two (ffelexToken first, ffelexToken second)
{
#if FFESTA_ABORT_ON_CONFIRM_
  ffelexHandler next;
#endif

  assert ((ffelex_token_type (first) == FFELEX_typeNAME)
	  || (ffelex_token_type (first) == FFELEX_typeNAMES));
  assert (ffesta_tokens[0] != NULL);

  if (ffesta_is_inhibited_)	/* Oh, not really done with statement. */
    {
      ffesta_current_shutdown_ = TRUE;
      /* To catch the EOS on shutdown. */
      return (ffelexHandler) ffelex_swallow_tokens (second,
					       (ffelexHandler) ffesta_zero);
    }

  ffestw_display_state ();

  ffelex_token_kill (ffesta_tokens[0]);

  if (ffesta_output_pool != NULL)
    {
      if (ffesta_outpooldisp_ == FFESTA_pooldispDISCARD)
	malloc_pool_kill (ffesta_output_pool);
      ffesta_output_pool = NULL;
    }

  if (ffesta_scratch_pool != NULL)
    {
      malloc_pool_kill (ffesta_scratch_pool);
      ffesta_scratch_pool = NULL;
    }

  ffesta_reset_possibles_ ();
  ffesta_confirmed_current_ = FALSE;

  /* What happens here is somewhat interesting.	 We effectively derail the
     line of handlers for these two tokens, the first two in a statement, by
     setting a flag to TRUE.  This flag tells ffesta_save_ (or, conceivably,
     the lexer via ffesta_second_'s case 1:, where it has only one possible
     kind of statement -- someday this will be more likely, i.e. after
     confirmation causes an immediate switch to only the one context rather
     than just setting a flag and running through the remaining possibles to
     look for ambiguities) that the last two tokens it sent did not reach the
     truly desired targets (ffest_first and ffesta_second_) since that would
     otherwise attempt to recursively invoke ffesta_save_ in most cases,
     while the existing ffesta_save_ was still alive and making use of static
     (nonrecursive) variables.	Instead, ffesta_save_, upon seeing this flag
     set TRUE, sets it to FALSE and resubmits the two tokens copied here to
     ffest_first and, presumably, ffesta_second_, kills them, and returns the
     handler returned by the handler for the second token.  Thus, even though
     ffesta_save_ is still (likely to be) recursively invoked, the former
     invocation is past the use of any static variables possibly changed
     during the first-two-token invocation of the latter invocation. */

#if FFESTA_ABORT_ON_CONFIRM_
  /* Shouldn't be in ffesta_save_ at all here. */

  next = (ffelexHandler) ffesta_first (first);
  return (ffelexHandler) (*next) (second);
#else
  ffesta_twotokens_1_ = ffelex_token_use (first);
  ffesta_twotokens_2_ = ffelex_token_use (second);

  ffesta_is_two_into_statement_ = TRUE;
  return (ffelexHandler) ffesta_send_two_;	/* Shouldn't get called. */
#endif
}

/* ffesta_zero -- Deal with the end of a swallowed statement

   return ffesta_zero;	// to lexer.

   NOTICE that this code is COPIED, largely, into a
   similar function named ffesta_two that gets invoked in place of
   _zero_ when the end of the statement happens before EOS or SEMICOLON and
   to tokens into the next statement have been read (as is the case with the
   logical-IF and WHERE-stmt statements).  So any changes made here should
   probably be made in _two_ at the same time.	*/

ffelexHandler
ffesta_zero (ffelexToken t)
{
  assert ((ffelex_token_type (t) == FFELEX_typeEOS)
	  || (ffelex_token_type (t) == FFELEX_typeSEMICOLON));
  assert (ffesta_tokens[0] != NULL);

  if (ffesta_is_inhibited_)
    ffesymbol_retract (TRUE);
  else
    ffestw_display_state ();

  /* Do CONTINUE if nothing else.  This is done specifically so that "IF
     (...) BLAH" causes the same things to happen as if "IF (...) CONTINUE"
     was done, so that tracking of labels and such works.  (Try a small
     program like "DO 10 ...", "IF (...) BLAH", "10 CONTINUE", "END".)

     But it turns out that just testing "!ffesta_confirmed_current_"
     isn't enough, because then typing "GOTO" instead of "BLAH" above
     doesn't work -- the statement is confirmed (we know the user
     attempted a GOTO) but ffestc hasn't seen it.  So, instead, just
     always tell ffestc to do "any" statement it needs to reset.  */

  if (!ffesta_is_inhibited_
      && ffesta_seen_first_exec)
    {
      ffestc_any ();
    }

  ffelex_token_kill (ffesta_tokens[0]);

  if (ffesta_is_inhibited_)	/* Oh, not really done with statement. */
    return (ffelexHandler) ffesta_zero;	/* Call me again when done! */

  if (ffesta_output_pool != NULL)
    {
      if (ffesta_outpooldisp_ == FFESTA_pooldispDISCARD)
	malloc_pool_kill (ffesta_output_pool);
      ffesta_output_pool = NULL;
    }

  if (ffesta_scratch_pool != NULL)
    {
      malloc_pool_kill (ffesta_scratch_pool);
      ffesta_scratch_pool = NULL;
    }

  ffesta_reset_possibles_ ();
  ffesta_confirmed_current_ = FALSE;

  if (ffelex_token_type (t) == FFELEX_typeSEMICOLON)
    {
      ffesta_line_has_semicolons = TRUE;
      if (ffe_is_pedantic_not_90 ())
	{
	  ffebad_start (FFEBAD_SEMICOLON);
	  ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
	  ffebad_finish ();
	}
    }
  else
    ffesta_line_has_semicolons = FALSE;

  if (ffesta_label_token != NULL)
    {
      ffelex_token_kill (ffesta_label_token);
      ffesta_label_token = NULL;
    }

  if (ffe_is_ffedebug ())
    {
      ffestorag_report ();
    }

  ffelex_set_names (TRUE);
  return (ffelexHandler) ffesta_first;
}
