]> granicus.if.org Git - re2c/commitdiff
Don't hide the ugly fact that default state in '-f' mode is always state 0.
authorUlya Trofimovich <skvadrik@gmail.com>
Tue, 26 May 2015 13:00:01 +0000 (14:00 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Tue, 26 May 2015 13:00:01 +0000 (14:00 +0100)
In '-f' mode, state dispatch generation can be triggered in two ways.
Both ways use 're2c::OutputFile::insert_state_goto', which generates
state dispatch only if it hasn't been already generated. The two ways
are:
1. Explicitly, using '/*!getstate:re2c*/'. In this case default state
   must be state 0 because it's hardcoded in the invocation of
   're2c::OutputFile::insert_state_goto' in 'src/parse/scanner_lex.re'.
2. Implicitly, in 're2c::DFA::emit'. In this case default state must
   be state 0 because if 'prolog_label' is not 0, it means that it's
   not the first time 're2c::DFA::emit' is called and state dispatch
   has already been generated.

This commit makes it explicit that re2c always uses state 0.

Note:
    Currently in '-f' mode re2c generates one global dispatch for
    the whole file (the enumeration of yyFillLabel's is also global).
    All re2c blocks share the same state dispatch, so in '-f' mode all
    re2c blocks must reside in the same function and must be parts of
    the same lexer (exception: in '-r' mode re2c generates one state
    dispatch per use block).

    This is clearly an ugly limitation: one is forced put disconnected
    lexers in different files in '-f' mode.

    Now re2c provides conditions as a way to express related blocks,
    so if users used multiple blocks only for unrelated lexers, we
    could safely limit the scope of state dispatch to a single block.
    But conditions can conflict with other re2c features, they are
    a bit broken and I'm pretty sure some users use multiple blocks
    (e.g. I used to do it).

    Thus we cannot just make '-f' generate state dispatch on per-block
    basis (there're some other obstacles: it's not quite clear which
    block '/*!getstate:re2c*/ directive is related to, etc.).

    I leave the situation 'as is' until better times (when lexer-
    parser loop is fixed and the whole code generation model is more
    robust).

re2c/bootstrap/scanner_lex.cc
re2c/src/codegen/emit_dfa.cc
re2c/src/codegen/output.cc
re2c/src/codegen/output.h
re2c/src/parse/scanner_lex.re

index 311c78edba051fb94978934f77562ddcc87f2f6c..469393ad1dff343b6e9a0a46ceaa7a965335c950 100644 (file)
@@ -328,7 +328,7 @@ yy50:
        ++YYCURSOR;
        {
                                        tok = pos = cursor;
-                                       out.insert_state_goto (topIndent, 0);
+                                       out.insert_state_goto (topIndent);
                                        ignore_eoc = true;
                                        goto echo;
                                }
index a331cc28e424266ae922f8b47c33ba22468b488b..cd3acaffd5e4f5af5a93bc9a27a23cdb5d52dcf4 100644 (file)
@@ -102,6 +102,10 @@ void DFA::emit(Output & output, uint32_t& ind, const RegExpMap* specMap, const s
                s->label = next_label++;
        }
 
+       if (fFlag)
+       {
+               vUsedLabels.insert(0);
+       }
        for (s = head; s; s = s->next)
        {
                s->go.used_labels ();
@@ -157,7 +161,7 @@ void DFA::emit(Output & output, uint32_t& ind, const RegExpMap* specMap, const s
        if (bProlog)
        {
                genCondTable(o, ind, *specMap);
-               o.insert_state_goto (ind, prolog_label);
+               o.insert_state_goto (ind);
                if (cFlag && !DFlag)
                {
                        if (vUsedLabels.count(prolog_label))
index 9d50ad8c23c7b2e3154ee021be26b81e391f64e3..72a88c906911625ea212338bb869e3c7614985b1 100644 (file)
@@ -51,7 +51,6 @@ OutputFile::OutputFile (const char * fn)
        : file_name (fn)
        , file (NULL)
        , blocks ()
-       , prolog_label (0)
 {
        new_block ();
 }
@@ -150,12 +149,10 @@ void OutputFile::insert_line_info ()
        insert_code ();
 }
 
-void OutputFile::insert_state_goto (uint32_t ind, uint32_t start_label)
+void OutputFile::insert_state_goto (uint32_t ind)
 {
        if (fFlag && !bWroteGetState)
        {
-               prolog_label = start_label;
-               vUsedLabels.insert (start_label);
                blocks.back ()->fragments.push_back (new OutputFragment (OutputFragment::STATE_GOTO, ind));
                insert_code ();
                bWroteGetState = true;
@@ -226,7 +223,7 @@ void OutputFile::emit
                                                output_line_info (f.stream, line_count + 1, file_name);
                                                break;
                                        case OutputFragment::STATE_GOTO:
-                                               output_state_goto (f.stream, f.indent, prolog_label);
+                                               output_state_goto (f.stream, f.indent, 0);
                                                break;
                                        case OutputFragment::TYPES:
                                                output_types (f.stream, f.indent, types);
index 860bae2540b591e2944ba1510b5142c2fcf0190e..fae5dea47d1208e51655d60bb2e6888f93cf4125 100644 (file)
@@ -69,7 +69,7 @@ struct OutputFile
        friend OutputFile & operator << (OutputFile & o, const char * s);
 
        void insert_line_info ();
-       void insert_state_goto (uint32_t ind, uint32_t start_label);
+       void insert_state_goto (uint32_t ind);
        void insert_types ();
        void insert_yyaccept_init (uint32_t ind);
        void insert_yyaccept_selector (uint32_t ind, uint32_t selector);
@@ -84,7 +84,6 @@ private:
        const char * file_name;
        FILE * file;
        std::vector<OutputBlock *> blocks;
-       uint32_t prolog_label;
 
        std::ostream & stream ();
        void insert_code ();
index 8a5c24c14c867fae003ccc795eadc14551a55da9..6ddc50825a1cf93a5b552a1c5f86dc061abb9651 100644 (file)
@@ -112,7 +112,7 @@ echo:
                                }
        "/*!getstate:re2c" {
                                        tok = pos = cursor;
-                                       out.insert_state_goto (topIndent, 0);
+                                       out.insert_state_goto (topIndent);
                                        ignore_eoc = true;
                                        goto echo;
                                }