From: John Millaway Date: Wed, 21 Aug 2002 01:54:20 +0000 (+0000) Subject: More work on tables. X-Git-Tag: flex-2-5-15~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=85c40a215fb57e3e29fa744e558f79b096dc61fb;p=flex More work on tables. --- diff --git a/flexdef.h b/flexdef.h index 8bfff42..9d0c7e9 100644 --- a/flexdef.h +++ b/flexdef.h @@ -390,7 +390,7 @@ extern int yymore_used, reject, real_reject, continued_action, in_rule; /* * tablesext - if true, create external tables - * tablestoggle - if true, then output extneral tables code + * tablestoggle - if true, output external tables code while processing skel * tablesfilename - filename for external tables * tablesout - FILE stream for external tables */ @@ -1094,5 +1094,8 @@ extern char* chomp(char* str); /* Tables serialization API declarations. */ #include "tables_shared.h" +struct yytbl_data * yytbl_data_create (enum yytbl_id id); +struct yytbl_data *mkftbl (void); + #endif /* not defined FLEXDEF_H */ diff --git a/gen.c b/gen.c index a8f095a..505898b 100644 --- a/gen.c +++ b/gen.c @@ -426,6 +426,36 @@ void gen_find_action() } } +/* mkftbl - make the full table and return the struct */ + +struct yytbl_data *mkftbl (void) +{ + register int i; + int end_of_buffer_action = num_rules + 1; + struct yytbl_data *tbl; + int32_t *tdata = 0; + + tbl = yytbl_data_create (YYT_ID_ACCEPT); + tbl->t_flags |= YYT_DATA32; + tbl->t_hilen = 0; /* it's a one-dimensional array */ + tbl->t_lolen = lastdfa + 1; + + tbl->t_data = tdata = (int32_t *) calloc (tbl->t_lolen, sizeof(int32_t)); + + dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; + + for (i = 1; i <= lastdfa; ++i) { + register int anum = dfaacc[i].dfaacc_state; + + tdata[i] = anum; + + if (trace && anum) + fprintf (stderr, _("state # %d accepts: [%d]\n"), i, anum); + } + + return tbl; +} + /* genftbl - generate full transition table */ @@ -1138,6 +1168,8 @@ void make_tables() 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 ); diff --git a/tables.c b/tables.c index 0ebf84f..5178f87 100644 --- a/tables.c +++ b/tables.c @@ -36,99 +36,208 @@ #include "flexdef.h" #define yypad64(n) ((8-((n)%8))%8) +#define TFLAGS2BYTES(flags)\ + (((flags) & YYT_DATA8)\ + ? sizeof(int8_t)\ + :(((flags) & YYT_DATA16)\ + ? sizeof(int16_t)\ + :sizeof(int32_t))) + +int yytbl_fwrite32 (FILE * out, uint32_t v); +int yytbl_fwrite16 (FILE * out, uint16_t v); +int yytbl_fwrite8 (FILE * out, uint8_t v); + +void 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_ssize = 0; // Not known at this point. + th->th_flags = 0; + th->th_version = copy_string (version_str); + th->th_name = copy_string (name); +} + +struct yytbl_data *yytbl_data_create (enum yytbl_id id) +{ + struct yytbl_data *td; + + td = (struct yytbl_data *) flex_alloc (sizeof (struct yytbl_data)); + memset (td, 0, sizeof (struct yytbl_data)); + td->t_id = id; + return td; +} -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_hdr_fwrite (FILE * out, struct yytbl_hdr *th) +{ + size_t sz, rv; + int pad, 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) + return -1; + else + bwritten += 3 * 4 + 2; + + sz = strlen (th->th_version) + 1; + if ((rv = fwrite (th->th_version, 1, sz, out)) != sz) + return -1; + bwritten += rv; + + sz = strlen (th->th_name) + 1; + if ((rv = fwrite (th->th_name, 1, sz, out)) != sz) + return 1; + bwritten += rv; + + /* add padding */ + pad = yypad64 (bwritten) - bwritten; + while (pad-- > 0) + if (yytbl_fwrite8 (out, 0) < 0) + return -1; + else + bwritten++; + + /* Sanity check */ + if (bwritten != th->th_hsize) { + /* Oops. */ + return -1; + } + + return bwritten; +} -void yytbl_hdr_init(struct yytbl_hdr *th, const char * version_str, const char *name) +int yytbl_fwrite32 (FILE * out, uint32_t v) { - 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_ssize = 0; // Not known at this point. - th->th_flags = 0; - th->th_version = copy_string(version_str); - th->th_name = copy_string(name); + uint32_t vnet; + size_t bytes, rv; + + vnet = htonl (v); + bytes = sizeof (uint32_t); + rv = fwrite (&vnet, bytes, 1, out); + if (rv != bytes) + return -1; + return bytes; } -int yytbl_hdr_fwrite(FILE* out, struct yytbl_hdr * th) +int yytbl_fwrite16 (FILE * out, uint16_t v) { - size_t sz,rv; - int pad,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) - return -1; - else - bwritten += 3*4 + 2; - - sz = strlen(th->th_version)+1; - if ((rv=fwrite(th->th_version,1,sz,out)) != sz) - return -1; - bwritten += rv; - - sz = strlen(th->th_name)+1; - if ((rv=fwrite(th->th_name,1,sz,out)) != sz) - return 1; - bwritten += rv; - - /* add padding */ - pad = yypad64(bwritten) - bwritten; - while(pad-- > 0) - if (yytbl_fwrite8(out, 0) < 0) - return -1; - else - bwritten++; - - /* Sanity check */ - if (bwritten != th->th_hsize){ - /* Oops. */ - return -1; - } - - return bwritten; + uint16_t vnet; + size_t bytes, rv; + + vnet = htons (v); + bytes = sizeof (uint16_t); + rv = fwrite (&vnet, bytes, 1, out); + if (rv != bytes) + return -1; + return bytes; } -int yytbl_fwrite32(FILE *out, uint32_t v) +int yytbl_fwrite8 (FILE * out, uint8_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) - return -1; - return bytes; + size_t bytes, rv; + + bytes = sizeof (uint8_t); + rv = fwrite (&v, bytes, 1, out); + if (rv != bytes) + return -1; + return bytes; } -int yytbl_fwrite16(FILE *out, uint16_t v) +/* calculate the number of bytes (1,2,4) needed to hold the largest absolute value + * in this array. */ +static int min_int_size (void *arr, int32_t len, int sz) { - uint16_t vnet; - size_t bytes, rv; - - vnet = htons(v); - bytes = sizeof(uint16_t); - rv = fwrite(&vnet,bytes,1,out); - if( rv != bytes) - return -1; - return bytes; + int32_t curr, max = 0, i; + + for (i = 0; i < len; i++) { + switch (sz) { + case 1: + curr = abs (((int8_t *) arr)[i]); + break; + case 2: + curr = abs (((int16_t *) arr)[i]); + break; + case 4: + curr = abs (((int32_t *) arr)[i]); + break; + default: + fprintf (stderr, "Illegal size (%d) in min_int_size\n", sz); + return 32; + } + if (curr > max) + max = curr; + } + if (max < INT8_MAX) + return sizeof (int8_t); + else if (max < INT16_MAX) + return sizeof (int16_t); + else + return sizeof (int32_t); } -int yytbl_fwrite8(FILE *out, uint8_t v) + +/* extract data element [i][j] from int array data tables. */ +static int32_t yytbl_data_geti (const struct yytbl_data *tbl, int i, int j) { - size_t bytes, rv; - - bytes = sizeof(uint8_t); - rv = fwrite(&v,bytes,1,out); - if( rv != bytes) - return -1; - return bytes; + /* TODO */ + return 0; } +/* Transform data to smallest possible of (int32, int16, int8) */ +void yytbl_data_compress (struct yytbl_data *tbl) +{ + int32_t i, sz; + void *newdata = 0; + + if (tbl->t_id != YYT_ID_TRANSITION && tbl->t_id != YYT_ID_START_STATE_LIST) { + if (tbl->t_hilen == 0) { + /* Data is a single-dimensional array of ints */ + sz = min_int_size (tbl->t_data, tbl->t_lolen, TFLAGS2BYTES (tbl->t_flags)); + if (sz == TFLAGS2BYTES (tbl->t_flags)) + /* No change in this table needed. */ + return; + + if (sz > TFLAGS2BYTES (tbl->t_flags)) { + /* TODO: ERROR. The code is wrong somewhere. */ + return; + } + + newdata = flex_alloc (sz * tbl->t_lolen); + for (i = 0; i < tbl->t_lolen; i++) { + int32_t n; + + n = yytbl_data_geti (tbl, 0, i); + switch (sz) { + case sizeof (int8_t): + ((int8_t *) newdata)[i] = (int8_t) n; + break; + case sizeof (int16_t): + ((int16_t *) newdata)[i] = (int16_t) n; + break; + case sizeof (int32_t): + ((int32_t *) newdata)[i] = (int32_t) n; + break; + default: /* TODO: ERROR: unknown 'sz' */ + break; + } + } + free (tbl->t_data); + tbl->t_data = newdata; + + } + else { + /* Data is a two-dimensional array of ints */ + } + } + else if (tbl->t_id == YYT_ID_TRANSITION) { + /* Data is an array of structs */ + } + else if (tbl->t_id == YYT_ID_START_STATE_LIST) { + /* Data is an array of pointers */ + } +} /* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ diff --git a/tables_shared.h b/tables_shared.h index eec13e0..3ef0905 100644 --- a/tables_shared.h +++ b/tables_shared.h @@ -72,9 +72,9 @@ enum yytbl_id /** bit flags for t_flags field of struct yytbl_data */ enum yytbl_flags { - YYT_DATA8 = 0x01, /**< data is an array of type int8 */ - YYT_DATA16 = 0x02, /**< data is an array of type int16 */ - YYT_DATA32 = 0x04, /**< data is an array of type int32 */ + YYT_DATA8 = 0x01, /**< data is an array of type int8_t */ + YYT_DATA16 = 0x02, /**< data is an array of type int16_t */ + YYT_DATA32 = 0x04, /**< data is an array of type int32_t */ YYT_PTRANS = 0x08, /**< data is a list of indexes of entries into the expanded `yy_transition' array. See notes in manual. */