]> granicus.if.org Git - re2c/commitdiff
Don't forget to dereference tag aliases.
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 14 May 2016 13:46:39 +0000 (14:46 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 14 May 2016 13:46:39 +0000 (14:46 +0100)
Some tags are merged to other tags during tag deduplication.
These tags are referenced by their distinct name in action code,
but in fact they are just aliases to their representative tag
(origin).

re2c/src/codegen/emit_action.cc
re2c/src/codegen/input_api.cc
re2c/src/codegen/input_api.h
re2c/test/tags/dedup4.i--tags.c [new file with mode: 0644]
re2c/test/tags/dedup4.i--tags.re [new file with mode: 0644]

index eb2efc2f4525d73b9a87aacd68720032472d68ea..bc42965b2cf81d9f2b1ef27a1fb7494d2d3d37ea 100644 (file)
@@ -215,17 +215,7 @@ void emit_rule(OutputFile &o, uint32_t ind, const DFA &dfa, size_t rule_idx)
        const RuleInfo *info = rule.info;
 
        if (rule.trail != Tag::NONE) {
-               const Tag &tag = dfa.tags[rule.trail];
-               if (tag.type == Tag::VAR) {
-                       if (dfa.basetag) {
-                               o.wstring(opts->input_api.stmt_restorectx_var_base(ind,
-                                       vartag_expr(tag.name, tag.rule)));
-                       } else {
-                               o.wstring(opts->input_api.stmt_restorectx_var(ind));
-                       }
-               } else {
-                       o.wstring(opts->input_api.stmt_restorectx_fix(ind, tag.fix.dist));
-               }
+               o.wstring(opts->input_api.stmt_restorectx(ind, dfa.tags, dfa.tags[rule.trail], dfa.basetag));
        }
 
        if (opts->target == opt_t::SKELETON) {
index b02e1c851155e6f7ba28dbc872314e3b32354d0e..95f37c0ba236562fe30b5e9bf63d9d1e41baee3a 100644 (file)
 namespace re2c
 {
 
+template<typename T>
+static std::string to_string(const T &v)
+{
+       std::ostringstream s;
+       s << v;
+       return s.str();
+}
+
 InputAPI::InputAPI ()
        : type_ (DEFAULT)
 {}
@@ -134,7 +142,8 @@ std::string InputAPI::expr_tag(const std::valarray<Tag> &tags, size_t idx) const
 {
        const Tag &t = tags[idx];
        if (t.type == Tag::VAR) {
-               return expr_tag_var(vartag_expr(t.name, t.rule));
+               const Tag &o = tags[t.var.orig];
+               return expr_tag_var(vartag_expr(o.name, o.rule));
        } else if (t.fix.base != Tag::NONE) {
                const Tag &o = tags[tags[t.fix.base].var.orig];
                std::ostringstream s;
@@ -171,45 +180,28 @@ std::string InputAPI::stmt_restore (uint32_t ind) const
        return indent (ind) + s + ";\n";
 }
 
-std::string InputAPI::stmt_restorectx_fix(uint32_t ind, size_t dist) const
-{
-       std::ostringstream s;
-       switch (type_) {
-               case DEFAULT:
-                       s << opts->yycursor << " -= " << dist;
-                       break;
-               case CUSTOM:
-                       s << opts->yyrestorectx << " (" + opts->tags_yydist + "() - " << dist << ")";
-                       break;
-       }
-       return indent(ind) + s.str() + ";\n";
-}
-
-std::string InputAPI::stmt_restorectx_var_base(uint32_t ind, const std::string &ctx) const
+std::string InputAPI::stmt_restorectx(uint32_t ind,
+       const std::valarray<Tag> &tags, const Tag &tag, bool basetag) const
 {
        std::string s;
-       switch (type_) {
-               case DEFAULT:
-                       s = opts->yycursor + " = " + opts->yyctxmarker + " + " + ctx;
-                       break;
-               case CUSTOM:
-                       s = opts->yyrestorectx + " (" + ctx + ")";
-                       break;
-       }
-       return indent(ind) + s + ";\n";
-}
 
-std::string InputAPI::stmt_restorectx_var(uint32_t ind) const
-{
-       std::string s;
-       switch (type_) {
-               case DEFAULT:
-                       s = opts->yycursor + " = " + opts->yyctxmarker;
-                       break;
-               case CUSTOM:
-                       s = opts->yyrestorectx + " ()";
-                       break;
+       if (tag.type == Tag::FIX) {
+               const std::string dist = to_string(tag.fix.dist);
+               s = (type_ == DEFAULT)
+                       ? opts->yycursor + " -= " + dist
+                       : opts->yyrestorectx + " (" + opts->tags_yydist + "() - " + dist + ")";
+       } else if (basetag) {
+               const Tag &orig = tags[tag.var.orig];
+               const std::string expr = vartag_expr(orig.name, orig.rule);
+               s = (type_ == DEFAULT)
+                       ? opts->yycursor + " = " + opts->yyctxmarker + " + " + expr
+                       : opts->yyrestorectx + " (" + expr + ")";
+       } else {
+               s = (type_ == DEFAULT)
+                       ? opts->yycursor + " = " + opts->yyctxmarker
+                       : opts->yyrestorectx + " ()";
        }
+
        return indent(ind) + s + ";\n";
 }
 
index e698f896f0166db98d427b5d8e8c6b2972d08c7c..8fee2c640770ed8f832809692794b1c6a3c1724c 100644 (file)
@@ -37,9 +37,8 @@ public:
                const std::valarray<Tag> &tags) const;
        std::string expr_tag(const std::valarray<Tag> &tags, size_t idx) const;
        std::string stmt_restore (uint32_t ind) const;
-       std::string stmt_restorectx_fix (uint32_t ind, size_t dist) const;
-       std::string stmt_restorectx_var (uint32_t ind) const;
-       std::string stmt_restorectx_var_base (uint32_t ind, const std::string &ctx) const;
+       std::string stmt_restorectx(uint32_t ind,
+               const std::valarray<Tag> &tags, const Tag &tag, bool basetag) const;
        std::string stmt_skip_peek (uint32_t ind) const;
        std::string stmt_skip_backup (uint32_t ind) const;
        std::string stmt_backup_peek (uint32_t ind) const;
diff --git a/re2c/test/tags/dedup4.i--tags.c b/re2c/test/tags/dedup4.i--tags.c
new file mode 100644 (file)
index 0000000..8c5aa46
--- /dev/null
@@ -0,0 +1,273 @@
+/* Generated by re2c */
+
+{
+       YYCTYPE yych;
+       long yytag0;
+       long yytag0p;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy4;
+       default:        goto yy2;
+       }
+yy2:
+       ++YYCURSOR;
+       {}
+yy4:
+       ++YYCURSOR;
+       switch ((yych = *YYCURSOR)) {
+       case 'b':
+               yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy6;
+       case 'c':
+               yytag0 = yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy8;
+       case 'd':
+               yytag0 = yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy11;
+       default:
+               yytag0 = yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy5;
+       }
+yy5:
+       YYCURSOR = YYCTXMARKER + yytag0;
+       { (YYCTXMARKER + yytag0p) }
+yy6:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy6;
+       case 'c':
+               yytag0 = (YYCURSOR - YYCTXMARKER);
+               goto yy8;
+       case 'd':
+               yytag0 = (YYCURSOR - YYCTXMARKER);
+               goto yy11;
+       default:
+               yytag0 = (YYCURSOR - YYCTXMARKER);
+               goto yy5;
+       }
+yy8:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy8;
+       default:        goto yy10;
+       }
+yy10:
+       YYCURSOR = YYCTXMARKER + yytag0;
+       { (YYCTXMARKER + yytag0p) }
+yy11:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'd':       goto yy11;
+       default:        goto yy5;
+       }
+}
+
+
+
+{
+       YYCTYPE yych;
+       long yytag0p;
+       long yytag1p;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy17;
+       default:        goto yy15;
+       }
+yy15:
+       ++YYCURSOR;
+       {}
+yy17:
+       ++YYCURSOR;
+       switch ((yych = *YYCURSOR)) {
+       case 'b':
+               yytag0p = yytag1p = (YYCURSOR - YYCTXMARKER);
+               goto yy19;
+       case 'c':
+               yytag0p = yytag1p = (YYCURSOR - YYCTXMARKER);
+               goto yy21;
+       default:
+               yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy18;
+       }
+yy18:
+       { (YYCTXMARKER + yytag0p) }
+yy19:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy19;
+       case 'c':
+               yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy21;
+       default:        goto yy18;
+       }
+yy21:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy21;
+       default:        goto yy23;
+       }
+yy23:
+       YYCURSOR = YYCTXMARKER + yytag0p;
+       { (YYCTXMARKER + yytag1p) }
+}
+
+
+
+{
+       YYCTYPE yych;
+       unsigned int yyaccept = 0;
+       long yytag0p;
+       long yytag1;
+       long yytag1p;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy28;
+       default:        goto yy26;
+       }
+yy26:
+       ++YYCURSOR;
+       {}
+yy28:
+       yyaccept = 0;
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case 'b':
+               yytag0p = yytag1p = (YYCURSOR - YYCTXMARKER);
+               goto yy30;
+       case 'c':
+               yytag1 = yytag1p = (YYCURSOR - YYCTXMARKER);
+               goto yy32;
+       default:
+               yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy29;
+       }
+yy29:
+       { (YYCTXMARKER + yytag0p) }
+yy30:
+       yyaccept = 1;
+       YYMARKER = ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy30;
+       case 'c':
+               yytag1 = (YYCURSOR - YYCTXMARKER);
+               goto yy32;
+       default:        goto yy29;
+       }
+yy32:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'd':       goto yy34;
+       default:        goto yy33;
+       }
+yy33:
+       YYCURSOR = YYMARKER;
+       switch (yyaccept) {
+       case 0: 
+               yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy29;
+       case 1:         goto yy29;
+       default:        goto yy35;
+       }
+yy34:
+       yyaccept = 2;
+       YYMARKER = ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy32;
+       default:        goto yy35;
+       }
+yy35:
+       YYCURSOR = YYCTXMARKER + yytag1;
+       { (YYCTXMARKER + yytag1p) }
+}
+
+
+
+{
+       YYCTYPE yych;
+       unsigned int yyaccept = 0;
+       long yytag0p;
+       long yytag1;
+       YYCTXMARKER = YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'a':       goto yy40;
+       default:        goto yy38;
+       }
+yy38:
+       ++YYCURSOR;
+yy39:
+       {}
+yy40:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case 'b':
+               yytag0p = (YYCURSOR - YYCTXMARKER);
+               goto yy41;
+       default:        goto yy39;
+       }
+yy41:
+       yyaccept = 0;
+       YYMARKER = ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy41;
+       case 'c':
+               yytag1 = (YYCURSOR - YYCTXMARKER);
+               goto yy44;
+       default:        goto yy43;
+       }
+yy43:
+       { (YYCTXMARKER + yytag0p) }
+yy44:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'd':       goto yy46;
+       default:        goto yy45;
+       }
+yy45:
+       YYCURSOR = YYMARKER;
+       if (yyaccept == 0) {
+               goto yy43;
+       } else {
+               goto yy47;
+       }
+yy46:
+       yyaccept = 1;
+       YYMARKER = ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'c':       goto yy44;
+       default:        goto yy47;
+       }
+yy47:
+       YYCURSOR = YYCTXMARKER + yytag1;
+       { (YYCTXMARKER + yytag0p) }
+}
+
diff --git a/re2c/test/tags/dedup4.i--tags.re b/re2c/test/tags/dedup4.i--tags.re
new file mode 100644 (file)
index 0000000..2cb604e
--- /dev/null
@@ -0,0 +1,23 @@
+/*!re2c
+    "a" @p "b"* / "d"* { @p }
+    "a" @p "b"* / "c"* { @p }
+    * {}
+*/
+
+/*!re2c
+    "a" @p "b"*        { @p }
+    "a" @p "b"* / "c"* { @p }
+    * {}
+*/
+
+/*!re2c
+    "a" @p "b"*         { @p }
+    "a" @p "b"* / "cd"* { @p }
+    * {}
+*/
+
+/*!re2c
+    "a" @p "b"+         { @p }
+    "a" @p "b"+ / "cd"* { @p }
+    * {}
+*/