UnprocessedStatement* LessParser::parseRulesetStatement (LessRuleset &ruleset) { UnprocessedStatement* statement; Selector tokens; size_t property_i; while (parseProperty(tokens) || parsePropertyVariable(tokens)) {} property_i = tokens.size(); parseWhitespace(tokens); parseSelector(tokens); tokens.trim(); if (tokens.empty()) return NULL; statement = ruleset.createUnprocessedStatement(); statement->getTokens()->swap(tokens); statement->property_i = property_i; if (tokenizer->getTokenType() == Token::BRACKET_OPEN) return statement; parseValue(*statement->getTokens()); if (tokenizer->getTokenType() == Token::DELIMITER) { tokenizer->readNextToken(); skipWhitespace(); } return statement; }
bool LessParser::parseStatement(Stylesheet &stylesheet) { Selector selector; Mixin* mixin; CssComment* comment; LessStylesheet* ls = (LessStylesheet*)&stylesheet; if (tokenizer->getTokenType() == Token::COMMENT) { comment = ls->createComment(); comment->setComment(tokenizer->getToken()); tokenizer->readNextToken(); skipWhitespace(); return true; } else if (parseSelector(selector) && !selector.empty()) { #ifdef WITH_LIBGLOG VLOG(2) << "Parse: Selector: " << selector.toString(); #endif if (parseRuleset(*ls, selector)) return true; // Parameter mixin in the root. Inserts nested rules but no // declarations. mixin = ls->createMixin(); mixin->setReference(reference); if (mixin->parse(selector)) { if (tokenizer->getTokenType() == Token::DELIMITER) { tokenizer->readNextToken(); skipWhitespace(); } return true; } else { ls->deleteMixin(*mixin); throw new ParseException(tokenizer->getToken(), "a declaration block ('{...}') following selector"); } } else { return parseAtRuleOrVariable(*ls); } }