From b101188a767f589340deed97125571db945d4865 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 22 Sep 2020 19:36:51 -0400 Subject: Push the definition of struct yy_trans_info out to m4. Required defining a new method table entry and shuffling the order in which things are generated a bit, but the generated-code diffs are all trivial. Some comments from the previous C code are now in the skeleton. #26 in the retargeting patch series --- src/cpp-flex.skl | 28 +++++++++++++++++++++++ src/cpp_backend.c | 7 ++++++ src/flexdef.h | 1 + src/gen.c | 68 ++++++++++--------------------------------------------- src/main.c | 6 +++++ 5 files changed, 54 insertions(+), 56 deletions(-) diff --git a/src/cpp-flex.skl b/src/cpp-flex.skl index 55dcd8b..22c2e42 100644 --- a/src/cpp-flex.skl +++ b/src/cpp-flex.skl @@ -670,6 +670,34 @@ static void yynoreturn yy_fatal_error ( const char* msg M4_YY_PROTO_LAST_ARG ); %endif +m4_ifdef( [[M4_YY_NOT_IN_HEADER]], [[ +struct yy_trans_info + { + /* We require that yy_verify and yy_nxt must be of the same size int. */ +m4_ifdef([[M4_MODE_REAL_FULLSPD]], [[ + YY_OFFSET_TYPE yy_verify; + + /* 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. + */ + YY_OFFSET_TYPE yy_nxt; +]]) +m4_ifdef([[M4_MODE_NO_REAL_FULLSPD]], [[ + /* 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. + */ + flex_int32_t yy_verify; + flex_int32_t yy_nxt; +]]) + }; +]]) + m4_ifdef( [[M4_YY_NOT_IN_HEADER]], [[ /* Done after the current pattern has been matched and before the diff --git a/src/cpp_backend.c b/src/cpp_backend.c index 0c77f0b..c868749 100644 --- a/src/cpp_backend.c +++ b/src/cpp_backend.c @@ -578,6 +578,12 @@ static void cpp_nultrans(int fullspd) "flex_int32_t"); } +static const char *cpp_trans_offset_type(int total_table_size) +{ + return (total_table_size >= INT16_MAX || long_align) ? + "flex_int32_t" : "flex_int16_t"; +} + const char *cpp_skel[] = { #include "cpp-skel.h" 0, @@ -618,6 +624,7 @@ struct flex_backend_t cpp_backend = { .gentabs_yy_nxt = cpp_gentabs_yy_nxt, .gentabs_yy_chk = cpp_gentabs_yy_chk, .nultrans = cpp_nultrans, + .trans_offset_type = cpp_trans_offset_type, .caseprefix = "case ", .fallthrough = NULL, .endcase = "yyterminate();" diff --git a/src/flexdef.h b/src/flexdef.h index 629d7e4..6bed71d 100644 --- a/src/flexdef.h +++ b/src/flexdef.h @@ -341,6 +341,7 @@ struct flex_backend_t { void (*gentabs_yy_nxt)(size_t); // Generate yy_nxt initializer void (*gentabs_yy_chk)(size_t); // Generate yy_chk initializer void (*nultrans)(int); // Generate nulltrans initializer + const char *(*trans_offset_type)(int); // Compute an efficient type for transition tables char *caseprefix; // Prefix of an arm in the language's case construct char *fallthrough; // Finish a case arm with this to fall through char *endcase; // What to ship after all EOF-state case arms diff --git a/src/gen.c b/src/gen.c index 8724713..076cdb8 100644 --- a/src/gen.c +++ b/src/gen.c @@ -896,6 +896,18 @@ void make_tables (void) int did_eof_rule = false; struct yytbl_data *yynultrans_tbl = NULL; + out_dec ("#define YY_NUM_RULES %d\n", num_rules); + out_dec ("#define YY_END_OF_BUFFER %d\n", num_rules + 1); + + fprintf (stdout, backend->int_define_fmt, "YY_JAMBASE", jambase); + fprintf (stdout, backend->int_define_fmt, "YY_JAMSTATE", jamstate); + + fprintf (stdout, backend->int_define_fmt, "YY_NUL_EC", NUL_ec); + + /* Need to define the transet type as a size large + * enough to hold the biggest offset. + */ + fprintf (stdout, backend->string_define_fmt, "YY_OFFSET_TYPE", backend->trans_offset_type(tblend + numecs + 1)); skelout (); /* %% [2.0] - break point in skel */ @@ -945,64 +957,8 @@ void make_tables (void) 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); - - fprintf (stdout, backend->int_define_fmt, "YY_JAMBASE", jambase); - fprintf (stdout, backend->int_define_fmt, "YY_JAMSTATE", jamstate); - - fprintf (stdout, backend->int_define_fmt, "YY_NUL_EC", NUL_ec); - - 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) { genctbl (); if (tablesext) { diff --git a/src/main.c b/src/main.c index e4fc498..5e63318 100644 --- a/src/main.c +++ b/src/main.c @@ -1420,6 +1420,12 @@ void readin (void) // stuff out to the skeleton file we make it easier // to retarget the code generation. + // mode switches for yy_trans_info specification + if (fullspd) + out_m4_define( "M4_MODE_REAL_FULLSPD", NULL); + else + out_m4_define( "M4_MODE_NO_REAL_FULLSPD", NULL); + // mode switches for next-action code if (variable_trailing_context_rules) { out_m4_define( "M4_MODE_VARIABLE_TRAILING_CONTEXT_RULES", NULL); -- cgit v1.2.1