Get rid of invalidSelectorVector, use Bison's error recovery instead
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Feb 2015 20:13:05 +0000 (20:13 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Feb 2015 20:13:05 +0000 (20:13 +0000)
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".

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@179485 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/css/CSSGrammar.y.in

index 60202a4779a6b05402ba00c2b2453d5994a59081..e6694d23e2d9cbe5080da3b3b8d46163d180b95f 100644 (file)
@@ -1,3 +1,29 @@
+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).
index 345ca0ce74572be6b37460f7e88cd9508be27301..0a1317f2cb564449ac81fcae744f3f4d678fc5c3 100644 (file)
@@ -85,8 +85,6 @@ static inline CSSParserValue makeIdentValue(CSSParserString string)
     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)
@@ -305,7 +303,7 @@ static bool selectorListDoesNotMatchAnyPseudoElement(const Vector<std::unique_pt
 %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
@@ -1323,7 +1321,7 @@ nth_selector_ending:
         if ($4)
             $$ = $4;
         else
-            $$ = invalidSelectorVector;
+            YYERROR;
     }
     ;
 
@@ -1405,53 +1403,47 @@ pseudo:
     // 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();
         }
     }