Commit 7ca92b95 by Aaron Leung

Parsing complete list and expression syntax (I think). We'll know for sure when…

Parsing complete list and expression syntax (I think). We'll know for sure when it actually gets emitted.
parent 9bcf75f7
...@@ -118,6 +118,13 @@ namespace Sass { ...@@ -118,6 +118,13 @@ namespace Sass {
Node parse_block(); Node parse_block();
Node parse_rule(); Node parse_rule();
Node parse_values(); Node parse_values();
Node parse_list();
Node parse_comma_list();
Node parse_space_list();
Node parse_expression();
Node parse_term();
Node parse_factor();
Node parse_value();
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);
......
...@@ -45,7 +45,8 @@ namespace Sass { ...@@ -45,7 +45,8 @@ namespace Sass {
lex< variable >(); lex< variable >();
const Token key(lexed); const Token key(lexed);
lex< exactly<':'> >(); lex< exactly<':'> >();
context.environment[key] = parse_values(); // context.environment[key] = parse_values();
context.environment[key] = parse_list();
} }
Node Document::parse_ruleset() Node Document::parse_ruleset()
...@@ -247,7 +248,8 @@ namespace Sass { ...@@ -247,7 +248,8 @@ namespace Sass {
lex< identifier >(); lex< identifier >();
rule << Node(line_number, Node::property, lexed); rule << Node(line_number, Node::property, lexed);
lex< exactly<':'> >(); lex< exactly<':'> >();
rule << parse_values(); // rule << parse_values();
rule << parse_list();
return rule; return rule;
} }
...@@ -270,6 +272,133 @@ namespace Sass { ...@@ -270,6 +272,133 @@ namespace Sass {
} }
return values; return values;
} }
Node Document::parse_list()
{
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position))
{ return Node(line_number, Node::nil); }
else
{ return parse_comma_list(); }
}
Node Document::parse_comma_list()
{
Node list1(parse_space_list());
// if it's a singleton, return it directly; don't wrap it
if (!peek< exactly<','> >(position)) return list1;
Node comma_list(line_number, Node::comma_list, 2);
comma_list << list1;
while (lex< exactly<','> >())
{ comma_list << parse_space_list(); }
return comma_list;
}
Node Document::parse_space_list()
{
Node expr1(parse_expression());
// if it's a singleton, return it directly; don't wrap it
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position))
{ return expr1; }
Node space_list(line_number, Node::space_list, 2);
space_list << expr1;
while (!(peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position)))
{ space_list << parse_expression(); }
return space_list;
}
Node Document::parse_expression()
{
Node term1(parse_term());
// if it's a singleton, return it directly; don't wrap it
if (!(peek< exactly<'+'> >(position) ||
peek< exactly<'-'> >(position)))
{ return term1; }
Node expression(line_number, Node::expression, 2);
expression << term1;
while (lex< exactly<'+'> >() || lex< exactly<'-'> >()) {
if (lexed.begin[0] == '+') {
expression << Node(line_number, Node::add, lexed);
}
else {
expression << Node(line_number, Node::sub, lexed);
}
expression << parse_term();
}
return expression;
}
Node Document::parse_term()
{
Node fact1(parse_factor());
// if it's a singleton, return it directly; don't wrap it
if (!(peek< exactly<'*'> >(position) ||
peek< exactly<'/'> >(position)))
{ return fact1; }
Node term(line_number, Node::term, 2);
term << fact1;
while (lex< exactly<'*'> >() || lex< exactly<'/'> >()) {
if (lexed.begin[0] == '*') {
term << Node(line_number, Node::mul, lexed);
}
else {
term << Node(line_number, Node::div, lexed);
}
term << parse_factor();
}
return term;
}
Node Document::parse_factor()
{
if (lex< exactly<'('> >()) {
Node value(parse_list());
value.parenthesized = true;
return value;
}
else {
return parse_value();
}
}
Node Document::parse_value()
{
lex< identifier >() || lex < dimension >() ||
lex< percentage >() || lex < number >() ||
lex< hex >() || lex < string_constant >() ||
lex< variable >();
if (lexed.begin[0] == '$') {
return context.environment[lexed];
}
else {
return Node(line_number, Node::value, lexed);
}
}
// const char* Document::look_for_rule(const char* start) // const char* Document::look_for_rule(const char* start)
// { // {
......
$x: 20px/10; $x: 1 2 3;
div { div {
a: a, b, c, d; a: a, b, c, d;
...@@ -9,4 +9,5 @@ div { ...@@ -9,4 +9,5 @@ div {
g: (1 (9*2))/3; g: (1 (9*2))/3;
h: (1/2 3/4 5/6); h: (1/2 3/4 5/6);
i: 4 - (2) 3; i: 4 - (2) 3;
j: 3 + $x;
} }
...@@ -30,6 +30,15 @@ namespace Sass { ...@@ -30,6 +30,15 @@ namespace Sass {
block, block,
rule, rule,
property, property,
comma_list,
space_list,
expression,
add,
sub,
term,
mul,
div,
factor,
values, values,
value value
}; };
...@@ -45,7 +54,7 @@ namespace Sass { ...@@ -45,7 +54,7 @@ namespace Sass {
bool has_rulesets; bool has_rulesets;
bool has_propsets; bool has_propsets;
bool has_backref; bool has_backref;
bool terminal_backref; bool parenthesized;
Node() : type(nil), children(0) { ++fresh; } Node() : type(nil), children(0) { ++fresh; }
...@@ -58,7 +67,7 @@ namespace Sass { ...@@ -58,7 +67,7 @@ namespace Sass {
has_rulesets(n.has_rulesets), has_rulesets(n.has_rulesets),
has_propsets(n.has_propsets), has_propsets(n.has_propsets),
has_backref(n.has_backref), has_backref(n.has_backref),
terminal_backref(n.terminal_backref) parenthesized(n.parenthesized)
{ /*n.release();*/ ++copied; } // No joint custody. { /*n.release();*/ ++copied; } // No joint custody.
Node(size_t line_number, Type type, size_t length = 0) Node(size_t line_number, Type type, size_t length = 0)
...@@ -70,7 +79,7 @@ namespace Sass { ...@@ -70,7 +79,7 @@ namespace Sass {
has_rulesets(false), has_rulesets(false),
has_propsets(false), has_propsets(false),
has_backref(false), has_backref(false),
terminal_backref(false) parenthesized(false)
{ children->reserve(length); ++fresh; } { children->reserve(length); ++fresh; }
Node(size_t line_number, Type type, const Node& n) Node(size_t line_number, Type type, const Node& n)
...@@ -82,7 +91,7 @@ namespace Sass { ...@@ -82,7 +91,7 @@ namespace Sass {
has_rulesets(false), has_rulesets(false),
has_propsets(false), has_propsets(false),
has_backref(false), has_backref(false),
terminal_backref(false) parenthesized(false)
{ ++fresh; } { ++fresh; }
Node(size_t line_number, Type type, const Node& n, const Node& m) Node(size_t line_number, Type type, const Node& n, const Node& m)
...@@ -94,7 +103,7 @@ namespace Sass { ...@@ -94,7 +103,7 @@ namespace Sass {
has_rulesets(false), has_rulesets(false),
has_propsets(false), has_propsets(false),
has_backref(false), has_backref(false),
terminal_backref(false) parenthesized(false)
{ {
children->reserve(2); children->reserve(2);
children->push_back(n); children->push_back(n);
...@@ -111,7 +120,7 @@ namespace Sass { ...@@ -111,7 +120,7 @@ namespace Sass {
has_rulesets(false), has_rulesets(false),
has_propsets(false), has_propsets(false),
has_backref(false), has_backref(false),
terminal_backref(false) parenthesized(false)
{ ++fresh; } { ++fresh; }
//~Node() { delete children; } //~Node() { delete children; }
...@@ -127,7 +136,7 @@ namespace Sass { ...@@ -127,7 +136,7 @@ namespace Sass {
has_rulesets = n.has_rulesets; has_rulesets = n.has_rulesets;
has_propsets = n.has_propsets; has_propsets = n.has_propsets;
has_backref = n.has_backref; has_backref = n.has_backref;
terminal_backref = n.terminal_backref; parenthesized = n.parenthesized;
++copied; ++copied;
return *this; return *this;
} }
......
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