Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(464)

Unified Diff: Source/core/css/CSSGrammar.y.in

Issue 14620012: Improved parse error handling for CSSMQ. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@query-selector-performance
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/css/CSSGrammar.y.in
diff --git a/Source/core/css/CSSGrammar.y.in b/Source/core/css/CSSGrammar.y.in
index f9cd738e00f12c95fb974a0efce3b85bccd5d959..7545c10b253a3aabdd1e484f425f6ac89e9c755a 100644
--- a/Source/core/css/CSSGrammar.y.in
+++ b/Source/core/css/CSSGrammar.y.in
@@ -4,6 +4,7 @@
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2013 Opera Software ASA. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -87,7 +88,7 @@ static inline bool isCSSTokenAString(int yytype)
%}
-%expect 33
+%expect 9
%nonassoc LOWEST_PREC
@@ -250,7 +251,9 @@ static inline bool isCSSTokenAString(int yytype)
%type <string> media_feature
%type <mediaList> media_list
%type <mediaList> maybe_media_list
+%type <mediaList> mq_list
%type <mediaQuery> media_query
+%type <mediaQuery> media_query_recovery
%type <mediaQueryRestrictor> maybe_media_restrictor
%type <valueList> maybe_media_value
%type <mediaQueryExp> media_query_exp
@@ -331,25 +334,25 @@ stylesheet:
;
internal_rule:
- INTERNAL_RULE_SYM '{' maybe_space valid_rule maybe_space '}' {
+ INTERNAL_RULE_SYM '{' maybe_space valid_rule maybe_space closing_brace {
parser->m_rule = $4;
}
;
webkit_keyframe_rule:
- WEBKIT_KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space '}' {
+ WEBKIT_KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space closing_brace{
parser->m_keyframe = $4;
}
;
internal_decls:
- INTERNAL_DECLS_SYM '{' maybe_space_before_declaration declaration_list '}' {
+ INTERNAL_DECLS_SYM '{' maybe_space_before_declaration declaration_list closing_brace {
/* can be empty */
}
;
internal_value:
- INTERNAL_VALUE_SYM '{' maybe_space expr '}' {
+ INTERNAL_VALUE_SYM '{' maybe_space expr closing_brace {
if ($4) {
parser->m_valueList = parser->sinkFloatingValueList($4);
int oldParsedProperties = parser->m_parsedProperties.size();
@@ -361,13 +364,13 @@ internal_value:
;
webkit_mediaquery:
- WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
- parser->m_mediaQuery = parser->sinkFloatingMediaQuery($4);
+ WEBKIT_MEDIAQUERY_SYM maybe_space media_query TOKEN_EOF {
+ parser->m_mediaQuery = parser->sinkFloatingMediaQuery($3);
}
;
internal_selector:
- INTERNAL_SELECTOR_SYM '{' maybe_space selector_list '}' {
+ INTERNAL_SELECTOR_SYM '{' maybe_space selector_list closing_brace {
if ($4) {
if (parser->m_selectorListForParseSelector)
parser->m_selectorListForParseSelector->adoptSelectorVector(*$4);
@@ -376,7 +379,7 @@ internal_selector:
;
webkit_supports_condition:
- WEBKIT_SUPPORTS_CONDITION_SYM '{' maybe_space supports_condition '}' {
+ WEBKIT_SUPPORTS_CONDITION_SYM '{' maybe_space supports_condition closing_brace {
parser->m_supportsCondition = $4;
}
;
@@ -408,6 +411,11 @@ closing_parenthesis:
| %prec LOWEST_PREC TOKEN_EOF
;
+closing_square_bracket:
+ ']'
+ | %prec LOWEST_PREC TOKEN_EOF
+ ;
+
charset:
CHARSET_SYM maybe_space STRING maybe_space ';' {
if (parser->m_styleSheet)
@@ -572,7 +580,7 @@ STRING
;
media_feature:
- IDENT maybe_space {
+ IDENT {
$$ = $1;
}
;
@@ -581,21 +589,15 @@ maybe_media_value:
/*empty*/ {
$$ = 0;
}
- | ':' maybe_space expr maybe_space {
+ | ':' maybe_space expr {
$$ = $3;
}
;
media_query_exp:
- maybe_media_restrictor maybe_space '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
- // If restrictor is specified, media query expression is invalid.
- // Create empty media query expression and continue parsing media query.
- if ($1 != MediaQuery::None)
- $$ = parser->createFloatingMediaQueryExp("", 0);
- else {
- $5.lower();
- $$ = parser->createFloatingMediaQueryExp($5, $7);
- }
+ '(' maybe_space media_feature maybe_space maybe_media_value closing_parenthesis maybe_space {
+ $3.lower();
+ $$ = parser->createFloatingMediaQueryExp($3, $5);
}
;
@@ -604,9 +606,9 @@ media_query_exp_list:
$$ = parser->createFloatingMediaQueryExpList();
$$->append(parser->sinkFloatingMediaQueryExp($1));
}
- | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
+ | media_query_exp_list MEDIA_AND maybe_space media_query_exp {
$$ = $1;
- $$->append(parser->sinkFloatingMediaQueryExp($5));
+ $$->append(parser->sinkFloatingMediaQueryExp($4));
}
;
@@ -623,10 +625,10 @@ maybe_media_restrictor:
/*empty*/ {
$$ = MediaQuery::None;
}
- | MEDIA_ONLY {
+ | MEDIA_ONLY maybe_space {
$$ = MediaQuery::Only;
}
- | MEDIA_NOT {
+ | MEDIA_NOT maybe_space {
$$ = MediaQuery::Not;
}
;
@@ -635,19 +637,34 @@ media_query:
media_query_exp_list {
$$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($1));
}
- |
- maybe_media_restrictor maybe_space medium maybe_and_media_query_exp_list {
- $3.lower();
- $$ = parser->createFloatingMediaQuery($1, $3, parser->sinkFloatingMediaQueryExpList($4));
+ | maybe_media_restrictor medium maybe_and_media_query_exp_list {
+ $2.lower();
+ $$ = parser->createFloatingMediaQuery($1, $2, parser->sinkFloatingMediaQueryExpList($3));
+ }
+ | '(' media_query_recovery closing_parenthesis {
+ $$ = $2;
+ }
+ | maybe_media_restrictor medium MEDIA_AND maybe_space '(' media_query_recovery closing_parenthesis {
+ $$ = $6;
+ }
+ | media_query_recovery {
+ $$ = $1;
+ }
+ ;
+
+media_query_recovery:
+ error error_location error_recovery_no_block {
+ parser->syntaxError($2);
+ $$ = parser->createFloatingMediaQuery(MediaQuery::Not, "all", parser->sinkFloatingMediaQueryExpList(parser->createFloatingMediaQueryExpList()));
}
;
maybe_media_list:
- /* empty */ {
+ /* empty */ {
$$ = parser->createMediaQuerySet();
- }
- | media_list
- ;
+ }
+ | media_list
+ ;
media_list:
media_query {
@@ -655,15 +672,27 @@ media_list:
$$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
parser->updateLastMediaLine($$);
}
- | media_list ',' maybe_space media_query {
+ | mq_list media_query {
$$ = $1;
- if ($$) {
- $$->addMediaQuery(parser->sinkFloatingMediaQuery($4));
- parser->updateLastMediaLine($$);
- }
+ $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
+ parser->updateLastMediaLine($$);
}
- | media_list error {
- $$ = 0;
+ | mq_list error_location {
+ parser->syntaxError($2);
+ $$ = $1;
+ $$->addMediaQuery(parser->sinkFloatingMediaQuery(parser->createFloatingMediaQuery(MediaQuery::Not, "all", parser->sinkFloatingMediaQueryExpList(parser->createFloatingMediaQueryExpList()))));
+ parser->updateLastMediaLine($$);
+ }
+ ;
+
+mq_list:
+ media_query ',' maybe_space {
+ $$ = parser->createMediaQuerySet();
+ $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
+ }
+ | mq_list media_query ',' maybe_space {
+ $$ = $1;
+ $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
}
;
@@ -692,7 +721,11 @@ media:
| before_media_rule MEDIA_SYM at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space block_rule_list save_block {
$$ = parser->createMediaRule(0, $7);
}
- | before_media_rule MEDIA_SYM at_rule_header_end_maybe_space ';' {
+ | before_media_rule MEDIA_SYM maybe_space media_list at_rule_header_end ';' {
+ $$ = 0;
+ parser->endRuleBody(true);
+ }
+ | before_media_rule MEDIA_SYM maybe_space media_list at_rule_header_end '}' {
$$ = 0;
parser->endRuleBody(true);
}
@@ -768,17 +801,17 @@ supports_disjunction:
;
supports_condition_in_parens:
- '(' maybe_space supports_condition ')' maybe_space {
+ '(' maybe_space supports_condition closing_parenthesis maybe_space {
$$ = $3;
}
| supports_declaration_condition
- | '(' error ')' {
+ | '(' error closing_parenthesis {
$$ = false;
}
;
supports_declaration_condition:
- '(' maybe_space property ':' maybe_space expr prio ')' maybe_space {
+ '(' maybe_space property ':' maybe_space expr prio closing_parenthesis maybe_space {
$$ = false;
CSSParser* p = static_cast<CSSParser*>(parser);
if ($3 && $6) {
@@ -821,7 +854,7 @@ keyframes_rule:
;
keyframe_rule:
- key_list maybe_space '{' maybe_space declaration_list '}' {
+ key_list maybe_space '{' maybe_space declaration_list closing_brace {
$$ = parser->createKeyframe($1);
}
;
@@ -1408,7 +1441,7 @@ pseudo:
$$ = 0;
}
// used by ::cue(:past/:future)
- | ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space ')' {
+ | ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
if ($5) {
$$ = parser->createFloatingSelector();
$$->setMatch(CSSSelector::PseudoClass);
@@ -1420,7 +1453,7 @@ pseudo:
} else
$$ = 0;
}
- | ':' ':' DISTRIBUTEDFUNCTION maybe_space selector maybe_space ')' {
+ | ':' ':' DISTRIBUTEDFUNCTION maybe_space selector maybe_space closing_parenthesis {
if (!$5)
$$ = 0;
else {
@@ -1436,7 +1469,7 @@ pseudo:
// Use simple_selector_list for now to match -moz-any.
// See http://lists.w3.org/Archives/Public/www-style/2010Sep/0566.html for some
// related discussion with respect to :not.
- | ':' ANYFUNCTION maybe_space simple_selector_list maybe_space ')' {
+ | ':' ANYFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
if ($4) {
$$ = parser->createFloatingSelector();
$$->setMatch(CSSSelector::PseudoClass);
@@ -1450,7 +1483,7 @@ pseudo:
$$ = 0;
}
// used by :nth-*(ax+b)
- | ':' FUNCTION maybe_space NTH maybe_space ')' {
+ | ':' FUNCTION maybe_space NTH maybe_space closing_parenthesis {
$$ = parser->createFloatingSelector();
$$->setMatch(CSSSelector::PseudoClass);
$$->setArgument($4);
@@ -1460,7 +1493,7 @@ pseudo:
$$ = 0;
}
// used by :nth-*
- | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space ')' {
+ | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space closing_parenthesis {
$$ = parser->createFloatingSelector();
$$->setMatch(CSSSelector::PseudoClass);
$$->setArgument(String::number($4 * $5));
@@ -1470,7 +1503,7 @@ pseudo:
$$ = 0;
}
// used by :nth-*(odd/even) and :lang
- | ':' FUNCTION maybe_space IDENT maybe_space ')' {
+ | ':' FUNCTION maybe_space IDENT maybe_space closing_parenthesis {
$$ = parser->createFloatingSelector();
$$->setMatch(CSSSelector::PseudoClass);
$$->setArgument($4);
@@ -1488,7 +1521,7 @@ pseudo:
}
}
// used by :not
- | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
+ | ':' NOTFUNCTION maybe_space simple_selector maybe_space closing_parenthesis {
if (!$4 || !$4->isSimple())
$$ = 0;
else {
@@ -1672,7 +1705,7 @@ term:
| UNICODERANGE maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
| HEX maybe_space { $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
| '#' maybe_space { $$.id = 0; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
- | VARFUNCTION maybe_space IDENT ')' maybe_space {
+ | VARFUNCTION maybe_space IDENT closing_parenthesis maybe_space {
$$.id = 0;
$$.string = $3;
$$.unit = CSSPrimitiveValue::CSS_VARIABLE_NAME;
@@ -1761,7 +1794,7 @@ function:
calc_func_term:
unary_term { $$ = $1; }
- | VARFUNCTION maybe_space IDENT ')' {
+ | VARFUNCTION maybe_space IDENT closing_parenthesis {
$$.id = 0;
$$.string = $3;
$$.unit = CSSPrimitiveValue::CSS_VARIABLE_NAME;
@@ -1884,7 +1917,7 @@ min_or_max:
;
min_or_max_function:
- min_or_max maybe_space calc_func_expr_list ')' maybe_space {
+ min_or_max maybe_space calc_func_expr_list closing_parenthesis maybe_space {
CSSParserFunction* f = parser->createFloatingFunction();
f->name = $1;
f->args = parser->sinkFloatingValueList($3);
@@ -1958,6 +1991,34 @@ error_recovery:
/* empty */
| error_recovery invalid_block
| error_recovery error
+ ;
+
+recover_block:
+ '{' error_recovery closing_brace error_recovery_no_block
+ ;
+
+block_recovery_list:
+ recover_block
+ | block_recovery_list recover_block
+ ;
+
+error_recovery_no_block:
+ /* empty */
+ | error_recovery_no_block error
+ | error_recovery_no_block '(' error_recovery_allow_block closing_parenthesis
+ | error_recovery_no_block '[' error_recovery_allow_block closing_square_bracket
+ | error_recovery_no_block FUNCTION error_recovery_allow_block closing_parenthesis
+ | error_recovery_no_block CALCFUNCTION error_recovery_allow_block closing_parenthesis
+ | error_recovery_no_block VARFUNCTION error_recovery_allow_block closing_parenthesis
+ | error_recovery_no_block MINFUNCTION error_recovery_allow_block closing_parenthesis
+ | error_recovery_no_block MAXFUNCTION error_recovery_allow_block closing_parenthesis
+ | error_recovery_no_block ANYFUNCTION error_recovery_allow_block closing_parenthesis
+ | error_recovery_no_block NOTFUNCTION error_recovery_allow_block closing_parenthesis
+ ;
+
+error_recovery_allow_block:
+ error_recovery_no_block
+ | error_recovery_no_block block_recovery_list
;
%%

Powered by Google App Engine
This is Rietveld 408576698