Commit 854ae564 authored by Nobuyoshi Nakada's avatar Nobuyoshi Nakada

fix embedded documents

tabs are allowed after `=begin` and `=end`.
raise `SyntaxError` if no =end is found.
parent 69c6ff7a
......@@ -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) {
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment