Skip to content

Commit

Permalink
Merge pull request sass#1177 from mgreter/bugfix/issue_1158
Browse files Browse the repository at this point in the history
Implement correct String Schema parsing
  • Loading branch information
mgreter committed May 9, 2015
2 parents 348fde8 + 974ae42 commit 8768c44
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 52 deletions.
14 changes: 7 additions & 7 deletions context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
#define PATH_SEP ':'
#endif

#include <string>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>

#include "ast.hpp"
#include "util.hpp"
#include "sass.h"
Expand All @@ -29,13 +36,6 @@
#include "prelexer.hpp"
#include "emitter.hpp"

#include <string>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <iostream>

namespace Sass {
using namespace Constants;
using namespace File;
Expand Down
45 changes: 12 additions & 33 deletions debugger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,6 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
cerr << endl;
} else if (dynamic_cast<Variable*>(node)) {
Variable* expression = dynamic_cast<Variable*>(node);
cerr << ind << "Variable " << expression << " [" << expression->name() << "]";
if (expression->is_delayed()) cerr << " [delayed]";
cerr << endl;
cerr << ind << "Variable " << expression;
cerr << " (" << pstate_source_position(node) << ")";
cerr << " [" << expression->name() << "]" << endl;
Expand Down Expand Up @@ -486,55 +483,37 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
cerr << " [" << expression->value() << expression->unit() << "]" << endl;
} else if (dynamic_cast<String_Quoted*>(node)) {
String_Quoted* expression = dynamic_cast<String_Quoted*>(node);
cerr << ind << "String_Quoted : " << expression << " [";
cerr << prettyprint(expression->value()) << "]";
cerr << ind << "String_Quoted " << expression;
cerr << " (" << pstate_source_position(node) << ")";
cerr << " [" << prettyprint(expression->value()) << "]";
if (expression->is_delayed()) cerr << " [delayed]";
if (expression->sass_fix_1291()) cerr << " [sass_fix_1291]";
if (expression->quote_mark()) cerr << " [quote_mark]";
if (expression->quote_mark()) cerr << " [quote_mark: " << expression->quote_mark() << "]";
cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
cerr << ind << "String_Quoted : " << expression;
cerr << " (" << pstate_source_position(node) << ")";
cerr << " [" << prettyprint(expression->value()) << "]" <<
(expression->is_delayed() ? " {delayed}" : "") <<
(expression->sass_fix_1291() ? " {sass_fix_1291}" : "") <<
(expression->quote_mark() != 0 ? " {qm:" + string(1, expression->quote_mark()) + "}" : "") <<
" <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
} else if (dynamic_cast<String_Constant*>(node)) {
String_Constant* expression = dynamic_cast<String_Constant*>(node);
cerr << ind << "String_Constant : " << expression;
cerr << ind << "String_Constant " << expression;
cerr << " " << expression->concrete_type() <<
cerr << " (" << pstate_source_position(node) << ")";
cerr << " [" << prettyprint(expression->value()) << "]";
if (expression->is_delayed()) cerr << " [delayed]";
if (expression->sass_fix_1291()) cerr << " [sass_fix_1291]";
cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
cerr << ind << "String_Constant : " << expression;
cerr << " (" << pstate_source_position(node) << ")";
cerr << " [" << prettyprint(expression->value()) << "]" <<
(expression->is_delayed() ? " {delayed}" : "") <<
(expression->sass_fix_1291() ? " {sass_fix_1291}" : "") <<
(expression->quote_mark() != 0 ? " {qm:" + string(1, expression->quote_mark()) + "}" : "") <<
" <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
} else if (dynamic_cast<String_Schema*>(node)) {
String_Schema* expression = dynamic_cast<String_Schema*>(node);
cerr << ind << "String_Schema " << expression << " [" << expression->concrete_type() << "]";
cerr << ind << "String_Schema " << expression;
cerr << " " << expression->concrete_type();
if (expression->is_delayed()) cerr << " [delayed]";
if (expression->has_interpolants()) cerr << " [has_interpolants]";
cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
cerr << ind << "String_Schema " << expression;
cerr << " (" << pstate_source_position(node) << ")";
cerr << " " << expression->concrete_type() <<
(expression->has_interpolants() ? " {has_interpolants}" : "") <<
endl;
for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
} else if (dynamic_cast<String*>(node)) {
String* expression = dynamic_cast<String*>(node);
cerr << ind << "String " << expression << expression->concrete_type();
if (expression->sass_fix_1291()) cerr << " [sass_fix_1291]";
cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
cerr << ind << "String " << expression;
cerr << " " << expression->concrete_type();
cerr << " (" << pstate_source_position(node) << ")";
cerr << expression->concrete_type() <<
" " << (expression->sass_fix_1291() ? "{sass_fix_1291}" : "") <<
endl;
if (expression->sass_fix_1291()) cerr << " [sass_fix_1291]";
cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << endl;
} else if (dynamic_cast<Expression*>(node)) {
Expression* expression = dynamic_cast<Expression*>(node);
cerr << ind << "Expression " << expression;
Expand Down
12 changes: 6 additions & 6 deletions eval.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <typeinfo>

#include "file.hpp"
#include "eval.hpp"
#include "ast.hpp"
Expand All @@ -11,12 +17,6 @@
#include "prelexer.hpp"
#include "parser.hpp"

#include <cstdlib>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <typeinfo>

namespace Sass {
using namespace std;

Expand Down
78 changes: 72 additions & 6 deletions parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -980,13 +980,25 @@ namespace Sass {
return new (ctx.mem) Declaration(prop->pstate(), prop, parse_static_value()/*, lex<important>()*/);
}
else {
Expression* list_ex = parse_list();
if (List* list = dynamic_cast<List*>(list_ex)) {
if (list->length() == 0 && !peek< exactly <'{'> >()) {
css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
Expression* value;
Selector_Lookahead lookahead = lookahead_for_value(position);
if (lookahead.found) {
if (lookahead.has_interpolants) {
value = parse_value_schema(lookahead.found);
} else {
value = parse_list();
}
}
return new (ctx.mem) Declaration(prop->pstate(), prop, list_ex/*, lex<important>()*/);
else {
value = parse_list();
if (List* list = dynamic_cast<List*>(value)) {
if (list->length() == 0 && !peek< exactly <'{'> >()) {
css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
}
}
}

return new (ctx.mem) Declaration(prop->pstate(), prop, value/*, lex<important>()*/);
}
}

Expand Down Expand Up @@ -1503,7 +1515,10 @@ namespace Sass {
String_Schema* schema = new (ctx.mem) String_Schema(pstate);
size_t num_items = 0;
while (position < stop) {
if (lex< interpolant >()) {
if (lex< spaces >() && num_items) {
(*schema) << new (ctx.mem) String_Constant(pstate, " ");
}
else if (lex< interpolant >()) {
Token insides(Token(lexed.begin + 2, lexed.end - 1));
Expression* interp_node = Parser::from_token(insides, ctx, pstate).parse_list();
interp_node->is_interpolant(true);
Expand Down Expand Up @@ -2008,6 +2023,7 @@ namespace Sass {
(q = peek< class_name >(p)) ||
(q = peek< sequence< pseudo_prefix, identifier > >(p)) ||
(q = peek< percentage >(p)) ||
(q = peek< variable >(p)) ||
(q = peek< dimension >(p)) ||
(q = peek< quoted_string >(p)) ||
(q = peek< exactly<'*'> >(p)) ||
Expand Down Expand Up @@ -2070,6 +2086,7 @@ namespace Sass {
(q = peek< sequence< pseudo_prefix, identifier > >(p)) ||
(q = peek< percentage >(p)) ||
(q = peek< dimension >(p)) ||
(q = peek< variable >(p)) ||
(q = peek< quoted_string >(p)) ||
(q = peek< exactly<'*'> >(p)) ||
(q = peek< exactly<'('> >(p)) ||
Expand Down Expand Up @@ -2117,6 +2134,55 @@ namespace Sass {
return result;
}


Selector_Lookahead Parser::lookahead_for_value(const char* start)
{
const char* p = start ? start : position;
const char* q;
bool saw_interpolant = false;
bool saw_stuff = false;

while ((q = peek< identifier >(p)) ||
(q = peek< percentage >(p)) ||
(q = peek< dimension >(p)) ||
(q = peek< quoted_string >(p)) ||
(q = peek< variable >(p)) ||
(q = peek< exactly<'*'> >(p)) ||
(q = peek< exactly<'+'> >(p)) ||
(q = peek< exactly<'~'> >(p)) ||
(q = peek< exactly<'>'> >(p)) ||
(q = peek< exactly<','> >(p)) ||
(saw_stuff && (q = peek< exactly<'-'> >(p))) ||
(q = peek< binomial >(p)) ||
(q = peek< block_comment >(p)) ||
(q = peek< sequence< optional<sign>,
zero_plus<digit>,
exactly<'n'> > >(p)) ||
(q = peek< sequence< optional<sign>,
one_plus<digit> > >(p)) ||
(q = peek< number >(p)) ||
(q = peek< sequence< exactly<'&'>,
identifier_alnums > >(p)) ||
(q = peek< exactly<'&'> >(p)) ||
(q = peek< exactly<'%'> >(p)) ||
(q = peek< sequence< exactly<'.'>, interpolant > >(p)) ||
(q = peek< sequence< exactly<'#'>, interpolant > >(p)) ||
(q = peek< sequence< one_plus< exactly<'-'> >, interpolant > >(p)) ||
(q = peek< sequence< pseudo_prefix, interpolant > >(p)) ||
(q = peek< interpolant >(p)) ||
(q = peek< optional >(p))) {
p = q;
if (*(p - 1) == '}') saw_interpolant = true;
saw_stuff = true;
}

Selector_Lookahead result;
result.found = peek< alternatives< exactly<';'>, exactly<'}'>, exactly<'{'> > >(p) && saw_stuff ? p : 0;
result.has_interpolants = saw_interpolant;

return result;
}

void Parser::read_bom()
{
size_t skip = 0;
Expand Down
1 change: 1 addition & 0 deletions parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ namespace Sass {

void parse_block_comments(Block* block);

Selector_Lookahead lookahead_for_value(const char* start = 0);
Selector_Lookahead lookahead_for_selector(const char* start = 0);
Selector_Lookahead lookahead_for_extension_target(const char* start = 0);

Expand Down

0 comments on commit 8768c44

Please sign in to comment.