[BACK]Return to nfa.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Diff for /src/usr.bin/lex/nfa.c between version 1.9 and 1.10

version 1.9, 2003/06/04 17:34:44 version 1.10, 2015/11/19 19:43:40
Line 2 
Line 2 
   
 /* nfa - NFA construction routines */  /* nfa - NFA construction routines */
   
 /*-  /*  Copyright (c) 1990 The Regents of the University of California. */
  * Copyright (c) 1990 The Regents of the University of California.  /*  All rights reserved. */
  * All rights reserved.  
  *  
  * This code is derived from software contributed to Berkeley by  
  * Vern Paxson.  
  *  
  * The United States Government has rights in this work pursuant  
  * to contract no. DE-AC03-76SF00098 between the United States  
  * Department of Energy and the University of California.  
  *  
  * Redistribution and use in source and binary forms, with or without  
  * modification, are permitted provided that the following conditions  
  * are met:  
  *  
  * 1. Redistributions of source code must retain the above copyright  
  *    notice, this list of conditions and the following disclaimer.  
  * 2. Redistributions in binary form must reproduce the above copyright  
  *    notice, this list of conditions and the following disclaimer in the  
  *    documentation and/or other materials provided with the distribution.  
  *  
  * Neither the name of the University nor the names of its contributors  
  * may be used to endorse or promote products derived from this software  
  * without specific prior written permission.  
  *  
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR  
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED  
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
  * PURPOSE.  
  */  
   
 /* $Header$ */  /*  This code is derived from software contributed to Berkeley by */
   /*  Vern Paxson. */
   
   /*  The United States Government has rights in this work pursuant */
   /*  to contract no. DE-AC03-76SF00098 between the United States */
   /*  Department of Energy and the University of California. */
   
   /*  This file is part of flex. */
   
   /*  Redistribution and use in source and binary forms, with or without */
   /*  modification, are permitted provided that the following conditions */
   /*  are met: */
   
   /*  1. Redistributions of source code must retain the above copyright */
   /*     notice, this list of conditions and the following disclaimer. */
   /*  2. Redistributions in binary form must reproduce the above copyright */
   /*     notice, this list of conditions and the following disclaimer in the */
   /*     documentation and/or other materials provided with the distribution. */
   
   /*  Neither the name of the University nor the names of its contributors */
   /*  may be used to endorse or promote products derived from this software */
   /*  without specific prior written permission. */
   
   /*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
   /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
   /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
   /*  PURPOSE. */
   
 #include "flexdef.h"  #include "flexdef.h"
   
   
 /* declare functions that have forward references */  /* declare functions that have forward references */
   
 int dupmachine PROTO((int));  int dupmachine PROTO ((int));
 void mkxtion PROTO((int, int));  void mkxtion PROTO ((int, int));
   
   
 /* add_accept - add an accepting state to a machine  /* add_accept - add an accepting state to a machine
Line 49 
Line 47 
  * accepting_number becomes mach's accepting number.   * accepting_number becomes mach's accepting number.
  */   */
   
 void add_accept( mach, accepting_number )  void    add_accept (mach, accepting_number)
 int mach, accepting_number;       int     mach, accepting_number;
         {  {
         /* Hang the accepting number off an epsilon state.  if it is associated          /* Hang the accepting number off an epsilon state.  if it is associated
          * with a state that has a non-epsilon out-transition, then the state           * with a state that has a non-epsilon out-transition, then the state
          * will accept BEFORE it makes that transition, i.e., one character           * will accept BEFORE it makes that transition, i.e., one character
          * too soon.           * too soon.
          */           */
   
         if ( transchar[finalst[mach]] == SYM_EPSILON )          if (transchar[finalst[mach]] == SYM_EPSILON)
                 accptnum[finalst[mach]] = accepting_number;                  accptnum[finalst[mach]] = accepting_number;
   
         else          else {
                 {                  int     astate = mkstate (SYM_EPSILON);
                 int astate = mkstate( SYM_EPSILON );  
                 accptnum[astate] = accepting_number;                  accptnum[astate] = accepting_number;
                 (void) link_machines( mach, astate );                  (void) link_machines (mach, astate);
                 }  
         }          }
   }
   
   
 /* copysingl - make a given number of copies of a singleton machine  /* copysingl - make a given number of copies of a singleton machine
Line 81 
Line 79 
  *     num    - the number of copies of singl to be present in newsng   *     num    - the number of copies of singl to be present in newsng
  */   */
   
 int copysingl( singl, num )  int     copysingl (singl, num)
 int singl, num;       int     singl, num;
         {  {
         int copy, i;          int     copy, i;
   
         copy = mkstate( SYM_EPSILON );          copy = mkstate (SYM_EPSILON);
   
         for ( i = 1; i <= num; ++i )          for (i = 1; i <= num; ++i)
                 copy = link_machines( copy, dupmachine( singl ) );                  copy = link_machines (copy, dupmachine (singl));
   
         return copy;          return copy;
         }  }
   
   
 /* dumpnfa - debugging routine to write out an nfa */  /* dumpnfa - debugging routine to write out an nfa */
   
 void dumpnfa( state1 )  void    dumpnfa (state1)
 int state1;       int     state1;
   
         {  {
         int sym, tsp1, tsp2, anum, ns;          int     sym, tsp1, tsp2, anum, ns;
   
         fprintf( stderr,          fprintf (stderr,
         _( "\n\n********** beginning dump of nfa with start state %d\n" ),                   _
                 state1 );                   ("\n\n********** beginning dump of nfa with start state %d\n"),
                    state1);
   
         /* We probably should loop starting at firstst[state1] and going to          /* We probably should loop starting at firstst[state1] and going to
          * lastst[state1], but they're not maintained properly when we "or"           * lastst[state1], but they're not maintained properly when we "or"
Line 114 
Line 113 
          */           */
   
         /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */          /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */
         for ( ns = 1; ns <= lastnfa; ++ns )          for (ns = 1; ns <= lastnfa; ++ns) {
                 {                  fprintf (stderr, _("state # %4d\t"), ns);
                 fprintf( stderr, _( "state # %4d\t" ), ns );  
   
                 sym = transchar[ns];                  sym = transchar[ns];
                 tsp1 = trans1[ns];                  tsp1 = trans1[ns];
                 tsp2 = trans2[ns];                  tsp2 = trans2[ns];
                 anum = accptnum[ns];                  anum = accptnum[ns];
   
                 fprintf( stderr, "%3d:  %4d, %4d", sym, tsp1, tsp2 );                  fprintf (stderr, "%3d:  %4d, %4d", sym, tsp1, tsp2);
   
                 if ( anum != NIL )                  if (anum != NIL)
                         fprintf( stderr, "  [%d]", anum );                          fprintf (stderr, "  [%d]", anum);
   
                 fprintf( stderr, "\n" );                  fprintf (stderr, "\n");
                 }  
   
         fprintf( stderr, _( "********** end of dump\n" ) );  
         }          }
   
           fprintf (stderr, _("********** end of dump\n"));
   }
   
   
 /* dupmachine - make a duplicate of a given machine  /* dupmachine - make a duplicate of a given machine
  *   *
  * synopsis   * synopsis
Line 152 
Line 150 
  * states accessible by the arrays firstst and lastst   * states accessible by the arrays firstst and lastst
  */   */
   
 int dupmachine( mach )  int     dupmachine (mach)
 int mach;       int     mach;
         {  {
         int i, init, state_offset;          int     i, init, state_offset;
         int state = 0;          int     state = 0;
         int last = lastst[mach];          int     last = lastst[mach];
   
         for ( i = firstst[mach]; i <= last; ++i )          for (i = firstst[mach]; i <= last; ++i) {
                 {                  state = mkstate (transchar[i]);
                 state = mkstate( transchar[i] );  
   
                 if ( trans1[i] != NO_TRANSITION )                  if (trans1[i] != NO_TRANSITION) {
                         {                          mkxtion (finalst[state], trans1[i] + state - i);
                         mkxtion( finalst[state], trans1[i] + state - i );  
   
                         if ( transchar[i] == SYM_EPSILON &&                          if (transchar[i] == SYM_EPSILON &&
                              trans2[i] != NO_TRANSITION )                              trans2[i] != NO_TRANSITION)
                                 mkxtion( finalst[state],                                          mkxtion (finalst[state],
                                         trans2[i] + state - i );                                                   trans2[i] + state - i);
                         }                  }
   
                 accptnum[state] = accptnum[i];                  accptnum[state] = accptnum[i];
                 }          }
   
         if ( state == 0 )          if (state == 0)
                 flexfatal( _( "empty machine in dupmachine()" ) );                  flexfatal (_("empty machine in dupmachine()"));
   
         state_offset = state - i + 1;          state_offset = state - i + 1;
   
Line 187 
Line 183 
         lastst[init] = lastst[mach] + state_offset;          lastst[init] = lastst[mach] + state_offset;
   
         return init;          return init;
         }  }
   
   
 /* finish_rule - finish up the processing for a rule  /* finish_rule - finish up the processing for a rule
Line 202 
Line 198 
  * context has variable length.   * context has variable length.
  */   */
   
 void finish_rule( mach, variable_trail_rule, headcnt, trailcnt )  void    finish_rule (mach, variable_trail_rule, headcnt, trailcnt,
 int mach, variable_trail_rule, headcnt, trailcnt;                       pcont_act)
         {       int     mach, variable_trail_rule, headcnt, trailcnt, pcont_act;
         char action_text[MAXLINE];  {
           char    action_text[MAXLINE];
   
         add_accept( mach, num_rules );          add_accept (mach, num_rules);
   
         /* We did this in new_rule(), but it often gets the wrong          /* We did this in new_rule(), but it often gets the wrong
          * number because we do it before we start parsing the current rule.           * number because we do it before we start parsing the current rule.
Line 217 
Line 214 
         /* If this is a continued action, then the line-number has already          /* If this is a continued action, then the line-number has already
          * been updated, giving us the wrong number.           * been updated, giving us the wrong number.
          */           */
         if ( continued_action )          if (continued_action)
                 --rule_linenum[num_rules];                  --rule_linenum[num_rules];
   
         snprintf( action_text, sizeof action_text, "case %d:\n", num_rules );  
         add_action( action_text );  
   
         if ( variable_trail_rule )          /* If the previous rule was continued action, then we inherit the
                 {           * previous newline flag, possibly overriding the current one.
            */
           if (pcont_act && rule_has_nl[num_rules - 1])
                   rule_has_nl[num_rules] = true;
   
           snprintf (action_text, sizeof(action_text), "case %d:\n", num_rules);
           add_action (action_text);
           if (rule_has_nl[num_rules]) {
                   snprintf (action_text, sizeof(action_text), "/* rule %d can match eol */\n",
                            num_rules);
                   add_action (action_text);
           }
   
   
           if (variable_trail_rule) {
                 rule_type[num_rules] = RULE_VARIABLE;                  rule_type[num_rules] = RULE_VARIABLE;
   
                 if ( performance_report > 0 )                  if (performance_report > 0)
                         fprintf( stderr,                          fprintf (stderr,
                         _( "Variable trailing context rule at line %d\n" ),                                   _
                                 rule_linenum[num_rules] );                                   ("Variable trailing context rule at line %d\n"),
                                    rule_linenum[num_rules]);
   
                 variable_trailing_context_rules = true;                  variable_trailing_context_rules = true;
                 }          }
   
         else          else {
                 {  
                 rule_type[num_rules] = RULE_NORMAL;                  rule_type[num_rules] = RULE_NORMAL;
   
                 if ( headcnt > 0 || trailcnt > 0 )                  if (headcnt > 0 || trailcnt > 0) {
                         {  
                         /* Do trailing context magic to not match the trailing                          /* Do trailing context magic to not match the trailing
                          * characters.                           * characters.
                          */                           */
                         char *scanner_cp = "yy_c_buf_p = yy_cp";                          char   *scanner_cp = "YY_G(yy_c_buf_p) = yy_cp";
                         char *scanner_bp = "yy_bp";                          char   *scanner_bp = "yy_bp";
   
                         add_action(                          add_action
         "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" );                                  ("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */\n");
   
                         if ( headcnt > 0 )                          if (headcnt > 0) {
                                 {                                  if (rule_has_nl[num_rules]) {
                                 snprintf( action_text, sizeof action_text,                                          snprintf (action_text, sizeof(action_text),
                                         "%s = %s + %d;\n",                                                  "YY_LINENO_REWIND_TO(%s + %d);\n", scanner_bp, headcnt);
                                         scanner_cp, scanner_bp, headcnt );                                          add_action (action_text);
                                 add_action( action_text );  
                                 }                                  }
                                   snprintf (action_text, sizeof(action_text), "%s = %s + %d;\n",
                                            scanner_cp, scanner_bp, headcnt);
                                   add_action (action_text);
                           }
   
                         else                          else {
                                 {                                  if (rule_has_nl[num_rules]) {
                                 snprintf( action_text, sizeof action_text,                                          snprintf (action_text, sizeof(action_text),
                                         "%s -= %d;\n",                                                   "YY_LINENO_REWIND_TO(yy_cp - %d);\n", trailcnt);
                                         scanner_cp, trailcnt );                                          add_action (action_text);
                                 add_action( action_text );  
                                 }                                  }
   
                         add_action(                                  snprintf (action_text, sizeof(action_text), "%s -= %d;\n",
                         "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" );                                           scanner_cp, trailcnt);
                                   add_action (action_text);
                         }                          }
   
                           add_action
                                   ("YY_DO_BEFORE_ACTION; /* set up yytext again */\n");
                 }                  }
           }
   
         /* Okay, in the action code at this point yytext and yyleng have          /* Okay, in the action code at this point yytext and yyleng have
          * their proper final values for this rule, so here's the point           * their proper final values for this rule, so here's the point
          * to do any user action.  But don't do it for continued actions,           * to do any user action.  But don't do it for continued actions,
          * as that'll result in multiple YY_RULE_SETUP's.           * as that'll result in multiple YY_RULE_SETUP's.
          */           */
         if ( ! continued_action )          if (!continued_action)
                 add_action( "YY_RULE_SETUP\n" );                  add_action ("YY_RULE_SETUP\n");
   
         line_directive_out( (FILE *) 0, 1 );          line_directive_out ((FILE *) 0, 1);
         }  }
   
   
 /* link_machines - connect two machines together  /* link_machines - connect two machines together
Line 299 
Line 314 
  *  FIRST is set to new by the operation.  last is unmolested.   *  FIRST is set to new by the operation.  last is unmolested.
  */   */
   
 int link_machines( first, last )  int     link_machines (first, last)
 int first, last;       int     first, last;
         {  {
         if ( first == NIL )          if (first == NIL)
                 return last;                  return last;
   
         else if ( last == NIL )          else if (last == NIL)
                 return first;                  return first;
   
         else          else {
                 {                  mkxtion (finalst[first], last);
                 mkxtion( finalst[first], last );  
                 finalst[first] = finalst[last];                  finalst[first] = finalst[last];
                 lastst[first] = MAX( lastst[first], lastst[last] );                  lastst[first] = MAX (lastst[first], lastst[last]);
                 firstst[first] = MIN( firstst[first], firstst[last] );                  firstst[first] = MIN (firstst[first], firstst[last]);
   
                 return first;                  return first;
                 }  
         }          }
   }
   
   
 /* mark_beginning_as_normal - mark each "beginning" state in a machine  /* mark_beginning_as_normal - mark each "beginning" state in a machine
Line 327 
Line 341 
  * The "beginning" states are the epsilon closure of the first state   * The "beginning" states are the epsilon closure of the first state
  */   */
   
 void mark_beginning_as_normal( mach )  void    mark_beginning_as_normal (mach)
 int mach;       int mach;
         {  {
         switch ( state_type[mach] )          switch (state_type[mach]) {
                 {          case STATE_NORMAL:
                 case STATE_NORMAL:                  /* Oh, we've already visited here. */
                         /* Oh, we've already visited here. */                  return;
                         return;  
   
                 case STATE_TRAILING_CONTEXT:          case STATE_TRAILING_CONTEXT:
                         state_type[mach] = STATE_NORMAL;                  state_type[mach] = STATE_NORMAL;
   
                         if ( transchar[mach] == SYM_EPSILON )                  if (transchar[mach] == SYM_EPSILON) {
                                 {                          if (trans1[mach] != NO_TRANSITION)
                                 if ( trans1[mach] != NO_TRANSITION )                                  mark_beginning_as_normal (trans1[mach]);
                                         mark_beginning_as_normal(  
                                                 trans1[mach] );  
   
                                 if ( trans2[mach] != NO_TRANSITION )                          if (trans2[mach] != NO_TRANSITION)
                                         mark_beginning_as_normal(                                  mark_beginning_as_normal (trans2[mach]);
                                                 trans2[mach] );  
                                 }  
                         break;  
   
                 default:  
                         flexerror(  
                         _( "bad state type in mark_beginning_as_normal()" ) );  
                         break;  
                 }                  }
                   break;
   
           default:
                   flexerror (_
                              ("bad state type in mark_beginning_as_normal()"));
                   break;
         }          }
   }
   
   
 /* mkbranch - make a machine that branches to two machines  /* mkbranch - make a machine that branches to two machines
Line 373 
Line 383 
  * more mkbranch's.  Compare with mkor()   * more mkbranch's.  Compare with mkor()
  */   */
   
 int mkbranch( first, second )  int     mkbranch (first, second)
 int first, second;       int     first, second;
         {  {
         int eps;          int     eps;
   
         if ( first == NO_TRANSITION )          if (first == NO_TRANSITION)
                 return second;                  return second;
   
         else if ( second == NO_TRANSITION )          else if (second == NO_TRANSITION)
                 return first;                  return first;
   
         eps = mkstate( SYM_EPSILON );          eps = mkstate (SYM_EPSILON);
   
         mkxtion( eps, first );          mkxtion (eps, first);
         mkxtion( eps, second );          mkxtion (eps, second);
   
         return eps;          return eps;
         }  }
   
   
 /* mkclos - convert a machine into a closure  /* mkclos - convert a machine into a closure
Line 401 
Line 411 
  * new - a new state which matches the closure of "state"   * new - a new state which matches the closure of "state"
  */   */
   
 int mkclos( state )  int     mkclos (state)
 int state;       int     state;
         {  {
         return mkopt( mkposcl( state ) );          return mkopt (mkposcl (state));
         }  }
   
   
 /* mkopt - make a machine optional  /* mkopt - make a machine optional
Line 422 
Line 432 
  *     2. mach is destroyed by the call   *     2. mach is destroyed by the call
  */   */
   
 int mkopt( mach )  int     mkopt (mach)
 int mach;       int     mach;
         {  {
         int eps;          int     eps;
   
         if ( ! SUPER_FREE_EPSILON(finalst[mach]) )          if (!SUPER_FREE_EPSILON (finalst[mach])) {
                 {                  eps = mkstate (SYM_EPSILON);
                 eps = mkstate( SYM_EPSILON );                  mach = link_machines (mach, eps);
                 mach = link_machines( mach, eps );          }
                 }  
   
         /* Can't skimp on the following if FREE_EPSILON(mach) is true because          /* Can't skimp on the following if FREE_EPSILON(mach) is true because
          * some state interior to "mach" might point back to the beginning           * some state interior to "mach" might point back to the beginning
          * for a closure.           * for a closure.
          */           */
         eps = mkstate( SYM_EPSILON );          eps = mkstate (SYM_EPSILON);
         mach = link_machines( eps, mach );          mach = link_machines (eps, mach);
   
         mkxtion( mach, finalst[mach] );          mkxtion (mach, finalst[mach]);
   
         return mach;          return mach;
         }  }
   
   
 /* mkor - make a machine that matches either one of two machines  /* mkor - make a machine that matches either one of two machines
Line 460 
Line 469 
  * the number of epsilon states needed   * the number of epsilon states needed
  */   */
   
 int mkor( first, second )  int     mkor (first, second)
 int first, second;       int     first, second;
         {  {
         int eps, orend;          int     eps, orend;
   
         if ( first == NIL )          if (first == NIL)
                 return second;                  return second;
   
         else if ( second == NIL )          else if (second == NIL)
                 return first;                  return first;
   
         else          else {
                 {  
                 /* See comment in mkopt() about why we can't use the first                  /* See comment in mkopt() about why we can't use the first
                  * state of "first" or "second" if they satisfy "FREE_EPSILON".                   * state of "first" or "second" if they satisfy "FREE_EPSILON".
                  */                   */
                 eps = mkstate( SYM_EPSILON );                  eps = mkstate (SYM_EPSILON);
   
                 first = link_machines( eps, first );                  first = link_machines (eps, first);
   
                 mkxtion( first, second );                  mkxtion (first, second);
   
                 if ( SUPER_FREE_EPSILON(finalst[first]) &&                  if (SUPER_FREE_EPSILON (finalst[first]) &&
                      accptnum[finalst[first]] == NIL )                      accptnum[finalst[first]] == NIL) {
                         {  
                         orend = finalst[first];                          orend = finalst[first];
                         mkxtion( finalst[second], orend );                          mkxtion (finalst[second], orend);
                         }                  }
   
                 else if ( SUPER_FREE_EPSILON(finalst[second]) &&                  else if (SUPER_FREE_EPSILON (finalst[second]) &&
                           accptnum[finalst[second]] == NIL )                           accptnum[finalst[second]] == NIL) {
                         {  
                         orend = finalst[second];                          orend = finalst[second];
                         mkxtion( finalst[first], orend );                          mkxtion (finalst[first], orend);
                         }                  }
   
                 else                  else {
                         {                          eps = mkstate (SYM_EPSILON);
                         eps = mkstate( SYM_EPSILON );  
   
                         first = link_machines( first, eps );                          first = link_machines (first, eps);
                         orend = finalst[first];                          orend = finalst[first];
   
                         mkxtion( finalst[second], orend );                          mkxtion (finalst[second], orend);
                         }  
                 }                  }
           }
   
         finalst[first] = orend;          finalst[first] = orend;
         return first;          return first;
         }  }
   
   
 /* mkposcl - convert a machine into a positive closure  /* mkposcl - convert a machine into a positive closure
Line 520 
Line 525 
  *    new - a machine matching the positive closure of "state"   *    new - a machine matching the positive closure of "state"
  */   */
   
 int mkposcl( state )  int     mkposcl (state)
 int state;       int     state;
         {  {
         int eps;          int     eps;
   
         if ( SUPER_FREE_EPSILON(finalst[state]) )          if (SUPER_FREE_EPSILON (finalst[state])) {
                 {                  mkxtion (finalst[state], state);
                 mkxtion( finalst[state], state );  
                 return state;                  return state;
                 }          }
   
         else          else {
                 {                  eps = mkstate (SYM_EPSILON);
                 eps = mkstate( SYM_EPSILON );                  mkxtion (eps, state);
                 mkxtion( eps, state );                  return link_machines (state, eps);
                 return link_machines( state, eps );  
                 }  
         }          }
   }
   
   
 /* mkrep - make a replicated machine  /* mkrep - make a replicated machine
Line 549 
Line 552 
  *          number of times to "ub" number of times   *          number of times to "ub" number of times
  *   *
  * note   * note
  *   if "ub" is INFINITY then "new" matches "lb" or more occurrences of "mach"   *   if "ub" is INFINITE_REPEAT then "new" matches "lb" or more occurrences of "mach"
  */   */
   
 int mkrep( mach, lb, ub )  int     mkrep (mach, lb, ub)
 int mach, lb, ub;       int     mach, lb, ub;
         {  {
         int base_mach, tail, copy, i;          int     base_mach, tail, copy, i;
   
         base_mach = copysingl( mach, lb - 1 );          base_mach = copysingl (mach, lb - 1);
   
         if ( ub == INFINITY )          if (ub == INFINITE_REPEAT) {
                 {                  copy = dupmachine (mach);
                 copy = dupmachine( mach );                  mach = link_machines (mach,
                 mach = link_machines( mach,                                        link_machines (base_mach,
                 link_machines( base_mach, mkclos( copy ) ) );                                                       mkclos (copy)));
                 }          }
   
         else          else {
                 {                  tail = mkstate (SYM_EPSILON);
                 tail = mkstate( SYM_EPSILON );  
   
                 for ( i = lb; i < ub; ++i )                  for (i = lb; i < ub; ++i) {
                         {                          copy = dupmachine (mach);
                         copy = dupmachine( mach );                          tail = mkopt (link_machines (copy, tail));
                         tail = mkopt( link_machines( copy, tail ) );  
                         }  
   
                 mach = link_machines( mach, link_machines( base_mach, tail ) );  
                 }                  }
   
         return mach;                  mach =
                           link_machines (mach,
                                          link_machines (base_mach, tail));
         }          }
   
           return mach;
   }
   
   
 /* mkstate - create a state with a transition on a given symbol  /* mkstate - create a state with a transition on a given symbol
  *   *
  * synopsis   * synopsis
Line 599 
Line 602 
  * that it admittedly is)   * that it admittedly is)
  */   */
   
 int mkstate( sym )  int     mkstate (sym)
 int sym;       int     sym;
         {  {
         if ( ++lastnfa >= current_mns )          if (++lastnfa >= current_mns) {
                 {                  if ((current_mns += MNS_INCREMENT) >= maximum_mns)
                 if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS )                          lerrif (_
                         lerrif(                                  ("input rules are too complicated (>= %d NFA states)"),
                 _( "input rules are too complicated (>= %d NFA states)" ),  current_mns);
                                 current_mns );  
   
                 ++num_reallocs;                  ++num_reallocs;
   
                 firstst = reallocate_integer_array( firstst, current_mns );                  firstst = reallocate_integer_array (firstst, current_mns);
                 lastst = reallocate_integer_array( lastst, current_mns );                  lastst = reallocate_integer_array (lastst, current_mns);
                 finalst = reallocate_integer_array( finalst, current_mns );                  finalst = reallocate_integer_array (finalst, current_mns);
                 transchar = reallocate_integer_array( transchar, current_mns );                  transchar =
                 trans1 = reallocate_integer_array( trans1, current_mns );                          reallocate_integer_array (transchar, current_mns);
                 trans2 = reallocate_integer_array( trans2, current_mns );                  trans1 = reallocate_integer_array (trans1, current_mns);
                 accptnum = reallocate_integer_array( accptnum, current_mns );                  trans2 = reallocate_integer_array (trans2, current_mns);
                   accptnum =
                           reallocate_integer_array (accptnum, current_mns);
                 assoc_rule =                  assoc_rule =
                         reallocate_integer_array( assoc_rule, current_mns );                          reallocate_integer_array (assoc_rule, current_mns);
                 state_type =                  state_type =
                         reallocate_integer_array( state_type, current_mns );                          reallocate_integer_array (state_type, current_mns);
                 }          }
   
         firstst[lastnfa] = lastnfa;          firstst[lastnfa] = lastnfa;
         finalst[lastnfa] = lastnfa;          finalst[lastnfa] = lastnfa;
Line 643 
Line 647 
          * elsewhere in the input).           * elsewhere in the input).
          */           */
   
         if ( sym < 0 )          if (sym < 0) {
                 {  
                 /* We don't have to update the equivalence classes since                  /* We don't have to update the equivalence classes since
                  * that was already done when the ccl was created for the                   * that was already done when the ccl was created for the
                  * first time.                   * first time.
                  */                   */
                 }          }
   
         else if ( sym == SYM_EPSILON )          else if (sym == SYM_EPSILON)
                 ++numeps;                  ++numeps;
   
         else          else {
                 {                  check_char (sym);
                 check_char( sym );  
   
                 if ( useecs )                  if (useecs)
                         /* Map NUL's to csize. */                          /* Map NUL's to csize. */
                         mkechar( sym ? sym : csize, nextecm, ecgroup );                          mkechar (sym ? sym : csize, nextecm, ecgroup);
                 }          }
   
         return lastnfa;          return lastnfa;
         }  }
   
   
 /* mkxtion - make a transition from one state to another  /* mkxtion - make a transition from one state to another
Line 677 
Line 679 
  *     stateto   - the state to which the transition is to be made   *     stateto   - the state to which the transition is to be made
  */   */
   
 void mkxtion( statefrom, stateto )  void    mkxtion (statefrom, stateto)
 int statefrom, stateto;       int     statefrom, stateto;
         {  {
         if ( trans1[statefrom] == NO_TRANSITION )          if (trans1[statefrom] == NO_TRANSITION)
                 trans1[statefrom] = stateto;                  trans1[statefrom] = stateto;
   
         else if ( (transchar[statefrom] != SYM_EPSILON) ||          else if ((transchar[statefrom] != SYM_EPSILON) ||
                   (trans2[statefrom] != NO_TRANSITION) )                   (trans2[statefrom] != NO_TRANSITION))
                 flexfatal( _( "found too many transitions in mkxtion()" ) );                  flexfatal (_("found too many transitions in mkxtion()"));
   
         else          else {                  /* second out-transition for an epsilon state */
                 { /* second out-transition for an epsilon state */  
                 ++eps2;                  ++eps2;
                 trans2[statefrom] = stateto;                  trans2[statefrom] = stateto;
                 }  
         }          }
   }
   
 /* new_rule - initialize for a new rule */  /* new_rule - initialize for a new rule */
   
 void new_rule()  void    new_rule ()
         {  {
         if ( ++num_rules >= current_max_rules )          if (++num_rules >= current_max_rules) {
                 {  
                 ++num_reallocs;                  ++num_reallocs;
                 current_max_rules += MAX_RULES_INCREMENT;                  current_max_rules += MAX_RULES_INCREMENT;
                 rule_type = reallocate_integer_array( rule_type,                  rule_type = reallocate_integer_array (rule_type,
                                                         current_max_rules );                                                        current_max_rules);
                 rule_linenum = reallocate_integer_array( rule_linenum,                  rule_linenum = reallocate_integer_array (rule_linenum,
                                                         current_max_rules );                                                           current_max_rules);
                 rule_useful = reallocate_integer_array( rule_useful,                  rule_useful = reallocate_integer_array (rule_useful,
                                                         current_max_rules );                                                          current_max_rules);
                 }                  rule_has_nl = reallocate_bool_array (rule_has_nl,
                                                        current_max_rules);
           }
   
         if ( num_rules > MAX_RULE )          if (num_rules > MAX_RULE)
                 lerrif( _( "too many rules (> %d)!" ), MAX_RULE );                  lerrif (_("too many rules (> %d)!"), MAX_RULE);
   
         rule_linenum[num_rules] = linenum;          rule_linenum[num_rules] = linenum;
         rule_useful[num_rules] = false;          rule_useful[num_rules] = false;
         }          rule_has_nl[num_rules] = false;
   }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10