summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2020-09-22 04:35:57 -0400
committerEric S. Raymond <esr@thyrsus.com>2020-09-22 04:47:05 -0400
commit30788806b98ae23151c921ad34c3a6f7ab1d0d76 (patch)
treed1637c49d04d9e3d7a5cb1088759b8a5326301b7
parent6711981a2d7e2fc3e3965156e0cb0887387f202a (diff)
downloadflex-git-30788806b98ae23151c921ad34c3a6f7ab1d0d76.tar.gz
gen_next_match() becomes m4 code.
To verify this patch, notice that the non-whitespace changes in the generated C from the tests are of only three kinds: 1. Addition of comments. I elected to copy the comments from the generator functions into their corresponding m4 macros in hopes of making the generated code less nasty to read. 2. Lines like "if ( yy_current_state >= 12 )" changing so the numeric literal is replaced by YY_JAMSTATE + 1. This was a consequence of the change in #15 to simplify the C code generators so they could be translated into static nacros. 3. "YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]" being replaced by "YY_CHAR yy_c = *(yy_ec+YY_SC_TO_UI(*yy_cp));". The strange way of indexing yy_ec avoids a syntactic collision with the use of [] as m4 quotes. #20 in the retargeting patch series
-rw-r--r--src/cpp-flex.skl89
-rw-r--r--src/flexdef.h3
-rw-r--r--src/gen.c104
3 files changed, 89 insertions, 107 deletions
diff --git a/src/cpp-flex.skl b/src/cpp-flex.skl
index 90f7c78..25ee2df 100644
--- a/src/cpp-flex.skl
+++ b/src/cpp-flex.skl
@@ -1209,6 +1209,35 @@ m4_ifdef([[M4_MODE_NO_FULLSPD]], [[
]])
]])
+m4_define([[M4_GEN_NEXT_COMPRESSED_STATE]], [[
+ YY_CHAR yy_c = $1;
+ /* 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
+ */
+ M4_GEN_BACKING_UP
+
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+
+m4_ifdef([[M4_MODE_USEMECS]], [[
+ /* We've arranged 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
+ */
+
+ /* lastdfa + 2 == YY_JAMSTATE + 1 is the beginning of the templates */
+ if (yy_current_state >= YY_JAMSTATE + 1)
+ yy_c = yy_meta[yy_c];
+]])
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+]])
+
m4_define([[M4_GEN_START_STATE]], [[
/* Generate the code to find the start state. */
m4_ifdef([[M4_MODE_FULLSPD]], [[
@@ -1226,6 +1255,26 @@ m4_ifdef([[M4_MODE_BOL_NEEDED]], [[yy_current_state += YY_AT_BOL();]])
]])
]])
+m4_define([[M4_GEN_NEXT_MATCH_FULLSPD]], [[
+ {
+ const struct yy_trans_info *yy_trans_info;
+ YY_CHAR yy_c;
+
+ for ( yy_c = $1;
+ (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;
+ yy_c = $2 )
+ {
+ yy_current_state += yy_trans_info->yy_nxt;
+
+ M4_GEN_BACKING_UP
+ }
+ }
+]])
+
+%# Conditional indirection through an equivalence map
+m4_ifdef([[M4_MODE_USEECS]], m4_define([[M4_EC]], [[*(yy_ec+$1)]]))
+m4_ifdef([[M4_NOT_MODE_USEECS]], [[m4_define([[M4_EC]], [[$1]])]])
+
%not-for-header
/** The main scanner function which does all the work.
*/
@@ -1321,6 +1370,46 @@ m4_ifdef( [[M4_MODE_USES_REJECT]],
%% [9.0] code to set up and find next match goes here
+ /* Generate the code to find the next match. */
+m4_ifdef([[M4_MODE_FULLTBL]], [[
+m4_ifdef([[M4_MODE_GENTABLES]], [[
+ while ((yy_current_state = yy_nxt[yy_current_state][ M4_EC(YY_SC_TO_UI(*yy_cp)) ]) > 0) {
+]])
+m4_ifdef([[M4_MODE_NO_GENTABLES]], [[
+ while ((yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + M4_EC(YY_SC_TO_UI(*yy_cp)) ]) > 0)
+ {
+]])
+M4_GEN_BACKING_UP
+ yy_cp++;
+ }
+ yy_current_state = -yy_current_state;
+]])
+m4_ifdef([[M4_MODE_FULLSPD]], [[
+ M4_GEN_NEXT_MATCH_FULLSPD(M4_EC(YY_SC_TO_UI(*yy_cp)), M4_EC(YY_SC_TO_UI(*++yy_cp)))
+]])
+m4_ifdef([[M4_MODE_NO_FULLSPD_OR_FULLTBL]], [[
+ do
+ {
+ M4_GEN_NEXT_COMPRESSED_STATE(M4_EC(YY_SC_TO_UI(*yy_cp)))
+
+ m4_ifdef([[M4_MODE_USES_REJECT]], [[*YY_G(yy_state_ptr)++ = yy_current_state;]])
+ ++yy_cp;
+
+ }
+ m4_ifdef([[M4_MODE_INTERACTIVE]], [[while ( yy_base[yy_current_state] != YY_JAMBASE );]])
+ m4_ifdef([[M4_MODE_NO_INTERACTIVE]], [[while ( yy_current_state != YY_JAMSTATE );]])
+
+m4_ifdef([[M4_MODE_NO_USES_REJECT]], [[
+m4_ifdef([[M4_MODE_NO_INTERACTIVE]], [[
+ /* Do the guaranteed-needed backing up to figure out
+ * the match.
+ */
+ yy_cp = YY_G(yy_last_accepting_cpos);
+ yy_current_state = YY_G(yy_last_accepting_state);
+]])
+]])
+]])
+
yy_find_action:
%% [10.0] code to find the action number goes here
m4_ifdef([[M4_MODE_FULLSPD]], [[yy_act = yy_current_state[-1].yy_nxt;]])
diff --git a/src/flexdef.h b/src/flexdef.h
index e84de08..b1de1b6 100644
--- a/src/flexdef.h
+++ b/src/flexdef.h
@@ -789,9 +789,6 @@ extern void genftbl(void); /* generate full transition table */
/* Generate the code to find the next compressed-table state. */
extern void gen_next_compressed_state(char *);
-/* Generate the code to find the next match. */
-extern void gen_next_match(void);
-
/* Generate the code to find the next state. */
extern void gen_next_state(int);
diff --git a/src/gen.c b/src/gen.c
index 07341ba..2b726a4 100644
--- a/src/gen.c
+++ b/src/gen.c
@@ -541,109 +541,6 @@ void gen_next_compressed_state (char *char_map)
}
-/* 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 ("{");
- outn ("M4_GEN_BACKING_UP");
- outc ('\n');
- }
-
- indent_puts ("++yy_cp;");
-
- if (num_backing_up > 0)
- outn ("M4_GEN_BACKING_UP");
- 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');
- outn ("M4_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;
-
- if (interactive)
- indent_puts ("while ( yy_base[yy_current_state] != YY_JAMBASE );");
- else
- indent_puts ("while ( yy_current_state != YY_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)
@@ -1677,7 +1574,6 @@ void make_tables (void)
/* Note, don't use any indentation. */
outn ("yy_match:");
- gen_next_match ();
skelout (); /* %% [10.0] - break point in skel */
set_indent (2);