]> granicus.if.org Git - re2c/commitdiff
Fixed bug #57: Wrong result only if another rule is present
authorUlya Trofimovich <skvadrik@gmail.com>
Wed, 25 Mar 2015 16:25:10 +0000 (16:25 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Wed, 25 Mar 2015 16:25:10 +0000 (16:25 +0000)
When making regexp alternative, only 'RegExp::PRIVATE' attribute
should be propagated. Propagating 'RegExp::SHARED' attribute is
a mistake, as can be observed from the following example:

    name = "smth1";
    "smth2" | name | "smth3" { ... }
    name                     { ... }

Here, 'name' must have 'RegExp::PRIVATE' attribute, but it gets
broken after alternation. See #bug57 or test 'bug57.re' for full
working example.

re2c/actions.cc
re2c/test/bug57.c [new file with mode: 0644]
re2c/test/bug57.re [new file with mode: 0644]

index 24356cf0d57983325a4eabebe15354bf412d47bc..60aba7982ed599ed8c8ca0e127f779fae8e89f95 100644 (file)
@@ -278,8 +278,11 @@ RegExp *mkAlt(RegExp *e1, RegExp *e2)
                m1 = dynamic_cast<MatchOp*>(a->exp1);
                if (m1 != NULL)
                {
-                       m1->ins_access = e1->ins_access;
-                       a->exp2->ins_access = e1->ins_access;
+                       if (e1->ins_access == RegExp::PRIVATE)
+                       {
+                               m1->ins_access = RegExp::PRIVATE;
+                               a->exp2->ins_access = RegExp::PRIVATE;
+                       }
                        e1 = a->exp2;
                }
        }
@@ -296,8 +299,11 @@ RegExp *mkAlt(RegExp *e1, RegExp *e2)
                m2 = dynamic_cast<MatchOp*>(a->exp1);
                if (m2 != NULL)
                {
-                       m2->ins_access = e2->ins_access;
-                       a->exp2->ins_access = e2->ins_access;
+                       if (e2->ins_access == RegExp::PRIVATE)
+                       {
+                               m2->ins_access = RegExp::PRIVATE;
+                               a->exp2->ins_access = RegExp::PRIVATE;
+                       }
                        e2 = a->exp2;
                }
        }
diff --git a/re2c/test/bug57.c b/re2c/test/bug57.c
new file mode 100644 (file)
index 0000000..96f1ce3
--- /dev/null
@@ -0,0 +1,114 @@
+/* Generated by re2c */
+#line 1 "bug57.re"
+#include <stdio.h>
+
+int scan(const char *p)
+{
+#define YYCTYPE char
+    const char *YYCURSOR = p;
+    const char *YYMARKER;
+
+
+#line 13 "<stdout>"
+{
+       YYCTYPE yych;
+       unsigned int yyaccept = 0;
+
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '\n':      goto yy2;
+       case '<':       goto yy3;
+       case '\\':      goto yy6;
+       case 'a':       goto yy5;
+       default:        goto yy7;
+       }
+yy2:
+#line 15 "bug57.re"
+       { return YYCURSOR - p; }
+#line 29 "<stdout>"
+yy3:
+       yyaccept = 0;
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case '>':       goto yy15;
+       case '\\':      goto yy14;
+       case 'x':
+       case 'y':       goto yy12;
+       default:        goto yy4;
+       }
+yy4:
+#line 16 "bug57.re"
+       { return 0; }
+#line 43 "<stdout>"
+yy5:
+       yyaccept = 1;
+       yych = *(YYMARKER = ++YYCURSOR);
+       goto yy9;
+yy6:
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy8;
+       default:        goto yy4;
+       }
+yy7:
+       yych = *++YYCURSOR;
+       goto yy4;
+yy8:
+       yyaccept = 1;
+       YYMARKER = ++YYCURSOR;
+       yych = *YYCURSOR;
+yy9:
+       switch (yych) {
+       case '\\':      goto yy10;
+       case 'a':       goto yy8;
+       default:        goto yy2;
+       }
+yy10:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy8;
+       default:        goto yy11;
+       }
+yy11:
+       YYCURSOR = YYMARKER;
+       if (yyaccept == 0) {
+               goto yy4;
+       } else {
+               goto yy2;
+       }
+yy12:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '>':       goto yy15;
+       case '\\':      goto yy14;
+       case 'x':
+       case 'y':       goto yy12;
+       default:        goto yy11;
+       }
+yy14:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case 'b':       goto yy12;
+       default:        goto yy11;
+       }
+yy15:
+       ++YYCURSOR;
+#line 14 "bug57.re"
+       { return YYCURSOR - p; }
+#line 102 "<stdout>"
+}
+#line 17 "bug57.re"
+
+}
+
+int main()
+{
+    const char *str = "aaa\\baaa";
+    int res = scan(str);
+    printf("%d: %s\n", res, str + res);
+    return 0;
+}
+
diff --git a/re2c/test/bug57.re b/re2c/test/bug57.re
new file mode 100644 (file)
index 0000000..f50abac
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+int scan(const char *p)
+{
+#define YYCTYPE char
+    const char *YYCURSOR = p;
+    const char *YYMARKER;
+
+/*!re2c
+    re2c:yyfill:enable = 0;
+
+    escaped_char = "\\b";
+
+    [<] ([x] | escaped_char | [y])* [>] { return YYCURSOR - p; }
+    ("a" | escaped_char)* { return YYCURSOR - p; }
+    . { return 0; }
+*/
+}
+
+int main()
+{
+    const char *str = "aaa\\baaa";
+    int res = scan(str);
+    printf("%d: %s\n", res, str + res);
+    return 0;
+}
+