This is Unofficial EPICS BASE Doxygen Site
nfa.c File Reference
#include "flexdef.h"
+ Include dependency graph for nfa.c:

Go to the source code of this file.

Functions

int dupmachine (int)
 
void mkxtion (int, int)
 
void add_accept (int mach, int accepting_number)
 
int copysingl (int singl, int num)
 
void dumpnfa (int state1)
 
void finish_rule (int mach, int variable_trail_rule, int headcnt, int trailcnt)
 
int link_machines (int first, int last)
 
void mark_beginning_as_normal (int mach)
 
int mkbranch (int first, int second)
 
int mkclos (int state)
 
int mkopt (int mach)
 
int mkor (int first, int second)
 
int mkposcl (int state)
 
int mkrep (int mach, int lb, int ub)
 
int mkstate (int sym)
 
void new_rule (void)
 

Function Documentation

void add_accept ( int  mach,
int  accepting_number 
)

Definition at line 55 of file nfa.c.

56 {
57  /* hang the accepting number off an epsilon state. if it is associated
58  * with a state that has a non-epsilon out-transition, then the state
59  * will accept BEFORE it makes that transition, i.e., one character
60  * too soon
61  */
62 
63  if ( transchar[finalst[mach]] == SYM_EPSILON )
64  accptnum[finalst[mach]] = accepting_number;
65 
66  else
67  {
68  int astate = mkstate( SYM_EPSILON );
69  accptnum[astate] = accepting_number;
70  mach = link_machines( mach, astate );
71  }
72  }
#define SYM_EPSILON
Definition: flexdef.h:192
int * finalst
Definition: flex.c:77
int * accptnum
Definition: flex.c:78
int mkstate(int sym)
Definition: nfa.c:578
int link_machines(int first, int last)
Definition: nfa.c:283
int * transchar
Definition: flex.c:77
int copysingl ( int  singl,
int  num 
)

Definition at line 86 of file nfa.c.

87 {
88  int copy, i;
89 
90  copy = mkstate( SYM_EPSILON );
91 
92  for ( i = 1; i <= num; ++i )
93  copy = link_machines( copy, dupmachine( singl ) );
94 
95  return ( copy );
96  }
int i
Definition: scan.c:967
#define SYM_EPSILON
Definition: flexdef.h:192
void copy(PVValueArray< T > &pvFrom, size_t fromOffset, size_t fromStride, PVValueArray< T > &pvTo, size_t toOffset, size_t toStride, size_t count)
Copy a subarray from one scalar array to another.
int dupmachine(int)
Definition: nfa.c:158
int mkstate(int sym)
Definition: nfa.c:578
int link_machines(int first, int last)
Definition: nfa.c:283
void dumpnfa ( int  state1)

Definition at line 106 of file nfa.c.

107 {
108  int sym, tsp1, tsp2, anum, ns;
109 
110  fprintf( stderr, "\n\n********** beginning dump of nfa with start state %d\n",
111  state1 );
112 
113  /* we probably should loop starting at firstst[state1] and going to
114  * lastst[state1], but they're not maintained properly when we "or"
115  * all of the rules together. So we use our knowledge that the machine
116  * starts at state 1 and ends at lastnfa.
117  */
118 
119  /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */
120  for ( ns = 1; ns <= lastnfa; ++ns )
121  {
122  fprintf( stderr, "state # %4d\t", ns );
123 
124  sym = transchar[ns];
125  tsp1 = trans1[ns];
126  tsp2 = trans2[ns];
127  anum = accptnum[ns];
128 
129  fprintf( stderr, "%3d: %4d, %4d", sym, tsp1, tsp2 );
130 
131  if ( anum != NIL )
132  fprintf( stderr, " [%d]", anum );
133 
134  fprintf( stderr, "\n" );
135  }
136 
137  fprintf( stderr, "********** end of dump\n" );
138  }
#define NIL
Definition: flexdef.h:153
int * accptnum
Definition: flex.c:78
int * trans2
Definition: flex.c:77
int * trans1
Definition: flex.c:77
int lastnfa
Definition: flex.c:76
#define stderr
Definition: epicsStdio.h:32
int * transchar
Definition: flex.c:77
int dupmachine ( int  mach)

Definition at line 158 of file nfa.c.

159 {
160  int i, init, state_offset;
161  int state = 0;
162  int last = lastst[mach];
163 
164  for ( i = firstst[mach]; i <= last; ++i )
165  {
166  state = mkstate( transchar[i] );
167 
168  if ( trans1[i] != NO_TRANSITION )
169  {
170  mkxtion( finalst[state], trans1[i] + state - i );
171 
172  if ( transchar[i] == SYM_EPSILON && trans2[i] != NO_TRANSITION )
173  mkxtion( finalst[state], trans2[i] + state - i );
174  }
175 
176  accptnum[state] = accptnum[i];
177  }
178 
179  if ( state == 0 )
180  flexfatal( "empty machine in dupmachine()" );
181 
182  state_offset = state - i + 1;
183 
184  init = mach + state_offset;
185  firstst[init] = firstst[mach] + state_offset;
186  finalst[init] = finalst[mach] + state_offset;
187  lastst[init] = lastst[mach] + state_offset;
188 
189  return ( init );
190  }
int i
Definition: scan.c:967
int * firstst
Definition: flex.c:77
#define SYM_EPSILON
Definition: flexdef.h:192
int * finalst
Definition: flex.c:77
int * accptnum
Definition: flex.c:78
int mkstate(int sym)
Definition: nfa.c:578
void mkxtion(int, int)
Definition: nfa.c:648
void flexfatal(char[])
int * trans2
Definition: flex.c:77
int * trans1
Definition: flex.c:77
#define NO_TRANSITION
Definition: flexdef.h:156
int * lastst
Definition: flex.c:77
int * transchar
Definition: flex.c:77
void finish_rule ( int  mach,
int  variable_trail_rule,
int  headcnt,
int  trailcnt 
)

Definition at line 209 of file nfa.c.

210 {
211  add_accept( mach, num_rules );
212 
213  /* we did this in new_rule(), but it often gets the wrong
214  * number because we do it before we start parsing the current rule
215  */
217 
218  /* if this is a continued action, then the line-number has
219  * already been updated, giving us the wrong number
220  */
221  if ( continued_action )
223 
224  fprintf( temp_action_file, "case %d:\n", num_rules );
225 
226  if ( variable_trail_rule )
227  {
229 
230  if ( performance_report )
231  fprintf( stderr, "Variable trailing context rule at line %d\n",
233 
235  }
236 
237  else
238  {
240 
241  if ( headcnt > 0 || trailcnt > 0 )
242  {
243  /* do trailing context magic to not match the trailing characters */
244  char *scanner_cp = "yy_c_buf_p = yy_cp";
245  char *scanner_bp = "yy_bp";
246 
247  fprintf( temp_action_file,
248  "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" );
249 
250  if ( headcnt > 0 )
251  fprintf( temp_action_file, "%s = %s + %d;\n",
252  scanner_cp, scanner_bp, headcnt );
253 
254  else
255  fprintf( temp_action_file,
256  "%s -= %d;\n", scanner_cp, trailcnt );
257 
258  fprintf( temp_action_file,
259  "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" );
260  }
261  }
262 
264  }
#define RULE_VARIABLE
Definition: flexdef.h:422
int continued_action
Definition: flex.c:69
int * rule_type
Definition: flex.c:78
int variable_trailing_context_rules
Definition: flex.c:80
int linenum
Definition: flex.c:71
int * rule_linenum
Definition: flex.c:78
int num_rules
Definition: flex.c:76
void add_accept(int mach, int accepting_number)
Definition: nfa.c:55
int performance_report
Definition: flex.c:68
void line_directive_out(FILE *)
Definition: misc.c:479
FILE * temp_action_file
Definition: flex.c:103
#define stderr
Definition: epicsStdio.h:32
#define RULE_NORMAL
Definition: flexdef.h:421
int link_machines ( int  first,
int  last 
)

Definition at line 283 of file nfa.c.

284 {
285  if ( first == NIL )
286  return ( last );
287 
288  else if ( last == NIL )
289  return ( first );
290 
291  else
292  {
293  mkxtion( finalst[first], last );
294  finalst[first] = finalst[last];
295  lastst[first] = max( lastst[first], lastst[last] );
296  firstst[first] = min( firstst[first], firstst[last] );
297 
298  return ( first );
299  }
300  }
#define max(x, y)
Definition: flexdef.h:81
int * firstst
Definition: flex.c:77
#define min(x, y)
Definition: flexdef.h:78
#define NIL
Definition: flexdef.h:153
int * finalst
Definition: flex.c:77
void mkxtion(int, int)
Definition: nfa.c:648
int * lastst
Definition: flex.c:77
void mark_beginning_as_normal ( int  mach)

Definition at line 316 of file nfa.c.

317 {
318  switch ( state_type[mach] )
319  {
320  case STATE_NORMAL:
321  /* oh, we've already visited here */
322  return;
323 
325  state_type[mach] = STATE_NORMAL;
326 
327  if ( transchar[mach] == SYM_EPSILON )
328  {
329  if ( trans1[mach] != NO_TRANSITION )
331 
332  if ( trans2[mach] != NO_TRANSITION )
334  }
335  break;
336 
337  default:
338  flexerror( "bad state type in mark_beginning_as_normal()" );
339  break;
340  }
341  }
#define SYM_EPSILON
Definition: flexdef.h:192
#define STATE_TRAILING_CONTEXT
Definition: flexdef.h:414
void mark_beginning_as_normal(int mach)
Definition: nfa.c:316
void flexerror(char[]) NORETURN
int * state_type
Definition: flex.c:78
int * trans2
Definition: flex.c:77
int * trans1
Definition: flex.c:77
#define NO_TRANSITION
Definition: flexdef.h:156
#define STATE_NORMAL
Definition: flexdef.h:413
int * transchar
Definition: flex.c:77
int mkbranch ( int  first,
int  second 
)

Definition at line 358 of file nfa.c.

359 {
360  int eps;
361 
362  if ( first == NO_TRANSITION )
363  return ( second );
364 
365  else if ( second == NO_TRANSITION )
366  return ( first );
367 
368  eps = mkstate( SYM_EPSILON );
369 
370  mkxtion( eps, first );
371  mkxtion( eps, second );
372 
373  return ( eps );
374  }
#define SYM_EPSILON
Definition: flexdef.h:192
int mkstate(int sym)
Definition: nfa.c:578
void mkxtion(int, int)
Definition: nfa.c:648
#define NO_TRANSITION
Definition: flexdef.h:156
int mkclos ( int  state)

Definition at line 385 of file nfa.c.

386 {
387  return ( mkopt( mkposcl( state ) ) );
388  }
int mkposcl(int state)
Definition: nfa.c:501
int mkopt(int mach)
Definition: nfa.c:405
int mkopt ( int  mach)

Definition at line 405 of file nfa.c.

406 {
407  int eps;
408 
409  if ( ! SUPER_FREE_EPSILON(finalst[mach]) )
410  {
411  eps = mkstate( SYM_EPSILON );
412  mach = link_machines( mach, eps );
413  }
414 
415  /* can't skimp on the following if FREE_EPSILON(mach) is true because
416  * some state interior to "mach" might point back to the beginning
417  * for a closure
418  */
419  eps = mkstate( SYM_EPSILON );
420  mach = link_machines( eps, mach );
421 
422  mkxtion( mach, finalst[mach] );
423 
424  return ( mach );
425  }
#define SYM_EPSILON
Definition: flexdef.h:192
int * finalst
Definition: flex.c:77
int mkstate(int sym)
Definition: nfa.c:578
int link_machines(int first, int last)
Definition: nfa.c:283
void mkxtion(int, int)
Definition: nfa.c:648
#define SUPER_FREE_EPSILON(state)
Definition: flexdef.h:120
int mkor ( int  first,
int  second 
)

Definition at line 442 of file nfa.c.

443 {
444  int eps, orend;
445 
446  if ( first == NIL )
447  return ( second );
448 
449  else if ( second == NIL )
450  return ( first );
451 
452  else
453  {
454  /* see comment in mkopt() about why we can't use the first state
455  * of "first" or "second" if they satisfy "FREE_EPSILON"
456  */
457  eps = mkstate( SYM_EPSILON );
458 
459  first = link_machines( eps, first );
460 
461  mkxtion( first, second );
462 
463  if ( SUPER_FREE_EPSILON(finalst[first]) &&
464  accptnum[finalst[first]] == NIL )
465  {
466  orend = finalst[first];
467  mkxtion( finalst[second], orend );
468  }
469 
470  else if ( SUPER_FREE_EPSILON(finalst[second]) &&
471  accptnum[finalst[second]] == NIL )
472  {
473  orend = finalst[second];
474  mkxtion( finalst[first], orend );
475  }
476 
477  else
478  {
479  eps = mkstate( SYM_EPSILON );
480 
481  first = link_machines( first, eps );
482  orend = finalst[first];
483 
484  mkxtion( finalst[second], orend );
485  }
486  }
487 
488  finalst[first] = orend;
489  return ( first );
490  }
#define SYM_EPSILON
Definition: flexdef.h:192
#define NIL
Definition: flexdef.h:153
int * finalst
Definition: flex.c:77
int * accptnum
Definition: flex.c:78
int mkstate(int sym)
Definition: nfa.c:578
int link_machines(int first, int last)
Definition: nfa.c:283
void mkxtion(int, int)
Definition: nfa.c:648
#define SUPER_FREE_EPSILON(state)
Definition: flexdef.h:120
int mkposcl ( int  state)

Definition at line 501 of file nfa.c.

502 {
503  int eps;
504 
505  if ( SUPER_FREE_EPSILON(finalst[state]) )
506  {
507  mkxtion( finalst[state], state );
508  return ( state );
509  }
510 
511  else
512  {
513  eps = mkstate( SYM_EPSILON );
514  mkxtion( eps, state );
515  return ( link_machines( state, eps ) );
516  }
517  }
#define SYM_EPSILON
Definition: flexdef.h:192
int * finalst
Definition: flex.c:77
int mkstate(int sym)
Definition: nfa.c:578
int link_machines(int first, int last)
Definition: nfa.c:283
void mkxtion(int, int)
Definition: nfa.c:648
#define SUPER_FREE_EPSILON(state)
Definition: flexdef.h:120
int mkrep ( int  mach,
int  lb,
int  ub 
)

Definition at line 532 of file nfa.c.

533 {
534  int base_mach, tail, copy, i;
535 
536  base_mach = copysingl( mach, lb - 1 );
537 
538  if ( ub == INFINITY )
539  {
540  copy = dupmachine( mach );
541  mach = link_machines( mach,
542  link_machines( base_mach, mkclos( copy ) ) );
543  }
544 
545  else
546  {
547  tail = mkstate( SYM_EPSILON );
548 
549  for ( i = lb; i < ub; ++i )
550  {
551  copy = dupmachine( mach );
552  tail = mkopt( link_machines( copy, tail ) );
553  }
554 
555  mach = link_machines( mach, link_machines( base_mach, tail ) );
556  }
557 
558  return ( mach );
559  }
int i
Definition: scan.c:967
#define SYM_EPSILON
Definition: flexdef.h:192
void copy(PVValueArray< T > &pvFrom, size_t fromOffset, size_t fromStride, PVValueArray< T > &pvTo, size_t toOffset, size_t toStride, size_t count)
Copy a subarray from one scalar array to another.
int dupmachine(int)
Definition: nfa.c:158
#define INFINITY
Definition: flexdef.h:158
int mkstate(int sym)
Definition: nfa.c:578
int link_machines(int first, int last)
Definition: nfa.c:283
int copysingl(int singl, int num)
Definition: nfa.c:86
int mkclos(int state)
Definition: nfa.c:385
int mkopt(int mach)
Definition: nfa.c:405
int mkstate ( int  sym)

Definition at line 578 of file nfa.c.

579 {
580  if ( ++lastnfa >= current_mns )
581  {
582  if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS )
583  lerrif( "input rules are too complicated (>= %d NFA states)",
584  current_mns );
585 
586  ++num_reallocs;
587 
597  }
598 
602  transchar[lastnfa] = sym;
605  accptnum[lastnfa] = NIL;
608 
609  /* fix up equivalence classes base on this transition. Note that any
610  * character which has its own transition gets its own equivalence class.
611  * Thus only characters which are only in character classes have a chance
612  * at being in the same equivalence class. E.g. "a|b" puts 'a' and 'b'
613  * into two different equivalence classes. "[ab]" puts them in the same
614  * equivalence class (barring other differences elsewhere in the input).
615  */
616 
617  if ( sym < 0 )
618  {
619  /* we don't have to update the equivalence classes since that was
620  * already done when the ccl was created for the first time
621  */
622  }
623 
624  else if ( sym == SYM_EPSILON )
625  ++numeps;
626 
627  else
628  {
629  if ( useecs )
630  /* map NUL's to csize */
631  mkechar( sym ? sym : csize, nextecm, ecgroup );
632  }
633 
634  return ( lastnfa );
635  }
#define MAXIMUM_MNS
Definition: flexdef.h:182
int ecgroup[CSIZE+1]
Definition: flex.c:83
int * firstst
Definition: flex.c:77
#define SYM_EPSILON
Definition: flexdef.h:192
int num_reallocs
Definition: flex.c:100
int nextecm[CSIZE+1]
Definition: flex.c:83
#define NIL
Definition: flexdef.h:153
int numeps
Definition: flex.c:100
int current_state_type
Definition: flex.c:79
int csize
Definition: flex.c:68
int num_rules
Definition: flex.c:76
int useecs
Definition: flex.c:67
int * finalst
Definition: flex.c:77
int current_mns
Definition: flex.c:76
void lerrif(char[], int)
int * accptnum
Definition: flex.c:78
int * state_type
Definition: flex.c:78
#define reallocate_integer_array(array, size)
Definition: flexdef.h:584
int * assoc_rule
Definition: flex.c:78
int * trans2
Definition: flex.c:77
int * trans1
Definition: flex.c:77
#define NO_TRANSITION
Definition: flexdef.h:156
int lastnfa
Definition: flex.c:76
#define MNS_INCREMENT
Definition: flexdef.h:171
int * lastst
Definition: flex.c:77
int * transchar
Definition: flex.c:77
void mkechar(int tch, int fwd[], int bck[])
Definition: ecs.c:328
void mkxtion ( int  statefrom,
int  stateto 
)

Definition at line 648 of file nfa.c.

649 {
650  if ( trans1[statefrom] == NO_TRANSITION )
651  trans1[statefrom] = stateto;
652 
653  else if ( (transchar[statefrom] != SYM_EPSILON) ||
654  (trans2[statefrom] != NO_TRANSITION) )
655  flexfatal( "found too many transitions in mkxtion()" );
656 
657  else
658  { /* second out-transition for an epsilon state */
659  ++eps2;
660  trans2[statefrom] = stateto;
661  }
662  }
#define SYM_EPSILON
Definition: flexdef.h:192
int eps2
Definition: flex.c:100
void flexfatal(char[])
int * trans2
Definition: flex.c:77
int * trans1
Definition: flex.c:77
#define NO_TRANSITION
Definition: flexdef.h:156
int * transchar
Definition: flex.c:77
void new_rule ( void  )

Definition at line 674 of file nfa.c.

675 {
676  if ( ++num_rules >= current_max_rules )
677  {
678  ++num_reallocs;
681  rule_linenum =
683  }
684 
685  if ( num_rules > MAX_RULE )
686  lerrif( "too many rules (> %d)!", MAX_RULE );
687 
689  }
int * rule_type
Definition: flex.c:78
#define MAX_RULE
Definition: flexdef.h:147
int num_reallocs
Definition: flex.c:100
int linenum
Definition: flex.c:71
int current_max_rules
Definition: flex.c:76
int * rule_linenum
Definition: flex.c:78
#define MAX_RULES_INCREMENT
Definition: flexdef.h:168
int num_rules
Definition: flex.c:76
void lerrif(char[], int)
#define reallocate_integer_array(array, size)
Definition: flexdef.h:584