* 0 elements of its arrays, too.)
*/
static const char *C_int_decl =
-
"static yyconst int %s[%d] =\n { 0,\n";
static const char *C_short_decl =
-
"static yyconst short int %s[%d] =\n { 0,\n";
static const char *C_long_decl =
-
"static yyconst long int %s[%d] =\n { 0,\n";
static const char *C_state_decl =
-
"static yyconst yy_state_type %s[%d] =\n { 0,\n";
/* Indent to the current level. */
-void do_indent ()
+void do_indent ()
{
register int i = indent_level * 8;
}
}
+
+/** Make the table for possible eol matches.
+ * @return the newly allocated rule_can_match_eol table
+ */
+struct yytbl_data *mkeoltbl (void)
+{
+ int i;
+ int8_t *tdata = 0;
+ struct yytbl_data *tbl;
+
+ tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+ yytbl_data_init (tbl, YYT_ID_RULE_CAN_MATCH_EOL);
+ tbl->td_flags = YYT_DATA8;
+ tbl->td_lolen = num_rules + 1;
+ tbl->td_data = tdata =
+ (int8_t *) calloc (tbl->td_lolen, sizeof (int8_t));
+
+ for (i = 0; i < num_rules; i++)
+ tdata[i] = rule_has_nl[i] ? 1 : 0;
+
+ tdata[i] = rule_has_nl[i] ? 1 : 0;
+
+ return tbl;
+}
+
/* Generate the table for possible eol matches. */
static void geneoltbl ()
{
outn ("#ifdef YY_USE_LINENO");
outn ("/* Table of booleans, true if rule could match eol. */");
- out_dec
- ("static const int yy_rule_can_match_eol[%d] =\n {\n ",
- num_rules + 1);
+ out_dec ("static const int yy_rule_can_match_eol[%d] =\n {\n ", num_rules + 1);
for (i = 0; i < num_rules; i++) {
out_dec ("%d, ", rule_has_nl[i] ? 1 : 0);
/* Generate the code to keep backing-up information. */
-void gen_backing_up ()
+void gen_backing_up ()
{
if (reject || num_backing_up == 0)
return;
/* Generate the code to perform the backing up. */
-void gen_bu_action ()
+void gen_bu_action ()
{
if (reject || num_backing_up == 0)
return;
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.
+ * Then, I think, mkecstbl(). Arrrg.
+ * @return the newly allocated trans table
+ */
+
+struct yytbl_data *mkctbl (void)
+{
+ register int i;
+ struct yytbl_data *tbl = 0;
+ int32_t *tdata = 0, curr = 0;
+ int end_of_buffer_action = num_rules + 1;
+
+ tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+ yytbl_data_init (tbl, YYT_ID_TRANSITION);
+ tbl->td_flags |= YYT_DATA32;
+ tbl->td_hilen = 0;
+ tbl->td_lolen = tblend + numecs + 1; /* number of structs */
+
+ tbl->td_data = tdata =
+ (int32_t *) calloc (tbl->td_lolen * 2, sizeof (int32_t));
+
+ /* We want the transition to be represented as the offset to the
+ * next state, not the actual state number, which is what it currently
+ * is. The offset is base[nxt[i]] - (base of current state)]. That's
+ * just the difference between the starting points of the two involved
+ * states (to - from).
+ *
+ * First, though, we need to find some way to put in our end-of-buffer
+ * flags and states. We do this by making a state with absolutely no
+ * transitions. We put it at the end of the table.
+ */
+
+ /* We need to have room in nxt/chk for two more slots: One for the
+ * action and one for the end-of-buffer transition. We now *assume*
+ * that we're guaranteed the only character we'll try to index this
+ * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
+ * there's room for jam entries for other characters.
+ */
+
+ while (tblend + 2 >= current_max_xpairs)
+ expand_nxt_chk ();
+
+ while (lastdfa + 1 >= current_max_dfas)
+ increase_max_dfas ();
+
+ base[lastdfa + 1] = tblend + 2;
+ nxt[tblend + 1] = end_of_buffer_action;
+ chk[tblend + 1] = numecs + 1;
+ chk[tblend + 2] = 1; /* anything but EOB */
+
+ /* So that "make test" won't show arb. differences. */
+ nxt[tblend + 2] = 0;
+
+ /* Make sure every state has an end-of-buffer transition and an
+ * action #.
+ */
+ for (i = 0; i <= lastdfa; ++i) {
+ int anum = dfaacc[i].dfaacc_state;
+ int offset = base[i];
+
+ chk[offset] = EOB_POSITION;
+ chk[offset - 1] = ACTION_POSITION;
+ nxt[offset - 1] = anum; /* action number */
+ }
+
+ for (i = 0; i <= tblend; ++i) {
+ if (chk[i] == EOB_POSITION) {
+ tdata[curr++] = 0;
+ tdata[curr++] = base[lastdfa + 1] - i;
+ }
+
+ else if (chk[i] == ACTION_POSITION) {
+ tdata[curr++] = 0;
+ tdata[curr++] = nxt[i];
+ }
+
+ else if (chk[i] > numecs || chk[i] == 0) {
+ tdata[curr++] = 0;
+ tdata[curr++] = 0;
+ }
+ else { /* verify, transition */
+
+ tdata[curr++] = chk[i];
+ tdata[curr++] = base[nxt[i]] - (i - chk[i]);
+ }
+ }
+
+
+ /* Here's the final, end-of-buffer state. */
+ tdata[curr++] = chk[tblend + 1];
+ tdata[curr++] = nxt[tblend + 1];
+
+ tdata[curr++] = chk[tblend + 2];
+ tdata[curr++] = nxt[tblend + 2];
+
+ /* TODO: deal with this:
+ if (useecs)
+ genecs ();
+ */
+ return tbl;
+}
+
+
+/** Make start_state_list table.
+ * @param trans_tbl The transition table created by mkctbl().
+ * @return the newly allocated start_state_list table
+ */
+struct yytbl_data *mkssltbl (struct yytbl_data *trans_tbl)
+{
+ struct yytbl_data *tbl = 0;
+ int32_t *tdata = 0;
+ int32_t i;
+
+ tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+ yytbl_data_init (tbl, YYT_ID_START_STATE_LIST);
+ tbl->td_flags = YYT_DATA32;
+ tbl->td_hilen = 0;
+ tbl->td_lolen = lastsc * 2 + 1;
+
+ tbl->td_data = tdata =
+ (int32_t *) calloc (tbl->td_lolen, sizeof (int32_t));
+
+ for (i = 0; i <= lastsc * 2; ++i)
+ tdata[i] = base[i];
+
+ return tbl;
+}
+
+
/* genctbl - generates full speed compressed transition table */
-void genctbl ()
+void genctbl ()
{
register int i;
int end_of_buffer_action = num_rules + 1;
/* Table of verify for transition and offset to next state. */
- out_dec
- ("static yyconst struct yy_trans_info yy_transition[%d] =\n",
- tblend + numecs + 1);
+ out_dec ("static yyconst struct yy_trans_info yy_transition[%d] =\n", tblend + numecs + 1);
outn (" {");
/* We want the transition to be represented as the offset to the
outn (" };\n");
/* Table of pointers to start states. */
- out_dec
- ("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n",
- lastsc * 2 + 1);
+ out_dec ("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1);
outn (" {");
for (i = 0; i <= lastsc * 2; ++i)
struct yytbl_data *tbl = 0;
int32_t *tdata = 0;
- tbl = (struct yytbl_data*)flex_alloc(sizeof(struct yytbl_data));
- yytbl_data_init (tbl,YYT_ID_EC);
+ tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+ yytbl_data_init (tbl, YYT_ID_EC);
tbl->td_flags |= YYT_DATA32;
tbl->td_hilen = 0;
tbl->td_lolen = csize;
/* Generate equivalence-class tables. */
-void genecs ()
+void genecs ()
{
register int i, j;
int numrows;
/* Generate the code to find the action number. */
-void gen_find_action ()
+void gen_find_action ()
{
if (fullspd)
indent_puts ("yy_act = yy_current_state[-1].yy_nxt;");
indent_puts ("yy_current_state = *--YY_G(yy_state_ptr);");
indent_puts ("YY_G(yy_lp) = yy_accept[yy_current_state];");
- outn
- ("find_rule: /* we branch to this label when backing up */");
+ outn ("find_rule: /* we branch to this label when backing up */");
indent_puts
("for ( ; ; ) /* until we find what rule we matched */");
struct yytbl_data *tbl;
int32_t *tdata = 0;
- tbl = (struct yytbl_data*)flex_alloc(sizeof(struct yytbl_data));
- yytbl_data_init (tbl,YYT_ID_ACCEPT);
+ tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
+ yytbl_data_init (tbl, YYT_ID_ACCEPT);
tbl->td_flags |= YYT_DATA32;
tbl->td_hilen = 0; /* it's a one-dimensional array */
tbl->td_lolen = lastdfa + 1;
/* genftbl - generate full transition table */
-void genftbl ()
+void genftbl ()
{
register int i;
int end_of_buffer_action = num_rules + 1;
/* Generate the code to find the next compressed-table state. */
-void gen_next_compressed_state (char_map)
+void gen_next_compressed_state (char_map)
char *char_map;
{
indent_put2s ("register YY_CHAR yy_c = %s;", char_map);
/* Generate the code to find the next match. */
-void gen_next_match ()
+void gen_next_match ()
{
/* 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) {
do_indent ();
if (interactive)
- out_dec
- ("while ( yy_base[yy_current_state] != %d );\n",
- jambase);
+ out_dec ("while ( yy_base[yy_current_state] != %d );\n", jambase);
else
out_dec ("while ( yy_current_state != %d );\n",
jamstate);
/* Generate the code to find the next state. */
-void gen_next_state (worry_about_NULs)
- int worry_about_NULs;
+void gen_next_state (worry_about_NULs)
+ int worry_about_NULs;
{ /* NOTE - changes in here should be reflected in gen_next_match() */
char char_map[256];
/* Generate the code to make a NUL transition. */
-void gen_NUL_trans ()
+void gen_NUL_trans ()
{ /* 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.
else if (fulltbl) {
do_indent ();
- out_dec
- ("yy_current_state = yy_nxt[yy_current_state][%d];\n",
- NUL_ec);
+ out_dec ("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec);
indent_puts ("yy_is_jam = (yy_current_state <= 0);");
}
/* Generate the code to find the start state. */
-void gen_start_state ()
+void gen_start_state ()
{
if (fullspd) {
if (bol_needed) {
/* gentabs - generate data statements for the transition tables */
-void gentabs ()
+void gentabs ()
{
int 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;
+ int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0,
+ *yynxt_data = 0, *yychk_data = 0;
+ int32_t yybase_curr = 0;
acc_array = allocate_integer_array (current_max_dfas);
nummt = 0;
acc_array[i] = 0;
}
+ /* Begin generating yy_accept */
+
/* Spit out "yy_accept" array. If we're doing "reject", it'll be
* pointers into the "yy_acclist" array. Otherwise it's actual
* accepting numbers. In either case, we just dump the numbers.
out_str_dec (long_align ? C_long_decl : C_short_decl, "yy_accept",
k);
+ yyacc_tbl =
+ (struct yytbl_data *) calloc (1,
+ sizeof (struct yytbl_data));
+ yytbl_data_init (yyacc_tbl, YYT_ID_ACCEPT);
+ yyacc_tbl->td_lolen = k;
+ yyacc_tbl->td_data = yyacc_data =
+ (int32_t *) calloc (yyacc_tbl->td_lolen, sizeof (int32_t));
+
for (i = 1; i <= lastdfa; ++i) {
mkdata (acc_array[i]);
+ yyacc_data[i] = acc_array[i];
if (!reject && trace && acc_array[i])
fprintf (stderr, _("state # %d accepts: [%d]\n"),
/* Add entry for "jam" state. */
mkdata (acc_array[i]);
+ yyacc_data[i] = acc_array[i];
- if (reject)
+ if (reject) {
/* Add "cap" for the list. */
mkdata (acc_array[i]);
+ yyacc_data[i] = acc_array[i];
+ }
dataend ();
+ if (tablesext) {
+ yytbl_data_compress (yyacc_tbl);
+ if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0)
+ flexerror (_("Could not write yyacc_tbl"));
+ yytbl_data_destroy (yyacc_tbl);
+ yyacc_tbl = NULL;
+ }
+ /* End generating yy_accept */
if (useecs)
genecs ();
if (usemecs) {
+ /* Begin generating yy_meta */
/* Write out meta-equivalence classes (used to index
* templates with).
*/
+ int32_t *yymecs_data = 0;
+ yymeta_tbl =
+ (struct yytbl_data *) calloc (1,
+ sizeof (struct
+ yytbl_data));
+ yytbl_data_init (yymeta_tbl, YYT_ID_META);
+ yymeta_tbl->td_lolen = numecs + 1;
+ yymeta_tbl->td_data = yymecs_data =
+ (int32_t *) calloc (yymeta_tbl->td_lolen,
+ sizeof (int32_t));
if (trace)
fputs (_("\n\nMeta-Equivalence Classes:\n"),
i, ABS (tecbck[i]));
mkdata (ABS (tecbck[i]));
+ yymecs_data[i] = ABS (tecbck[i]);
}
dataend ();
+ if (tablesext) {
+ yytbl_data_compress (yymeta_tbl);
+ if (yytbl_data_fwrite (&tableswr, yymeta_tbl) < 0)
+ flexerror (_
+ ("Could not write yymeta_tbl"));
+ yytbl_data_destroy (yymeta_tbl);
+ yymeta_tbl = NULL;
+ }
+ /* End generating yy_meta */
}
total_states = lastdfa + numtemps;
+ /* Begin generating yy_base */
out_str_dec ((tblend >= MAX_SHORT || long_align) ?
C_long_decl : C_short_decl,
"yy_base", total_states + 1);
+ yybase_tbl =
+ (struct yytbl_data *) calloc (1,
+ sizeof (struct yytbl_data));
+ yytbl_data_init (yybase_tbl, YYT_ID_BASE);
+ yybase_tbl->td_lolen = total_states + 1;
+ yybase_tbl->td_data = yybase_data =
+ (int32_t *) calloc (yybase_tbl->td_lolen,
+ sizeof (int32_t));
+ yybase_curr = 1;
+
for (i = 1; i <= lastdfa; ++i) {
register int d = def[i];
}
mkdata (base[i]);
+ yybase_data[yybase_curr++] = base[i];
}
/* Generate jam state's base index. */
mkdata (base[i]);
+ yybase_data[yybase_curr++] = base[i];
for (++i /* skip jam state */ ; i <= total_states; ++i) {
mkdata (base[i]);
+ yybase_data[yybase_curr++] = base[i];
def[i] = jamstate;
}
dataend ();
+ if (tablesext) {
+ yytbl_data_compress (yybase_tbl);
+ if (yytbl_data_fwrite (&tableswr, yybase_tbl) < 0)
+ flexerror (_("Could not write yybase_tbl"));
+ yytbl_data_destroy (yybase_tbl);
+ yybase_tbl = NULL;
+ }
+ /* End generating yy_base */
+
+ /* Begin generating yy_def */
out_str_dec ((total_states >= MAX_SHORT || long_align) ?
C_long_decl : C_short_decl,
"yy_def", total_states + 1);
- for (i = 1; i <= total_states; ++i)
+
+ yydef_tbl =
+ (struct yytbl_data *) calloc (1,
+ sizeof (struct yytbl_data));
+ yytbl_data_init (yydef_tbl, YYT_ID_DEF);
+ yydef_tbl->td_lolen = total_states + 1;
+ yydef_tbl->td_data = yydef_data =
+ (int32_t *) calloc (yydef_tbl->td_lolen, sizeof (int32_t));
+
+ for (i = 1; i <= total_states; ++i) {
mkdata (def[i]);
+ yydef_data[i] = base[i];
+ }
dataend ();
+ if (tablesext) {
+ yytbl_data_compress (yydef_tbl);
+ if (yytbl_data_fwrite (&tableswr, yydef_tbl) < 0)
+ flexerror (_("Could not write yydef_tbl"));
+ yytbl_data_destroy (yydef_tbl);
+ yydef_tbl = NULL;
+ }
+ /* End generating yy_def */
+
+ /* Begin generating yy_nxt */
out_str_dec ((total_states >= MAX_SHORT || long_align) ?
C_long_decl : C_short_decl, "yy_nxt", tblend + 1);
+ yynxt_tbl =
+ (struct yytbl_data *) calloc (1,
+ sizeof (struct yytbl_data));
+ yytbl_data_init (yynxt_tbl, YYT_ID_NXT);
+ yynxt_tbl->td_lolen = tblend + 1;
+ yynxt_tbl->td_data = yynxt_data =
+ (int32_t *) calloc (yynxt_tbl->td_lolen, sizeof (int32_t));
+
for (i = 1; i <= tblend; ++i) {
/* Note, the order of the following test is important.
* If chk[i] is 0, then nxt[i] is undefined.
nxt[i] = jamstate; /* new state is the JAM state */
mkdata (nxt[i]);
+ yynxt_data[i] = nxt[i];
}
dataend ();
+ if (tablesext) {
+ yytbl_data_compress (yynxt_tbl);
+ if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0)
+ flexerror (_("Could not write yynxt_tbl"));
+ yytbl_data_destroy (yynxt_tbl);
+ yynxt_tbl = NULL;
+ }
+ /* End generating yy_nxt */
+ /* Begin generating yy_chk */
out_str_dec ((total_states >= MAX_SHORT || long_align) ?
C_long_decl : C_short_decl, "yy_chk", tblend + 1);
+ yychk_tbl =
+ (struct yytbl_data *) calloc (1,
+ sizeof (struct yytbl_data));
+ yytbl_data_init (yychk_tbl, YYT_ID_CHK);
+ yychk_tbl->td_lolen = tblend + 1;
+ yychk_tbl->td_data = yychk_data =
+ (int32_t *) calloc (yychk_tbl->td_lolen, sizeof (int32_t));
+
for (i = 1; i <= tblend; ++i) {
if (chk[i] == 0)
++nummt;
mkdata (chk[i]);
+ yychk_data[i] = chk[i];
}
dataend ();
+ if (tablesext) {
+ yytbl_data_compress (yychk_tbl);
+ if (yytbl_data_fwrite (&tableswr, yychk_tbl) < 0)
+ flexerror (_("Could not write yychk_tbl"));
+ yytbl_data_destroy (yychk_tbl);
+ yychk_tbl = NULL;
+ }
+ /* End generating yy_chk */
flex_free ((void *) acc_array);
}
* current indentation level, adding a final newline.
*/
-void indent_put2s (fmt, arg)
+void indent_put2s (fmt, arg)
const char *fmt, *arg;
{
do_indent ();
* newline.
*/
-void indent_puts (str)
+void indent_puts (str)
const char *str;
{
do_indent ();
/* make_tables - generate transition tables and finishes generating output file
*/
-void make_tables ()
+void make_tables ()
{
register int i;
int did_eof_rule = false;
+ struct yytbl_data *yynultrans_tbl;
+
skelout (); /* %% [2.0] - break point in skel */
indent_down ();
}
- if (fullspd)
+ if (fullspd) {
genctbl ();
+ if (tablesext) {
+ /* TODO: mkctbl(); */
+ }
+ }
else if (fulltbl)
genftbl ();
else
}
if (nultrans) {
+ int32_t *yynultrans_data = 0;
+
+ /* Begin generating yy_NUL_trans */
out_str_dec (C_state_decl, "yy_NUL_trans", lastdfa + 1);
+ yynultrans_tbl =
+ (struct yytbl_data *) calloc (1,
+ sizeof (struct
+ yytbl_data));
+ yytbl_data_init (yynultrans_tbl, YYT_ID_NUL_TRANS);
+ yynultrans_tbl->td_lolen = lastdfa + 1;
+ yynultrans_tbl->td_data = yynultrans_data =
+ (int32_t *) calloc (yynultrans_tbl->td_lolen,
+ sizeof (int32_t));
+
for (i = 1; i <= lastdfa; ++i) {
- if (fullspd)
+ if (fullspd) {
out_dec (" &yy_transition[%d],\n",
base[i]);
- else
+ yynultrans_data[i] = base[i];
+ }
+ else {
mkdata (nultrans[i]);
+ yynultrans_data[i] = nultrans[i];
+ }
}
dataend ();
+ if (tablesext) {
+ yytbl_data_compress (yynultrans_tbl);
+ if (yytbl_data_fwrite (&tableswr, yynultrans_tbl) <
+ 0)
+ flexerror (_
+ ("Could not write yynultrans_tbl"));
+ yytbl_data_destroy (yynultrans_tbl);
+ yynultrans_tbl = NULL;
+ }
+ /* End generating yy_NUL_trans */
}
if (ddebug) { /* Spit out table mapping rules to line numbers. */
outn ("#ifdef YY_USES_REJECT");
/* Declare state buffer variables. */
if (!C_plus_plus && !reentrant) {
- outn
- ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;");
+ 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) {
- outn
- ("static int yy_looking_for_trail_begin = 0;");
+ outn ("static int yy_looking_for_trail_begin = 0;");
outn ("static int yy_full_lp;");
outn ("static int *yy_full_state;");
}
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 */ \\");
+ 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_full_lp; /* restore orig. accepting pos. */ \\");
- outn
- ("YY_G(yy_state_ptr) = yy_full_state; /* restore orig. state */ \\");
- outn
- ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\");
+ outn ("YY_G(yy_lp) = yy_full_lp; /* restore orig. accepting pos. */ \\");
+ outn ("YY_G(yy_state_ptr) = yy_full_state; /* restore orig. state */ \\");
+ outn ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\");
}
outn ("++YY_G(yy_lp); \\");
}
else {
- outn
- ("/* The intent behind this definition is that it'll catch");
+ 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 (!C_plus_plus) {
if (use_read) {
outn ("\terrno=0; \\");
- outn
- ("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\");
+ outn ("\twhile ( (result = read( fileno(yyin), (char *) buf, 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\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
outn ("\t\t\tbreak; \\");
outn ("\t\t} \\");
outn ("\t\terrno=0; \\");
}
else {
- outn
- ("\tif ( YY_G(yy_current_buffer)->yy_is_interactive ) \\");
+ outn ("\tif ( YY_G(yy_current_buffer)->yy_is_interactive ) \\");
outn ("\t\t{ \\");
outn ("\t\tint c = '*'; \\");
outn ("\t\tsize_t n; \\");
outn ("\t\tfor ( n = 0; n < max_size && \\");
- outn
- ("\t\t\t (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\");
+ 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\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 = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\");
+ outn ("\t\twhile ( (result = fread(buf, 1, 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\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
outn ("\t\t\t\tbreak; \\");
outn ("\t\t\t\t} \\");
outn ("\t\t\terrno=0; \\");
useecs, fulltbl, usemecs;
int fullspd, gen_line_dirs, performance_report, backing_up_report;
int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap,
-
csize;
int reentrant, reentrant_bison_pure;
int yymore_used, reject, real_reject, continued_action, in_rule;
int skel_ind = 0;
char *action_array;
int action_size, defs1_offset, prolog_offset, action_offset,
-
action_index;
char *infilename = NULL, *outfilename = NULL, *headerfilename = NULL;
int did_outfilename;
bool tablesext, tablestoggle;
char *tablesfilename;
-FILE *tablesout;
+struct yytbl_writer tableswr;
/* Make sure program_name is initialized so we don't crash if writing
* out an error message before getting the program name from argv[0].
#ifndef SHORT_FILE_NAMES
static char *outfile_template = "lex.%s.%s";
static char *backing_name = "lex.backup";
+static char *tablesfile_template = "lex.%s.tables";
#else
static char *outfile_template = "lex%s.%s";
static char *backing_name = "lex.bck";
+static char *tablesfile_template = "lex%s.tbl";
#endif
#ifdef MS_DOS
int main PROTO ((int argc, char *argv[]));
void fix_line_dirs PROTO ((char *, char *, char *, int));
-int flex_main (argc, argv)
- int argc;
+int flex_main (argc, argv)
+ int argc;
char *argv[];
{
int i, exit_status;
if (spprdflt && !reject && rule_useful[default_rule])
line_warning (_
("-s option given but default rule can be matched"),
-rule_linenum[default_rule]);
+ rule_linenum[default_rule]);
/* Generate the C state transition tables from the DFA. */
make_tables ();
}
/* Wrapper around flex_main, so flex_main can be built as a library. */
-int main (argc, argv)
- int argc;
+int main (argc, argv)
+ int argc;
char *argv[];
{
#if ENABLE_NLS
/* check_options - check user-specified options */
-void check_options ()
+void check_options ()
{
int i;
outfile_created = 1;
}
+ if (tablesext) {
+ FILE *tablesout;
+ struct yytbl_hdr hdr;
+ char *pname = 0;
+ int nbytes = 0;
+
+ if (!tablesfilename) {
+ nbytes = strlen (prefix) +
+ strlen (tablesfile_template) + 2;
+ tablesfilename = pname =
+ (char *) calloc (nbytes, 1);
+ sprintf (pname, tablesfile_template, prefix);
+ }
+
+ if ((tablesout = fopen (tablesfilename, "w")) == NULL)
+ lerrsf (_("could not create %s"), tablesfilename);
+ if (pname)
+ free (pname);
+ tablesfilename = 0;
+
+ yytbl_writer_init (&tableswr, tablesout);
+
+ nbytes = strlen (prefix) + strlen ("tables") + 2;
+ pname = (char *) calloc (nbytes, 1);
+ sprintf (pname, "%stables", prefix);
+ yytbl_hdr_init (&hdr, "TODO", pname);
+ free (pname);
+
+ if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0)
+ flexerror (_("could not write tables header"));
+ }
+
if (skelname && (skelfile = fopen (skelname, "r")) == NULL)
lerrsf (_("can't open skeleton file %s"), skelname);
* for the generated header. We chaneg the line number and filename.
* linebuf is modified in place.
*/
-void fix_line_dirs (linebuf, outfilename, headerfilename, nlines)
+void fix_line_dirs (linebuf, outfilename, headerfilename, nlines)
char *linebuf;
char *outfilename;
char *headerfilename;
- int nlines;
+ int nlines;
{
char *pname, *p;
* This routine does not return.
*/
-void flexend (exit_status)
- int exit_status;
+void flexend (exit_status)
+ int exit_status;
{
static int called_before = -1; /* prevent infinite recursion. */
while (fgets (linebuf, LINE_SZ, stdout)) {
if (strstr (linebuf, "YY-DISCARD-FROM-HEADER"))
discard++;
- else
- if (strstr
- (linebuf,
- "YY-END-DISCARD-FROM-HEADER")) {
+ else if (strstr
+ (linebuf, "YY-END-DISCARD-FROM-HEADER")) {
discard--;
continue;
}
/* flexinit - initialize flex */
-void flexinit (argc, argv)
- int argc;
+void flexinit (argc, argv)
+ int argc;
char **argv;
{
int i, sawcmpflag, rv, optind;
use_read = use_stdout = false;
tablesext = tablestoggle = false;
tablesfilename = NULL;
- tablesout = NULL;
sawcmpflag = false;
else
lerrif (_
("unknown -R option '%c'"),
-(int) arg[0]);
+ (int) arg[0]);
}
break;
"1");
break;
- case OPT_TABLES:
+ case OPT_TABLES_FILE:
tablesext = true;
+ tablesfilename = arg;
break;
case OPT_TRACE:
/* readin - read in the rules section of the input file(s) */
-void readin ()
+void readin ()
{
static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;";
static char yy_nostdinit[] =
-
"FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;";
line_directive_out ((FILE *) 0, 1);
if (backing_up_file == NULL)
lerrsf (_
("could not create backing-up info file %s"),
-backing_name);
+ backing_name);
}
else
OUT_BEGIN_CODE ();
if (fullspd)
- outn
- ("typedef yyconst struct yy_trans_info *yy_state_type;");
+ outn ("typedef yyconst struct yy_trans_info *yy_state_type;");
else if (!C_plus_plus)
outn ("typedef int yy_state_type;");
OUT_END_CODE ();
if (yyclass) {
outn ("int yyFlexLexer::yylex()");
outn ("\t{");
- outn
- ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );");
+ outn ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );");
outn ("\treturn 0;");
outn ("\t}");
/* set_up_initial_allocations - allocate memory for internal tables */
-void set_up_initial_allocations ()
+void set_up_initial_allocations ()
{
maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS);
current_mns = INITIAL_MNS;
* (same concept as /bin/sh `basename`, but different handling of extension). */
static char *basename2 (path, strip_ext)
char *path;
- int strip_ext; /* boolean */
+ int strip_ext; /* boolean */
{
char *b, *e = 0;
return b;
}
-void usage ()
+void usage ()
{
FILE *f = stdout;
" -t, --stdout write scanner on stdout instead of %s\n"
" --yyclass=NAME name of C++ class\n"
" --header=FILE create a C header file in addition to the scanner\n"
- " --tables[=FILE] write tables to FILE\n" "\n"
+ " --tables-file[=FILE] write tables to FILE\n" "\n"
"Scanner behavior:\n"
" -7, --7bit generate 7-bit scanner\n"
" -8, --8bit generate 8-bit scanner\n"
*/
#define TFLAGS_CLRDATA(flg) ((flg) & ~(YYT_DATA8 | YYT_DATA16 | YYT_DATA32))
-int yytbl_fwrite32 (FILE * out, uint32_t v);
-int yytbl_fwrite16 (FILE * out, uint16_t v);
-int yytbl_fwrite8 (FILE * out, uint8_t v);
+int yytbl_fwrite32 (struct yytbl_writer *wr, uint32_t v);
+int yytbl_fwrite16 (struct yytbl_writer *wr, uint16_t v);
+int yytbl_fwrite8 (struct yytbl_writer *wr, uint8_t v);
+int yytbl_fwriten (struct yytbl_writer *wr, void *v, int32_t len);
+static int32_t tbl_get_total_len (struct yytbl_data *tbl);
+static int32_t yytbl_data_geti (const struct yytbl_data *tbl, int i);
+
+
+/** Initialize the table writer.
+ * @param wr an uninitialized writer
+ * @param the output file
+ * @return 0 on success
+ */
+int yytbl_writer_init (struct yytbl_writer *wr, FILE * out)
+{
+ wr->out = out;
+ wr->total_written = 0;
+ return 0;
+}
/** Initialize a table header.
* @param th The uninitialized structure
* @param version_str the version string
* @param name the name of this table set
*/
-void yytbl_hdr_init (struct yytbl_hdr *th, const char *version_str,
- const char *name)
+int yytbl_hdr_init (struct yytbl_hdr *th, const char *version_str,
+ const char *name)
{
memset (th, 0, sizeof (struct yytbl_hdr));
th->th_magic = 0xF13C57B1;
- th->th_hsize =
- yypad64 (20 + strlen (version_str) + 1 + strlen (name) +
- 1);
+ th->th_hsize = 14 + strlen (version_str) + 1 + strlen (name) + 1;
+ th->th_hsize += yypad64 (th->th_hsize);
th->th_ssize = 0; // Not known at this point.
th->th_flags = 0;
th->th_version = copy_string (version_str);
th->th_name = copy_string (name);
+ return 0;
}
/** Allocate and initialize a table data structure.
return 0;
}
+int yytbl_data_destroy (struct yytbl_data *td)
+{
+ if (td->td_data)
+ free (td->td_data);
+ td->td_data = 0;
+ free (td);
+ return 0;
+}
+static int yytbl_fwrite_pad64 (struct yytbl_writer *wr)
+{
+ int pad, bwritten = 0;
+
+ pad = yypad64 (wr->total_written);
+ while (pad-- > 0)
+ if (yytbl_fwrite8 (wr, 0) < 0)
+ return -1;
+ else
+ bwritten++;
+ return bwritten;
+}
+
/** write the header.
* @param out the output stream
* @param th table header to be written
* @return -1 on error, or bytes written on success.
*/
-int yytbl_hdr_fwrite (FILE * out, const struct yytbl_hdr *th)
+int yytbl_hdr_fwrite (struct yytbl_writer *wr, const struct yytbl_hdr *th)
{
size_t sz, rv;
- int pad, bwritten = 0;
+ int bwritten = 0;
- if (yytbl_fwrite32 (out, th->th_magic) < 0
- || yytbl_fwrite32 (out, th->th_hsize) < 0
- || yytbl_fwrite32 (out, th->th_ssize) < 0
- || yytbl_fwrite16 (out, th->th_flags) < 0)
+ if (yytbl_fwrite32 (wr, th->th_magic) < 0
+ || yytbl_fwrite32 (wr, th->th_hsize) < 0)
return -1;
- else
- bwritten += 3 * 4 + 2;
+ bwritten += 8;
+
+ if (fgetpos (wr->out, &(wr->th_ssize_pos)) != 0)
+ return -1;
+
+ if (yytbl_fwrite32 (wr, th->th_ssize) < 0
+ || yytbl_fwrite16 (wr, th->th_flags) < 0)
+ return -1;
+ bwritten += 6;
sz = strlen (th->th_version) + 1;
- if ((rv = fwrite (th->th_version, 1, sz, out)) != sz)
+ if ((rv = yytbl_fwriten (wr, th->th_version, sz)) != sz)
return -1;
bwritten += rv;
sz = strlen (th->th_name) + 1;
- if ((rv = fwrite (th->th_name, 1, sz, out)) != sz)
+ if ((rv = yytbl_fwriten (wr, th->th_name, sz)) != sz)
return 1;
bwritten += rv;
/* add padding */
- pad = yypad64 (bwritten) - bwritten;
- while (pad-- > 0)
- if (yytbl_fwrite8 (out, 0) < 0)
- return -1;
- else
- bwritten++;
+ if ((rv = yytbl_fwrite_pad64 (wr)) < 0)
+ return -1;
+ bwritten += rv;
/* Sanity check */
if (bwritten != th->th_hsize) {
return bwritten;
}
+
+/** Write this table.
+ * @param out the file writer
+ * @param td table data to be written
+ * @return -1 on error, or bytes written on success.
+ */
+int yytbl_data_fwrite (struct yytbl_writer *wr, struct yytbl_data *td)
+{
+ size_t rv;
+ int32_t bwritten = 0;
+ int32_t i, total_len;
+ fpos_t pos;
+
+ if ((rv = yytbl_fwrite16 (wr, td->td_id)) < 0)
+ return -1;
+ bwritten += rv;
+
+ if ((rv = yytbl_fwrite16 (wr, td->td_flags)) < 0)
+ return -1;
+ bwritten += rv;
+
+ if ((rv = yytbl_fwrite32 (wr, td->td_hilen)) < 0)
+ return -1;
+ bwritten += rv;
+
+ if ((rv = yytbl_fwrite32 (wr, td->td_lolen)) < 0)
+ return -1;
+ bwritten += rv;
+
+ total_len = tbl_get_total_len (td);
+ for (i = 0; i < total_len; i++) {
+ switch (TFLAGS2BYTES (td->td_flags)) {
+ case sizeof (int8_t):
+ rv = yytbl_fwrite8 (wr, yytbl_data_geti (td, i));
+ break;
+ case sizeof (int16_t):
+ rv = yytbl_fwrite16 (wr, yytbl_data_geti (td, i));
+ break;
+ case sizeof (int32_t):
+ rv = yytbl_fwrite32 (wr, yytbl_data_geti (td, i));
+ break;
+ default: /* TODO: error. Something really wrong. */
+ }
+ if (rv < 0)
+ return -1;
+ bwritten += rv;
+ }
+
+ /* Sanity check */
+ if (bwritten != (12 + total_len * TFLAGS2BYTES (td->td_flags))) {
+ /* Oops. */
+ return -1;
+ }
+
+ /* add padding */
+ if ((rv = yytbl_fwrite_pad64 (wr)) < 0)
+ return -1;
+ bwritten += rv;
+
+ /* Now go back and update the th_hsize member */
+ if (fgetpos (wr->out, &pos) != 0
+ || fsetpos (wr->out, &(wr->th_ssize_pos)) != 0
+ || yytbl_fwrite32 (wr, wr->total_written) < 0
+ || fsetpos (wr->out, &pos))
+ return -1;
+ else
+ /* Don't count the int we just wrote. */
+ wr->total_written -= sizeof (int32_t);
+ return bwritten;
+}
+
+/** Write n bytes.
+ * @param wr the table writer
+ * @param v data to be written
+ * @param len number of bytes
+ * @return -1 on error. number of bytes written on success.
+ */
+int yytbl_fwriten (struct yytbl_writer *wr, void *v, int32_t len)
+{
+ size_t rv;
+
+ rv = fwrite (v, 1, len, wr->out);
+ if (rv != len)
+ return -1;
+ wr->total_written += len;
+ return len;
+}
+
/** Write four bytes in network byte order
- * @param out the output stream
+ * @param wr the table writer
* @param v a dword in host byte order
* @return -1 on error. number of bytes written on success.
*/
-int yytbl_fwrite32 (FILE * out, uint32_t v)
+int yytbl_fwrite32 (struct yytbl_writer *wr, uint32_t v)
{
uint32_t vnet;
size_t bytes, rv;
vnet = htonl (v);
bytes = sizeof (uint32_t);
- rv = fwrite (&vnet, bytes, 1, out);
- if (rv != bytes)
+ rv = fwrite (&vnet, bytes, 1, wr->out);
+ if (rv != 1)
return -1;
+ wr->total_written += bytes;
return bytes;
}
/** Write two bytes in network byte order.
- * @param out the output stream
+ * @param wr the table writer
* @param v a word in host byte order
* @return -1 on error. number of bytes written on success.
*/
-int yytbl_fwrite16 (FILE * out, uint16_t v)
+int yytbl_fwrite16 (struct yytbl_writer *wr, uint16_t v)
{
uint16_t vnet;
size_t bytes, rv;
vnet = htons (v);
bytes = sizeof (uint16_t);
- rv = fwrite (&vnet, bytes, 1, out);
- if (rv != bytes)
+ rv = fwrite (&vnet, bytes, 1, wr->out);
+ if (rv != 1)
return -1;
+ wr->total_written += bytes;
return bytes;
}
/** Write a byte.
- * @param out the output stream
+ * @param wr the table writer
* @param v the value to be written
* @return -1 on error. number of bytes written on success.
*/
-int yytbl_fwrite8 (FILE * out, uint8_t v)
+int yytbl_fwrite8 (struct yytbl_writer *wr, uint8_t v)
{
size_t bytes, rv;
bytes = sizeof (uint8_t);
- rv = fwrite (&v, bytes, 1, out);
- if (rv != bytes)
+ rv = fwrite (&v, bytes, 1, wr->out);
+ if (rv != 1)
return -1;
+ wr->total_written += bytes;
return bytes;
}
* @param newval new value for data[i]
*/
static void yytbl_data_seti (const struct yytbl_data *tbl, int i,
- int newval)
+ int32_t newval)
{
switch (TFLAGS2BYTES (tbl->td_flags)) {
case sizeof (int8_t):
((int8_t *) (tbl->td_data))[i] = (int8_t) newval;
+ break;
case sizeof (int16_t):
((int16_t *) (tbl->td_data))[i] = (int16_t) newval;
+ break;
case sizeof (int32_t):
((int32_t *) (tbl->td_data))[i] = (int32_t) newval;
+ break;
default: /* TODO: error. major foobar somewhere. */
break;
}
newsz = min_int_size (tbl);
-
if (newsz == TFLAGS2BYTES (tbl->td_flags))
/* No change in this table needed. */
return;
}
total_len = tbl_get_total_len (tbl);
- newtbl.td_data = flex_alloc (newsz * total_len);
+ newtbl.td_data = calloc (total_len, newsz);
newtbl.td_flags =
- TFLAGS_CLRDATA (newtbl.td_flags) & BYTES2TFLAG (newsz);
+ TFLAGS_CLRDATA (newtbl.td_flags) | BYTES2TFLAG (newsz);
- for (i = 0; i < total_len; i++)
- yytbl_data_seti (&newtbl, i, yytbl_data_geti (tbl, i));
+ for (i = 0; i < total_len; i++) {
+ int32_t g;
+
+ g = yytbl_data_geti (tbl, i);
+ yytbl_data_seti (&newtbl, i, g);
+ }
/* Now copy over the old table */