|
@@ -218,9 +218,21 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
|
|
|
|
Vector<Selector::ComplexSelector> selectors;
|
|
Vector<Selector::ComplexSelector> selectors;
|
|
|
|
|
|
|
|
+ auto check_for_eof_or_whitespace = [&](T& current_value) -> bool {
|
|
|
|
+ if (current_value.is(Token::Type::EndOfFile))
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ if (current_value.is(Token::Type::Whitespace)) {
|
|
|
|
+ tokens.reconsume_current_input_token();
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ };
|
|
|
|
+
|
|
auto parse_simple_selector = [&]() -> Optional<Selector::SimpleSelector> {
|
|
auto parse_simple_selector = [&]() -> Optional<Selector::SimpleSelector> {
|
|
auto current_value = tokens.next_token();
|
|
auto current_value = tokens.next_token();
|
|
- if (current_value.is(Token::Type::EndOfFile))
|
|
|
|
|
|
+ dbgln("parse_simple_selector, start token: {}", current_value.to_string());
|
|
|
|
+ if (check_for_eof_or_whitespace(current_value))
|
|
return {};
|
|
return {};
|
|
|
|
|
|
Selector::SimpleSelector::Type type;
|
|
Selector::SimpleSelector::Type type;
|
|
@@ -245,7 +257,7 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
value = ((Token)current_value).m_value.to_string();
|
|
value = ((Token)current_value).m_value.to_string();
|
|
} else if (current_value.is(Token::Type::Delim) && ((Token)current_value).delim() == ".") {
|
|
} else if (current_value.is(Token::Type::Delim) && ((Token)current_value).delim() == ".") {
|
|
current_value = tokens.next_token();
|
|
current_value = tokens.next_token();
|
|
- if (current_value.is(Token::Type::EndOfFile))
|
|
|
|
|
|
+ if (check_for_eof_or_whitespace(current_value))
|
|
return {};
|
|
return {};
|
|
|
|
|
|
if (!current_value.is(Token::Type::Ident)) {
|
|
if (!current_value.is(Token::Type::Ident)) {
|
|
@@ -267,7 +279,7 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
simple_selector.value = value;
|
|
simple_selector.value = value;
|
|
|
|
|
|
current_value = tokens.next_token();
|
|
current_value = tokens.next_token();
|
|
- if (current_value.is(Token::Type::EndOfFile))
|
|
|
|
|
|
+ if (check_for_eof_or_whitespace(current_value))
|
|
return simple_selector;
|
|
return simple_selector;
|
|
|
|
|
|
// FIXME: Attribute selectors want to be their own Selector::SimpleSelector::Type according to the spec.
|
|
// FIXME: Attribute selectors want to be their own Selector::SimpleSelector::Type according to the spec.
|
|
@@ -337,14 +349,6 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- while (attribute_parts.at(attribute_index).is(Token::Type::Whitespace)) {
|
|
|
|
- attribute_index++;
|
|
|
|
- if (attribute_index >= attribute_parts.size()) {
|
|
|
|
- dbgln("Attribute selector ended without a value to match.");
|
|
|
|
- return {};
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (attribute_index >= attribute_parts.size()) {
|
|
if (attribute_index >= attribute_parts.size()) {
|
|
dbgln("Attribute selector ended without a value to match.");
|
|
dbgln("Attribute selector ended without a value to match.");
|
|
return {};
|
|
return {};
|
|
@@ -366,13 +370,13 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
bool is_pseudo = false;
|
|
bool is_pseudo = false;
|
|
|
|
|
|
current_value = tokens.next_token();
|
|
current_value = tokens.next_token();
|
|
- if (current_value.is(Token::Type::EndOfFile))
|
|
|
|
|
|
+ if (check_for_eof_or_whitespace(current_value))
|
|
return {};
|
|
return {};
|
|
|
|
|
|
if (current_value.is(Token::Type::Colon)) {
|
|
if (current_value.is(Token::Type::Colon)) {
|
|
is_pseudo = true;
|
|
is_pseudo = true;
|
|
current_value = tokens.next_token();
|
|
current_value = tokens.next_token();
|
|
- if (current_value.is(Token::Type::EndOfFile))
|
|
|
|
|
|
+ if (check_for_eof_or_whitespace(current_value))
|
|
return {};
|
|
return {};
|
|
}
|
|
}
|
|
|
|
|
|
@@ -382,7 +386,7 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
return {};
|
|
return {};
|
|
|
|
|
|
current_value = tokens.next_token();
|
|
current_value = tokens.next_token();
|
|
- if (current_value.is(Token::Type::EndOfFile))
|
|
|
|
|
|
+ if (check_for_eof_or_whitespace(current_value))
|
|
return simple_selector;
|
|
return simple_selector;
|
|
|
|
|
|
if (current_value.is(Token::Type::Ident)) {
|
|
if (current_value.is(Token::Type::Ident)) {
|
|
@@ -452,6 +456,8 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
auto parse_complex_selector = [&]() -> Optional<Selector::ComplexSelector> {
|
|
auto parse_complex_selector = [&]() -> Optional<Selector::ComplexSelector> {
|
|
auto relation = Selector::ComplexSelector::Relation::Descendant;
|
|
auto relation = Selector::ComplexSelector::Relation::Descendant;
|
|
|
|
|
|
|
|
+ tokens.skip_whitespace();
|
|
|
|
+
|
|
auto current_value = tokens.peek_token();
|
|
auto current_value = tokens.peek_token();
|
|
if (current_value.is(Token::Type::Delim)) {
|
|
if (current_value.is(Token::Type::Delim)) {
|
|
auto delim = ((Token)current_value).delim();
|
|
auto delim = ((Token)current_value).delim();
|
|
@@ -475,12 +481,20 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
relation = Selector::ComplexSelector::Relation::Column;
|
|
relation = Selector::ComplexSelector::Relation::Column;
|
|
tokens.next_token();
|
|
tokens.next_token();
|
|
}
|
|
}
|
|
|
|
+ } else {
|
|
|
|
+ dbgln("Unrecognized relation delimiter: '{}'", delim);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ tokens.skip_whitespace();
|
|
|
|
+
|
|
Vector<Selector::SimpleSelector> simple_selectors;
|
|
Vector<Selector::SimpleSelector> simple_selectors;
|
|
|
|
|
|
for (;;) {
|
|
for (;;) {
|
|
|
|
+ auto current_value = tokens.peek_token();
|
|
|
|
+ if (current_value.is(Token::Type::EndOfFile) || current_value.is(Token::Type::Whitespace))
|
|
|
|
+ break;
|
|
|
|
+
|
|
auto component = parse_simple_selector();
|
|
auto component = parse_simple_selector();
|
|
if (!component.has_value())
|
|
if (!component.has_value())
|
|
break;
|
|
break;
|
|
@@ -495,17 +509,13 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
|
};
|
|
};
|
|
|
|
|
|
for (;;) {
|
|
for (;;) {
|
|
- auto complex = parse_complex_selector();
|
|
|
|
- if (complex.has_value())
|
|
|
|
- selectors.append(complex.value());
|
|
|
|
-
|
|
|
|
auto current_value = tokens.peek_token();
|
|
auto current_value = tokens.peek_token();
|
|
if (current_value.is(Token::Type::EndOfFile))
|
|
if (current_value.is(Token::Type::EndOfFile))
|
|
break;
|
|
break;
|
|
- if (current_value.is(Token::Type::Comma))
|
|
|
|
- break;
|
|
|
|
|
|
|
|
- tokens.next_token();
|
|
|
|
|
|
+ auto complex = parse_complex_selector();
|
|
|
|
+ if (complex.has_value())
|
|
|
|
+ selectors.append(complex.value());
|
|
}
|
|
}
|
|
|
|
|
|
if (selectors.is_empty())
|
|
if (selectors.is_empty())
|