version 1.10, 2015/11/19 19:43:40 |
version 1.11, 2015/11/19 22:52:40 |
|
|
|
|
/* 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 |
|
|
* accepting_number becomes mach's accepting number. |
* accepting_number becomes mach's accepting number. |
*/ |
*/ |
|
|
void add_accept (mach, accepting_number) |
void |
int mach, accepting_number; |
add_accept(mach, accepting_number) |
|
int mach, accepting_number; |
{ |
{ |
/* 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 |
* Hang the accepting number off an epsilon state. if it is |
* will accept BEFORE it makes that transition, i.e., one character |
* associated with a state that has a non-epsilon out-transition, |
* too soon. |
* then the state will accept BEFORE it makes that transition, i.e., |
|
* one character 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); |
} |
} |
} |
} |
|
|
|
|
* 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 |
int singl, num; |
copysingl(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 |
int state1; |
dumpnfa(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"), |
("\n\n********** beginning dump of nfa with start state %d\n"), |
state1); |
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" |
* all of the rules together. So we use our knowledge that the machine |
* all of the rules together. So we use our knowledge that the |
* starts at state 1 and ends at lastnfa. |
* machine starts at state 1 and ends at lastnfa. |
*/ |
*/ |
|
|
/* 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")); |
} |
} |
|
|
|
|
|
|
* states accessible by the arrays firstst and lastst |
* states accessible by the arrays firstst and lastst |
*/ |
*/ |
|
|
int dupmachine (mach) |
int |
int mach; |
dupmachine(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; |
|
|
|
|
* context has variable length. |
* context has variable length. |
*/ |
*/ |
|
|
void finish_rule (mach, variable_trail_rule, headcnt, trailcnt, |
void |
pcont_act) |
finish_rule(mach, variable_trail_rule, headcnt, trailcnt, |
int mach, variable_trail_rule, headcnt, trailcnt, pcont_act; |
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 |
/* |
* number because we do it before we start parsing the current rule. |
* We did this in new_rule(), but it often gets the wrong number |
|
* because we do it before we start parsing the current rule. |
*/ |
*/ |
rule_linenum[num_rules] = linenum; |
rule_linenum[num_rules] = linenum; |
|
|
/* 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]; |
|
|
|
|
/* If the previous rule was continued action, then we inherit the |
/* |
|
* If the previous rule was continued action, then we inherit the |
* previous newline flag, possibly overriding the current one. |
* previous newline flag, possibly overriding the current one. |
*/ |
*/ |
if (pcont_act && rule_has_nl[num_rules - 1]) |
if (pcont_act && rule_has_nl[num_rules - 1]) |
rule_has_nl[num_rules] = true; |
rule_has_nl[num_rules] = true; |
|
|
snprintf (action_text, sizeof(action_text), "case %d:\n", num_rules); |
snprintf(action_text, sizeof(action_text), "case %d:\n", num_rules); |
add_action (action_text); |
add_action(action_text); |
if (rule_has_nl[num_rules]) { |
if (rule_has_nl[num_rules]) { |
snprintf (action_text, sizeof(action_text), "/* rule %d can match eol */\n", |
snprintf(action_text, sizeof(action_text), "/* rule %d can match eol */\n", |
num_rules); |
num_rules); |
add_action (action_text); |
add_action(action_text); |
} |
} |
|
|
|
|
if (variable_trail_rule) { |
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"), |
("Variable trailing context rule at line %d\n"), |
rule_linenum[num_rules]); |
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 |
/* |
* characters. |
* Do trailing context magic to not match the |
|
* trailing characters. |
*/ |
*/ |
char *scanner_cp = "YY_G(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_G(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]) { |
if (rule_has_nl[num_rules]) { |
snprintf (action_text, sizeof(action_text), |
snprintf(action_text, sizeof(action_text), |
"YY_LINENO_REWIND_TO(%s + %d);\n", scanner_bp, headcnt); |
"YY_LINENO_REWIND_TO(%s + %d);\n", scanner_bp, headcnt); |
add_action (action_text); |
add_action(action_text); |
} |
} |
snprintf (action_text, sizeof(action_text), "%s = %s + %d;\n", |
snprintf(action_text, sizeof(action_text), "%s = %s + %d;\n", |
scanner_cp, scanner_bp, headcnt); |
scanner_cp, scanner_bp, headcnt); |
add_action (action_text); |
add_action(action_text); |
} |
} else { |
|
|
else { |
|
if (rule_has_nl[num_rules]) { |
if (rule_has_nl[num_rules]) { |
snprintf (action_text, sizeof(action_text), |
snprintf(action_text, sizeof(action_text), |
"YY_LINENO_REWIND_TO(yy_cp - %d);\n", trailcnt); |
"YY_LINENO_REWIND_TO(yy_cp - %d);\n", trailcnt); |
add_action (action_text); |
add_action(action_text); |
} |
} |
|
snprintf(action_text, sizeof(action_text), "%s -= %d;\n", |
snprintf (action_text, sizeof(action_text), "%s -= %d;\n", |
scanner_cp, trailcnt); |
scanner_cp, trailcnt); |
add_action(action_text); |
add_action (action_text); |
|
} |
} |
|
|
add_action |
add_action |
("YY_DO_BEFORE_ACTION; /* set up yytext again */\n"); |
("YY_DO_BEFORE_ACTION; /* set up yytext again */\n"); |
} |
} |
} |
} |
|
|
/* Okay, in the action code at this point yytext and yyleng have |
/* |
* their proper final values for this rule, so here's the point |
* Okay, in the action code at this point yytext and yyleng have |
* to do any user action. But don't do it for continued actions, |
* their proper final values for this rule, so here's the point to do |
* as that'll result in multiple YY_RULE_SETUP's. |
* any user action. But don't do it for continued actions, 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); |
} |
} |
|
|
|
|
|
|
* 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 |
int first, last; |
link_machines(first, last) |
|
int first, last; |
{ |
{ |
if (first == NIL) |
if (first == NIL) |
return last; |
return last; |
|
|
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; |
} |
} |
|
|
* 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 |
int mach; |
mark_beginning_as_normal(mach) |
|
int mach; |
{ |
{ |
switch (state_type[mach]) { |
switch (state_type[mach]) { |
case STATE_NORMAL: |
case 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 (trans2[mach]); |
mark_beginning_as_normal(trans2[mach]); |
} |
} |
break; |
break; |
|
|
default: |
default: |
flexerror (_ |
flexerror(_ |
("bad state type in mark_beginning_as_normal()")); |
("bad state type in mark_beginning_as_normal()")); |
break; |
break; |
} |
} |
} |
} |
|
|
* more mkbranch's. Compare with mkor() |
* more mkbranch's. Compare with mkor() |
*/ |
*/ |
|
|
int mkbranch (first, second) |
int |
int first, second; |
mkbranch(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; |
} |
} |
|
|
* new - a new state which matches the closure of "state" |
* new - a new state which matches the closure of "state" |
*/ |
*/ |
|
|
int mkclos (state) |
int |
int state; |
mkclos(state) |
|
int state; |
{ |
{ |
return mkopt (mkposcl (state)); |
return mkopt(mkposcl(state)); |
} |
} |
|
|
|
|
|
|
* 2. mach is destroyed by the call |
* 2. mach is destroyed by the call |
*/ |
*/ |
|
|
int mkopt (mach) |
int |
int mach; |
mkopt(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; |
} |
} |
|
|
* the number of epsilon states needed |
* the number of epsilon states needed |
*/ |
*/ |
|
|
int mkor (first, second) |
int |
int first, second; |
mkor(first, second) |
|
int first, second; |
{ |
{ |
int eps, orend; |
int eps, orend; |
|
|
if (first == NIL) |
if (first == NIL) |
return second; |
return second; |
|
|
return first; |
return first; |
|
|
else { |
else { |
/* See comment in mkopt() about why we can't use the first |
/* |
* state of "first" or "second" if they satisfy "FREE_EPSILON". |
* See comment in mkopt() about why we can't use the first |
|
* 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]) && |
|
accptnum[finalst[second]] == NIL) { |
else if (SUPER_FREE_EPSILON (finalst[second]) && |
|
accptnum[finalst[second]] == NIL) { |
|
orend = finalst[second]; |
orend = finalst[second]; |
mkxtion (finalst[first], orend); |
mkxtion(finalst[first], orend); |
} |
} else { |
|
eps = mkstate(SYM_EPSILON); |
|
|
else { |
first = link_machines(first, eps); |
eps = mkstate (SYM_EPSILON); |
|
|
|
first = link_machines (first, eps); |
|
orend = finalst[first]; |
orend = finalst[first]; |
|
|
mkxtion (finalst[second], orend); |
mkxtion(finalst[second], orend); |
} |
} |
} |
} |
|
|
|
|
* new - a machine matching the positive closure of "state" |
* new - a machine matching the positive closure of "state" |
*/ |
*/ |
|
|
int mkposcl (state) |
int |
int state; |
mkposcl(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 { |
|
eps = mkstate(SYM_EPSILON); |
|
mkxtion(eps, state); |
|
return link_machines(state, eps); |
} |
} |
|
|
else { |
|
eps = mkstate (SYM_EPSILON); |
|
mkxtion (eps, state); |
|
return link_machines (state, eps); |
|
} |
|
} |
} |
|
|
|
|
|
|
* if "ub" is INFINITE_REPEAT 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 |
int mach, lb, ub; |
mkrep(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 == INFINITE_REPEAT) { |
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 { |
|
tail = mkstate(SYM_EPSILON); |
|
|
else { |
|
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 = |
mach = |
link_machines (mach, |
link_machines(mach, |
link_machines (base_mach, tail)); |
link_machines(base_mach, tail)); |
} |
} |
|
|
return mach; |
return mach; |
|
|
* that it admittedly is) |
* that it admittedly is) |
*/ |
*/ |
|
|
int mkstate (sym) |
int |
int sym; |
mkstate(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 = |
transchar = |
reallocate_integer_array (transchar, current_mns); |
reallocate_integer_array(transchar, current_mns); |
trans1 = reallocate_integer_array (trans1, current_mns); |
trans1 = reallocate_integer_array(trans1, current_mns); |
trans2 = reallocate_integer_array (trans2, current_mns); |
trans2 = reallocate_integer_array(trans2, current_mns); |
accptnum = |
accptnum = |
reallocate_integer_array (accptnum, current_mns); |
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; |
lastst[lastnfa] = lastnfa; |
lastst[lastnfa] = lastnfa; |
|
|
assoc_rule[lastnfa] = num_rules; |
assoc_rule[lastnfa] = num_rules; |
state_type[lastnfa] = current_state_type; |
state_type[lastnfa] = current_state_type; |
|
|
/* Fix up equivalence classes base on this transition. Note that any |
/* |
|
* Fix up equivalence classes base on this transition. Note that any |
* character which has its own transition gets its own equivalence |
* character which has its own transition gets its own equivalence |
* class. Thus only characters which are only in character classes |
* class. Thus only characters which are only in character classes |
* have a chance at being in the same equivalence class. E.g. "a|b" |
* have a chance at being in the same equivalence class. E.g. "a|b" |
|
|
*/ |
*/ |
|
|
if (sym < 0) { |
if (sym < 0) { |
/* We don't have to update the equivalence classes since |
/* |
* that was already done when the ccl was created for the |
* We don't have to update the equivalence classes since that |
* first time. |
* was already done when the ccl was created for the 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; |
|
|
* 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 |
int statefrom, stateto; |
mkxtion(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 { /* second out-transition for an epsilon state */ |
else { /* second out-transition for an epsilon state */ |
++eps2; |
++eps2; |
|
|
|
|
/* 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, |
rule_has_nl = reallocate_bool_array(rule_has_nl, |
current_max_rules); |
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; |