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

Diff for /src/usr.bin/lex/dfa.c between version 1.6 and 1.7

version 1.6, 2003/06/04 17:34:44 version 1.7, 2015/11/19 19:43:40
Line 2 
Line 2 
   
 /* dfa - DFA construction routines */  /* dfa - DFA 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. */
   
 #include "flexdef.h"  /*  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. */
   
   #include "flexdef.h"
   #include "tables.h"
   
 /* declare functions that have forward references */  /* declare functions that have forward references */
   
 void dump_associated_rules PROTO((FILE*, int));  void dump_associated_rules PROTO ((FILE *, int));
 void dump_transitions PROTO((FILE*, int[]));  void dump_transitions PROTO ((FILE *, int[]));
 void sympartition PROTO((int[], int, int[], int[]));  void sympartition PROTO ((int[], int, int[], int[]));
 int symfollowset PROTO((int[], int, int, int[]));  int symfollowset PROTO ((int[], int, int, int[]));
   
   
 /* check_for_backing_up - check a DFA state for backing up  /* check_for_backing_up - check a DFA state for backing up
Line 55 
Line 51 
  * indexed by equivalence class.   * indexed by equivalence class.
  */   */
   
 void check_for_backing_up( ds, state )  void check_for_backing_up (ds, state)
 int ds;       int ds;
 int state[];       int state[];
         {  {
         if ( (reject && ! dfaacc[ds].dfaacc_set) ||          if ((reject && !dfaacc[ds].dfaacc_set) || (!reject && !dfaacc[ds].dfaacc_state)) {      /* state is non-accepting */
              (! reject && ! dfaacc[ds].dfaacc_state) )  
                 { /* state is non-accepting */  
                 ++num_backing_up;                  ++num_backing_up;
   
                 if ( backing_up_report )                  if (backing_up_report) {
                         {                          fprintf (backing_up_file,
                         fprintf( backing_up_file,                                   _("State #%d is non-accepting -\n"), ds);
                                 _( "State #%d is non-accepting -\n" ), ds );  
   
                         /* identify the state */                          /* identify the state */
                         dump_associated_rules( backing_up_file, ds );                          dump_associated_rules (backing_up_file, ds);
   
                         /* Now identify it further using the out- and                          /* Now identify it further using the out- and
                          * jam-transitions.                           * jam-transitions.
                          */                           */
                         dump_transitions( backing_up_file, state );                          dump_transitions (backing_up_file, state);
   
                         putc( '\n', backing_up_file );                          putc ('\n', backing_up_file);
                         }  
                 }                  }
         }          }
   }
   
   
 /* check_trailing_context - check to see if NFA state set constitutes  /* check_trailing_context - check to see if NFA state set constitutes
Line 105 
Line 98 
  *    accset[1 .. nacc] is the list of accepting numbers for the DFA state.   *    accset[1 .. nacc] is the list of accepting numbers for the DFA state.
  */   */
   
 void check_trailing_context( nfa_states, num_states, accset, nacc )  void check_trailing_context (nfa_states, num_states, accset, nacc)
 int *nfa_states, num_states;       int    *nfa_states, num_states;
 int *accset;       int    *accset;
 int nacc;       int nacc;
         {  {
         int i, j;          int i, j;
   
         for ( i = 1; i <= num_states; ++i )          for (i = 1; i <= num_states; ++i) {
                 {                  int     ns = nfa_states[i];
                 int ns = nfa_states[i];  
                 int type = state_type[ns];                  int type = state_type[ns];
                 int ar = assoc_rule[ns];                  int ar = assoc_rule[ns];
   
                 if ( type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE )                  if (type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE) {   /* do nothing */
                         { /* do nothing */                  }
                         }  
   
                 else if ( type == STATE_TRAILING_CONTEXT )                  else if (type == STATE_TRAILING_CONTEXT) {
                         {  
                         /* Potential trouble.  Scan set of accepting numbers                          /* Potential trouble.  Scan set of accepting numbers
                          * for the one marking the end of the "head".  We                           * for the one marking the end of the "head".  We
                          * assume that this looping will be fairly cheap                           * assume that this looping will be fairly cheap
                          * since it's rare that an accepting number set                           * since it's rare that an accepting number set
                          * is large.                           * is large.
                          */                           */
                         for ( j = 1; j <= nacc; ++j )                          for (j = 1; j <= nacc; ++j)
                                 if ( accset[j] & YY_TRAILING_HEAD_MASK )                                  if (accset[j] & YY_TRAILING_HEAD_MASK) {
                                         {                                          line_warning (_
                                         line_warning(                                                        ("dangerous trailing context"),
                                         _( "dangerous trailing context" ),                                                        rule_linenum[ar]);
                                                 rule_linenum[ar] );  
                                         return;                                          return;
                                         }                                  }
                         }  
                 }                  }
         }          }
   }
   
   
 /* dump_associated_rules - list the rules associated with a DFA state  /* dump_associated_rules - list the rules associated with a DFA state
Line 150 
Line 139 
  * and writes a report to the given file.   * and writes a report to the given file.
  */   */
   
 void dump_associated_rules( file, ds )  void dump_associated_rules (file, ds)
 FILE *file;       FILE   *file;
 int ds;       int ds;
         {  {
         int i, j;          int i, j;
         int num_associated_rules = 0;          int num_associated_rules = 0;
         int rule_set[MAX_ASSOC_RULES + 1];          int     rule_set[MAX_ASSOC_RULES + 1];
         int *dset = dss[ds];          int    *dset = dss[ds];
         int size = dfasiz[ds];          int     size = dfasiz[ds];
   
         for ( i = 1; i <= size; ++i )          for (i = 1; i <= size; ++i) {
                 {  
                 int rule_num = rule_linenum[assoc_rule[dset[i]]];                  int rule_num = rule_linenum[assoc_rule[dset[i]]];
   
                 for ( j = 1; j <= num_associated_rules; ++j )                  for (j = 1; j <= num_associated_rules; ++j)
                         if ( rule_num == rule_set[j] )                          if (rule_num == rule_set[j])
                                 break;                                  break;
   
                 if ( j > num_associated_rules )                  if (j > num_associated_rules) { /* new rule */
                         { /* new rule */                          if (num_associated_rules < MAX_ASSOC_RULES)
                         if ( num_associated_rules < MAX_ASSOC_RULES )                                  rule_set[++num_associated_rules] =
                                 rule_set[++num_associated_rules] = rule_num;                                          rule_num;
                         }  
                 }                  }
           }
   
         bubble( rule_set, num_associated_rules );          qsort (&rule_set [1], num_associated_rules, sizeof (rule_set [1]), intcmp);
   
         fprintf( file, _( " associated rule line numbers:" ) );          fprintf (file, _(" associated rule line numbers:"));
   
         for ( i = 1; i <= num_associated_rules; ++i )          for (i = 1; i <= num_associated_rules; ++i) {
                 {                  if (i % 8 == 1)
                 if ( i % 8 == 1 )                          putc ('\n', file);
                         putc( '\n', file );  
   
                 fprintf( file, "\t%d", rule_set[i] );                  fprintf (file, "\t%d", rule_set[i]);
                 }  
   
         putc( '\n', file );  
         }          }
   
           putc ('\n', file);
   }
   
   
 /* dump_transitions - list the transitions associated with a DFA state  /* dump_transitions - list the transitions associated with a DFA state
  *   *
  * synopsis   * synopsis
Line 202 
Line 189 
  * is done to the given file.   * is done to the given file.
  */   */
   
 void dump_transitions( file, state )  void dump_transitions (file, state)
 FILE *file;       FILE   *file;
 int state[];       int state[];
         {  {
         int i, ec;          int i, ec;
         int out_char_set[CSIZE];          int     out_char_set[CSIZE];
   
         for ( i = 0; i < csize; ++i )          for (i = 0; i < csize; ++i) {
                 {                  ec = ABS (ecgroup[i]);
                 ec = ABS( ecgroup[i] );  
                 out_char_set[i] = state[ec];                  out_char_set[i] = state[ec];
                 }          }
   
         fprintf( file, _( " out-transitions: " ) );          fprintf (file, _(" out-transitions: "));
   
         list_character_set( file, out_char_set );          list_character_set (file, out_char_set);
   
         /* now invert the members of the set to get the jam transitions */          /* now invert the members of the set to get the jam transitions */
         for ( i = 0; i < csize; ++i )          for (i = 0; i < csize; ++i)
                 out_char_set[i] = ! out_char_set[i];                  out_char_set[i] = !out_char_set[i];
   
         fprintf( file, _( "\n jam-transitions: EOF " ) );          fprintf (file, _("\n jam-transitions: EOF "));
   
         list_character_set( file, out_char_set );          list_character_set (file, out_char_set);
   
         putc( '\n', file );          putc ('\n', file);
         }  }
   
   
 /* epsclosure - construct the epsilon closure of a set of ndfa states  /* epsclosure - construct the epsilon closure of a set of ndfa states
Line 251 
Line 237 
  *  hashval is the hash value for the dfa corresponding to the state set.   *  hashval is the hash value for the dfa corresponding to the state set.
  */   */
   
 int *epsclosure( t, ns_addr, accset, nacc_addr, hv_addr )  int    *epsclosure (t, ns_addr, accset, nacc_addr, hv_addr)
 int *t, *ns_addr, accset[], *nacc_addr, *hv_addr;       int    *t, *ns_addr, accset[], *nacc_addr, *hv_addr;
         {  {
         int stkpos, ns, tsp;          int stkpos, ns, tsp;
         int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum;          int     numstates = *ns_addr, nacc, hashval, transsym, nfaccnum;
         int stkend, nstate;          int     stkend, nstate;
         static int did_stk_init = false, *stk;          static int did_stk_init = false, *stk;
   
 #define MARK_STATE(state) \  #define MARK_STATE(state) \
 trans1[state] = trans1[state] - MARKER_DIFFERENCE;  do{ trans1[state] = trans1[state] - MARKER_DIFFERENCE;} while(0)
   
 #define IS_MARKED(state) (trans1[state] < 0)  #define IS_MARKED(state) (trans1[state] < 0)
   
 #define UNMARK_STATE(state) \  #define UNMARK_STATE(state) \
 trans1[state] = trans1[state] + MARKER_DIFFERENCE;  do{ trans1[state] = trans1[state] + MARKER_DIFFERENCE;} while(0)
   
 #define CHECK_ACCEPT(state) \  #define CHECK_ACCEPT(state) \
 { \  do{ \
 nfaccnum = accptnum[state]; \  nfaccnum = accptnum[state]; \
 if ( nfaccnum != NIL ) \  if ( nfaccnum != NIL ) \
 accset[++nacc] = nfaccnum; \  accset[++nacc] = nfaccnum; \
 }  }while(0)
   
 #define DO_REALLOCATION \  #define DO_REALLOCATION() \
 { \  do { \
 current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \  current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \
 ++num_reallocs; \  ++num_reallocs; \
 t = reallocate_integer_array( t, current_max_dfa_size ); \  t = reallocate_integer_array( t, current_max_dfa_size ); \
 stk = reallocate_integer_array( stk, current_max_dfa_size ); \  stk = reallocate_integer_array( stk, current_max_dfa_size ); \
 } \  }while(0) \
   
 #define PUT_ON_STACK(state) \  #define PUT_ON_STACK(state) \
 { \  do { \
 if ( ++stkend >= current_max_dfa_size ) \  if ( ++stkend >= current_max_dfa_size ) \
 DO_REALLOCATION \  DO_REALLOCATION(); \
 stk[stkend] = state; \  stk[stkend] = state; \
 MARK_STATE(state) \  MARK_STATE(state); \
 }  }while(0)
   
 #define ADD_STATE(state) \  #define ADD_STATE(state) \
 { \  do { \
 if ( ++numstates >= current_max_dfa_size ) \  if ( ++numstates >= current_max_dfa_size ) \
 DO_REALLOCATION \  DO_REALLOCATION(); \
 t[numstates] = state; \  t[numstates] = state; \
 hashval += state; \  hashval += state; \
 }  }while(0)
   
 #define STACK_STATE(state) \  #define STACK_STATE(state) \
 { \  do { \
 PUT_ON_STACK(state) \  PUT_ON_STACK(state); \
 CHECK_ACCEPT(state) \  CHECK_ACCEPT(state); \
 if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \  if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \
 ADD_STATE(state) \  ADD_STATE(state); \
 }  }while(0)
   
   
         if ( ! did_stk_init )          if (!did_stk_init) {
                 {                  stk = allocate_integer_array (current_max_dfa_size);
                 stk = allocate_integer_array( current_max_dfa_size );  
                 did_stk_init = true;                  did_stk_init = true;
                 }          }
   
         nacc = stkend = hashval = 0;          nacc = stkend = hashval = 0;
   
         for ( nstate = 1; nstate <= numstates; ++nstate )          for (nstate = 1; nstate <= numstates; ++nstate) {
                 {  
                 ns = t[nstate];                  ns = t[nstate];
   
                 /* The state could be marked if we've already pushed it onto                  /* The state could be marked if we've already pushed it onto
                  * the stack.                   * the stack.
                  */                   */
                 if ( ! IS_MARKED(ns) )                  if (!IS_MARKED (ns)) {
                         {                          PUT_ON_STACK (ns);
                         PUT_ON_STACK(ns)                          CHECK_ACCEPT (ns);
                         CHECK_ACCEPT(ns)  
                         hashval += ns;                          hashval += ns;
                         }  
                 }                  }
           }
   
         for ( stkpos = 1; stkpos <= stkend; ++stkpos )          for (stkpos = 1; stkpos <= stkend; ++stkpos) {
                 {  
                 ns = stk[stkpos];                  ns = stk[stkpos];
                 transsym = transchar[ns];                  transsym = transchar[ns];
   
                 if ( transsym == SYM_EPSILON )                  if (transsym == SYM_EPSILON) {
                         {  
                         tsp = trans1[ns] + MARKER_DIFFERENCE;                          tsp = trans1[ns] + MARKER_DIFFERENCE;
   
                         if ( tsp != NO_TRANSITION )                          if (tsp != NO_TRANSITION) {
                                 {                                  if (!IS_MARKED (tsp))
                                 if ( ! IS_MARKED(tsp) )                                          STACK_STATE (tsp);
                                         STACK_STATE(tsp)  
   
                                 tsp = trans2[ns];                                  tsp = trans2[ns];
   
                                 if ( tsp != NO_TRANSITION && ! IS_MARKED(tsp) )                                  if (tsp != NO_TRANSITION
                                         STACK_STATE(tsp)                                      && !IS_MARKED (tsp))
                                 }                                          STACK_STATE (tsp);
                         }                          }
                 }                  }
           }
   
         /* Clear out "visit" markers. */          /* Clear out "visit" markers. */
   
         for ( stkpos = 1; stkpos <= stkend; ++stkpos )          for (stkpos = 1; stkpos <= stkend; ++stkpos) {
                 {                  if (IS_MARKED (stk[stkpos]))
                 if ( IS_MARKED(stk[stkpos]) )                          UNMARK_STATE (stk[stkpos]);
                         UNMARK_STATE(stk[stkpos])  
                 else                  else
                         flexfatal(                          flexfatal (_
                         _( "consistency check failed in epsclosure()" ) );                                     ("consistency check failed in epsclosure()"));
                 }          }
   
         *ns_addr = numstates;          *ns_addr = numstates;
         *hv_addr = hashval;          *hv_addr = hashval;
         *nacc_addr = nacc;          *nacc_addr = nacc;
   
         return t;          return t;
         }  }
   
   
 /* increase_max_dfas - increase the maximum number of DFAs */  /* increase_max_dfas - increase the maximum number of DFAs */
   
 void increase_max_dfas()  void increase_max_dfas ()
         {  {
         current_max_dfas += MAX_DFAS_INCREMENT;          current_max_dfas += MAX_DFAS_INCREMENT;
   
         ++num_reallocs;          ++num_reallocs;
   
         base = reallocate_integer_array( base, current_max_dfas );          base = reallocate_integer_array (base, current_max_dfas);
         def = reallocate_integer_array( def, current_max_dfas );          def = reallocate_integer_array (def, current_max_dfas);
         dfasiz = reallocate_integer_array( dfasiz, current_max_dfas );          dfasiz = reallocate_integer_array (dfasiz, current_max_dfas);
         accsiz = reallocate_integer_array( accsiz, current_max_dfas );          accsiz = reallocate_integer_array (accsiz, current_max_dfas);
         dhash = reallocate_integer_array( dhash, current_max_dfas );          dhash = reallocate_integer_array (dhash, current_max_dfas);
         dss = reallocate_int_ptr_array( dss, current_max_dfas );          dss = reallocate_int_ptr_array (dss, current_max_dfas);
         dfaacc = reallocate_dfaacc_union( dfaacc, current_max_dfas );          dfaacc = reallocate_dfaacc_union (dfaacc, current_max_dfas);
   
         if ( nultrans )          if (nultrans)
                 nultrans =                  nultrans =
                         reallocate_integer_array( nultrans, current_max_dfas );                          reallocate_integer_array (nultrans,
         }                                                    current_max_dfas);
   }
   
   
 /* ntod - convert an ndfa to a dfa  /* ntod - convert an ndfa to a dfa
Line 399 
Line 380 
  * dfa starts out in state #1.   * dfa starts out in state #1.
  */   */
   
 void ntod()  void ntod ()
         {  {
         int *accset, ds, nacc, newds;          int    *accset, ds, nacc, newds;
         int sym, hashval, numstates, dsize;          int     sym, hashval, numstates, dsize;
         int num_full_table_rows;        /* used only for -f */          int     num_full_table_rows=0;  /* used only for -f */
         int *nset, *dset;          int    *nset, *dset;
         int targptr, totaltrans, i, comstate, comfreq, targ;          int     targptr, totaltrans, i, comstate, comfreq, targ;
         int symlist[CSIZE + 1];          int     symlist[CSIZE + 1];
         int num_start_states;          int     num_start_states;
         int todo_head, todo_next;          int     todo_head, todo_next;
   
           struct yytbl_data *yynxt_tbl = 0;
           flex_int32_t *yynxt_data = 0, yynxt_curr = 0;
   
         /* Note that the following are indexed by *equivalence classes*          /* Note that the following are indexed by *equivalence classes*
          * and not by characters.  Since equivalence classes are indexed           * and not by characters.  Since equivalence classes are indexed
          * beginning with 1, even if the scanner accepts NUL's, this           * beginning with 1, even if the scanner accepts NUL's, this
Line 417 
Line 401 
          * equivalence class) these arrays must have room for indices           * equivalence class) these arrays must have room for indices
          * from 1 to CSIZE, so their size must be CSIZE + 1.           * from 1 to CSIZE, so their size must be CSIZE + 1.
          */           */
         int duplist[CSIZE + 1], state[CSIZE + 1];          int     duplist[CSIZE + 1], state[CSIZE + 1];
         int targfreq[CSIZE + 1], targstate[CSIZE + 1];          int     targfreq[CSIZE + 1], targstate[CSIZE + 1];
   
         accset = allocate_integer_array( num_rules + 1 );          /* accset needs to be large enough to hold all of the rules present
         nset = allocate_integer_array( current_max_dfa_size );           * in the input, *plus* their YY_TRAILING_HEAD_MASK variants.
            */
           accset = allocate_integer_array ((num_rules + 1) * 2);
           nset = allocate_integer_array (current_max_dfa_size);
   
         /* The "todo" queue is represented by the head, which is the DFA          /* The "todo" queue is represented by the head, which is the DFA
          * state currently being processed, and the "next", which is the           * state currently being processed, and the "next", which is the
Line 431 
Line 418 
          */           */
         todo_head = todo_next = 0;          todo_head = todo_next = 0;
   
         for ( i = 0; i <= csize; ++i )          for (i = 0; i <= csize; ++i) {
                 {  
                 duplist[i] = NIL;                  duplist[i] = NIL;
                 symlist[i] = false;                  symlist[i] = false;
                 }          }
   
         for ( i = 0; i <= num_rules; ++i )          for (i = 0; i <= num_rules; ++i)
                 accset[i] = NIL;                  accset[i] = NIL;
   
         if ( trace )          if (trace) {
                 {                  dumpnfa (scset[1]);
                 dumpnfa( scset[1] );                  fputs (_("\n\nDFA Dump:\n\n"), stderr);
                 fputs( _( "\n\nDFA Dump:\n\n" ), stderr );          }
                 }  
   
         inittbl();          inittbl ();
   
         /* Check to see whether we should build a separate table for          /* Check to see whether we should build a separate table for
          * transitions on NUL characters.  We don't do this for full-speed           * transitions on NUL characters.  We don't do this for full-speed
Line 480 
Line 465 
         /* Note that the test for ecgroup[0] == numecs below accomplishes          /* Note that the test for ecgroup[0] == numecs below accomplishes
          * both (1) and (2) above           * both (1) and (2) above
          */           */
         if ( ! fullspd && ecgroup[0] == numecs )          if (!fullspd && ecgroup[0] == numecs) {
                 {  
                 /* NUL is alone in its equivalence class, which is the                  /* NUL is alone in its equivalence class, which is the
                  * last one.                   * last one.
                  */                   */
                 int use_NUL_table = (numecs == csize);                  int     use_NUL_table = (numecs == csize);
   
                 if ( fulltbl && ! use_NUL_table )                  if (fulltbl && !use_NUL_table) {
                         {  
                         /* We still may want to use the table if numecs                          /* We still may want to use the table if numecs
                          * is a power of 2.                           * is a power of 2.
                          */                           */
                         int power_of_two;                          int     power_of_two;
   
                         for ( power_of_two = 1; power_of_two <= csize;                          for (power_of_two = 1; power_of_two <= csize;
                               power_of_two *= 2 )                               power_of_two *= 2)
                                 if ( numecs == power_of_two )                                  if (numecs == power_of_two) {
                                         {  
                                         use_NUL_table = true;                                          use_NUL_table = true;
                                         break;                                          break;
                                         }                                  }
                         }                  }
   
                 if ( use_NUL_table )                  if (use_NUL_table)
                         nultrans = allocate_integer_array( current_max_dfas );                          nultrans =
                                   allocate_integer_array (current_max_dfas);
   
                 /* From now on, nultrans != nil indicates that we're                  /* From now on, nultrans != nil indicates that we're
                  * saving null transitions for later, separate encoding.                   * saving null transitions for later, separate encoding.
                  */                   */
                 }          }
   
   
         if ( fullspd )          if (fullspd) {
                 {                  for (i = 0; i <= numecs; ++i)
                 for ( i = 0; i <= numecs; ++i )  
                         state[i] = 0;                          state[i] = 0;
   
                 place_state( state, 0, 0 );                  place_state (state, 0, 0);
                 dfaacc[0].dfaacc_state = 0;                  dfaacc[0].dfaacc_state = 0;
                 }          }
   
         else if ( fulltbl )          else if (fulltbl) {
                 {                  if (nultrans)
                 if ( nultrans )  
                         /* We won't be including NUL's transitions in the                          /* We won't be including NUL's transitions in the
                          * table, so build it for entries from 0 .. numecs - 1.                           * table, so build it for entries from 0 .. numecs - 1.
                          */                           */
Line 536 
Line 517 
                          */                           */
                         num_full_table_rows = numecs + 1;                          num_full_table_rows = numecs + 1;
   
                   /* Begin generating yy_nxt[][]
                    * This spans the entire LONG function.
                    * This table is tricky because we don't know how big it will be.
                    * So we'll have to realloc() on the way...
                    * we'll wait until we can calculate yynxt_tbl->td_hilen.
                    */
                   yynxt_tbl =
                           (struct yytbl_data *) calloc (1,
                                                         sizeof (struct
                                                                 yytbl_data));
                   yytbl_data_init (yynxt_tbl, YYTD_ID_NXT);
                   yynxt_tbl->td_hilen = 1;
                   yynxt_tbl->td_lolen = num_full_table_rows;
                   yynxt_tbl->td_data = yynxt_data =
                           (flex_int32_t *) calloc (yynxt_tbl->td_lolen *
                                               yynxt_tbl->td_hilen,
                                               sizeof (flex_int32_t));
                   yynxt_curr = 0;
   
                   buf_prints (&yydmap_buf,
                               "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n",
                               long_align ? "flex_int32_t" : "flex_int16_t");
   
                 /* Unless -Ca, declare it "short" because it's a real                  /* Unless -Ca, declare it "short" because it's a real
                  * long-shot that that won't be large enough.                   * long-shot that that won't be large enough.
                  */                   */
                 out_str_dec( "static yyconst %s yy_nxt[][%d] =\n    {\n",                  if (gentables)
                         /* '}' so vi doesn't get too confused */                          out_str_dec
                         long_align ? "long" : "short", num_full_table_rows );                                  ("static yyconst %s yy_nxt[][%d] =\n    {\n",
                                    long_align ? "flex_int32_t" : "flex_int16_t",
                                    num_full_table_rows);
                   else {
                           out_dec ("#undef YY_NXT_LOLEN\n#define YY_NXT_LOLEN (%d)\n", num_full_table_rows);
                           out_str ("static yyconst %s *yy_nxt =0;\n",
                                    long_align ? "flex_int32_t" : "flex_int16_t");
                   }
   
                 outn( "    {" );  
   
                 /* Generate 0 entries for state #0. */                  if (gentables)
                 for ( i = 0; i < num_full_table_rows; ++i )                          outn ("    {");
                         mk2data( 0 );  
   
                 dataflush();                  /* Generate 0 entries for state #0. */
                 outn( "    },\n" );                  for (i = 0; i < num_full_table_rows; ++i) {
                           mk2data (0);
                           yynxt_data[yynxt_curr++] = 0;
                 }                  }
   
                   dataflush ();
                   if (gentables)
                           outn ("    },\n");
           }
   
         /* Create the first states. */          /* Create the first states. */
   
         num_start_states = lastsc * 2;          num_start_states = lastsc * 2;
   
         for ( i = 1; i <= num_start_states; ++i )          for (i = 1; i <= num_start_states; ++i) {
                 {  
                 numstates = 1;                  numstates = 1;
   
                 /* For each start condition, make one state for the case when                  /* For each start condition, make one state for the case when
                  * we're at the beginning of the line (the '^' operator) and                   * we're at the beginning of the line (the '^' operator) and
                  * one for the case when we're not.                   * one for the case when we're not.
                  */                   */
                 if ( i % 2 == 1 )                  if (i % 2 == 1)
                         nset[numstates] = scset[(i / 2) + 1];                          nset[numstates] = scset[(i / 2) + 1];
                 else                  else
                         nset[numstates] =                          nset[numstates] =
                                 mkbranch( scbol[i / 2], scset[i / 2] );                                  mkbranch (scbol[i / 2], scset[i / 2]);
   
                 nset = epsclosure( nset, &numstates, accset, &nacc, &hashval );                  nset = epsclosure (nset, &numstates, accset, &nacc,
                                      &hashval);
   
                 if ( snstods( nset, numstates, accset, nacc, hashval, &ds ) )                  if (snstods (nset, numstates, accset, nacc, hashval, &ds)) {
                         {  
                         numas += nacc;                          numas += nacc;
                         totnst += numstates;                          totnst += numstates;
                         ++todo_next;                          ++todo_next;
   
                         if ( variable_trailing_context_rules && nacc > 0 )                          if (variable_trailing_context_rules && nacc > 0)
                                 check_trailing_context( nset, numstates,                                  check_trailing_context (nset, numstates,
                                                         accset, nacc );                                                          accset, nacc);
                         }  
                 }                  }
           }
   
         if ( ! fullspd )          if (!fullspd) {
                 {                  if (!snstods (nset, 0, accset, 0, 0, &end_of_buffer_state))
                 if ( ! snstods( nset, 0, accset, 0, 0, &end_of_buffer_state ) )                          flexfatal (_
                         flexfatal(                                     ("could not create unique end-of-buffer state"));
                         _( "could not create unique end-of-buffer state" ) );  
   
                 ++numas;                  ++numas;
                 ++num_start_states;                  ++num_start_states;
                 ++todo_next;                  ++todo_next;
                 }          }
   
         while ( todo_head < todo_next )  
                 {          while (todo_head < todo_next) {
                 targptr = 0;                  targptr = 0;
                 totaltrans = 0;                  totaltrans = 0;
   
                 for ( i = 1; i <= numecs; ++i )                  for (i = 1; i <= numecs; ++i)
                         state[i] = 0;                          state[i] = 0;
   
                 ds = ++todo_head;                  ds = ++todo_head;
Line 609 
Line 623 
                 dset = dss[ds];                  dset = dss[ds];
                 dsize = dfasiz[ds];                  dsize = dfasiz[ds];
   
                 if ( trace )                  if (trace)
                         fprintf( stderr, _( "state # %d:\n" ), ds );                          fprintf (stderr, _("state # %d:\n"), ds);
   
                 sympartition( dset, dsize, symlist, duplist );                  sympartition (dset, dsize, symlist, duplist);
   
                 for ( sym = 1; sym <= numecs; ++sym )                  for (sym = 1; sym <= numecs; ++sym) {
                         {                          if (symlist[sym]) {
                         if ( symlist[sym] )  
                                 {  
                                 symlist[sym] = 0;                                  symlist[sym] = 0;
   
                                 if ( duplist[sym] == NIL )                                  if (duplist[sym] == NIL) {
                                         {  
                                         /* Symbol has unique out-transitions. */                                          /* Symbol has unique out-transitions. */
                                         numstates = symfollowset( dset, dsize,                                          numstates =
                                                                 sym, nset );                                                  symfollowset (dset, dsize,
                                         nset = epsclosure( nset, &numstates,                                                                sym, nset);
                                                 accset, &nacc, &hashval );                                          nset = epsclosure (nset,
                                                              &numstates,
                                                              accset, &nacc,
                                                              &hashval);
   
                                         if ( snstods( nset, numstates, accset,                                          if (snstods
                                                 nacc, hashval, &newds ) )                                              (nset, numstates, accset, nacc,
                                                 {                                               hashval, &newds)) {
                                                 totnst = totnst + numstates;                                                  totnst = totnst +
                                                           numstates;
                                                 ++todo_next;                                                  ++todo_next;
                                                 numas += nacc;                                                  numas += nacc;
   
                                                 if (                                                  if (variable_trailing_context_rules && nacc > 0)
                                         variable_trailing_context_rules &&                                                          check_trailing_context
                                                         nacc > 0 )                                                                  (nset,
                                                         check_trailing_context(                                                                   numstates,
                                                                 nset, numstates,                                                                   accset,
                                                                 accset, nacc );                                                                   nacc);
                                                 }                                          }
   
                                         state[sym] = newds;                                          state[sym] = newds;
   
                                         if ( trace )                                          if (trace)
                                                 fprintf( stderr, "\t%d\t%d\n",                                                  fprintf (stderr,
                                                         sym, newds );                                                           "\t%d\t%d\n", sym,
                                                            newds);
   
                                         targfreq[++targptr] = 1;                                          targfreq[++targptr] = 1;
                                         targstate[targptr] = newds;                                          targstate[targptr] = newds;
                                         ++numuniq;                                          ++numuniq;
                                         }                                  }
   
                                 else                                  else {
                                         {  
                                         /* sym's equivalence class has the same                                          /* sym's equivalence class has the same
                                          * transitions as duplist(sym)'s                                           * transitions as duplist(sym)'s
                                          * equivalence class.                                           * equivalence class.
Line 663 
Line 678 
                                         targ = state[duplist[sym]];                                          targ = state[duplist[sym]];
                                         state[sym] = targ;                                          state[sym] = targ;
   
                                         if ( trace )                                          if (trace)
                                                 fprintf( stderr, "\t%d\t%d\n",                                                  fprintf (stderr,
                                                         sym, targ );                                                           "\t%d\t%d\n", sym,
                                                            targ);
   
                                         /* Update frequency count for                                          /* Update frequency count for
                                          * destination state.                                           * destination state.
                                          */                                           */
   
                                         i = 0;                                          i = 0;
                                         while ( targstate[++i] != targ )                                          while (targstate[++i] != targ) ;
                                                 ;  
   
                                         ++targfreq[i];                                          ++targfreq[i];
                                         ++numdup;                                          ++numdup;
                                         }                                  }
   
                                 ++totaltrans;                                  ++totaltrans;
                                 duplist[sym] = NIL;                                  duplist[sym] = NIL;
                                 }  
                         }                          }
                   }
   
                 if ( caseins && ! useecs )  
                         {  
                         int j;  
   
                         for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j )  
                                 {  
                                 if ( state[i] == 0 && state[j] != 0 )  
                                         /* We're adding a transition. */  
                                         ++totaltrans;  
   
                                 else if ( state[i] != 0 && state[j] == 0 )  
                                         /* We're taking away a transition. */  
                                         --totaltrans;  
   
                                 state[i] = state[j];  
                                 }  
                         }  
   
                 numsnpairs += totaltrans;                  numsnpairs += totaltrans;
   
                 if ( ds > num_start_states )                  if (ds > num_start_states)
                         check_for_backing_up( ds, state );                          check_for_backing_up (ds, state);
   
                 if ( nultrans )                  if (nultrans) {
                         {  
                         nultrans[ds] = state[NUL_ec];                          nultrans[ds] = state[NUL_ec];
                         state[NUL_ec] = 0;      /* remove transition */                          state[NUL_ec] = 0;      /* remove transition */
                         }                  }
   
                 if ( fulltbl )                  if (fulltbl) {
                         {  
                         outn( "    {" );  
   
                           /* Each time we hit here, it's another td_hilen, so we realloc. */
                           yynxt_tbl->td_hilen++;
                           yynxt_tbl->td_data = yynxt_data =
                                   (flex_int32_t *) realloc (yynxt_data,
                                                        yynxt_tbl->td_hilen *
                                                        yynxt_tbl->td_lolen *
                                                        sizeof (flex_int32_t));
   
   
                           if (gentables)
                                   outn ("    {");
   
                         /* Supply array's 0-element. */                          /* Supply array's 0-element. */
                         if ( ds == end_of_buffer_state )                          if (ds == end_of_buffer_state) {
                                 mk2data( -end_of_buffer_state );                                  mk2data (-end_of_buffer_state);
                         else                                  yynxt_data[yynxt_curr++] =
                                 mk2data( end_of_buffer_state );                                          -end_of_buffer_state;
                           }
                           else {
                                   mk2data (end_of_buffer_state);
                                   yynxt_data[yynxt_curr++] =
                                           end_of_buffer_state;
                           }
   
                         for ( i = 1; i < num_full_table_rows; ++i )                          for (i = 1; i < num_full_table_rows; ++i) {
                                 /* Jams are marked by negative of state                                  /* Jams are marked by negative of state
                                  * number.                                   * number.
                                  */                                   */
                                 mk2data( state[i] ? state[i] : -ds );                                  mk2data (state[i] ? state[i] : -ds);
                                   yynxt_data[yynxt_curr++] =
                         dataflush();                                          state[i] ? state[i] : -ds;
                         outn( "    },\n" );  
                         }                          }
   
                 else if ( fullspd )                          dataflush ();
                         place_state( state, ds, totaltrans );                          if (gentables)
                                   outn ("    },\n");
                   }
   
                 else if ( ds == end_of_buffer_state )                  else if (fullspd)
                           place_state (state, ds, totaltrans);
   
                   else if (ds == end_of_buffer_state)
                         /* Special case this state to make sure it does what                          /* Special case this state to make sure it does what
                          * it's supposed to, i.e., jam on end-of-buffer.                           * it's supposed to, i.e., jam on end-of-buffer.
                          */                           */
                         stack1( ds, 0, 0, JAMSTATE );                          stack1 (ds, 0, 0, JAMSTATE);
   
                 else /* normal, compressed state */                  else {          /* normal, compressed state */
                         {  
                         /* Determine which destination state is the most                          /* Determine which destination state is the most
                          * common, and how many transitions to it there are.                           * common, and how many transitions to it there are.
                          */                           */
Line 751 
Line 768 
                         comfreq = 0;                          comfreq = 0;
                         comstate = 0;                          comstate = 0;
   
                         for ( i = 1; i <= targptr; ++i )                          for (i = 1; i <= targptr; ++i)
                                 if ( targfreq[i] > comfreq )                                  if (targfreq[i] > comfreq) {
                                         {  
                                         comfreq = targfreq[i];                                          comfreq = targfreq[i];
                                         comstate = targstate[i];                                          comstate = targstate[i];
                                         }                                  }
   
                         bldtbl( state, ds, totaltrans, comstate, comfreq );                          bldtbl (state, ds, totaltrans, comstate, comfreq);
                         }  
                 }                  }
           }
   
         if ( fulltbl )          if (fulltbl) {
                 dataend();                  dataend ();
                   if (tablesext) {
                           yytbl_data_compress (yynxt_tbl);
                           if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0)
                                   flexerror (_
                                              ("Could not write yynxt_tbl[][]"));
                   }
                   if (yynxt_tbl) {
                           yytbl_data_destroy (yynxt_tbl);
                           yynxt_tbl = 0;
                   }
           }
   
         else if ( ! fullspd )          else if (!fullspd) {
                 {                  cmptmps ();     /* create compressed template entries */
                 cmptmps();  /* create compressed template entries */  
   
                 /* Create tables for all the states with only one                  /* Create tables for all the states with only one
                  * out-transition.                   * out-transition.
                  */                   */
                 while ( onesp > 0 )                  while (onesp > 0) {
                         {                          mk1tbl (onestate[onesp], onesym[onesp],
                         mk1tbl( onestate[onesp], onesym[onesp], onenext[onesp],                                  onenext[onesp], onedef[onesp]);
                         onedef[onesp] );  
                         --onesp;                          --onesp;
                         }  
   
                 mkdeftbl();  
                 }                  }
   
         flex_free( (void *) accset );                  mkdeftbl ();
         flex_free( (void *) nset );  
         }          }
   
           flex_free ((void *) accset);
           flex_free ((void *) nset);
   }
   
   
 /* snstods - converts a set of ndfa states into a dfa state  /* snstods - converts a set of ndfa states into a dfa state
  *   *
  * synopsis   * synopsis
Line 797 
Line 822 
  * On return, the dfa state number is in newds.   * On return, the dfa state number is in newds.
  */   */
   
 int snstods( sns, numstates, accset, nacc, hashval, newds_addr )  int snstods (sns, numstates, accset, nacc, hashval, newds_addr)
 int sns[], numstates, accset[], nacc, hashval, *newds_addr;       int sns[], numstates, accset[], nacc, hashval, *newds_addr;
         {  {
         int didsort = 0;          int     didsort = 0;
         int i, j;          int i, j;
         int newds, *oldsns;          int     newds, *oldsns;
   
         for ( i = 1; i <= lastdfa; ++i )          for (i = 1; i <= lastdfa; ++i)
                 if ( hashval == dhash[i] )                  if (hashval == dhash[i]) {
                         {                          if (numstates == dfasiz[i]) {
                         if ( numstates == dfasiz[i] )  
                                 {  
                                 oldsns = dss[i];                                  oldsns = dss[i];
   
                                 if ( ! didsort )                                  if (!didsort) {
                                         {  
                                         /* We sort the states in sns so we                                          /* We sort the states in sns so we
                                          * can compare it to oldsns quickly.                                           * can compare it to oldsns quickly.
                                          * We use bubble because there probably  
                                          * aren't very many states.  
                                          */                                           */
                                         bubble( sns, numstates );                                          qsort (&sns [1], numstates, sizeof (sns [1]), intcmp);
                                         didsort = 1;                                          didsort = 1;
                                         }                                  }
   
                                 for ( j = 1; j <= numstates; ++j )                                  for (j = 1; j <= numstates; ++j)
                                         if ( sns[j] != oldsns[j] )                                          if (sns[j] != oldsns[j])
                                                 break;                                                  break;
   
                                 if ( j > numstates )                                  if (j > numstates) {
                                         {  
                                         ++dfaeql;                                          ++dfaeql;
                                         *newds_addr = i;                                          *newds_addr = i;
                                         return 0;                                          return 0;
                                         }                                  }
   
                                 ++hshcol;                                  ++hshcol;
                                 }                          }
   
                         else                          else
                                 ++hshsave;                                  ++hshsave;
                         }                  }
   
         /* Make a new dfa. */          /* Make a new dfa. */
   
         if ( ++lastdfa >= current_max_dfas )          if (++lastdfa >= current_max_dfas)
                 increase_max_dfas();                  increase_max_dfas ();
   
         newds = lastdfa;          newds = lastdfa;
   
         dss[newds] = allocate_integer_array( numstates + 1 );          dss[newds] = allocate_integer_array (numstates + 1);
   
         /* If we haven't already sorted the states in sns, we do so now,          /* If we haven't already sorted the states in sns, we do so now,
          * so that future comparisons with it can be made quickly.           * so that future comparisons with it can be made quickly.
          */           */
   
         if ( ! didsort )          if (!didsort)
                 bubble( sns, numstates );                  qsort (&sns [1], numstates, sizeof (sns [1]), intcmp);
   
         for ( i = 1; i <= numstates; ++i )          for (i = 1; i <= numstates; ++i)
                 dss[newds][i] = sns[i];                  dss[newds][i] = sns[i];
   
         dfasiz[newds] = numstates;          dfasiz[newds] = numstates;
         dhash[newds] = hashval;          dhash[newds] = hashval;
   
         if ( nacc == 0 )          if (nacc == 0) {
                 {                  if (reject)
                 if ( reject )  
                         dfaacc[newds].dfaacc_set = (int *) 0;                          dfaacc[newds].dfaacc_set = (int *) 0;
                 else                  else
                         dfaacc[newds].dfaacc_state = 0;                          dfaacc[newds].dfaacc_state = 0;
   
                 accsiz[newds] = 0;                  accsiz[newds] = 0;
                 }          }
   
         else if ( reject )          else if (reject) {
                 {  
                 /* We sort the accepting set in increasing order so the                  /* We sort the accepting set in increasing order so the
                  * disambiguating rule that the first rule listed is considered                   * disambiguating rule that the first rule listed is considered
                  * match in the event of ties will work.  We use a bubble                   * match in the event of ties will work.
                  * sort since the list is probably quite small.  
                  */                   */
   
                 bubble( accset, nacc );                  qsort (&accset [1], nacc, sizeof (accset [1]), intcmp);
   
                 dfaacc[newds].dfaacc_set = allocate_integer_array( nacc + 1 );                  dfaacc[newds].dfaacc_set =
                           allocate_integer_array (nacc + 1);
   
                 /* Save the accepting set for later */                  /* Save the accepting set for later */
                 for ( i = 1; i <= nacc; ++i )                  for (i = 1; i <= nacc; ++i) {
                         {  
                         dfaacc[newds].dfaacc_set[i] = accset[i];                          dfaacc[newds].dfaacc_set[i] = accset[i];
   
                         if ( accset[i] <= num_rules )                          if (accset[i] <= num_rules)
                                 /* Who knows, perhaps a REJECT can yield                                  /* Who knows, perhaps a REJECT can yield
                                  * this rule.                                   * this rule.
                                  */                                   */
                                 rule_useful[accset[i]] = true;                                  rule_useful[accset[i]] = true;
                         }                  }
   
                 accsiz[newds] = nacc;                  accsiz[newds] = nacc;
                 }          }
   
         else          else {
                 {  
                 /* Find lowest numbered rule so the disambiguating rule                  /* Find lowest numbered rule so the disambiguating rule
                  * will work.                   * will work.
                  */                   */
                 j = num_rules + 1;                  j = num_rules + 1;
   
                 for ( i = 1; i <= nacc; ++i )                  for (i = 1; i <= nacc; ++i)
                         if ( accset[i] < j )                          if (accset[i] < j)
                                 j = accset[i];                                  j = accset[i];
   
                 dfaacc[newds].dfaacc_state = j;                  dfaacc[newds].dfaacc_state = j;
   
                 if ( j <= num_rules )                  if (j <= num_rules)
                         rule_useful[j] = true;                          rule_useful[j] = true;
                 }          }
   
         *newds_addr = newds;          *newds_addr = newds;
   
         return 1;          return 1;
         }  }
   
   
 /* symfollowset - follow the symbol transitions one step  /* symfollowset - follow the symbol transitions one step
Line 929 
Line 944 
  *                              int transsym, int nset[current_max_dfa_size] );   *                              int transsym, int nset[current_max_dfa_size] );
  */   */
   
 int symfollowset( ds, dsize, transsym, nset )  int symfollowset (ds, dsize, transsym, nset)
 int ds[], dsize, transsym, nset[];       int ds[], dsize, transsym, nset[];
         {  {
         int ns, tsp, sym, i, j, lenccl, ch, numstates, ccllist;          int     ns, tsp, sym, i, j, lenccl, ch, numstates, ccllist;
   
         numstates = 0;          numstates = 0;
   
         for ( i = 1; i <= dsize; ++i )          for (i = 1; i <= dsize; ++i) {  /* for each nfa state ns in the state set of ds */
                 { /* for each nfa state ns in the state set of ds */  
                 ns = ds[i];                  ns = ds[i];
                 sym = transchar[ns];                  sym = transchar[ns];
                 tsp = trans1[ns];                  tsp = trans1[ns];
   
                 if ( sym < 0 )                  if (sym < 0) {  /* it's a character class */
                         { /* it's a character class */  
                         sym = -sym;                          sym = -sym;
                         ccllist = cclmap[sym];                          ccllist = cclmap[sym];
                         lenccl = ccllen[sym];                          lenccl = ccllen[sym];
   
                         if ( cclng[sym] )                          if (cclng[sym]) {
                                 {                                  for (j = 0; j < lenccl; ++j) {
                                 for ( j = 0; j < lenccl; ++j )  
                                         {  
                                         /* Loop through negated character                                          /* Loop through negated character
                                          * class.                                           * class.
                                          */                                           */
                                         ch = ccltbl[ccllist + j];                                          ch = ccltbl[ccllist + j];
   
                                         if ( ch == 0 )                                          if (ch == 0)
                                                 ch = NUL_ec;                                                  ch = NUL_ec;
   
                                         if ( ch > transsym )                                          if (ch > transsym)
                                                 /* Transsym isn't in negated                                                  /* Transsym isn't in negated
                                                  * ccl.                                                   * ccl.
                                                  */                                                   */
                                                 break;                                                  break;
   
                                         else if ( ch == transsym )                                          else if (ch == transsym)
                                                 /* next 2 */ goto bottom;                                                  /* next 2 */
                                         }                                                  goto bottom;
                                   }
   
                                 /* Didn't find transsym in ccl. */                                  /* Didn't find transsym in ccl. */
                                 nset[++numstates] = tsp;                                  nset[++numstates] = tsp;
                                 }                          }
   
                         else                          else
                                 for ( j = 0; j < lenccl; ++j )                                  for (j = 0; j < lenccl; ++j) {
                                         {  
                                         ch = ccltbl[ccllist + j];                                          ch = ccltbl[ccllist + j];
   
                                         if ( ch == 0 )                                          if (ch == 0)
                                                 ch = NUL_ec;                                                  ch = NUL_ec;
   
                                         if ( ch > transsym )                                          if (ch > transsym)
                                                 break;                                                  break;
                                         else if ( ch == transsym )                                          else if (ch == transsym) {
                                                 {  
                                                 nset[++numstates] = tsp;                                                  nset[++numstates] = tsp;
                                                 break;                                                  break;
                                                 }  
                                         }                                          }
                         }                                  }
                   }
   
                 else if ( sym >= 'A' && sym <= 'Z' && caseins )                  else if (sym == SYM_EPSILON) {  /* do nothing */
                         flexfatal(                  }
                         _( "consistency check failed in symfollowset" ) );  
   
                 else if ( sym == SYM_EPSILON )                  else if (ABS (ecgroup[sym]) == transsym)
                         { /* do nothing */  
                         }  
   
                 else if ( ABS( ecgroup[sym] ) == transsym )  
                         nset[++numstates] = tsp;                          nset[++numstates] = tsp;
   
                 bottom: ;                bottom:;
                 }          }
   
         return numstates;          return numstates;
         }  }
   
   
 /* sympartition - partition characters with same out-transitions  /* sympartition - partition characters with same out-transitions
Line 1017 
Line 1022 
  *                      int symlist[numecs], int duplist[numecs] );   *                      int symlist[numecs], int duplist[numecs] );
  */   */
   
 void sympartition( ds, numstates, symlist, duplist )  void sympartition (ds, numstates, symlist, duplist)
 int ds[], numstates;       int ds[], numstates;
 int symlist[], duplist[];       int symlist[], duplist[];
         {  {
         int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich;          int     tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich;
   
         /* Partitioning is done by creating equivalence classes for those          /* Partitioning is done by creating equivalence classes for those
          * characters which have out-transitions from the given state.  Thus           * characters which have out-transitions from the given state.  Thus
          * we are really creating equivalence classes of equivalence classes.           * we are really creating equivalence classes of equivalence classes.
          */           */
   
         for ( i = 1; i <= numecs; ++i )          for (i = 1; i <= numecs; ++i) { /* initialize equivalence class list */
                 { /* initialize equivalence class list */  
                 duplist[i] = i - 1;                  duplist[i] = i - 1;
                 dupfwd[i] = i + 1;                  dupfwd[i] = i + 1;
                 }          }
   
         duplist[1] = NIL;          duplist[1] = NIL;
         dupfwd[numecs] = NIL;          dupfwd[numecs] = NIL;
   
         for ( i = 1; i <= numstates; ++i )          for (i = 1; i <= numstates; ++i) {
                 {  
                 ns = ds[i];                  ns = ds[i];
                 tch = transchar[ns];                  tch = transchar[ns];
   
                 if ( tch != SYM_EPSILON )                  if (tch != SYM_EPSILON) {
                         {                          if (tch < -lastccl || tch >= csize) {
                         if ( tch < -lastccl || tch >= csize )                                  flexfatal (_
                                 {                                             ("bad transition character detected in sympartition()"));
                                 flexfatal(                          }
                 _( "bad transition character detected in sympartition()" ) );  
                                 }  
   
                         if ( tch >= 0 )                          if (tch >= 0) { /* character transition */
                                 { /* character transition */                                  int     ec = ecgroup[tch];
                                 int ec = ecgroup[tch];  
   
                                 mkechar( ec, dupfwd, duplist );                                  mkechar (ec, dupfwd, duplist);
                                 symlist[ec] = 1;                                  symlist[ec] = 1;
                                 }                          }
   
                         else                          else {  /* character class */
                                 { /* character class */  
                                 tch = -tch;                                  tch = -tch;
   
                                 lenccl = ccllen[tch];                                  lenccl = ccllen[tch];
                                 cclp = cclmap[tch];                                  cclp = cclmap[tch];
                                 mkeccl( ccltbl + cclp, lenccl, dupfwd,                                  mkeccl (ccltbl + cclp, lenccl, dupfwd,
                                         duplist, numecs, NUL_ec );                                          duplist, numecs, NUL_ec);
   
                                 if ( cclng[tch] )                                  if (cclng[tch]) {
                                         {  
                                         j = 0;                                          j = 0;
   
                                         for ( k = 0; k < lenccl; ++k )                                          for (k = 0; k < lenccl; ++k) {
                                                 {  
                                                 ich = ccltbl[cclp + k];                                                  ich = ccltbl[cclp + k];
   
                                                 if ( ich == 0 )                                                  if (ich == 0)
                                                         ich = NUL_ec;                                                          ich = NUL_ec;
   
                                                 for ( ++j; j < ich; ++j )                                                  for (++j; j < ich; ++j)
                                                         symlist[j] = 1;                                                          symlist[j] = 1;
                                                 }                                          }
   
                                         for ( ++j; j <= numecs; ++j )                                          for (++j; j <= numecs; ++j)
                                                 symlist[j] = 1;                                                  symlist[j] = 1;
                                         }                                  }
   
                                 else                                  else
                                         for ( k = 0; k < lenccl; ++k )                                          for (k = 0; k < lenccl; ++k) {
                                                 {  
                                                 ich = ccltbl[cclp + k];                                                  ich = ccltbl[cclp + k];
   
                                                 if ( ich == 0 )                                                  if (ich == 0)
                                                         ich = NUL_ec;                                                          ich = NUL_ec;
   
                                                 symlist[ich] = 1;                                                  symlist[ich] = 1;
                                                 }                                          }
                                 }  
                         }                          }
                 }                  }
         }          }
   }

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7