Skip to content

Commit

Permalink
Add improvements to interpolate parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed Mar 7, 2015
1 parent c90ab53 commit 9d07a48
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 12 deletions.
12 changes: 6 additions & 6 deletions parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ namespace Sass {
{
const char* i = chunk.begin;
// see if there any interpolants
const char* p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(i, chunk.end);
const char* p = find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end);
if (!p) {
String_Quoted* str_quoted = new (ctx.mem) String_Quoted(pstate, string(i, chunk.end));
if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');
Expand All @@ -1283,7 +1283,7 @@ namespace Sass {

String_Schema* schema = new (ctx.mem) String_Schema(pstate);
while (i < chunk.end) {
p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(i, chunk.end);
p = find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end);
if (p) {
if (i < p) {
// accumulate the preceding segment if it's nonempty
Expand Down Expand Up @@ -1338,7 +1338,7 @@ namespace Sass {
Token str(lexed);
const char* i = str.begin;
// see if there any interpolants
const char* p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(str.begin, str.end);
const char* p = find_first_in_interval< exactly<hash_lbrace> >(str.begin, str.end);
if (!p) {
String_Constant* str_node = new (ctx.mem) String_Constant(pstate, normalize_wspace(string(str.begin, str.end)));
str_node->is_delayed(true);
Expand All @@ -1347,7 +1347,7 @@ namespace Sass {

String_Schema* schema = new (ctx.mem) String_Schema(pstate);
while (i < str.end) {
p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(i, str.end);
p = find_first_in_interval< exactly<hash_lbrace> >(i, str.end);
if (p) {
if (i < p) {
(*schema) << new (ctx.mem) String_Constant(pstate, string(i, p)); // accumulate the preceding segment if it's nonempty
Expand Down Expand Up @@ -1474,14 +1474,14 @@ namespace Sass {
Token id(lexed);
const char* i = id.begin;
// see if there any interpolants
const char* p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(id.begin, id.end);
const char* p = find_first_in_interval< exactly<hash_lbrace> >(id.begin, id.end);
if (!p) {
return new (ctx.mem) String_Quoted(pstate, string(id.begin, id.end));
}

String_Schema* schema = new (ctx.mem) String_Schema(pstate);
while (i < id.end) {
p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(i, id.end);
p = find_first_in_interval< exactly<hash_lbrace> >(i, id.end);
if (p) {
if (i < p) {
// accumulate the preceding segment if it's nonempty
Expand Down
4 changes: 2 additions & 2 deletions prelexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ namespace Sass {
zero_plus <
alternatives <
// skip all escaped chars first
sequence < exactly < '\\' >, any_char >,
backslash_something,
// skip interpolants
interpolant,
// skip non delimiters
Expand All @@ -186,7 +186,7 @@ namespace Sass {
zero_plus <
alternatives <
// skip all escaped chars first
sequence < exactly < '\\' >, any_char >,
backslash_something,
// skip interpolants
interpolant,
// skip non delimiters
Expand Down
19 changes: 16 additions & 3 deletions prelexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,27 +565,40 @@ namespace Sass {
}
template<prelexer mx>
const char* find_first_in_interval(const char* beg, const char* end) {
bool esc = false;
while ((beg < end) && *beg) {
if (mx(beg)) return beg;
if (esc) esc = false;
else if (*beg == '\\') esc = true;
else if (mx(beg)) return beg;
++beg;
}
return 0;
}
template <char c>
unsigned int count_interval(const char* beg, const char* end) {
unsigned int counter = 0;
bool esc = false;
while (beg < end && *beg) {
if (*beg == c) ++counter;
if (esc) esc = false;
else if (*beg == '\\') esc = true;
else if (*beg == c) ++counter;
++beg;
}
return counter;
}
template <prelexer mx>
unsigned int count_interval(const char* beg, const char* end) {
unsigned int counter = 0;
bool esc = false;
while (beg < end && *beg) {
const char* p;
if ((p = mx(beg))) {
if (esc) {
esc = false;
++beg;
} else if (*beg == '\\') {
esc = true;
++beg;
} else if ((p = mx(beg))) {
++counter;
beg = p;
}
Expand Down
5 changes: 4 additions & 1 deletion util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ namespace Sass {
out += i;
}
}
if (esc) out += 'Z';
// happens when parsing does not correctly skip
// over escaped sequences for ie. interpolations
// one example: foo\#{interpolate}
// if (esc) out += '\\';
return out;
}

Expand Down

0 comments on commit 9d07a48

Please sign in to comment.