Skip to content

Commit fad76c8

Browse files
committed
Merge pull request #1244 from xzyfer/fix/parsing-optional-semicolons
Fix parsing of optional ; in top level directives
2 parents 8878396 + 904df20 commit fad76c8

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

parser.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ namespace Sass {
8585
}
8686
}
8787

88+
bool semicolon = false;
89+
string(error_message);
8890
lex< optional_spaces >();
8991
Selector_Lookahead lookahead_result;
9092
while (position < end) {
@@ -97,22 +99,27 @@ namespace Sass {
9799
(*root) << new (ctx.mem) Import_Stub(pstate, imp->files()[i]);
98100
}
99101
}
100-
if (!lex< one_plus< exactly<';'> > >()) error("top-level @import directive must be terminated by ';'", pstate);
102+
semicolon = true;
103+
error_message = "top-level @import directive must be terminated by ';'";
101104
}
102105
else if (peek< kwd_mixin >() || peek< kwd_function >()) {
103106
(*root) << parse_definition();
104107
}
105108
else if (peek< variable >()) {
106109
(*root) << parse_assignment();
107-
if (!lex< one_plus< exactly<';'> > >()) error("top-level variable binding must be terminated by ';'", pstate);
110+
semicolon = true;
111+
error_message = "top-level variable binding must be terminated by ';'";
108112
}
109113
/*else if (peek< sequence< optional< exactly<'*'> >, alternatives< identifier_schema, identifier >, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position)) {
110114
(*root) << parse_propset();
111115
}*/
112116
else if (peek< kwd_include >() /* || peek< exactly<'+'> >() */) {
113117
Mixin_Call* mixin_call = parse_mixin_call();
114118
(*root) << mixin_call;
115-
if (!mixin_call->block() && !lex< one_plus< exactly<';'> > >()) error("top-level @include directive must be terminated by ';'", pstate);
119+
if (!mixin_call->block()) {
120+
semicolon = true;
121+
error_message = "top-level @include directive must be terminated by ';'";
122+
}
116123
}
117124
else if (peek< kwd_if_directive >()) {
118125
(*root) << parse_if_directive();
@@ -137,15 +144,18 @@ namespace Sass {
137144
}
138145
else if (peek< kwd_warn >()) {
139146
(*root) << parse_warning();
140-
if (!lex< one_plus< exactly<';'> > >()) error("top-level @warn directive must be terminated by ';'", pstate);
147+
semicolon = true;
148+
error_message = "top-level @warn directive must be terminated by ';'";
141149
}
142150
else if (peek< kwd_err >()) {
143151
(*root) << parse_error();
144-
if (!lex< one_plus< exactly<';'> > >()) error("top-level @error directive must be terminated by ';'", pstate);
152+
semicolon = true;
153+
error_message = "top-level @error directive must be terminated by ';'";
145154
}
146155
else if (peek< kwd_dbg >()) {
147156
(*root) << parse_debug();
148-
if (!lex< one_plus< exactly<';'> > >()) error("top-level @debug directive must be terminated by ';'", pstate);
157+
semicolon = true;
158+
error_message = "top-level @debug directive must be terminated by ';'";
149159
}
150160
// ignore the @charset directive for now
151161
else if (lex< exactly< charset_kwd > >()) {
@@ -155,7 +165,10 @@ namespace Sass {
155165
else if (peek< at_keyword >()) {
156166
At_Rule* at_rule = parse_at_rule();
157167
(*root) << at_rule;
158-
if (!at_rule->block() && !lex< one_plus< exactly<';'> > >()) error("top-level directive must be terminated by ';'", pstate);
168+
if (!at_rule->block()){
169+
semicolon = true;
170+
error_message = "top-level directive must be terminated by ';'";
171+
}
159172
}
160173
else if ((lookahead_result = lookahead_for_selector(position)).found) {
161174
(*root) << parse_ruleset(lookahead_result);
@@ -168,6 +181,11 @@ namespace Sass {
168181
if (position >= end) break;
169182
error("invalid top-level expression", after_token);
170183
}
184+
if (semicolon) {
185+
if (!lex< one_plus< exactly<';'> > >() && peek_css< optional_css_whitespace >() != end)
186+
{ error(error_message, pstate); }
187+
semicolon = false;
188+
}
171189
lex< optional_spaces >();
172190
}
173191
block_stack.pop_back();
@@ -1174,7 +1192,7 @@ namespace Sass {
11741192
exactly<ellipsis>,
11751193
default_flag,
11761194
global_flag
1177-
> >(position))
1195+
> >(position)) && peek_css< optional_css_whitespace >() != end
11781196
) {
11791197
(*space_list) << parse_disjunction();
11801198
}

0 commit comments

Comments
 (0)