+2015-02-02 Benjamin Poulain <benjamin@webkit.org>
+
+ Get rid of invalidSelectorVector, use Bison's error recovery instead
+ https://bugs.webkit.org/show_bug.cgi?id=141147
+
+ Reviewed by Darin Adler.
+
+ * css/CSSGrammar.y.in:
+ Instead of reducing a null selector, we can use a real parsing error
+ to get out of invalid selector endings.
+
+ When that happens, Bison will pop the stack until it can reduce any
+ valid error recovery rules.
+
+ The problem is to make sure there is no floating values because
+ none of the reduce block between the error and the recovery would
+ be executed.
+
+ In this case, "nth_selector_ending" is a non-recursive production of
+ the NTHCHILDFUNCTIONS. In turn, NTHCHILDFUNCTIONS are productions
+ of the non-recursive "pseudo". "pseudo" is only used as a trivial
+ production of "specifier". "specifier" is only used by "specifier_list".
+
+ "specifier_list" has error recovery code -> no production could have
+ generated a floating values between "specifier_list" and "nth_selector_ending".
+
2015-01-30 Roger Fong <roger_fong@apple.com>
WebGL2: Implement spec section 3.7.1 Setting and getting state (Part 1).
return v;
}
-static auto* const invalidSelectorVector = reinterpret_cast<Vector<std::unique_ptr<CSSParserSelector>>*>(-1);
-
static bool selectorListDoesNotMatchAnyPseudoElement(const Vector<std::unique_ptr<CSSParserSelector>>* selectorVector)
{
if (!selectorVector)
%union { Vector<std::unique_ptr<CSSParserSelector>>* selectorList; }
%type <selectorList> selector_list nested_selector_list simple_selector_list nth_selector_ending
%destructor { delete $$; } selector_list nested_selector_list simple_selector_list
-%destructor { if ($$ != invalidSelectorVector) delete $$; } nth_selector_ending
+%destructor { delete $$; } nth_selector_ending
%union { bool boolean; }
%type <boolean> declaration declaration_list decl_list priority
if ($4)
$$ = $4;
else
- $$ = invalidSelectorVector;
+ YYERROR;
}
;
// Definition of :nth-child().
| ':' NTHCHILDFUNCTIONS maybe_space NTH nth_selector_ending {
$$ = nullptr;
- if ($5 != invalidSelectorVector) {
- std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> ending($5);
- if (selectorListDoesNotMatchAnyPseudoElement(ending.get())) {
- auto selector = std::make_unique<CSSParserSelector>();
- selector->setMatch(CSSSelector::PseudoClass);
- selector->setArgument($4);
- selector->setPseudoClassValue($2);
- if (ending)
- selector->adoptSelectorVector(*ending);
- CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType();
- if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild)
- $$ = selector.release();
- }
+ std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> ending($5);
+ if (selectorListDoesNotMatchAnyPseudoElement(ending.get())) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument($4);
+ selector->setPseudoClassValue($2);
+ if (ending)
+ selector->adoptSelectorVector(*ending);
+ CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType();
+ if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild)
+ $$ = selector.release();
}
}
| ':' NTHCHILDFUNCTIONS maybe_space maybe_unary_operator INTEGER nth_selector_ending {
$$ = nullptr;
- if ($6 != invalidSelectorVector) {
- std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> ending($6);
- if (selectorListDoesNotMatchAnyPseudoElement(ending.get())) {
- auto selector = std::make_unique<CSSParserSelector>();
- selector->setMatch(CSSSelector::PseudoClass);
- selector->setArgument(AtomicString::number($4 * $5));
- selector->setPseudoClassValue($2);
- if (ending)
- selector->adoptSelectorVector(*ending);
- CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType();
- if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild)
- $$ = selector.release();
- }
+ std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> ending($6);
+ if (selectorListDoesNotMatchAnyPseudoElement(ending.get())) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument(AtomicString::number($4 * $5));
+ selector->setPseudoClassValue($2);
+ if (ending)
+ selector->adoptSelectorVector(*ending);
+ CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType();
+ if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild)
+ $$ = selector.release();
}
}
| ':' NTHCHILDFUNCTIONS maybe_space IDENT nth_selector_ending {
$$ = nullptr;
- if ($5 != invalidSelectorVector) {
- std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> ending($5);
- if (isValidNthToken($4) && selectorListDoesNotMatchAnyPseudoElement(ending.get())) {
- auto selector = std::make_unique<CSSParserSelector>();
- selector->setMatch(CSSSelector::PseudoClass);
- selector->setArgument($4);
- selector->setPseudoClassValue($2);
- if (ending)
- selector->adoptSelectorVector(*ending);
- CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType();
- if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild)
- $$ = selector.release();
- }
+ std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> ending($5);
+ if (isValidNthToken($4) && selectorListDoesNotMatchAnyPseudoElement(ending.get())) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument($4);
+ selector->setPseudoClassValue($2);
+ if (ending)
+ selector->adoptSelectorVector(*ending);
+ CSSSelector::PseudoClassType pseudoClassType = selector->pseudoClassType();
+ if (pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild)
+ $$ = selector.release();
}
}