Commit 3b0663f4 by Aaron Leung

More flexible lookahead; provides better compatibility with Sass, and is probably faster too.

parent b4b88d1a
...@@ -145,6 +145,8 @@ namespace Sass { ...@@ -145,6 +145,8 @@ namespace Sass {
Node parse_string(); Node parse_string();
Node parse_value_schema(); Node parse_value_schema();
const char* lookahead_for_selector(const char* start = 0);
const char* look_for_rule(const char* start = 0); const char* look_for_rule(const char* start = 0);
const char* look_for_values(const char* start = 0); const char* look_for_values(const char* start = 0);
......
...@@ -38,7 +38,8 @@ namespace Sass { ...@@ -38,7 +38,8 @@ namespace Sass {
root << parse_assignment(); root << parse_assignment();
if (!lex< exactly<';'> >()) syntax_error("top-level variable binding must be terminated by ';'"); if (!lex< exactly<';'> >()) syntax_error("top-level variable binding must be terminated by ';'");
} }
else if (look_for_selector_group(position)) { // else if (look_for_selector_group(position)) {
else if (lookahead_for_selector(position)) {
root << parse_ruleset(); root << parse_ruleset();
} }
else if (peek< exactly<'+'> >()) { else if (peek< exactly<'+'> >()) {
...@@ -474,7 +475,8 @@ namespace Sass { ...@@ -474,7 +475,8 @@ namespace Sass {
// block << parse_ruleset(); // block << parse_ruleset();
// block.has_blocks = true; // block.has_blocks = true;
// } // }
else if (const char* p = look_for_selector_group(position)) { //else if (const char* p = look_for_selector_group(position)) {
else if (const char* p = lookahead_for_selector(position)) {
block << parse_ruleset(definition); block << parse_ruleset(definition);
block[0].has_blocks = true; block[0].has_blocks = true;
} }
...@@ -905,6 +907,44 @@ namespace Sass { ...@@ -905,6 +907,44 @@ namespace Sass {
// return p == start ? 0 : p; // return p == start ? 0 : p;
// } // }
const char* Document::lookahead_for_selector(const char* start)
{
const char* p = start ? start : position;
const char* q;
while ((q = peek< identifier >(p)) ||
(q = peek< id_name >(p)) ||
(q = peek< class_name >(p)) ||
(q = peek< sequence< pseudo_prefix, identifier > >(p)) ||
(q = peek< string_constant >(p)) ||
(q = peek< exactly<'*'> >(p)) ||
(q = peek< exactly<'('> >(p)) ||
(q = peek< exactly<')'> >(p)) ||
(q = peek< exactly<'['> >(p)) ||
(q = peek< exactly<']'> >(p)) ||
(q = peek< exactly<'+'> >(p)) ||
(q = peek< exactly<'~'> >(p)) ||
(q = peek< exactly<'>'> >(p)) ||
(q = peek< exactly<','> >(p)) ||
(q = peek< binomial >(p)) ||
(q = peek< sequence< optional<sign>,
optional<digits>,
exactly<'n'> > >(p)) ||
(q = peek< sequence< optional<sign>,
digits > >(p)) ||
(q = peek< number >(p)) ||
(q = peek< exactly<'&'> >(p)) ||
(q = peek< alternatives<exact_match,
class_match,
dash_match,
prefix_match,
suffix_match,
substring_match> >(p))) { p = q; }
if (peek< exactly<'{'> >(p)) return p;
else return 0;
}
// NEW LOOKAHEAD FUNCTIONS. THIS ESSENTIALLY IMPLEMENTS A BACKTRACKING // NEW LOOKAHEAD FUNCTIONS. THIS ESSENTIALLY IMPLEMENTS A BACKTRACKING
// PARSER, BECAUSE SELECTORS AND VALUES ARE NOT EXPRESSIBLE IN A // PARSER, BECAUSE SELECTORS AND VALUES ARE NOT EXPRESSIBLE IN A
// REGULAR LANGUAGE. // REGULAR LANGUAGE.
......
...@@ -72,7 +72,10 @@ namespace Sass { ...@@ -72,7 +72,10 @@ namespace Sass {
} break; } break;
case selector_combinator: { case selector_combinator: {
return content.token.to_string(); string result(prefix.empty() ? "" : prefix + " ");
result += content.token.to_string();
return result;
// return content.token.to_string();
// if (std::isspace(content.token.begin[0])) return string(" "); // if (std::isspace(content.token.begin[0])) return string(" ");
// else return string(content.token); // else return string(content.token);
} break; } break;
......
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