From 69c6ff7aa06045a3fdaf6a134041e9206cb95a9e Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 30 Apr 2014 10:15:18 +0900 Subject: fix condition for the rest of input the input must rest the length of a string to be peeked at least. fixes parse error at embedded documents by string eval, and `-e` command line options. --- src/parse.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/parse.y b/src/parse.y index aab1aaa40..7f1139a07 100644 --- a/src/parse.y +++ b/src/parse.y @@ -3454,7 +3454,7 @@ peeks(parser_state *p, const char *s) } else #endif - if (p->s && p->s + len >= p->send) { + if (p->s && p->s + len <= p->send) { if (memcmp(p->s, s, len) == 0) return TRUE; } return FALSE; -- cgit v1.2.3 From 854ae564a34910fe3bd13a83a3d4bfa10cf0d838 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 30 Apr 2014 10:27:05 +0900 Subject: fix embedded documents tabs are allowed after `=begin` and `=end`. raise `SyntaxError` if no =end is found. --- src/parse.y | 33 ++++++++++++++++++++++----------- test/t/syntax.rb | 3 +++ 2 files changed, 25 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/parse.y b/src/parse.y index 7f1139a07..477305db4 100644 --- a/src/parse.y +++ b/src/parse.y @@ -3417,15 +3417,15 @@ skip(parser_state *p, char term) } } -static mrb_bool -peek_n(parser_state *p, int c, int n) +static int +peekc_n(parser_state *p, int n) { node *list = 0; int c0; do { c0 = nextc(p); - if (c0 < 0) return FALSE; + if (c0 < 0) return c0; list = push(list, (node*)(intptr_t)c0); } while(n--); if (p->pb) { @@ -3434,8 +3434,13 @@ peek_n(parser_state *p, int c, int n) else { p->pb = list; } - if (c0 == c) return TRUE; - return FALSE; + return c0; +} + +static mrb_bool +peek_n(parser_state *p, int c, int n) +{ + return peekc_n(p, n) == c && c >= 0; } #define peek(p,c) peek_n((p), (c), 0) @@ -4189,14 +4194,20 @@ parser_yylex(parser_state *p) case '=': if (p->column == 1) { - if (peeks(p, "begin ") || peeks(p, "begin\n")) { - if (skips(p, "\n=end ")) { - goto retry; - } - if (skips(p, "\n=end\n")) { + static const char begin[] = "begin"; + static const char end[] = "\n=end"; + if (peeks(p, begin)) { + c = peekc_n(p, sizeof(begin)-1); + if (c < 0 || isspace(c)) { + do { + if (!skips(p, end)) { + yyerror(p, "embedded document meets end of file"); + return 0; + } + c = nextc_n(p, sizeof(end)-1); + } while (!(c < 0 || isspace(c))); goto retry; } - goto retry; } } if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 0bb3fa389..05d4a15b1 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -307,5 +307,8 @@ this is a comment that has =end with spaces after it =begin this is a comment this is a comment that has extra after =begin and =end with spaces after it =end +=begin this is a comment +this is a comment that has extra after =begin and =end with tabs after it +=end true end -- cgit v1.2.3 From 82fce52211f729c98bce1f4cd020157e56a4fd4d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 30 Apr 2014 12:23:28 +0900 Subject: fix char after `=end` skips() advance after the string skipped. --- src/parse.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/parse.y b/src/parse.y index 477305db4..082b49294 100644 --- a/src/parse.y +++ b/src/parse.y @@ -4204,7 +4204,7 @@ parser_yylex(parser_state *p) yyerror(p, "embedded document meets end of file"); return 0; } - c = nextc_n(p, sizeof(end)-1); + c = nextc(p); } while (!(c < 0 || isspace(c))); goto retry; } -- cgit v1.2.3 From cf3b880df6df004b9471c3bf67aa44774e3ca952 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 30 Apr 2014 12:32:18 +0900 Subject: skip to the next line and reset column after `=end` --- src/parse.y | 3 +++ test/t/syntax.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/parse.y b/src/parse.y index 082b49294..b0e324202 100644 --- a/src/parse.y +++ b/src/parse.y @@ -4206,6 +4206,9 @@ parser_yylex(parser_state *p) } c = nextc(p); } while (!(c < 0 || isspace(c))); + if (c != '\n') skip(p, '\n'); + p->lineno++; + p->column = 0; goto retry; } } diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 05d4a15b1..a64000534 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -309,6 +309,6 @@ this is a comment that has extra after =begin and =end with spaces after it =end =begin this is a comment this is a comment that has extra after =begin and =end with tabs after it -=end +=end xxxxxxxxxxxxxxxxxxxxxxxxxx true end -- cgit v1.2.3 From 8b13efc26d4a753490427a6db4c874844ea4a5de Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 30 Apr 2014 12:43:14 +0900 Subject: count skipped line numbers --- src/parse.y | 9 ++++++++- test/t/syntax.rb | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/parse.y b/src/parse.y index b0e324202..230d7659e 100644 --- a/src/parse.y +++ b/src/parse.y @@ -3475,6 +3475,10 @@ skips(parser_state *p, const char *s) for (;;) { c = nextc(p); if (c < 0) return c; + if (c == '\n') { + p->lineno++; + p->column = 0; + } if (c == *s) break; } s++; @@ -3482,7 +3486,10 @@ skips(parser_state *p, const char *s) int len = strlen(s); while (len--) { - nextc(p); + if (nextc(p) == '\n') { + p->lineno++; + p->column = 0; + } } return TRUE; } diff --git a/test/t/syntax.rb b/test/t/syntax.rb index a64000534..e105cd3d4 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -307,8 +307,9 @@ this is a comment that has =end with spaces after it =begin this is a comment this is a comment that has extra after =begin and =end with spaces after it =end + line = __LINE__ =begin this is a comment this is a comment that has extra after =begin and =end with tabs after it =end xxxxxxxxxxxxxxxxxxxxxxxxxx - true + assert_equal(line + 4, __LINE__) end -- cgit v1.2.3