CSS-Sass
view release on metacpan or search on metacpan
libsass/parser.cpp view on Meta::CPAN
else if ((lookahead_result = lookahead_for_selector(position)).found) {
(*block) << parse_ruleset(lookahead_result);
}/* not used anymore - remove?
else if (peek< sequence< optional< exactly<'*'> >, alternatives< identifier_schema, identifier >, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position)) {
(*block) << parse_propset();
}*/
else if (!peek< exactly<';'> >()) {
bool indent = ! peek< sequence< optional< exactly<'*'> >, alternatives< identifier_schema, identifier >, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position);
/* not used anymore - remove?
if (peek< sequence< optional< exactly<'*'> >, identifier_schema, exactly<':'>, exactly<'{'> > >()) {
(*block) << parse_propset();
}
else if (peek< sequence< optional< exactly<'*'> >, identifier, exactly<':'>, exactly<'{'> > >()) {
(*block) << parse_propset();
}
else */ {
Declaration* decl = parse_declaration();
decl->tabs(indentation);
(*block) << decl;
if (peek< exactly<'{'> >()) {
// parse a propset that rides on the declaration's property
if (indent) indentation++;
Propset* ps = new (ctx.mem) Propset(pstate, decl->property(), parse_block());
if (indent) indentation--;
(*block) << ps;
}
else {
// finish and let the semicolon get munched
semicolon = true;
}
}
}
else lex< one_plus< exactly<';'> > >();
parse_block_comments(block);
}
block_stack.pop_back();
return block;
}
Declaration* Parser::parse_declaration() {
String* prop = 0;
if (peek< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
prop = parse_identifier_schema();
}
else if (lex< sequence< optional< exactly<'*'> >, identifier > >()) {
prop = new (ctx.mem) String_Quoted(pstate, lexed);
}
else {
error("invalid property name", pstate);
}
const string property(lexed);
if (!lex_css< one_plus< exactly<':'> > >()) error("property \"" + property + "\" must be followed by a ':'", pstate);
if (peek_css< exactly<';'> >()) error("style declaration must contain a value", pstate);
if (peek_css< static_value >()) {
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 ");
}
}
return new (ctx.mem) Declaration(prop->pstate(), prop, list_ex/*, lex<important>()*/);
}
}
// parse +/- and return false if negative
bool Parser::parse_number_prefix()
{
bool positive = true;
while(true) {
if (lex < block_comment >()) continue;
if (lex < number_prefix >()) continue;
if (lex < exactly < '-' > >()) {
positive = !positive;
continue;
}
break;
}
return positive;
}
Expression* Parser::parse_map()
{
To_String to_string(&ctx);
Expression* key = parse_list();
// it's not a map so return the lexed value as a list value
if (!peek< exactly<':'> >())
{ return key; }
lex< exactly<':'> >();
Expression* value = parse_space_list();
Map* map = new (ctx.mem) Map(pstate, 1);
(*map) << make_pair(key, value);
while (lex_css< exactly<','> >())
{
// allow trailing commas - #495
if (peek_css< exactly<')'> >(position))
{ break; }
Expression* key = parse_list();
if (!(lex< exactly<':'> >()))
{ error("invalid syntax", pstate); }
Expression* value = parse_space_list();
(*map) << make_pair(key, value);
}
if (map->has_duplicate_key())
{ error("Duplicate key \"" + map->get_duplicate_key()->perform(&to_string) + "\" in map " + map->perform(&to_string) + ".", pstate); }
return map;
}
( run in 0.720 second using v1.01-cache-2.11-cpan-39bf76dae61 )