diff options
Diffstat (limited to 'src/gen.c')
-rw-r--r-- | src/gen.c | 1558 |
1 files changed, 240 insertions, 1318 deletions
@@ -34,69 +34,31 @@ #include "flexdef.h" #include "tables.h" +/* These typedefs are only used for computing footprint sizes, + * You need to make sure they match reality in the skeleton file to + * get accurate numbers, but they don't otherwise matter. + */ +typedef char YY_CHAR; +struct yy_trans_info {int32_t yy_verify; int32_t yy_nxt;}; /* declare functions that have forward references */ void genecs(void); - -static int indent_level = 0; /* each level is 8 spaces */ - -#define set_indent(indent_val) indent_level = indent_val - -/* Almost everything is done in terms of arrays starting at 1, so provide - * a null entry for the zero element of all C arrays. (The exception - * to this is that the fast table representation generally uses the - * 0 elements of its arrays, too.) - */ - -static const char *get_int16_decl (void) -{ - return (gentables) - ? "static const flex_int16_t %s[%d] =\n { 0,\n" - : "static const flex_int16_t * %s = 0;\n"; -} - - -static const char *get_int32_decl (void) -{ - return (gentables) - ? "static const flex_int32_t %s[%d] =\n { 0,\n" - : "static const flex_int32_t * %s = 0;\n"; -} - -static const char *get_state_decl (void) -{ - return (gentables) - ? "static const yy_state_type %s[%d] =\n { 0,\n" - : "static const yy_state_type * %s = 0;\n"; -} - -static const char *get_yy_char_decl (void) +struct packtype_t *optimize_pack(size_t sz) { - return (gentables) - ? "static const YY_CHAR %s[%d] =\n { 0,\n" - : "static const YY_CHAR * %s = 0;\n"; + /* FIXME: There's a 32-bit assumption lurking here */ + static struct packtype_t out; + if (sz == 0) { + out.name = ctrl.long_align ? "M4_HOOK_INT32" : "M4_HOOK_INT16"; + out.width = ctrl.long_align ? 32 : 16; + } else { + out.name = (ctrl.long_align || sz >= INT16_MAX) ? "M4_HOOK_INT32" : "M4_HOOK_INT16"; + out.width = (ctrl.long_align || sz >= INT16_MAX) ? 32 : 16; + } + return &out; } -/* Indent to the current level. */ - -void do_indent (void) -{ - int i = indent_level * 8; - - while (i >= 8) { - outc ('\t'); - i -= 8; - } - - while (i > 0) { - outc (' '); - --i; - } -} - - /** Make the table for possible eol matches. * @return the newly allocated rule_can_match_eol table */ @@ -116,9 +78,6 @@ static struct yytbl_data *mkeoltbl (void) for (i = 1; i <= num_rules; i++) tdata[i] = rule_has_nl[i] ? 1 : 0; - buf_prints (&yydmap_buf, - "\t{YYTD_ID_RULE_CAN_MATCH_EOL, (void**)&yy_rule_can_match_eol, sizeof(%s)},\n", - "flex_int32_t"); return tbl; } @@ -126,11 +85,12 @@ static struct yytbl_data *mkeoltbl (void) static void geneoltbl (void) { int i; + struct packtype_t *ptype = optimize_pack(num_rules); - outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[["); - outn ("/* Table of booleans, true if rule could match eol. */"); - out_str_dec (get_int32_decl (), "yy_rule_can_match_eol", - num_rules + 1); + outn ("m4_ifdef( [[M4_MODE_YYLINENO]],[["); + out_str ("m4_define([[M4_HOOK_EOLTABLE_TYPE]], [[%s]])\n", ptype->name); + out_dec ("m4_define([[M4_HOOK_EOLTABLE_SIZE]], [[%d]])", num_rules + 1); + outn ("m4_define([[M4_HOOK_EOLTABLE_BODY]], [[m4_dnl"); if (gentables) { for (i = 1; i <= num_rules; i++) { @@ -139,61 +99,13 @@ static void geneoltbl (void) if ((i % 20) == 19) out ("\n "); } - out (" };\n"); } + footprint += num_rules * ptype->width; + outn ("]])"); outn ("]])"); } -/* Generate the code to keep backing-up information. */ - -void gen_backing_up (void) -{ - if (reject || num_backing_up == 0) - return; - - if (fullspd) - indent_puts ("if ( yy_current_state[-1].yy_nxt )"); - else - indent_puts ("if ( yy_accept[yy_current_state] )"); - - ++indent_level; - indent_puts ("{"); - indent_puts ("YY_G(yy_last_accepting_state) = yy_current_state;"); - indent_puts ("YY_G(yy_last_accepting_cpos) = yy_cp;"); - indent_puts ("}"); - --indent_level; -} - - -/* Generate the code to perform the backing up. */ - -void gen_bu_action (void) -{ - if (reject || num_backing_up == 0) - return; - - set_indent (3); - - indent_puts ("case 0: /* must back up */"); - indent_puts ("/* undo the effects of YY_DO_BEFORE_ACTION */"); - indent_puts ("*yy_cp = YY_G(yy_hold_char);"); - - if (fullspd || fulltbl) - indent_puts ("yy_cp = YY_G(yy_last_accepting_cpos) + 1;"); - else - /* Backing-up info for compressed tables is taken \after/ - * yy_cp has been incremented for the next state. - */ - indent_puts ("yy_cp = YY_G(yy_last_accepting_cpos);"); - - indent_puts ("yy_current_state = YY_G(yy_last_accepting_state);"); - indent_puts ("goto yy_find_action;"); - outc ('\n'); - - set_indent (0); -} - /** mkctbl - make full speed compressed transition table * This is an array of structs; each struct a pair of integers. * You should call mkssltbl() immediately after this. @@ -208,10 +120,8 @@ static struct yytbl_data *mkctbl (void) flex_int32_t *tdata = 0, curr = 0; int end_of_buffer_action = num_rules + 1; - buf_prints (&yydmap_buf, - "\t{YYTD_ID_TRANSITION, (void**)&yy_transition, sizeof(%s)},\n", - ((tblend + numecs + 1) >= INT16_MAX - || long_align) ? "flex_int32_t" : "flex_int16_t"); + struct packtype_t *ptype = optimize_pack(tblend + numecs + 1); + out_str ("m4_define([[M4_HOOK_MKCTBL_TYPE]], [[%s]])", ptype->name); tbl = calloc(1, sizeof (struct yytbl_data)); yytbl_data_init (tbl, YYTD_ID_TRANSITION); @@ -288,7 +198,6 @@ static struct yytbl_data *mkctbl (void) } } - /* Here's the final, end-of-buffer state. */ tdata[curr++] = chk[tblend + 1]; tdata[curr++] = nxt[tblend + 1]; @@ -321,10 +230,6 @@ static struct yytbl_data *mkssltbl (void) for (i = 0; i <= lastsc * 2; ++i) tdata[i] = base[i]; - buf_prints (&yydmap_buf, - "\t{YYTD_ID_START_STATE_LIST, (void**)&yy_start_state_list, sizeof(%s)},\n", - "struct yy_trans_info*"); - return tbl; } @@ -338,10 +243,8 @@ void genctbl (void) int end_of_buffer_action = num_rules + 1; /* Table of verify for transition and offset to next state. */ - if (gentables) - out_dec ("static const struct yy_trans_info yy_transition[%d] =\n {\n", tblend + numecs + 1); - else - outn ("static const struct yy_trans_info *yy_transition = 0;"); + out_dec ("m4_define([[M4_HOOK_TRANSTABLE_SIZE]], [[%d]])", tblend + numecs + 1); + outn ("m4_define([[M4_HOOK_TRANSTABLE_BODY]], [[m4_dnl"); /* We want the transition to be represented as the offset to the * next state, not the actual state number, which is what it currently @@ -408,25 +311,22 @@ void genctbl (void) transition_struct_out (chk[tblend + 1], nxt[tblend + 1]); transition_struct_out (chk[tblend + 2], nxt[tblend + 2]); - if (gentables) - outn (" };\n"); + outn ("]])"); + footprint += sizeof(struct yy_trans_info) * (tblend + numecs + 1); - /* Table of pointers to start states. */ - if (gentables) - out_dec ("static const struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1); - else - outn ("static const struct yy_trans_info **yy_start_state_list =0;"); + out_dec ("m4_define([[M4_HOOK_STARTTABLE_SIZE]], [[%d]])", lastsc * 2 + 1); if (gentables) { - outn (" {"); - + outn ("m4_define([[M4_HOOK_STARTTABLE_BODY]], [[m4_dnl"); for (i = 0; i <= lastsc * 2; ++i) - out_dec (" &yy_transition[%d],\n", base[i]); + out_dec ("M4_HOOK_STATE_ENTRY_FORMAT(%d)", base[i]); - dataend (); + dataend (NULL); + outn("]])"); + footprint += sizeof(struct yy_trans_info *) * (lastsc * 2 + 1); } - if (useecs) + if (ctrl.useecs) genecs (); } @@ -443,20 +343,16 @@ static struct yytbl_data *mkecstbl (void) yytbl_data_init (tbl, YYTD_ID_EC); tbl->td_flags |= YYTD_DATA32; tbl->td_hilen = 0; - tbl->td_lolen = (flex_uint32_t) csize; + tbl->td_lolen = (flex_uint32_t) ctrl.csize; tbl->td_data = tdata = calloc(tbl->td_lolen, sizeof (flex_int32_t)); - for (i = 1; i < csize; ++i) { + for (i = 1; i < ctrl.csize; ++i) { ecgroup[i] = ABS (ecgroup[i]); tdata[i] = ecgroup[i]; } - buf_prints (&yydmap_buf, - "\t{YYTD_ID_EC, (void**)&yy_ec, sizeof(%s)},\n", - "YY_CHAR"); - return tbl; } @@ -467,23 +363,26 @@ void genecs (void) int ch, row; int numrows; - out_str_dec (get_yy_char_decl (), "yy_ec", csize); + out_dec ("m4_define([[M4_HOOK_ECSTABLE_SIZE]], [[%d]])", ctrl.csize); + outn ("m4_define([[M4_HOOK_ECSTABLE_BODY]], [[m4_dnl"); - for (ch = 1; ch < csize; ++ch) { + for (ch = 1; ch < ctrl.csize; ++ch) { ecgroup[ch] = ABS (ecgroup[ch]); mkdata (ecgroup[ch]); } - dataend (); + dataend (NULL); + outn("]])"); + footprint += sizeof(YY_CHAR) * ctrl.csize; - if (trace) { + if (env.trace) { fputs (_("\n\nEquivalence Classes:\n\n"), stderr); /* Print in 8 columns */ - numrows = csize / 8; + numrows = ctrl.csize / 8; for (row = 0; row < numrows; ++row) { - for (ch = row; ch < csize; ch += numrows) { + for (ch = row; ch < ctrl.csize; ch += numrows) { fprintf (stderr, "%4s = %-2d", readable_form (ch), ecgroup[ch]); @@ -495,150 +394,6 @@ void genecs (void) } } - -/* Generate the code to find the action number. */ - -void gen_find_action (void) -{ - if (fullspd) - indent_puts ("yy_act = yy_current_state[-1].yy_nxt;"); - - else if (fulltbl) - indent_puts ("yy_act = yy_accept[yy_current_state];"); - - else if (reject) { - indent_puts ("yy_current_state = *--YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_lp) = yy_accept[yy_current_state];"); - - if (!variable_trailing_context_rules) - outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); - if(reject_really_used) - outn ("find_rule: /* we branch to this label when backing up */"); - if (!variable_trailing_context_rules) - outn ("]])\n"); - - indent_puts - ("for ( ; ; ) /* until we find what rule we matched */"); - - ++indent_level; - - indent_puts ("{"); - - indent_puts - ("if ( YY_G(yy_lp) && YY_G(yy_lp) < yy_accept[yy_current_state + 1] )"); - ++indent_level; - indent_puts ("{"); - indent_puts ("yy_act = yy_acclist[YY_G(yy_lp)];"); - - if (variable_trailing_context_rules) { - indent_puts - ("if ( yy_act & YY_TRAILING_HEAD_MASK ||"); - indent_puts (" YY_G(yy_looking_for_trail_begin) )"); - ++indent_level; - indent_puts ("{"); - - indent_puts - ("if ( yy_act == YY_G(yy_looking_for_trail_begin) )"); - ++indent_level; - indent_puts ("{"); - indent_puts ("YY_G(yy_looking_for_trail_begin) = 0;"); - indent_puts ("yy_act &= ~YY_TRAILING_HEAD_MASK;"); - indent_puts ("break;"); - indent_puts ("}"); - --indent_level; - - indent_puts ("}"); - --indent_level; - - indent_puts - ("else if ( yy_act & YY_TRAILING_MASK )"); - ++indent_level; - indent_puts ("{"); - indent_puts - ("YY_G(yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK;"); - indent_puts - ("YY_G(yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK;"); - - if (real_reject) { - /* Remember matched text in case we back up - * due to REJECT. - */ - indent_puts - ("YY_G(yy_full_match) = yy_cp;"); - indent_puts - ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_full_lp) = YY_G(yy_lp);"); - } - - indent_puts ("}"); - --indent_level; - - indent_puts ("else"); - ++indent_level; - indent_puts ("{"); - indent_puts ("YY_G(yy_full_match) = yy_cp;"); - indent_puts - ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_full_lp) = YY_G(yy_lp);"); - indent_puts ("break;"); - indent_puts ("}"); - --indent_level; - - indent_puts ("++YY_G(yy_lp);"); - indent_puts ("goto find_rule;"); - } - - else { - /* Remember matched text in case we back up due to - * trailing context plus REJECT. - */ - ++indent_level; - indent_puts ("{"); - indent_puts ("YY_G(yy_full_match) = yy_cp;"); - indent_puts ("break;"); - indent_puts ("}"); - --indent_level; - } - - indent_puts ("}"); - --indent_level; - - indent_puts ("--yy_cp;"); - - /* We could consolidate the following two lines with those at - * the beginning, but at the cost of complaints that we're - * branching inside a loop. - */ - indent_puts ("yy_current_state = *--YY_G(yy_state_ptr);"); - indent_puts ("YY_G(yy_lp) = yy_accept[yy_current_state];"); - - indent_puts ("}"); - - --indent_level; - } - - else { /* compressed */ - indent_puts ("yy_act = yy_accept[yy_current_state];"); - - if (interactive && !reject) { - /* Do the guaranteed-needed backing up to figure out - * the match. - */ - indent_puts ("if ( yy_act == 0 )"); - ++indent_level; - indent_puts ("{ /* have to back up */"); - indent_puts - ("yy_cp = YY_G(yy_last_accepting_cpos);"); - indent_puts - ("yy_current_state = YY_G(yy_last_accepting_state);"); - indent_puts - ("yy_act = yy_accept[yy_current_state];"); - indent_puts ("}"); - --indent_level; - } - } -} - /* mkftbl - make the full table and return the struct . * you should call mkecstbl() after this. */ @@ -666,14 +421,11 @@ struct yytbl_data *mkftbl (void) tdata[i] = anum; - if (trace && anum) + if (env.trace && anum) fprintf (stderr, _("state # %d accepts: [%d]\n"), i, anum); } - buf_prints (&yydmap_buf, - "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", - long_align ? "flex_int32_t" : "flex_int16_t"); return tbl; } @@ -684,25 +436,30 @@ void genftbl (void) { int i; int end_of_buffer_action = num_rules + 1; - - out_str_dec (long_align ? get_int32_decl () : get_int16_decl (), - "yy_accept", lastdfa + 1); + struct packtype_t *ptype = optimize_pack(num_rules + 1); dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; + outn ("m4_define([[M4_HOOK_NEED_ACCEPT]], 1)"); + out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_ACCEPT_SIZE]], [[%d]])", lastdfa + 1); + outn ("m4_define([[M4_HOOK_ACCEPT_BODY]], [[m4_dnl"); + for (i = 1; i <= lastdfa; ++i) { int anum = dfaacc[i].dfaacc_state; mkdata (anum); - if (trace && anum) + if (env.trace && anum) fprintf (stderr, _("state # %d accepts: [%d]\n"), i, anum); } - dataend (); + dataend (NULL); + outn("]])"); + footprint += (lastdfa + 1) * ptype->width; - if (useecs) + if (ctrl.useecs) genecs (); /* Don't have to dump the actual full table entries - they were @@ -710,356 +467,18 @@ void genftbl (void) */ } - -/* Generate the code to find the next compressed-table state. */ - -void gen_next_compressed_state (char *char_map) -{ - indent_put2s ("YY_CHAR yy_c = %s;", char_map); - - /* Save the backing-up info \before/ computing the next state - * because we always compute one more state than needed - we - * always proceed until we reach a jam state - */ - gen_backing_up (); - - indent_puts - ("while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )"); - ++indent_level; - indent_puts ("{"); - indent_puts ("yy_current_state = (int) yy_def[yy_current_state];"); - - if (usemecs) { - /* We've arrange it so that templates are never chained - * to one another. This means we can afford to make a - * very simple test to see if we need to convert to - * yy_c's meta-equivalence class without worrying - * about erroneously looking up the meta-equivalence - * class twice - */ - do_indent (); - - /* lastdfa + 2 is the beginning of the templates */ - out_dec ("if ( yy_current_state >= %d )\n", lastdfa + 2); - - ++indent_level; - indent_puts ("yy_c = yy_meta[yy_c];"); - --indent_level; - } - - indent_puts ("}"); - --indent_level; - - indent_puts - ("yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];"); -} - - -/* Generate the code to find the next match. */ - -void gen_next_match (void) -{ - /* NOTE - changes in here should be reflected in gen_next_state() and - * gen_NUL_trans(). - */ - char *char_map = useecs ? - "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)"; - - char *char_map_2 = useecs ? - "yy_ec[YY_SC_TO_UI(*++yy_cp)] " : "YY_SC_TO_UI(*++yy_cp)"; - - if (fulltbl) { - if (gentables) - indent_put2s - ("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )", - char_map); - else - indent_put2s - ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s ]) > 0 )", - char_map); - - ++indent_level; - - if (num_backing_up > 0) { - indent_puts ("{"); - gen_backing_up (); - outc ('\n'); - } - - indent_puts ("++yy_cp;"); - - if (num_backing_up > 0) - - indent_puts ("}"); - - --indent_level; - - outc ('\n'); - indent_puts ("yy_current_state = -yy_current_state;"); - } - - else if (fullspd) { - indent_puts ("{"); - indent_puts - ("const struct yy_trans_info *yy_trans_info;\n"); - indent_puts ("YY_CHAR yy_c;\n"); - indent_put2s ("for ( yy_c = %s;", char_map); - indent_puts - (" (yy_trans_info = &yy_current_state[yy_c])->"); - indent_puts ("yy_verify == yy_c;"); - indent_put2s (" yy_c = %s )", char_map_2); - - ++indent_level; - - if (num_backing_up > 0) - indent_puts ("{"); - - indent_puts ("yy_current_state += yy_trans_info->yy_nxt;"); - - if (num_backing_up > 0) { - outc ('\n'); - gen_backing_up (); - indent_puts ("}"); - } - - --indent_level; - indent_puts ("}"); - } - - else { /* compressed */ - indent_puts ("do"); - - ++indent_level; - indent_puts ("{"); - - gen_next_state (false); - - indent_puts ("++yy_cp;"); - - - indent_puts ("}"); - --indent_level; - - do_indent (); - - if (interactive) - out_dec ("while ( yy_base[yy_current_state] != %d );\n", jambase); - else - out_dec ("while ( yy_current_state != %d );\n", - jamstate); - - if (!reject && !interactive) { - /* Do the guaranteed-needed backing up to figure out - * the match. - */ - indent_puts - ("yy_cp = YY_G(yy_last_accepting_cpos);"); - indent_puts - ("yy_current_state = YY_G(yy_last_accepting_state);"); - } - } -} - - -/* Generate the code to find the next state. */ - -void gen_next_state (int worry_about_NULs) -{ /* NOTE - changes in here should be reflected in gen_next_match() */ - char char_map[256]; - - if (worry_about_NULs && !nultrans) { - if (useecs) - snprintf (char_map, sizeof(char_map), - "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)", - NUL_ec); - else - snprintf (char_map, sizeof(char_map), - "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", - NUL_ec); - } - - else - strcpy (char_map, useecs ? - "yy_ec[YY_SC_TO_UI(*yy_cp)] " : - "YY_SC_TO_UI(*yy_cp)"); - - if (worry_about_NULs && nultrans) { - if (!fulltbl && !fullspd) - /* Compressed tables back up *before* they match. */ - gen_backing_up (); - - indent_puts ("if ( *yy_cp )"); - ++indent_level; - indent_puts ("{"); - } - - if (fulltbl) { - if (gentables) - indent_put2s - ("yy_current_state = yy_nxt[yy_current_state][%s];", - char_map); - else - indent_put2s - ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s];", - char_map); - } - - else if (fullspd) - indent_put2s - ("yy_current_state += yy_current_state[%s].yy_nxt;", - char_map); - - else - gen_next_compressed_state (char_map); - - if (worry_about_NULs && nultrans) { - - indent_puts ("}"); - --indent_level; - indent_puts ("else"); - ++indent_level; - indent_puts - ("yy_current_state = yy_NUL_trans[yy_current_state];"); - --indent_level; - } - - if (fullspd || fulltbl) - gen_backing_up (); - - if (reject) - indent_puts ("*YY_G(yy_state_ptr)++ = yy_current_state;"); -} - - -/* Generate the code to make a NUL transition. */ - -void gen_NUL_trans (void) -{ /* NOTE - changes in here should be reflected in gen_next_match() */ - /* Only generate a definition for "yy_cp" if we'll generate code - * that uses it. Otherwise lint and the like complain. - */ - int need_backing_up = (num_backing_up > 0 && !reject); - - if (need_backing_up && (!nultrans || fullspd || fulltbl)) - /* We're going to need yy_cp lying around for the call - * below to gen_backing_up(). - */ - indent_puts ("char *yy_cp = YY_G(yy_c_buf_p);"); - - outc ('\n'); - - if (nultrans) { - indent_puts - ("yy_current_state = yy_NUL_trans[yy_current_state];"); - indent_puts ("yy_is_jam = (yy_current_state == 0);"); - } - - else if (fulltbl) { - do_indent (); - if (gentables) - out_dec ("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec); - else - out_dec ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %d];\n", NUL_ec); - indent_puts ("yy_is_jam = (yy_current_state <= 0);"); - } - - else if (fullspd) { - do_indent (); - out_dec ("int yy_c = %d;\n", NUL_ec); - - indent_puts - ("const struct yy_trans_info *yy_trans_info;\n"); - indent_puts - ("yy_trans_info = &yy_current_state[(unsigned int) yy_c];"); - indent_puts ("yy_current_state += yy_trans_info->yy_nxt;"); - - indent_puts - ("yy_is_jam = (yy_trans_info->yy_verify != yy_c);"); - } - - else { - char NUL_ec_str[20]; - - snprintf (NUL_ec_str, sizeof(NUL_ec_str), "%d", NUL_ec); - gen_next_compressed_state (NUL_ec_str); - - do_indent (); - out_dec ("yy_is_jam = (yy_current_state == %d);\n", - jamstate); - - if (reject) { - /* Only stack this state if it's a transition we - * actually make. If we stack it on a jam, then - * the state stack and yy_c_buf_p get out of sync. - */ - indent_puts ("if ( ! yy_is_jam )"); - ++indent_level; - indent_puts - ("*YY_G(yy_state_ptr)++ = yy_current_state;"); - --indent_level; - } - } - - /* If we've entered an accepting state, back up; note that - * compressed tables have *already* done such backing up, so - * we needn't bother with it again. - */ - if (need_backing_up && (fullspd || fulltbl)) { - outc ('\n'); - indent_puts ("if ( ! yy_is_jam )"); - ++indent_level; - indent_puts ("{"); - gen_backing_up (); - indent_puts ("}"); - --indent_level; - } -} - - -/* Generate the code to find the start state. */ - -void gen_start_state (void) -{ - if (fullspd) { - if (bol_needed) { - indent_puts - ("yy_current_state = yy_start_state_list[YY_G(yy_start) + YY_AT_BOL()];"); - } - else - indent_puts - ("yy_current_state = yy_start_state_list[YY_G(yy_start)];"); - } - - else { - indent_puts ("yy_current_state = YY_G(yy_start);"); - - if (bol_needed) - indent_puts ("yy_current_state += YY_AT_BOL();"); - - if (reject) { - /* Set up for storing up states. */ - outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); - indent_puts - ("YY_G(yy_state_ptr) = YY_G(yy_state_buf);"); - indent_puts - ("*YY_G(yy_state_ptr)++ = yy_current_state;"); - outn ("]])"); - } - } -} - - /* gentabs - generate data statements for the transition tables */ void gentabs (void) { - int i, j, k, *accset, nacc, *acc_array, total_states; + int sz, i, j, k, *accset, nacc, *acc_array, total_states; int end_of_buffer_action = num_rules + 1; struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0, - *yydef_tbl = 0, *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl=0; + *yydef_tbl = 0, *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl=0; flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0, - *yynxt_data = 0, *yychk_data = 0, *yyacclist_data=0; + *yynxt_data = 0, *yychk_data = 0, *yyacclist_data=0; flex_int32_t yybase_curr = 0, yyacclist_curr=0,yyacc_curr=0; + struct packtype_t *ptype; acc_array = allocate_integer_array (current_max_dfas); nummt = 0; @@ -1085,22 +504,20 @@ void gentabs (void) EOB_accepting_list[1] = end_of_buffer_action; accsiz[end_of_buffer_state] = 1; dfaacc[end_of_buffer_state].dfaacc_set = - EOB_accepting_list; - - out_str_dec (long_align ? get_int32_decl () : - get_int16_decl (), "yy_acclist", MAX (numas, - 1) + 1); - - buf_prints (&yydmap_buf, - "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n", - long_align ? "flex_int32_t" : "flex_int16_t"); - - yyacclist_tbl = calloc(1,sizeof(struct yytbl_data)); - yytbl_data_init (yyacclist_tbl, YYTD_ID_ACCLIST); - yyacclist_tbl->td_lolen = (flex_uint32_t) (MAX(numas,1) + 1); - yyacclist_tbl->td_data = yyacclist_data = - calloc(yyacclist_tbl->td_lolen, sizeof (flex_int32_t)); - yyacclist_curr = 1; + EOB_accepting_list; + + sz = MAX (numas, 1) + 1; + ptype = optimize_pack(sz); + out_str ("m4_define([[M4_HOOK_ACCLIST_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_ACCLIST_SIZE]], [[%d]])", sz); + outn ("m4_define([[M4_HOOK_ACCLIST_BODY]], [[m4_dnl"); + + yyacclist_tbl = calloc(1,sizeof(struct yytbl_data)); + yytbl_data_init (yyacclist_tbl, YYTD_ID_ACCLIST); + yyacclist_tbl->td_lolen = (flex_uint32_t) (MAX(numas,1) + 1); + yyacclist_tbl->td_data = yyacclist_data = + calloc(yyacclist_tbl->td_lolen, sizeof (flex_int32_t)); + yyacclist_curr = 1; j = 1; /* index into "yy_acclist" array */ @@ -1111,7 +528,7 @@ void gentabs (void) accset = dfaacc[i].dfaacc_set; nacc = accsiz[i]; - if (trace) + if (env.trace) fprintf (stderr, _("state # %d accepts: "), i); @@ -1136,9 +553,9 @@ void gentabs (void) } mkdata (accnum); - yyacclist_data[yyacclist_curr++] = accnum; + yyacclist_data[yyacclist_curr++] = accnum; - if (trace) { + if (env.trace) { fprintf (stderr, "[%d]", accset[k]); @@ -1156,19 +573,21 @@ void gentabs (void) /* add accepting number for the "jam" state */ acc_array[i] = j; - dataend (); - if (tablesext) { - yytbl_data_compress (yyacclist_tbl); - if (yytbl_data_fwrite (&tableswr, yyacclist_tbl) < 0) - flexerror (_("Could not write yyacclist_tbl")); - yytbl_data_destroy (yyacclist_tbl); - yyacclist_tbl = NULL; - } + dataend (NULL); + outn("]])"); + footprint += sz * ptype->width; + if (tablesext) { + yytbl_data_compress (yyacclist_tbl); + if (yytbl_data_fwrite (&tableswr, yyacclist_tbl) < 0) + flexerror (_("Could not write yyacclist_tbl")); + yytbl_data_destroy (yyacclist_tbl); + yyacclist_tbl = NULL; + } } else { dfaacc[end_of_buffer_state].dfaacc_state = - end_of_buffer_action; + end_of_buffer_action; for (i = 1; i <= lastdfa; ++i) acc_array[i] = dfaacc[i].dfaacc_state; @@ -1187,7 +606,7 @@ void gentabs (void) /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays * beginning at 0 and for "jam" state. */ - k = lastdfa + 2; + sz = lastdfa + 2; if (reject) /* We put a "cap" on the table associating lists of accepting @@ -1195,27 +614,27 @@ void gentabs (void) * where the end of an accepting list is by looking at where * the list for the next state starts. */ - ++k; + ++sz; - out_str_dec (long_align ? get_int32_decl () : get_int16_decl (), - "yy_accept", k); - - buf_prints (&yydmap_buf, - "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", - long_align ? "flex_int32_t" : "flex_int16_t"); + /* Note that this table is alternately defined if ctrl.fulltbl */ + ptype = optimize_pack(sz); + outn ("m4_define([[M4_HOOK_NEED_ACCEPT]], 1)"); + out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_ACCEPT_SIZE]], [[%d]])", sz); + outn ("m4_define([[M4_HOOK_ACCEPT_BODY]], [[m4_dnl"); yyacc_tbl = calloc(1, sizeof (struct yytbl_data)); yytbl_data_init (yyacc_tbl, YYTD_ID_ACCEPT); - yyacc_tbl->td_lolen = (flex_uint32_t) k; + yyacc_tbl->td_lolen = (flex_uint32_t) sz; yyacc_tbl->td_data = yyacc_data = - calloc(yyacc_tbl->td_lolen, sizeof (flex_int32_t)); - yyacc_curr=1; + calloc(yyacc_tbl->td_lolen, sizeof (flex_int32_t)); + yyacc_curr=1; for (i = 1; i <= lastdfa; ++i) { mkdata (acc_array[i]); yyacc_data[yyacc_curr++] = acc_array[i]; - if (!reject && trace && acc_array[i]) + if (!reject && env.trace && acc_array[i]) fprintf (stderr, _("state # %d accepts: [%d]\n"), i, acc_array[i]); } @@ -1230,7 +649,10 @@ void gentabs (void) yyacc_data[yyacc_curr++] = acc_array[i]; } - dataend (); + dataend (NULL); + outn ("]])"); + footprint += sz * ptype->width; + if (tablesext) { yytbl_data_compress (yyacc_tbl); if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0) @@ -1240,7 +662,7 @@ void gentabs (void) yyacc_tbl = NULL; /* End generating yy_accept */ - if (useecs) { + if (ctrl.useecs) { genecs (); if (tablesext) { @@ -1255,7 +677,7 @@ void gentabs (void) } } - if (usemecs) { + if (ctrl.usemecs) { /* Begin generating yy_meta */ /* Write out meta-equivalence classes (used to index * templates with). @@ -1265,20 +687,17 @@ void gentabs (void) yytbl_data_init (yymeta_tbl, YYTD_ID_META); yymeta_tbl->td_lolen = (flex_uint32_t) (numecs + 1); yymeta_tbl->td_data = yymecs_data = - calloc(yymeta_tbl->td_lolen, - sizeof (flex_int32_t)); + calloc(yymeta_tbl->td_lolen, + sizeof (flex_int32_t)); - if (trace) + if (env.trace) fputs (_("\n\nMeta-Equivalence Classes:\n"), stderr); - - out_str_dec (get_yy_char_decl (), "yy_meta", numecs + 1); - buf_prints (&yydmap_buf, - "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n", - "YY_CHAR"); - + out_dec ("m4_define([[M4_HOOK_MECSTABLE_SIZE]], [[%d]])", numecs+1); + outn ("m4_define([[M4_HOOK_MECSTABLE_BODY]], [[m4_dnl"); + for (i = 1; i <= numecs; ++i) { - if (trace) + if (env.trace) fprintf (stderr, "%d = %d\n", i, ABS (tecbck[i])); @@ -1286,7 +705,9 @@ void gentabs (void) yymecs_data[i] = ABS (tecbck[i]); } - dataend (); + dataend (NULL); + outn ("]])"); + footprint += sizeof(YY_CHAR) * (numecs + 1); if (tablesext) { yytbl_data_compress (yymeta_tbl); if (yytbl_data_fwrite (&tableswr, yymeta_tbl) < 0) @@ -1300,20 +721,18 @@ void gentabs (void) total_states = lastdfa + numtemps; /* Begin generating yy_base */ - out_str_dec ((tblend >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), - "yy_base", total_states + 1); - - buf_prints (&yydmap_buf, - "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n", - (tblend >= INT16_MAX - || long_align) ? "flex_int32_t" : "flex_int16_t"); + sz = total_states + 1; + ptype = optimize_pack(sz); + out_str ("m4_define([[M4_HOOK_BASE_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_BASE_SIZE]], [[%d]])", sz); + outn ("m4_define([[M4_HOOK_BASE_BODY]], [[m4_dnl"); + yybase_tbl = calloc (1, sizeof (struct yytbl_data)); yytbl_data_init (yybase_tbl, YYTD_ID_BASE); yybase_tbl->td_lolen = (flex_uint32_t) (total_states + 1); yybase_tbl->td_data = yybase_data = - calloc(yybase_tbl->td_lolen, - sizeof (flex_int32_t)); + calloc(yybase_tbl->td_lolen, + sizeof (flex_int32_t)); yybase_curr = 1; for (i = 1; i <= lastdfa; ++i) { @@ -1345,7 +764,10 @@ void gentabs (void) def[i] = jamstate; } - dataend (); + dataend (NULL); + outn ("]])"); + footprint += sz * ptype->width; + if (tablesext) { yytbl_data_compress (yybase_tbl); if (yytbl_data_fwrite (&tableswr, yybase_tbl) < 0) @@ -1357,27 +779,26 @@ void gentabs (void) /* Begin generating yy_def */ - out_str_dec ((total_states >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), - "yy_def", total_states + 1); - - buf_prints (&yydmap_buf, - "\t{YYTD_ID_DEF, (void**)&yy_def, sizeof(%s)},\n", - (total_states >= INT16_MAX - || long_align) ? "flex_int32_t" : "flex_int16_t"); + ptype = optimize_pack(total_states + 1); + out_str ("m4_define([[M4_HOOK_DEF_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_DEF_SIZE]], [[%d]])", total_states + 1); + outn ("m4_define([[M4_HOOK_DEF_BODY]], [[m4_dnl"); yydef_tbl = calloc(1, sizeof (struct yytbl_data)); yytbl_data_init (yydef_tbl, YYTD_ID_DEF); - yydef_tbl->td_lolen = (flex_uint32_t) (total_states + 1); + yydef_tbl->td_lolen = (flex_uint32_t)(total_states + 1); yydef_tbl->td_data = yydef_data = - calloc(yydef_tbl->td_lolen, sizeof (flex_int32_t)); + calloc(yydef_tbl->td_lolen, sizeof (flex_int32_t)); for (i = 1; i <= total_states; ++i) { mkdata (def[i]); yydef_data[i] = def[i]; } - dataend (); + dataend (NULL); + outn ("]])"); + footprint += (total_states + 1) * ptype->width; + if (tablesext) { yytbl_data_compress (yydef_tbl); if (yytbl_data_fwrite (&tableswr, yydef_tbl) < 0) @@ -1388,21 +809,19 @@ void gentabs (void) /* End generating yy_def */ - /* Begin generating yy_nxt */ - out_str_dec ((total_states >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), "yy_nxt", - tblend + 1); - - buf_prints (&yydmap_buf, - "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", - (total_states >= INT16_MAX - || long_align) ? "flex_int32_t" : "flex_int16_t"); + ptype = optimize_pack(tblend + 1); + /* Note: Used when !ctrl.fulltbl && !ctrl.fullspd). + * (Alternately defined when ctrl.fullspd) + */ + out_str ("m4_define([[M4_HOOK_YYNXT_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_YYNXT_SIZE]], [[%d]])", tblend + 1); + outn ("m4_define([[M4_HOOK_YYNXT_BODY]], [[m4_dnl"); yynxt_tbl = calloc (1, sizeof (struct yytbl_data)); yytbl_data_init (yynxt_tbl, YYTD_ID_NXT); yynxt_tbl->td_lolen = (flex_uint32_t) (tblend + 1); yynxt_tbl->td_data = yynxt_data = - calloc (yynxt_tbl->td_lolen, sizeof (flex_int32_t)); + calloc (yynxt_tbl->td_lolen, sizeof (flex_int32_t)); for (i = 1; i <= tblend; ++i) { /* Note, the order of the following test is important. @@ -1415,7 +834,10 @@ void gentabs (void) yynxt_data[i] = nxt[i]; } - dataend (); + dataend (NULL); + outn("]])"); + footprint += ptype->width * (tblend + 1); + if (tablesext) { yytbl_data_compress (yynxt_tbl); if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0) @@ -1426,20 +848,16 @@ void gentabs (void) /* End generating yy_nxt */ /* Begin generating yy_chk */ - out_str_dec ((total_states >= INT16_MAX || long_align) ? - get_int32_decl () : get_int16_decl (), "yy_chk", - tblend + 1); - - buf_prints (&yydmap_buf, - "\t{YYTD_ID_CHK, (void**)&yy_chk, sizeof(%s)},\n", - (total_states >= INT16_MAX - || long_align) ? "flex_int32_t" : "flex_int16_t"); - + ptype = optimize_pack(tblend + 1); + out_str ("m4_define([[M4_HOOK_CHK_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_CHK_SIZE]], [[%d]])", tblend + 1); + outn ("m4_define([[M4_HOOK_CHK_BODY]], [[m4_dnl"); + yychk_tbl = calloc (1, sizeof (struct yytbl_data)); yytbl_data_init (yychk_tbl, YYTD_ID_CHK); yychk_tbl->td_lolen = (flex_uint32_t) (tblend + 1); yychk_tbl->td_data = yychk_data = - calloc(yychk_tbl->td_lolen, sizeof (flex_int32_t)); + calloc(yychk_tbl->td_lolen, sizeof (flex_int32_t)); for (i = 1; i <= tblend; ++i) { if (chk[i] == 0) @@ -1449,7 +867,10 @@ void gentabs (void) yychk_data[i] = chk[i]; } - dataend (); + dataend (NULL); + outn ("]])"); + footprint += ptype->width * (tblend + 1); + if (tablesext) { yytbl_data_compress (yychk_tbl); if (yytbl_data_fwrite (&tableswr, yychk_tbl) < 0) @@ -1463,141 +884,44 @@ void gentabs (void) } -/* Write out a formatted string (with a secondary string argument) at the - * current indentation level, adding a final newline. - */ - -void indent_put2s (const char *fmt, const char *arg) +void visible_define (const char *symname) { - do_indent (); - out_str (fmt, arg); - outn (""); + out_m4_define(symname, NULL); + comment(symname); + outc ('\n'); } - -/* Write out a string at the current indentation level, adding a final - * newline. - */ - -void indent_puts (const char *str) +void visible_define_str (const char *symname, const char *val) { - do_indent (); - outn (str); + char buf[128]; + out_m4_define(symname, val); + snprintf(buf, sizeof(buf), "%s = %s", symname, val); + comment(buf); + outc ('\n'); } +void visible_define_int (const char *symname, const int val) +{ + char nbuf[24], buf[128]; + snprintf(nbuf, sizeof(nbuf), "%d", val); + out_m4_define(symname, nbuf); + snprintf(buf, sizeof(buf), "%s = %d", symname, val); + comment(buf); + outc ('\n'); +} -/* make_tables - generate transition tables and finishes generating output file +/* make_tables - generate transition tables */ void make_tables (void) { + char buf[128]; int i; - int did_eof_rule = false; struct yytbl_data *yynultrans_tbl = NULL; - - skelout (); /* %% [2.0] - break point in skel */ - - /* First, take care of YY_DO_BEFORE_ACTION depending on yymore - * being used. - */ - set_indent (1); - - if (yymore_used && !yytext_is_array) { - indent_puts ("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\"); - indent_puts - ("yyleng = (int) (yy_cp - YY_G(yytext_ptr)); \\"); - } - - else - indent_puts ("yyleng = (int) (yy_cp - yy_bp); \\"); - - /* Now also deal with copying yytext_ptr to yytext if needed. */ - skelout (); /* %% [3.0] - break point in skel */ - if (yytext_is_array) { - if (yymore_used) - indent_puts - ("if ( yyleng + YY_G(yy_more_offset) >= YYLMAX ) \\"); - else - indent_puts ("if ( yyleng >= YYLMAX ) \\"); - - ++indent_level; - indent_puts - ("YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\"); - --indent_level; - - if (yymore_used) { - indent_puts - ("yy_flex_strncpy( &yytext[YY_G(yy_more_offset)], YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); - indent_puts ("yyleng += YY_G(yy_more_offset); \\"); - indent_puts - ("YY_G(yy_prev_more_offset) = YY_G(yy_more_offset); \\"); - indent_puts ("YY_G(yy_more_offset) = 0; \\"); - } - else { - indent_puts - ("yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); - } - } - - set_indent (0); - - skelout (); /* %% [4.0] - break point in skel */ - - /* This is where we REALLY begin generating the tables. */ - out_dec ("#define YY_NUM_RULES %d\n", num_rules); - out_dec ("#define YY_END_OF_BUFFER %d\n", num_rules + 1); - - if (fullspd) { - /* Need to define the transet type as a size large - * enough to hold the biggest offset. - */ - int total_table_size = tblend + numecs + 1; - char *trans_offset_type = - (total_table_size >= INT16_MAX || long_align) ? - "flex_int32_t" : "flex_int16_t"; - - set_indent (0); - indent_puts ("struct yy_trans_info"); - ++indent_level; - indent_puts ("{"); - - /* We require that yy_verify and yy_nxt must be of the same size int. */ - indent_put2s ("%s yy_verify;", trans_offset_type); - - /* In cases where its sister yy_verify *is* a "yes, there is - * a transition", yy_nxt is the offset (in records) to the - * next state. In most cases where there is no transition, - * the value of yy_nxt is irrelevant. If yy_nxt is the -1th - * record of a state, though, then yy_nxt is the action number - * for that state. - */ - - indent_put2s ("%s yy_nxt;", trans_offset_type); - indent_puts ("};"); - --indent_level; - } - else { - /* We generate a bogus 'struct yy_trans_info' data type - * so we can guarantee that it is always declared in the skel. - * This is so we can compile "sizeof(struct yy_trans_info)" - * in any scanner. - */ - indent_puts - ("/* This struct is not used in this scanner,"); - indent_puts (" but its presence is necessary. */"); - indent_puts ("struct yy_trans_info"); - ++indent_level; - indent_puts ("{"); - indent_puts ("flex_int32_t yy_verify;"); - indent_puts ("flex_int32_t yy_nxt;"); - indent_puts ("};"); - --indent_level; - } - - if (fullspd) { + if (ctrl.fullspd) { genctbl (); if (tablesext) { struct yytbl_data *tbl; @@ -1615,7 +939,7 @@ void make_tables (void) yytbl_data_destroy (tbl); tbl = 0; - if (useecs) { + if (ctrl.useecs) { tbl = mkecstbl (); yytbl_data_compress (tbl); if (yytbl_data_fwrite (&tableswr, tbl) < 0) @@ -1626,19 +950,23 @@ void make_tables (void) } } } - else if (fulltbl) { + else if (ctrl.fulltbl) { genftbl (); if (tablesext) { struct yytbl_data *tbl; + /* Alternately defined if !ctrl.ffullspd && !ctrl.fulltbl */ + struct packtype_t *ptype; tbl = mkftbl (); yytbl_data_compress (tbl); + ptype = optimize_pack(tbl->td_lolen); + out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name); if (yytbl_data_fwrite (&tableswr, tbl) < 0) flexerror (_("Could not write ftbl")); yytbl_data_destroy (tbl); tbl = 0; - if (useecs) { + if (ctrl.useecs) { tbl = mkecstbl (); yytbl_data_compress (tbl); if (yytbl_data_fwrite (&tableswr, tbl) < 0) @@ -1652,7 +980,28 @@ void make_tables (void) else gentabs (); - if (do_yylineno) { + snprintf(buf, sizeof(buf), "footprint: %ld bytes\n", footprint); + comment(buf); + outc ('\n'); + + // Only at this point do we know if the automaton has backups. + // Some m4 conditionals require this information. + + comment("m4 controls begin\n"); + + if (num_backing_up > 0) + visible_define ( "M4_MODE_HAS_BACKING_UP"); + + // These are used for NUL transitions + if ((num_backing_up > 0 && !reject) && (!nultrans || ctrl.fullspd || ctrl.fulltbl)) + visible_define ( "M4_MODE_NEED_YY_CP"); + if ((num_backing_up > 0 && !reject) && (ctrl.fullspd || ctrl.fulltbl)) + visible_define ( "M4_MODE_NULTRANS_WRAP"); + + comment("m4 controls end\n"); + out ("\n"); + + if (ctrl.do_yylineno) { geneoltbl (); @@ -1668,52 +1017,42 @@ void make_tables (void) } } - /* Definitions for backing up. We don't need them if REJECT - * is being used because then we use an alternative backin-up - * technique instead. - */ - if (num_backing_up > 0 && !reject) { - if (!C_plus_plus && !reentrant) { - indent_puts - ("static yy_state_type yy_last_accepting_state;"); - indent_puts - ("static char *yy_last_accepting_cpos;\n"); - } - } - if (nultrans) { flex_int32_t *yynultrans_data = 0; /* Begin generating yy_NUL_trans */ - out_str_dec (get_state_decl (), "yy_NUL_trans", - lastdfa + 1); - buf_prints (&yydmap_buf, - "\t{YYTD_ID_NUL_TRANS, (void**)&yy_NUL_trans, sizeof(%s)},\n", - (fullspd) ? "struct yy_trans_info*" : - "flex_int32_t"); + out_str ("m4_define([[M4_HOOK_NULTRANS_TYPE]], [[%s]])", (ctrl.fullspd) ? "struct yy_trans_info*" : "M4_HOOK_INT32"); + out_dec ("m4_define([[M4_HOOK_NULTRANS_SIZE]], [[%d]])", lastdfa + 1); + outn ("m4_define([[M4_HOOK_NULTRANS_BODY]], [[m4_dnl"); yynultrans_tbl = calloc(1, sizeof (struct yytbl_data)); yytbl_data_init (yynultrans_tbl, YYTD_ID_NUL_TRANS); - if (fullspd) + // Performance kludge for C. Gives a small improvement + // in table loading time. + if (ctrl.fullspd && ctrl.have_state_entry_format) yynultrans_tbl->td_flags |= YYTD_PTRANS; yynultrans_tbl->td_lolen = (flex_uint32_t) (lastdfa + 1); yynultrans_tbl->td_data = yynultrans_data = - calloc(yynultrans_tbl->td_lolen, - sizeof (flex_int32_t)); + calloc(yynultrans_tbl->td_lolen, + sizeof (flex_int32_t)); for (i = 1; i <= lastdfa; ++i) { - if (fullspd) { + if ((yynultrans_tbl->td_flags & YYTD_PTRANS) != 0) { + // Only works in very C-like languages out_dec (" &yy_transition[%d],\n", base[i]); yynultrans_data[i] = base[i]; } else { + // This will work anywhere mkdata (nultrans[i]); yynultrans_data[i] = nultrans[i]; } } - dataend (); + dataend (NULL); + outn("]])"); + footprint += (lastdfa + 1) * (ctrl.fullspd ? sizeof(struct yy_trans_info *) : sizeof(int32_t)); if (tablesext) { yytbl_data_compress (yynultrans_tbl); if (yytbl_data_fwrite (&tableswr, yynultrans_tbl) < @@ -1725,440 +1064,23 @@ void make_tables (void) if (yynultrans_tbl != NULL) { yytbl_data_destroy (yynultrans_tbl); yynultrans_tbl = NULL; - } + } /* End generating yy_NUL_trans */ } - if (!C_plus_plus && !reentrant) { - indent_puts ("extern int yy_flex_debug;"); - indent_put2s ("int yy_flex_debug = %s;\n", - ddebug ? "1" : "0"); - } + if (ctrl.ddebug) { /* Spit out table mapping rules to line numbers. */ + /* Policy choice: we don't include this space + * in the table metering. + */ + struct packtype_t *ptype = optimize_pack(num_rules); + out_str ("m4_define([[M4_HOOK_DEBUGTABLE_TYPE]], [[%s]])", ptype->name); + out_dec ("m4_define([[M4_HOOK_DEBUGTABLE_SIZE]], [[%d]])", num_rules); + outn ("m4_define([[M4_HOOK_DEBUGTABLE_BODY]], [[m4_dnl"); - if (ddebug) { /* Spit out table mapping rules to line numbers. */ - out_str_dec (long_align ? get_int32_decl () : - get_int16_decl (), "yy_rule_linenum", - num_rules); for (i = 1; i < num_rules; ++i) mkdata (rule_linenum[i]); - dataend (); - } - - if (reject) { - outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); - /* Declare state buffer variables. */ - if (!C_plus_plus && !reentrant) { - outn ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;"); - outn ("static char *yy_full_match;"); - outn ("static int yy_lp;"); - } - - if (variable_trailing_context_rules) { - if (!C_plus_plus && !reentrant) { - outn ("static int yy_looking_for_trail_begin = 0;"); - outn ("static int yy_full_lp;"); - outn ("static int *yy_full_state;"); - } - - out_hex ("#define YY_TRAILING_MASK 0x%x\n", - (unsigned int) YY_TRAILING_MASK); - out_hex ("#define YY_TRAILING_HEAD_MASK 0x%x\n", - (unsigned int) YY_TRAILING_HEAD_MASK); - } - - outn ("#define REJECT \\"); - outn ("{ \\"); - outn ("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */ \\"); - outn ("yy_cp = YY_G(yy_full_match); /* restore poss. backed-over text */ \\"); - - if (variable_trailing_context_rules) { - outn ("YY_G(yy_lp) = YY_G(yy_full_lp); /* restore orig. accepting pos. */ \\"); - outn ("YY_G(yy_state_ptr) = YY_G(yy_full_state); /* restore orig. state */ \\"); - outn ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\"); - } - - outn ("++YY_G(yy_lp); \\"); - outn ("goto find_rule; \\"); - - outn ("}"); - outn ("]])\n"); - } - - else { - outn ("/* The intent behind this definition is that it'll catch"); - outn (" * any uses of REJECT which flex missed."); - outn (" */"); - outn ("#define REJECT reject_used_but_not_detected"); - } - - if (yymore_used) { - if (!C_plus_plus) { - if (yytext_is_array) { - if (!reentrant){ - indent_puts ("static int yy_more_offset = 0;"); - indent_puts ("static int yy_prev_more_offset = 0;"); - } - } - else if (!reentrant) { - indent_puts - ("static int yy_more_flag = 0;"); - indent_puts - ("static int yy_more_len = 0;"); - } - } - - if (yytext_is_array) { - indent_puts - ("#define yymore() (YY_G(yy_more_offset) = yy_flex_strlen( yytext M4_YY_CALL_LAST_ARG))"); - indent_puts ("#define YY_NEED_STRLEN"); - indent_puts ("#define YY_MORE_ADJ 0"); - indent_puts - ("#define YY_RESTORE_YY_MORE_OFFSET \\"); - ++indent_level; - indent_puts ("{ \\"); - indent_puts - ("YY_G(yy_more_offset) = YY_G(yy_prev_more_offset); \\"); - indent_puts ("yyleng -= YY_G(yy_more_offset); \\"); - indent_puts ("}"); - --indent_level; - } - else { - indent_puts - ("#define yymore() (YY_G(yy_more_flag) = 1)"); - indent_puts - ("#define YY_MORE_ADJ YY_G(yy_more_len)"); - indent_puts ("#define YY_RESTORE_YY_MORE_OFFSET"); - } - } - - else { - indent_puts - ("#define yymore() yymore_used_but_not_detected"); - indent_puts ("#define YY_MORE_ADJ 0"); - indent_puts ("#define YY_RESTORE_YY_MORE_OFFSET"); - } - - if (!C_plus_plus) { - if (yytext_is_array) { - outn ("#ifndef YYLMAX"); - outn ("#define YYLMAX 8192"); - outn ("#endif\n"); - if (!reentrant){ - outn ("char yytext[YYLMAX];"); - outn ("char *yytext_ptr;"); - } - } - - else { - if(! reentrant) - outn ("char *yytext;"); - } - } - - out (&action_array[defs1_offset]); - - line_directive_out (stdout, 0); - - skelout (); /* %% [5.0] - break point in skel */ - - if (!C_plus_plus) { - if (use_read) { - outn ("\terrno=0; \\"); - outn ("\twhile ( (result = (int) read( fileno(yyin), buf, (yy_size_t) max_size )) < 0 ) \\"); - outn ("\t{ \\"); - outn ("\t\tif( errno != EINTR) \\"); - outn ("\t\t{ \\"); - outn ("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); - outn ("\t\t\tbreak; \\"); - outn ("\t\t} \\"); - outn ("\t\terrno=0; \\"); - outn ("\t\tclearerr(yyin); \\"); - outn ("\t}\\"); - } - - else { - outn ("\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\"); - outn ("\t\t{ \\"); - outn ("\t\tint c = '*'; \\"); - outn ("\t\tint n; \\"); - outn ("\t\tfor ( n = 0; n < max_size && \\"); - outn ("\t\t\t (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\"); - outn ("\t\t\tbuf[n] = (char) c; \\"); - outn ("\t\tif ( c == '\\n' ) \\"); - outn ("\t\t\tbuf[n++] = (char) c; \\"); - outn ("\t\tif ( c == EOF && ferror( yyin ) ) \\"); - outn ("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); - outn ("\t\tresult = n; \\"); - outn ("\t\t} \\"); - outn ("\telse \\"); - outn ("\t\t{ \\"); - outn ("\t\terrno=0; \\"); - outn ("\t\twhile ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \\"); - outn ("\t\t\t{ \\"); - outn ("\t\t\tif( errno != EINTR) \\"); - outn ("\t\t\t\t{ \\"); - outn ("\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); - outn ("\t\t\t\tbreak; \\"); - outn ("\t\t\t\t} \\"); - outn ("\t\t\terrno=0; \\"); - outn ("\t\t\tclearerr(yyin); \\"); - outn ("\t\t\t} \\"); - outn ("\t\t}\\"); - } - } - - skelout (); /* %% [6.0] - break point in skel */ - - indent_puts ("#define YY_RULE_SETUP \\"); - ++indent_level; - if (bol_needed) { - indent_puts ("if ( yyleng > 0 ) \\"); - ++indent_level; - indent_puts ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \\"); - indent_puts ("\t\t(yytext[yyleng - 1] == '\\n'); \\"); - --indent_level; - } - indent_puts ("YY_USER_ACTION"); - --indent_level; - - skelout (); /* %% [7.0] - break point in skel */ - - /* Copy prolog to output file. */ - out (&action_array[prolog_offset]); - - line_directive_out (stdout, 0); - - skelout (); /* %% [8.0] - break point in skel */ - - set_indent (2); - - if (yymore_used && !yytext_is_array) { - indent_puts ("YY_G(yy_more_len) = 0;"); - indent_puts ("if ( YY_G(yy_more_flag) )"); - ++indent_level; - indent_puts ("{"); - indent_puts - ("YY_G(yy_more_len) = (int) (YY_G(yy_c_buf_p) - YY_G(yytext_ptr));"); - indent_puts ("YY_G(yy_more_flag) = 0;"); - indent_puts ("}"); - --indent_level; - } - - skelout (); /* %% [9.0] - break point in skel */ - - gen_start_state (); - - /* Note, don't use any indentation. */ - outn ("yy_match:"); - gen_next_match (); - - skelout (); /* %% [10.0] - break point in skel */ - set_indent (2); - gen_find_action (); - - skelout (); /* %% [11.0] - break point in skel */ - outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[["); - indent_puts - ("if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )"); - ++indent_level; - indent_puts ("{"); - indent_puts ("int yyl;"); - do_indent (); - out_str ("for ( yyl = %s; yyl < yyleng; ++yyl )\n", - yymore_used ? (yytext_is_array ? "YY_G(yy_prev_more_offset)" : - "YY_G(yy_more_len)") : "0"); - ++indent_level; - indent_puts ("if ( yytext[yyl] == '\\n' )"); - ++indent_level; - indent_puts ("M4_YY_INCR_LINENO();"); - --indent_level; - --indent_level; - indent_puts ("}"); - --indent_level; - outn ("]])"); - - skelout (); /* %% [12.0] - break point in skel */ - if (ddebug) { - indent_puts ("if ( yy_flex_debug )"); - ++indent_level; - - indent_puts ("{"); - indent_puts ("if ( yy_act == 0 )"); - ++indent_level; - indent_puts (C_plus_plus ? - "std::cerr << \"--scanner backing up\\n\";" : - "fprintf( stderr, \"--scanner backing up\\n\" );"); - --indent_level; - - do_indent (); - out_dec ("else if ( yy_act < %d )\n", num_rules); - ++indent_level; - - if (C_plus_plus) { - indent_puts - ("std::cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<"); - indent_puts - (" \"(\\\"\" << yytext << \"\\\")\\n\";"); - } - else { - indent_puts - ("fprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\","); - - indent_puts - (" (long)yy_rule_linenum[yy_act], yytext );"); - } - - --indent_level; - - do_indent (); - out_dec ("else if ( yy_act == %d )\n", num_rules); - ++indent_level; - - if (C_plus_plus) { - indent_puts - ("std::cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";"); - } - else { - indent_puts - ("fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\","); - indent_puts (" yytext );"); - } - - --indent_level; - - do_indent (); - out_dec ("else if ( yy_act == %d )\n", num_rules + 1); - ++indent_level; - - indent_puts (C_plus_plus ? - "std::cerr << \"--(end of buffer or a NUL)\\n\";" : - "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );"); - - --indent_level; - - do_indent (); - outn ("else"); - ++indent_level; - - if (C_plus_plus) { - indent_puts - ("std::cerr << \"--EOF (start condition \" << YY_START << \")\\n\";"); - } - else { - indent_puts - ("fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );"); - } - - --indent_level; - - indent_puts ("}"); - --indent_level; - } - - /* Copy actions to output file. */ - skelout (); /* %% [13.0] - break point in skel */ - ++indent_level; - gen_bu_action (); - out (&action_array[action_offset]); - - line_directive_out (stdout, 0); - - /* generate cases for any missing EOF rules */ - for (i = 1; i <= lastsc; ++i) - if (!sceof[i]) { - do_indent (); - out_str ("case YY_STATE_EOF(%s):\n", scname[i]); - did_eof_rule = true; - } - - if (did_eof_rule) { - ++indent_level; - indent_puts ("yyterminate();"); - --indent_level; - } - - - /* Generate code for handling NUL's, if needed. */ - - /* First, deal with backing up and setting up yy_cp if the scanner - * finds that it should JAM on the NUL. - */ - skelout (); /* %% [14.0] - break point in skel */ - set_indent (4); - - if (fullspd || fulltbl) - indent_puts ("yy_cp = YY_G(yy_c_buf_p);"); - - else { /* compressed table */ - if (!reject && !interactive) { - /* Do the guaranteed-needed backing up to figure - * out the match. - */ - indent_puts - ("yy_cp = YY_G(yy_last_accepting_cpos);"); - indent_puts - ("yy_current_state = YY_G(yy_last_accepting_state);"); - } - - else - /* Still need to initialize yy_cp, though - * yy_current_state was set up by - * yy_get_previous_state(). - */ - indent_puts ("yy_cp = YY_G(yy_c_buf_p);"); - } - - - /* Generate code for yy_get_previous_state(). */ - set_indent (1); - skelout (); /* %% [15.0] - break point in skel */ - - gen_start_state (); - - set_indent (2); - skelout (); /* %% [16.0] - break point in skel */ - gen_next_state (true); - - set_indent (1); - skelout (); /* %% [17.0] - break point in skel */ - gen_NUL_trans (); - - skelout (); /* %% [18.0] - break point in skel */ - skelout (); /* %% [19.0] - break point in skel */ - /* Update BOL and yylineno inside of input(). */ - if (bol_needed) { - indent_puts - ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\\n');"); - if (do_yylineno) { - indent_puts - ("if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )"); - ++indent_level; - indent_puts ("M4_YY_INCR_LINENO();"); - --indent_level; - } - } - - else if (do_yylineno) { - indent_puts ("if ( c == '\\n' )"); - ++indent_level; - indent_puts ("M4_YY_INCR_LINENO();"); - --indent_level; - } - - skelout (); - - /* Copy remainder of input to output. */ - - line_directive_out (stdout, 1); - - if (sectnum == 3) { - OUT_BEGIN_CODE (); - if (!no_section3_escape) - fputs("[[", stdout); - (void) flexscan (); /* copy remainder of input to output */ - if (!no_section3_escape) - fputs("]]", stdout); - OUT_END_CODE (); + dataend (NULL); + outn("]])"); } } |