From: Ulya Trofimovich Date: Wed, 25 Mar 2015 16:25:10 +0000 (+0000) Subject: Fixed bug #57: Wrong result only if another rule is present X-Git-Tag: 0.14.2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1a97c678d5ae0dac02234ee65d9bd847dd43c449;p=re2c Fixed bug #57: Wrong result only if another rule is present 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. --- diff --git a/re2c/actions.cc b/re2c/actions.cc index 24356cf0..60aba798 100644 --- a/re2c/actions.cc +++ b/re2c/actions.cc @@ -278,8 +278,11 @@ RegExp *mkAlt(RegExp *e1, RegExp *e2) m1 = dynamic_cast(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(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 index 00000000..96f1ce30 --- /dev/null +++ b/re2c/test/bug57.c @@ -0,0 +1,114 @@ +/* Generated by re2c */ +#line 1 "bug57.re" +#include + +int scan(const char *p) +{ +#define YYCTYPE char + const char *YYCURSOR = p; + const char *YYMARKER; + + +#line 13 "" +{ + 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 "" +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 "" +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 "" +} +#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 index 00000000..f50abac3 --- /dev/null +++ b/re2c/test/bug57.re @@ -0,0 +1,27 @@ +#include + +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; +} +