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 |
; |
%% |