summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/css/CSSGrammar.y.in
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/css/CSSGrammar.y.in')
-rw-r--r--Source/WebCore/css/CSSGrammar.y.in1772
1 files changed, 892 insertions, 880 deletions
diff --git a/Source/WebCore/css/CSSGrammar.y.in b/Source/WebCore/css/CSSGrammar.y.in
index d43d3c9bd..8cc70be80 100644
--- a/Source/WebCore/css/CSSGrammar.y.in
+++ b/Source/WebCore/css/CSSGrammar.y.in
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2015 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2012 Intel Corporation. All rights reserved.
@@ -21,35 +21,36 @@
*
*/
-%pure_parser
+%pure-parser
%parse-param { CSSParser* parser }
%lex-param { CSSParser* parser }
%union {
- bool boolean;
- char character;
- int integer;
double number;
CSSParserString string;
-
- StyleRuleBase* rule;
- Vector<RefPtr<StyleRuleBase> >* ruleList;
- CSSParserSelector* selector;
- Vector<OwnPtr<CSSParserSelector> >* selectorList;
CSSSelector::MarginBoxType marginBox;
- CSSSelector::Relation relation;
+ CSSParserValue value;
+ CSSParserSelectorCombinator relation;
+ StyleRuleBase* rule;
+ Vector<RefPtr<StyleRuleBase>>* ruleList;
MediaQuerySet* mediaList;
MediaQuery* mediaQuery;
MediaQuery::Restrictor mediaQueryRestrictor;
MediaQueryExp* mediaQueryExp;
- CSSParserValue value;
- CSSParserValueList* valueList;
- Vector<OwnPtr<MediaQueryExp> >* mediaQueryExpList;
+ Vector<CSSParser::SourceSize>* sourceSizeList;
+ Vector<std::unique_ptr<MediaQueryExp>>* mediaQueryExpList;
StyleKeyframe* keyframe;
- Vector<RefPtr<StyleKeyframe> >* keyframeRuleList;
- float val;
+ Vector<RefPtr<StyleKeyframe>>* keyframeRuleList;
CSSPropertyID id;
+ CSSParserSelector* selector;
+ Vector<std::unique_ptr<CSSParserSelector>>* selectorList;
+ bool boolean;
+ CSSSelector::Match match;
+ int integer;
+ char character;
+ CSSParserValueList* valueList;
+ Vector<CSSParserString>* stringList;
CSSParser::Location location;
}
@@ -60,6 +61,8 @@ static inline int cssyyerror(void*, const char*)
return 1;
}
+#if YYDEBUG > 0
+
static inline bool isCSSTokenAString(int yytype)
{
switch (yytype) {
@@ -75,9 +78,18 @@ static inline bool isCSSTokenAString(int yytype)
case ANYFUNCTION:
case NOTFUNCTION:
case CALCFUNCTION:
- case MINFUNCTION:
+ case MATCHESFUNCTION:
case MAXFUNCTION:
- case VAR_DEFINITION:
+ case MINFUNCTION:
+ case NTHCHILDFUNCTIONS:
+ case NTHCHILDSELECTORSEPARATOR:
+ case LANGFUNCTION:
+ case VARFUNCTION:
+#if ENABLE_CSS_SELECTORS_LEVEL4
+ case DIRFUNCTION:
+ case ROLEFUNCTION:
+#endif
+ case CUSTOM_PROPERTY:
case UNICODERANGE:
return true;
default:
@@ -85,12 +97,37 @@ static inline bool isCSSTokenAString(int yytype)
}
}
+#endif
+
+static inline CSSParserValue makeIdentValue(CSSParserString string)
+{
+ CSSParserValue v;
+ v.id = cssValueKeywordID(string);
+ v.unit = CSSPrimitiveValue::CSS_IDENT;
+ v.string = string;
+ return v;
+}
+
+static bool selectorListDoesNotMatchAnyPseudoElement(const Vector<std::unique_ptr<CSSParserSelector>>* selectorVector)
+{
+ if (!selectorVector)
+ return true;
+
+ for (unsigned i = 0; i < selectorVector->size(); ++i) {
+ for (const CSSParserSelector* selector = selectorVector->at(i).get(); selector; selector = selector->tagHistory()) {
+ if (selector->matchesPseudoElement())
+ return false;
+ }
+ }
+ return true;
+}
+
%}
-#if ENABLE_SHADOW_DOM
-%expect 32
+#if ENABLE_CSS_GRID_LAYOUT
+%expect 39
#else
-%expect 31
+%expect 38
#endif
%nonassoc LOWEST_PREC
@@ -109,6 +146,7 @@ static inline bool isCSSTokenAString(int yytype)
%token <string> STRING
%right <string> IDENT
%token <string> NTH
+%token <string> NTHCHILDSELECTORSEPARATOR
%nonassoc <string> HEX
%nonassoc <string> IDSEL
@@ -122,31 +160,19 @@ static inline bool isCSSTokenAString(int yytype)
%token IMPORT_SYM
%token PAGE_SYM
%token MEDIA_SYM
-#if ENABLE_CSS3_CONDITIONAL_RULES
-%token SUPPORTS_SYM
-#endif
%token FONT_FACE_SYM
-#if ENABLE_SHADOW_DOM
-%token HOST_SYM
-#endif
%token CHARSET_SYM
+%token KEYFRAME_RULE_SYM
+%token KEYFRAMES_SYM
%token NAMESPACE_SYM
-%token VARFUNCTION
%token WEBKIT_RULE_SYM
%token WEBKIT_DECLS_SYM
-%token WEBKIT_KEYFRAME_RULE_SYM
-%token WEBKIT_KEYFRAMES_SYM
%token WEBKIT_VALUE_SYM
%token WEBKIT_MEDIAQUERY_SYM
+%token WEBKIT_SIZESATTR_SYM
%token WEBKIT_SELECTOR_SYM
%token WEBKIT_REGION_RULE_SYM
%token WEBKIT_VIEWPORT_RULE_SYM
-#if ENABLE_CSS3_CONDITIONAL_RULES
-%token WEBKIT_SUPPORTS_CONDITION_SYM
-#endif
-#if ENABLE_CSS_SHADERS
-%token WEBKIT_FILTER_RULE_SYM
-#endif
%token <marginBox> TOPLEFTCORNER_SYM
%token <marginBox> TOPLEFT_SYM
%token <marginBox> TOPCENTER_SYM
@@ -170,11 +196,6 @@ static inline bool isCSSTokenAString(int yytype)
%token MEDIA_ONLY
%token MEDIA_NOT
%token MEDIA_AND
-#if ENABLE_CSS3_CONDITIONAL_RULES
-%token SUPPORTS_NOT
-%token SUPPORTS_AND
-%token SUPPORTS_OR
-#endif
%token <number> REMS
%token <number> CHS
@@ -207,139 +228,143 @@ static inline bool isCSSTokenAString(int yytype)
%token <number> DPPX
%token <number> DPI
%token <number> DPCM
+%token <number> FR
%token <string> URI
%token <string> FUNCTION
%token <string> ANYFUNCTION
-#if ENABLE_VIDEO_TRACK
-%token <string> CUEFUNCTION
-#endif
%token <string> NOTFUNCTION
%token <string> CALCFUNCTION
-%token <string> MINFUNCTION
+%token <string> MATCHESFUNCTION
%token <string> MAXFUNCTION
-%token <string> VAR_DEFINITION
+%token <string> MINFUNCTION
+%token <string> NTHCHILDFUNCTIONS
+%token <string> LANGFUNCTION
+%token <string> VARFUNCTION
+
+#if ENABLE_CSS_SELECTORS_LEVEL4
+%token <string> DIRFUNCTION
+%token <string> ROLEFUNCTION
+#endif
+
+%token <string> CUSTOM_PROPERTY
%token <string> UNICODERANGE
%type <relation> combinator
-%type <rule> charset
-%type <rule> ignored_charset
-%type <rule> ruleset
-%type <rule> media
-%type <rule> import
-%type <rule> namespace
-%type <rule> page
-%type <rule> margin_box
-%type <rule> font_face
-#if ENABLE_SHADOW_DOM
-%type <rule> host
-#endif
-%type <rule> keyframes
-%type <rule> invalid_rule
-%type <rule> save_block
-%type <rule> invalid_at
-%type <rule> rule
-%type <rule> valid_rule
-%type <ruleList> block_rule_list
-%type <ruleList> region_block_rule_list
-%type <rule> block_rule
-%type <rule> block_valid_rule
-%type <rule> region
-#if ENABLE_CSS3_CONDITIONAL_RULES
-%type <rule> supports
-#endif
-#if ENABLE_CSS_DEVICE_ADAPTATION
-%type <rule> viewport
-#endif
-#if ENABLE_CSS_SHADERS
-%type <rule> filter
-#endif
+%type <rule> block_rule block_valid_rule font_face import keyframes media page region rule ruleset valid_rule
+%destructor { if ($$) $$->deref(); } block_rule block_valid_rule font_face import keyframes media page region rule ruleset valid_rule
-%type <string> maybe_ns_prefix
+%type <ruleList> block_rule_list block_valid_rule_list
+%destructor { delete $$; } block_rule_list block_valid_rule_list
-%type <string> namespace_selector
+%type <string> ident_or_string maybe_ns_prefix namespace_selector string_or_uri
-%type <string> string_or_uri
-%type <string> ident_or_string
-%type <string> medium
%type <marginBox> margin_sym
-%type <string> media_feature
-%type <mediaList> media_list
-%type <mediaList> maybe_media_list
+%type <mediaList> media_list maybe_media_list
+%destructor { if ($$) $$->deref(); } media_list maybe_media_list
+
%type <mediaQuery> media_query
+%destructor { delete $$; } media_query
+
%type <mediaQueryRestrictor> maybe_media_restrictor
-%type <valueList> maybe_media_value
-%type <mediaQueryExp> media_query_exp
-%type <mediaQueryExpList> media_query_exp_list
-%type <mediaQueryExpList> maybe_and_media_query_exp_list
-
-#if ENABLE_CSS3_CONDITIONAL_RULES
-%type <boolean> supports_condition
-%type <boolean> supports_condition_in_parens
-%type <boolean> supports_negation
-%type <boolean> supports_conjunction
-%type <boolean> supports_disjunction
-%type <boolean> supports_declaration_condition
-%type <boolean> supports_error
-#endif
+
+%type <mediaQueryExp> media_query_exp base_media_query_exp
+%destructor { delete $$; } media_query_exp base_media_query_exp
+
+%type <sourceSizeList> source_size_list
+%destructor { delete $$; } source_size_list
+
+%type <mediaQueryExp> maybe_source_media_query_exp
+%destructor { delete $$; } maybe_source_media_query_exp
+
+%type <value> source_size_length
+%destructor { destroy($$); } source_size_length
+
+%type <mediaQueryExpList> media_query_exp_list maybe_and_media_query_exp_list
+%destructor { delete $$; } media_query_exp_list maybe_and_media_query_exp_list
%type <string> keyframe_name
+
%type <keyframe> keyframe_rule
+%destructor { if ($$) $$->deref(); } keyframe_rule
+
%type <keyframeRuleList> keyframes_rule
-%type <valueList> key_list
-%type <value> key
+%destructor { delete $$; } keyframes_rule
+
+// These parser values never need to be destroyed because they are never functions or value lists.
+%type <value> calc_func_term key unary_term
+
+// These parser values need to be destroyed because they might be functions.
+%type <value> calc_function function variable_function min_or_max_function term
+%destructor { destroy($$); } calc_function function variable_function min_or_max_function term
%type <id> property
-%type <selector> specifier
-%type <selector> specifier_list
-%type <selector> simple_selector
-%type <selector> selector
-%type <selectorList> selector_list
-%type <selectorList> simple_selector_list
-%type <selectorList> region_selector
-%type <selector> selector_with_trailing_whitespace
-%type <selector> class
-%type <selector> attrib
-%type <selector> pseudo
-%type <selector> pseudo_page
-%type <selector> page_selector
-
-%type <boolean> declaration_list
-%type <boolean> decl_list
-%type <boolean> declaration
-%type <boolean> declarations_and_margins
-
-%type <boolean> prio
-
-%type <integer> match
-%type <integer> unary_operator
-%type <integer> maybe_unary_operator
-%type <character> operator
-
-%type <valueList> expr
-%type <valueList> valid_expr
-%type <value> term
-%type <value> unary_term
-%type <value> function
-%type <value> calc_func_term
-%type <character> calc_func_operator
-%type <valueList> calc_func_expr
-%type <valueList> valid_calc_func_expr
-%type <valueList> calc_func_expr_list
-%type <valueList> calc_func_paren_expr
-%type <value> calc_function
+%type <selector> attrib class page_selector pseudo pseudo_page complex_selector complex_selector_with_trailing_whitespace compound_selector specifier specifier_list
+%destructor { delete $$; } attrib class page_selector pseudo pseudo_page complex_selector complex_selector_with_trailing_whitespace compound_selector specifier specifier_list
+
+%type <selectorList> selector_list nested_selector_list simple_selector_list nth_selector_ending
+%destructor { delete $$; } selector_list nested_selector_list simple_selector_list
+%destructor { delete $$; } nth_selector_ending
+
+%type <boolean> attrib_flags declaration declaration_list decl_list priority
+
+%type <match> match
+
+%type <integer> unary_operator maybe_unary_operator
+
+%type <character> operator calc_func_operator
+
+%type <valueList> calc_func_expr calc_func_expr_list calc_func_paren_expr expr key_list maybe_media_value valid_calc_func_expr valid_expr whitespace_or_expr maybe_expr
+%destructor { delete $$; } calc_func_expr calc_func_expr_list calc_func_paren_expr expr key_list maybe_media_value valid_calc_func_expr valid_expr whitespace_or_expr maybe_expr
+
+%type <string> lang_range
+%type <stringList> comma_separated_lang_ranges
+%destructor { delete $$; } comma_separated_lang_ranges
+
%type <string> min_or_max
-%type <value> min_or_max_function
%type <string> element_name
-%type <string> attr_name
%type <location> error_location
+#if ENABLE_CSS_GRID_LAYOUT
+
+%type <valueList> ident_list
+%destructor { delete $$; } ident_list
+
+%type <value> track_names_list
+%destructor { destroy($$); } track_names_list
+
+#endif
+
+%token SUPPORTS_AND
+%token SUPPORTS_NOT
+%token SUPPORTS_OR
+%token SUPPORTS_SYM
+%token WEBKIT_SUPPORTS_CONDITION_SYM
+
+%type <rule> supports
+%destructor { if ($$) $$->deref(); } supports
+
+%type <boolean> supports_condition supports_condition_in_parens supports_conjunction supports_declaration_condition supports_disjunction supports_error supports_negation
+
+#if ENABLE_CSS_DEVICE_ADAPTATION
+
+%type <rule> viewport
+%destructor { if ($$) $$->deref(); } viewport
+
+#endif
+
+#if ENABLE_VIDEO_TRACK
+
+%token <string> CUEFUNCTION
+
+#endif
+
%%
stylesheet:
@@ -348,35 +373,22 @@ stylesheet:
| webkit_decls maybe_space
| webkit_value maybe_space
| webkit_mediaquery maybe_space
+ | webkit_source_size_list maybe_space
| webkit_selector maybe_space
| webkit_keyframe_rule maybe_space
-#if ENABLE_CSS3_CONDITIONAL_RULES
| webkit_supports_condition maybe_space
-#endif
;
-webkit_rule:
- WEBKIT_RULE_SYM '{' maybe_space valid_rule maybe_space '}' {
- parser->m_rule = $4;
- }
-;
+webkit_rule: WEBKIT_RULE_SYM '{' maybe_space valid_rule maybe_space '}' { parser->m_rule = adoptRef($4); } ;
-webkit_keyframe_rule:
- WEBKIT_KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space '}' {
- parser->m_keyframe = $4;
- }
-;
+webkit_keyframe_rule: KEYFRAME_RULE_SYM '{' maybe_space keyframe_rule maybe_space '}' { parser->m_keyframe = adoptRef($4); } ;
-webkit_decls:
- WEBKIT_DECLS_SYM '{' maybe_space_before_declaration declaration_list '}' {
- /* can be empty */
- }
-;
+webkit_decls: WEBKIT_DECLS_SYM '{' maybe_space_before_declaration declaration_list '}' ;
webkit_value:
WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
if ($4) {
- parser->m_valueList = parser->sinkFloatingValueList($4);
+ parser->m_valueList = std::unique_ptr<CSSParserValueList>($4);
int oldParsedProperties = parser->m_parsedProperties.size();
if (!parser->parseValue(parser->m_id, parser->m_important))
parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
@@ -385,55 +397,34 @@ webkit_value:
}
;
-webkit_mediaquery:
- WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
- parser->m_mediaQuery = parser->sinkFloatingMediaQuery($4);
- }
-;
+webkit_mediaquery: WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' { parser->m_mediaQuery = std::unique_ptr<MediaQuery>($4); } ;
webkit_selector:
WEBKIT_SELECTOR_SYM '{' maybe_space selector_list '}' {
if ($4) {
if (parser->m_selectorListForParseSelector)
parser->m_selectorListForParseSelector->adoptSelectorVector(*$4);
+ parser->recycleSelectorVector(std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>>($4));
}
}
;
-#if ENABLE_CSS3_CONDITIONAL_RULES
-webkit_supports_condition:
- WEBKIT_SUPPORTS_CONDITION_SYM '{' maybe_space supports_condition '}' {
- parser->m_supportsCondition = $4;
- }
-;
-#endif
+webkit_supports_condition: WEBKIT_SUPPORTS_CONDITION_SYM WHITESPACE maybe_space supports_condition '}' { parser->m_supportsCondition = $4; } ;
-maybe_space:
- /* empty */ %prec UNIMPORTANT_TOK
- | maybe_space WHITESPACE
- ;
+/* for expressions that require at least one whitespace to be present, like the + and - operators in calc expressions */
+space: WHITESPACE | space WHITESPACE ;
-maybe_sgml:
- /* empty */
- | maybe_sgml SGML_CD
- | maybe_sgml WHITESPACE
- ;
+maybe_space: /* empty */ %prec UNIMPORTANT_TOK | maybe_space WHITESPACE ;
-maybe_charset:
- /* empty */
- | charset {
- }
- ;
+maybe_sgml: /* empty */ | maybe_sgml SGML_CD | maybe_sgml WHITESPACE ;
-closing_brace:
- '}'
- | %prec LOWEST_PREC TOKEN_EOF
- ;
+maybe_charset: /* empty */ | charset ;
-closing_parenthesis:
- ')'
- | %prec LOWEST_PREC TOKEN_EOF
- ;
+closing_brace: '}' | %prec LOWEST_PREC TOKEN_EOF ;
+
+closing_parenthesis: ')' | %prec LOWEST_PREC TOKEN_EOF ;
+
+closing_bracket: ']' | %prec LOWEST_PREC TOKEN_EOF;
charset:
CHARSET_SYM maybe_space STRING maybe_space ';' {
@@ -441,31 +432,23 @@ charset:
parser->m_styleSheet->parserSetEncodingFromCharsetRule($3);
if (parser->isExtractingSourceData() && parser->m_currentRuleDataStack->isEmpty() && parser->m_ruleSourceDataResult)
parser->addNewRuleToSourceTree(CSSRuleSourceData::createUnknown());
- $$ = 0;
- }
- | CHARSET_SYM error invalid_block {
- }
- | CHARSET_SYM error ';' {
}
+ | CHARSET_SYM error invalid_block
+ | CHARSET_SYM error ';'
;
-ignored_charset:
- CHARSET_SYM maybe_space STRING maybe_space ';' {
- // Ignore any @charset rule not at the beginning of the style sheet.
- $$ = 0;
- }
- | CHARSET_SYM maybe_space ';' {
- $$ = 0;
- }
-;
+// Ignore any @charset rule not at the beginning of the style sheet.
+ignored_charset: CHARSET_SYM maybe_space STRING maybe_space ';' | CHARSET_SYM maybe_space ';' ;
rule_list:
- /* empty */
- | rule_list rule maybe_sgml {
- if ($2 && parser->m_styleSheet)
- parser->m_styleSheet->parserAppendRule($2);
- }
- ;
+ /* empty */
+ | rule_list rule maybe_sgml {
+ if (RefPtr<StyleRuleBase> rule = adoptRef($2)) {
+ if (parser->m_styleSheet)
+ parser->m_styleSheet->parserAppendRule(rule.releaseNonNull());
+ }
+ }
+ ;
valid_rule:
ruleset
@@ -473,52 +456,45 @@ valid_rule:
| page
| font_face
| keyframes
- | namespace
+ | namespace { $$ = nullptr; }
| import
| region
-#if ENABLE_CSS3_CONDITIONAL_RULES
| supports
-#endif
-#if ENABLE_SHADOW_DOM
- | host
-#endif
#if ENABLE_CSS_DEVICE_ADAPTATION
| viewport
#endif
-#if ENABLE_CSS_SHADERS
- | filter
-#endif
;
rule:
valid_rule {
+ $$ = $1;
parser->m_hadSyntacticallyValidCSSRule = true;
}
- | ignored_charset
- | invalid_rule
- | invalid_at
- ;
+ | ignored_charset { $$ = nullptr; }
+ | invalid_rule { $$ = nullptr; }
+ | invalid_at { $$ = nullptr; }
+ ;
block_rule_list:
- /* empty */ { $$ = 0; }
+ /* empty */ { $$ = nullptr; }
| block_rule_list block_rule maybe_sgml {
$$ = $1;
- if ($2) {
+ if (RefPtr<StyleRuleBase> rule = adoptRef($2)) {
if (!$$)
- $$ = parser->createRuleList();
- $$->append($2);
+ $$ = new Vector<RefPtr<StyleRuleBase>>;
+ $$->append(rule.release());
}
}
;
-region_block_rule_list:
- /* empty */ { $$ = 0; }
- | region_block_rule_list block_valid_rule maybe_sgml {
+block_valid_rule_list:
+ /* empty */ { $$ = nullptr; }
+ | block_valid_rule_list block_valid_rule maybe_sgml {
$$ = $1;
- if ($2) {
+ if (RefPtr<StyleRuleBase> rule = adoptRef($2)) {
if (!$$)
- $$ = parser->createRuleList();
- $$->append($2);
+ $$ = new Vector<RefPtr<StyleRuleBase>>;
+ $$->append(rule.release());
}
}
;
@@ -529,25 +505,13 @@ block_valid_rule:
| font_face
| media
| keyframes
-#if ENABLE_CSS3_CONDITIONAL_RULES
| supports
-#endif
#if ENABLE_CSS_DEVICE_ADAPTATION
| viewport
#endif
-#if ENABLE_CSS_SHADERS
- | filter
-#endif
;
-block_rule:
- block_valid_rule
- | invalid_rule
- | invalid_at
- | namespace
- | import
- | region
- ;
+block_rule: block_valid_rule | invalid_rule { $$ = nullptr; } | invalid_at { $$ = nullptr; } | namespace { $$ = nullptr; } | import | region ;
at_import_header_end_maybe_space:
maybe_space {
@@ -564,93 +528,98 @@ before_import_rule:
import:
before_import_rule IMPORT_SYM at_import_header_end_maybe_space string_or_uri maybe_space maybe_media_list ';' {
- $$ = parser->createImportRule($4, $6);
+ $$ = parser->createImportRule($4, adoptRef($6)).leakRef();
}
| before_import_rule IMPORT_SYM at_import_header_end_maybe_space string_or_uri maybe_space maybe_media_list TOKEN_EOF {
- $$ = parser->createImportRule($4, $6);
+ $$ = parser->createImportRule($4, adoptRef($6)).leakRef();
}
| before_import_rule IMPORT_SYM at_import_header_end_maybe_space string_or_uri maybe_space maybe_media_list invalid_block {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
+ if ($6)
+ $6->deref();
}
| before_import_rule IMPORT_SYM error ';' {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
}
| before_import_rule IMPORT_SYM error invalid_block {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
}
;
namespace:
-NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
- parser->addNamespace($3, $4);
- $$ = 0;
-}
-| NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space invalid_block {
- $$ = 0;
-}
-| NAMESPACE_SYM error invalid_block {
- $$ = 0;
-}
-| NAMESPACE_SYM error ';' {
- $$ = 0;
-}
-;
+ NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' { parser->addNamespace($3, $4); }
+ | NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space invalid_block
+ | NAMESPACE_SYM error invalid_block
+ | NAMESPACE_SYM error ';'
+ ;
-maybe_ns_prefix:
-/* empty */ { $$.clear(); }
-| IDENT maybe_space { $$ = $1; }
-;
+maybe_ns_prefix: /* empty */ { $$.clear(); } | IDENT maybe_space;
-string_or_uri:
-STRING
-| URI
-;
+string_or_uri: STRING | URI ;
-media_feature:
- IDENT maybe_space {
+maybe_media_value: /*empty*/ { $$ = nullptr; } | ':' maybe_space expr maybe_space { $$ = $3; } ;
+
+webkit_source_size_list:
+ WEBKIT_SIZESATTR_SYM WHITESPACE source_size_list maybe_space '}' {
+ parser->m_sourceSizeList = std::unique_ptr<Vector<CSSParser::SourceSize>>($3);
+ }
+ ;
+
+source_size_list:
+ maybe_source_media_query_exp source_size_length {
+ $$ = new Vector<CSSParser::SourceSize>;
+ $$->append(parser->sourceSize(std::unique_ptr<MediaQueryExp>($1), $2));
+ }
+ | source_size_list maybe_space ',' maybe_space maybe_source_media_query_exp source_size_length {
$$ = $1;
+ $$->append(parser->sourceSize(std::unique_ptr<MediaQueryExp>($5), $6));
}
;
-maybe_media_value:
- /*empty*/ {
- $$ = 0;
+maybe_source_media_query_exp:
+ /* empty */ {
+ $$ = new MediaQueryExp;
}
- | ':' maybe_space expr maybe_space {
- $$ = $3;
+ | base_media_query_exp maybe_space;
+
+source_size_length: unary_term | calc_function;
+
+base_media_query_exp: '(' maybe_space IDENT maybe_space maybe_media_value ')' {
+ std::unique_ptr<CSSParserValueList> mediaValue($5);
+ $3.convertToASCIILowercaseInPlace();
+ $$ = new MediaQueryExp($3, mediaValue.get());
}
;
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_media_restrictor maybe_space base_media_query_exp maybe_space {
+ if ($1 != MediaQuery::None) {
+ // If restrictor is specified, media query expression is invalid.
+ // Create empty media query expression and continue parsing media query.
+ delete $3;
+ $$ = new MediaQueryExp;
+ } else
+ $$ = $3;
}
;
media_query_exp_list:
media_query_exp {
- $$ = parser->createFloatingMediaQueryExpList();
- $$->append(parser->sinkFloatingMediaQueryExp($1));
+ $$ = new Vector<std::unique_ptr<MediaQueryExp>>;
+ $$->append(std::unique_ptr<MediaQueryExp>($1));
}
| media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
$$ = $1;
- $$->append(parser->sinkFloatingMediaQueryExp($5));
+ $$->append(std::unique_ptr<MediaQueryExp>($5));
}
;
maybe_and_media_query_exp_list:
/*empty*/ {
- $$ = parser->createFloatingMediaQueryExpList();
+ $$ = new Vector<std::unique_ptr<MediaQueryExp>>;
}
| MEDIA_AND maybe_space media_query_exp_list {
$$ = $3;
@@ -671,37 +640,35 @@ maybe_media_restrictor:
media_query:
media_query_exp_list {
- $$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($1));
+ $$ = new MediaQuery(MediaQuery::None, "all", std::unique_ptr<Vector<std::unique_ptr<MediaQueryExp>>>($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 maybe_space IDENT maybe_space maybe_and_media_query_exp_list {
+ $3.convertToASCIILowercaseInPlace();
+ $$ = new MediaQuery($1, $3, std::unique_ptr<Vector<std::unique_ptr<MediaQueryExp>>>($5));
}
;
-maybe_media_list:
- /* empty */ {
- $$ = parser->createMediaQuerySet();
- }
- | media_list
- ;
+maybe_media_list: /* empty */ { $$ = &MediaQuerySet::create().leakRef(); } | media_list ;
media_list:
media_query {
- $$ = parser->createMediaQuerySet();
- $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
+ $$ = &MediaQuerySet::create().leakRef();
+ $$->addMediaQuery(std::unique_ptr<MediaQuery>($1));
parser->updateLastMediaLine($$);
}
| media_list ',' maybe_space media_query {
$$ = $1;
+ std::unique_ptr<MediaQuery> mediaQuery($4);
if ($$) {
- $$->addMediaQuery(parser->sinkFloatingMediaQuery($4));
+ $$->addMediaQuery(WTFMove(mediaQuery));
parser->updateLastMediaLine($$);
}
}
| media_list error {
- $$ = 0;
+ $$ = nullptr;
+ if ($1)
+ $1->deref();
}
;
@@ -725,38 +692,36 @@ at_rule_header_end_maybe_space:
media:
before_media_rule MEDIA_SYM maybe_space media_list at_rule_header_end '{' at_rule_body_start maybe_space block_rule_list save_block {
- $$ = parser->createMediaRule($4, $9);
+ $$ = parser->createMediaRule(adoptRef($4), std::unique_ptr<Vector<RefPtr<StyleRuleBase>>>($9).get()).leakRef();
}
| before_media_rule MEDIA_SYM at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space block_rule_list save_block {
- $$ = parser->createEmptyMediaRule($7);
+ $$ = parser->createEmptyMediaRule(std::unique_ptr<Vector<RefPtr<StyleRuleBase>>>($7).get()).leakRef();
}
| before_media_rule MEDIA_SYM at_rule_header_end_maybe_space ';' {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
}
;
-medium:
- IDENT maybe_space {
- $$ = $1;
- }
- ;
-
-#if ENABLE_CSS3_CONDITIONAL_RULES
supports:
before_supports_rule SUPPORTS_SYM maybe_space supports_condition at_supports_rule_header_end '{' at_rule_body_start maybe_space block_rule_list save_block {
- $$ = parser->createSupportsRule($4, $9);
+ $$ = parser->createSupportsRule($4, std::unique_ptr<Vector<RefPtr<StyleRuleBase>>>($9).get()).leakRef();
}
| before_supports_rule SUPPORTS_SYM supports_error {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
parser->popSupportsRuleData();
}
;
-supports_error:
- error ';'
- | error invalid_block
+supports_error:
+ error ';' {
+ $$ = false;
+ }
+ | error invalid_block {
+ $$ = false;
+ }
+ ;
before_supports_rule:
/* empty */ {
@@ -772,53 +737,35 @@ at_supports_rule_header_end:
}
;
-supports_condition:
- supports_condition_in_parens
- | supports_negation
- | supports_conjunction
- | supports_disjunction
- ;
+supports_condition: supports_condition_in_parens | supports_negation | supports_conjunction | supports_disjunction ;
-supports_negation:
- SUPPORTS_NOT maybe_space supports_condition_in_parens {
- $$ = !$3;
- }
- ;
+supports_negation: SUPPORTS_NOT maybe_space supports_condition_in_parens { $$ = !$3; } ;
supports_conjunction:
- supports_condition_in_parens SUPPORTS_AND maybe_space supports_condition_in_parens {
- $$ = $1 && $4;
- }
- | supports_conjunction SUPPORTS_AND maybe_space supports_condition_in_parens {
- $$ = $1 && $4;
- }
+ supports_condition_in_parens SUPPORTS_AND maybe_space supports_condition_in_parens { $$ = $1 && $4; }
+ | supports_conjunction SUPPORTS_AND maybe_space supports_condition_in_parens { $$ = $1 && $4; }
;
supports_disjunction:
- supports_condition_in_parens SUPPORTS_OR maybe_space supports_condition_in_parens {
- $$ = $1 || $4;
- }
- | supports_disjunction SUPPORTS_OR maybe_space supports_condition_in_parens {
- $$ = $1 || $4;
- }
+ supports_condition_in_parens SUPPORTS_OR maybe_space supports_condition_in_parens { $$ = $1 || $4; }
+ | supports_disjunction SUPPORTS_OR maybe_space supports_condition_in_parens { $$ = $1 || $4; }
;
supports_condition_in_parens:
- '(' maybe_space supports_condition ')' maybe_space {
- $$ = $3;
- }
- | supports_declaration_condition
- | '(' error ')'
+ '(' maybe_space supports_condition ')' maybe_space { $$ = $3; }
+ | supports_declaration_condition { $$ = $1; }
+ | '(' error ')' { $$ = false; }
;
supports_declaration_condition:
- '(' maybe_space property ':' maybe_space expr prio ')' maybe_space {
+ '(' maybe_space property ':' maybe_space expr priority ')' maybe_space {
$$ = false;
CSSParser* p = static_cast<CSSParser*>(parser);
- if ($3 && $6) {
- p->m_valueList = p->sinkFloatingValueList($6);
+ std::unique_ptr<CSSParserValueList> propertyValue($6);
+ if ($3 && propertyValue) {
+ p->m_valueList = WTFMove(propertyValue);
int oldParsedProperties = p->m_parsedProperties.size();
- $$ = p->parseValue(static_cast<CSSPropertyID>($3), $7);
+ $$ = p->parseValue($3, $7);
// We just need to know if the declaration is supported as it is written. Rollback any additions.
if ($$)
p->rollbackLastProperties(p->m_parsedProperties.size() - oldParsedProperties);
@@ -826,8 +773,23 @@ supports_declaration_condition:
}
p->markPropertyEnd($7, false);
}
+ |
+ '(' maybe_space CUSTOM_PROPERTY maybe_space ':' whitespace_or_expr priority ')' maybe_space {
+ $$ = false;
+ CSSParser* p = static_cast<CSSParser*>(parser);
+ std::unique_ptr<CSSParserValueList> propertyValue($6);
+ if (propertyValue) {
+ parser->m_valueList = WTFMove(propertyValue);
+ int oldParsedProperties = p->m_parsedProperties.size();
+ p->setCustomPropertyName($3);
+ $$ = p->parseValue(CSSPropertyCustom, $7);
+ if ($$)
+ p->rollbackLastProperties(p->m_parsedProperties.size() - oldParsedProperties);
+ p->m_valueList = nullptr;
+ }
+ p->markPropertyEnd($7, false);
+ }
;
-#endif
before_keyframes_rule:
/* empty */ {
@@ -836,56 +798,51 @@ before_keyframes_rule:
;
keyframes:
- before_keyframes_rule WEBKIT_KEYFRAMES_SYM maybe_space keyframe_name at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space keyframes_rule closing_brace {
- $$ = parser->createKeyframesRule($4, parser->sinkFloatingKeyframeVector($9));
+ before_keyframes_rule KEYFRAMES_SYM maybe_space keyframe_name at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space keyframes_rule closing_brace {
+ $$ = parser->createKeyframesRule($4, std::unique_ptr<Vector<RefPtr<StyleKeyframe>>>($9)).leakRef();
}
;
-
-keyframe_name:
- IDENT
- | STRING
- ;
+
+keyframe_name: IDENT | STRING ;
keyframes_rule:
- /* empty */ { $$ = parser->createFloatingKeyframeVector(); }
+ /* empty */ { $$ = new Vector<RefPtr<StyleKeyframe>>; }
| keyframes_rule keyframe_rule maybe_space {
$$ = $1;
- if ($2)
- $$->append($2);
+ if (RefPtr<StyleKeyframe> keyframe = adoptRef($2))
+ $$->append(keyframe.release());
}
;
-keyframe_rule:
- key_list maybe_space '{' maybe_space declaration_list closing_brace {
- $$ = parser->createKeyframe($1);
- }
- ;
+keyframe_rule: key_list maybe_space '{' maybe_space declaration_list closing_brace { $$ = parser->createKeyframe(*std::unique_ptr<CSSParserValueList>($1)).leakRef(); } ;
key_list:
key {
- $$ = parser->createFloatingValueList();
- $$->addValue(parser->sinkFloatingValue($1));
+ $$ = new CSSParserValueList;
+ $$->addValue($1);
}
| key_list maybe_space ',' maybe_space key {
$$ = $1;
+ ASSERT($5.unit != CSSParserValue::Function); // No need to call destroy.
if ($$)
- $$->addValue(parser->sinkFloatingValue($5));
+ $$->addValue($5);
}
;
key:
maybe_unary_operator PERCENTAGE { $$.id = CSSValueInvalid; $$.isInt = false; $$.fValue = $1 * $2; $$.unit = CSSPrimitiveValue::CSS_NUMBER; }
| IDENT {
- $$.id = CSSValueInvalid; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_NUMBER;
- CSSParserString& str = $1;
- if (str.equalIgnoringCase("from"))
+ $$.id = CSSValueInvalid;
+ $$.isInt = false;
+ if (equalLettersIgnoringASCIICase($1, "from"))
$$.fValue = 0;
- else if (str.equalIgnoringCase("to"))
+ else if (equalLettersIgnoringASCIICase($1, "to"))
$$.fValue = 100;
else {
$$.unit = 0;
YYERROR;
}
+ $$.unit = CSSPrimitiveValue::CSS_NUMBER;
}
| error {
$$.unit = 0;
@@ -902,28 +859,28 @@ page:
before_page_rule PAGE_SYM maybe_space page_selector at_rule_header_end_maybe_space
'{' at_rule_body_start maybe_space_before_declaration declarations_and_margins closing_brace {
if ($4)
- $$ = parser->createPageRule(parser->sinkFloatingSelector($4));
+ $$ = parser->createPageRule(std::unique_ptr<CSSParserSelector>($4)).leakRef();
else {
// Clear properties in the invalid @page rule.
parser->clearProperties();
// Also clear margin at-rules here once we fully implement margin at-rules parsing.
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
}
}
| before_page_rule PAGE_SYM error invalid_block {
- parser->popRuleData();
- $$ = 0;
+ parser->popRuleData();
+ $$ = nullptr;
}
| before_page_rule PAGE_SYM error ';' {
- parser->popRuleData();
- $$ = 0;
+ parser->popRuleData();
+ $$ = nullptr;
}
;
page_selector:
IDENT {
- $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
+ $$ = new CSSParserSelector(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
$$->setForPage();
}
| IDENT pseudo_page {
@@ -939,25 +896,22 @@ page_selector:
$$->setForPage();
}
| /* empty */ {
- $$ = parser->createFloatingSelector();
+ $$ = new CSSParserSelector;
$$->setForPage();
}
;
-declarations_and_margins:
- declaration_list
- | declarations_and_margins margin_box maybe_space declaration_list
- ;
+declarations_and_margins: declaration_list | declarations_and_margins margin_box maybe_space declaration_list ;
margin_box:
margin_sym {
parser->startDeclarationsForMarginBox();
} maybe_space '{' maybe_space declaration_list closing_brace {
- $$ = parser->createMarginAtRule($1);
+ parser->createMarginAtRule($1);
}
;
-margin_sym :
+margin_sym:
TOPLEFTCORNER_SYM {
$$ = CSSSelector::TopLeftCornerMarginBox;
}
@@ -1015,40 +969,21 @@ before_font_face_rule:
;
font_face:
- before_font_face_rule FONT_FACE_SYM at_rule_header_end_maybe_space
- '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
- $$ = parser->createFontFaceRule();
+ before_font_face_rule FONT_FACE_SYM at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
+ $$ = parser->createFontFaceRule().leakRef();
}
| before_font_face_rule FONT_FACE_SYM error invalid_block {
- $$ = 0;
- parser->popRuleData();
+ $$ = nullptr;
+ parser->popRuleData();
}
| before_font_face_rule FONT_FACE_SYM error ';' {
- $$ = 0;
- parser->popRuleData();
- }
-;
-
-#if ENABLE_SHADOW_DOM
-before_host_rule:
- /* empty */ {
- parser->markRuleHeaderStart(CSSRuleSourceData::HOST_RULE);
- }
- ;
-
-host:
- before_host_rule HOST_SYM at_rule_header_end_maybe_space
- '{' at_rule_body_start maybe_space block_rule_list save_block {
- $$ = parser->createHostRule($7);
- }
- | before_host_rule HOST_SYM at_rule_header_end_maybe_space ';' {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
}
- ;
-#endif
+;
#if ENABLE_CSS_DEVICE_ADAPTATION
+
before_viewport_rule:
/* empty */ {
parser->markViewportRuleBodyStart();
@@ -1059,32 +994,22 @@ before_viewport_rule:
viewport:
before_viewport_rule WEBKIT_VIEWPORT_RULE_SYM at_rule_header_end_maybe_space
'{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
- $$ = parser->createViewportRule();
+ $$ = parser->createViewportRule().leakRef();
parser->markViewportRuleBodyEnd();
}
| before_viewport_rule WEBKIT_VIEWPORT_RULE_SYM error invalid_block {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
parser->markViewportRuleBodyEnd();
}
| before_viewport_rule WEBKIT_VIEWPORT_RULE_SYM error ';' {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
parser->markViewportRuleBodyEnd();
}
;
-#endif
-region_selector:
- selector_list {
- if ($1) {
- parser->setReusableRegionSelectorVector($1);
- $$ = parser->reusableRegionSelectorVector();
- }
- else
- $$ = 0;
- }
-;
+#endif
before_region_rule:
/* empty */ {
@@ -1093,240 +1018,233 @@ before_region_rule:
;
region:
- before_region_rule WEBKIT_REGION_RULE_SYM WHITESPACE region_selector at_rule_header_end '{' at_rule_body_start maybe_space region_block_rule_list save_block {
+ before_region_rule WEBKIT_REGION_RULE_SYM maybe_space selector_list at_rule_header_end '{' at_rule_body_start maybe_space block_valid_rule_list save_block {
+ std::unique_ptr<Vector<RefPtr<StyleRuleBase>>> ruleList($9);
if ($4)
- $$ = parser->createRegionRule($4, $9);
+ $$ = parser->createRegionRule(std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>>($4).get(), ruleList.get()).leakRef();
else {
- $$ = 0;
+ $$ = nullptr;
parser->popRuleData();
}
}
;
-#if ENABLE_CSS_SHADERS
-before_filter_rule:
- /* empty */ {
- parser->markRuleHeaderStart(CSSRuleSourceData::FILTER_RULE);
- parser->m_inFilterRule = true;
- }
- ;
-
-filter:
- before_filter_rule WEBKIT_FILTER_RULE_SYM WHITESPACE IDENT at_rule_header_end_maybe_space
- '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
- parser->m_inFilterRule = false;
- $$ = parser->createFilterRule($4);
- }
- ;
-#endif
-
combinator:
- '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
- | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
- | '>' maybe_space { $$ = CSSSelector::Child; }
+ '+' maybe_space { $$ = CSSParserSelectorCombinator::DirectAdjacent; }
+ | '~' maybe_space { $$ = CSSParserSelectorCombinator::IndirectAdjacent; }
+ | '>' maybe_space { $$ = CSSParserSelectorCombinator::Child; }
+#if ENABLE_CSS_SELECTORS_LEVEL4
+ | '>' '>' maybe_space { $$ = CSSParserSelectorCombinator::DescendantDoubleChild; }
+#endif
;
-maybe_unary_operator:
- unary_operator { $$ = $1; }
- | { $$ = 1; }
- ;
+maybe_unary_operator: unary_operator | { $$ = 1; } ;
-unary_operator:
- '-' { $$ = -1; }
- | '+' { $$ = 1; }
- ;
+unary_operator: '-' { $$ = -1; } | '+' { $$ = 1; } ;
-maybe_space_before_declaration:
- maybe_space {
- parser->markPropertyStart();
- }
- ;
+maybe_space_before_declaration: maybe_space { parser->markPropertyStart(); } ;
before_selector_list:
- /* empty */ {
+ {
parser->markRuleHeaderStart(CSSRuleSourceData::STYLE_RULE);
parser->markSelectorStart();
}
;
-at_rule_header_end:
- /* empty */ {
- parser->markRuleHeaderEnd();
- }
- ;
+at_rule_header_end: { parser->markRuleHeaderEnd(); } ;
-at_selector_end:
- /* empty */ {
- parser->markSelectorEnd();
- }
- ;
+at_selector_end: { parser->markSelectorEnd(); } ;
ruleset:
before_selector_list selector_list at_selector_end at_rule_header_end '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
- $$ = parser->createStyleRule($2);
+ $$ = parser->createStyleRule($2).leakRef();
+ parser->recycleSelectorVector(std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>>($2));
}
;
-before_selector_group_item:
- /* empty */ {
- parser->markSelectorStart();
- }
+before_selector_group_item: { parser->markSelectorStart(); } ;
selector_list:
- selector %prec UNIMPORTANT_TOK {
+ complex_selector %prec UNIMPORTANT_TOK {
+ $$ = nullptr;
if ($1) {
- $$ = parser->reusableSelectorVector();
- $$->shrink(0);
- $$->append(parser->sinkFloatingSelector($1));
+ $$ = parser->createSelectorVector().release();
+ $$->append(std::unique_ptr<CSSParserSelector>($1));
parser->updateLastSelectorLineAndPosition();
}
}
- | selector_list at_selector_end ',' maybe_space before_selector_group_item selector %prec UNIMPORTANT_TOK {
- if ($1 && $6) {
- $$ = $1;
- $$->append(parser->sinkFloatingSelector($6));
+ | selector_list at_selector_end ',' maybe_space before_selector_group_item complex_selector %prec UNIMPORTANT_TOK {
+ std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> selectorList($1);
+ std::unique_ptr<CSSParserSelector> selector($6);
+ $$ = nullptr;
+ if (selectorList && selector) {
+ $$ = selectorList.release();
+ $$->append(WTFMove(selector));
parser->updateLastSelectorLineAndPosition();
- } else
- $$ = 0;
+ }
}
- | selector_list error {
- $$ = 0;
+ | selector_list error {
+ $$ = nullptr;
+ delete $1;
}
;
-selector_with_trailing_whitespace:
- selector WHITESPACE {
- $$ = $1;
+before_nested_selector_list: { parser->startNestedSelectorList(); } ;
+after_nested_selector_list: { parser->endNestedSelectorList(); } ;
+
+nested_selector_list:
+ before_nested_selector_list selector_list after_nested_selector_list {
+ $$ = $2;
}
;
-selector:
- simple_selector {
- $$ = $1;
+lang_range: IDENT | STRING ;
+
+comma_separated_lang_ranges:
+ lang_range %prec UNIMPORTANT_TOK {
+ $$ = new Vector<CSSParserString>;
+ $$->append($1);
}
- | selector_with_trailing_whitespace
- {
+ | comma_separated_lang_ranges maybe_space ',' maybe_space lang_range %prec UNIMPORTANT_TOK {
$$ = $1;
+ if ($$)
+ $1->append($5);
}
- | selector_with_trailing_whitespace simple_selector
- {
- $$ = $2;
- if (!$1)
- $$ = 0;
- else if ($$)
- $$->appendTagHistory(CSSSelector::Descendant, parser->sinkFloatingSelector($1));
+ | comma_separated_lang_ranges error {
+ $$ = nullptr;
+ delete $1;
}
- | selector combinator simple_selector {
- $$ = $3;
- if (!$1)
- $$ = 0;
- else if ($$)
- $$->appendTagHistory($2, parser->sinkFloatingSelector($1));
+ ;
+
+complex_selector_with_trailing_whitespace:
+ complex_selector WHITESPACE;
+
+complex_selector:
+ compound_selector
+ | complex_selector_with_trailing_whitespace
+ | complex_selector_with_trailing_whitespace compound_selector {
+ std::unique_ptr<CSSParserSelector> left($1);
+ std::unique_ptr<CSSParserSelector> right($2);
+ $$ = nullptr;
+ if (left && right) {
+ right->appendTagHistory(CSSParserSelectorCombinator::DescendantSpace, WTFMove(left));
+ $$ = right.release();
+ }
}
- | selector error {
- $$ = 0;
+ | complex_selector combinator compound_selector {
+ std::unique_ptr<CSSParserSelector> left($1);
+ std::unique_ptr<CSSParserSelector> right($3);
+ $$ = nullptr;
+ if (left && right) {
+ right->appendTagHistory($2, WTFMove(left));
+ $$ = right.release();
+ }
+ }
+ | complex_selector error {
+ $$ = nullptr;
+ delete $1;
}
;
namespace_selector:
- /* empty */ '|' { $$.clear(); }
+ '|' { $$.clear(); }
| '*' '|' { static LChar star = '*'; $$.init(&star, 1); }
- | IDENT '|' { $$ = $1; }
+ | IDENT '|'
;
-
-simple_selector:
+
+compound_selector:
element_name {
- $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
+ $$ = new CSSParserSelector(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
}
| element_name specifier_list {
$$ = $2;
if ($$)
- $$ = parser->rewriteSpecifiersWithElementName(nullAtom, $1, $$);
+ parser->rewriteSpecifiersWithElementName(nullAtom, $1, *$$);
}
| specifier_list {
$$ = $1;
if ($$)
- $$ = parser->rewriteSpecifiersWithNamespaceIfNeeded($$);
+ parser->rewriteSpecifiersWithNamespaceIfNeeded(*$$);
}
| namespace_selector element_name {
- $$ = parser->createFloatingSelectorWithTagName(parser->determineNameInNamespace($1, $2));
+ $$ = new CSSParserSelector(parser->determineNameInNamespace($1, $2));
}
| namespace_selector element_name specifier_list {
$$ = $3;
if ($$)
- $$ = parser->rewriteSpecifiersWithElementName($1, $2, $$);
+ parser->rewriteSpecifiersWithElementName($1, $2, *$$);
}
| namespace_selector specifier_list {
$$ = $2;
if ($$)
- $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $$);
+ parser->rewriteSpecifiersWithElementName($1, starAtom, *$$);
}
;
simple_selector_list:
- simple_selector %prec UNIMPORTANT_TOK {
+ compound_selector %prec UNIMPORTANT_TOK {
+ $$ = nullptr;
if ($1) {
- $$ = parser->createFloatingSelectorVector();
- $$->append(parser->sinkFloatingSelector($1));
- } else
- $$ = 0;
+ $$ = parser->createSelectorVector().release();
+ $$->append(std::unique_ptr<CSSParserSelector>($1));
+ }
}
- | simple_selector_list maybe_space ',' maybe_space simple_selector %prec UNIMPORTANT_TOK {
- if ($1 && $5) {
- $$ = $1;
- $$->append(parser->sinkFloatingSelector($5));
- } else
- $$ = 0;
+ | simple_selector_list maybe_space ',' maybe_space compound_selector %prec UNIMPORTANT_TOK {
+ std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> list($1);
+ std::unique_ptr<CSSParserSelector> selector($5);
+ $$ = nullptr;
+ if (list && selector) {
+ $$ = list.release();
+ $$->append(WTFMove(selector));
+ }
}
| simple_selector_list error {
- $$ = 0;
+ $$ = nullptr;
+ delete $1;
}
- ;
+ ;
element_name:
IDENT {
- CSSParserString& str = $1;
- if (parser->m_context.isHTMLDocument)
- str.lower();
- $$ = str;
+ $$ = $1;
}
| '*' {
static LChar star = '*';
$$.init(&star, 1);
}
- ;
+ ;
specifier_list:
- specifier {
- $$ = $1;
- }
+ specifier
| specifier_list specifier {
- if (!$2)
- $$ = 0;
- else if ($1)
- $$ = parser->rewriteSpecifiers($1, $2);
+ std::unique_ptr<CSSParserSelector> list($1);
+ std::unique_ptr<CSSParserSelector> specifier($2);
+ $$ = nullptr;
+ if (list && specifier)
+ $$ = parser->rewriteSpecifiers(WTFMove(list), WTFMove(specifier)).release();
}
| specifier_list error {
- $$ = 0;
+ $$ = nullptr;
+ delete $1;
}
;
specifier:
IDSEL {
- $$ = parser->createFloatingSelector();
+ $$ = new CSSParserSelector;
$$->setMatch(CSSSelector::Id);
if (parser->m_context.mode == CSSQuirksMode)
- $1.lower();
+ $1.convertToASCIILowercaseInPlace();
$$->setValue($1);
}
| HEX {
- if ($1[0] >= '0' && $1[0] <= '9') {
- $$ = 0;
- } else {
- $$ = parser->createFloatingSelector();
+ if ($1[0] >= '0' && $1[0] <= '9')
+ $$ = nullptr;
+ else {
+ $$ = new CSSParserSelector;
$$->setMatch(CSSSelector::Id);
if (parser->m_context.mode == CSSQuirksMode)
- $1.lower();
+ $1.convertToASCIILowercaseInPlace();
$$->setValue($1);
}
}
@@ -1337,45 +1255,52 @@ specifier:
class:
'.' IDENT {
- $$ = parser->createFloatingSelector();
+ $$ = new CSSParserSelector;
$$->setMatch(CSSSelector::Class);
if (parser->m_context.mode == CSSQuirksMode)
- $2.lower();
+ $2.convertToASCIILowercaseInPlace();
$$->setValue($2);
}
;
-attr_name:
- IDENT maybe_space {
- $$ = $1;
- }
- ;
-
attrib:
- '[' maybe_space attr_name ']' {
- $$ = parser->createFloatingSelector();
+ '[' maybe_space IDENT maybe_space ']' {
+ $$ = new CSSParserSelector;
$$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), parser->m_context.isHTMLDocument);
$$->setMatch(CSSSelector::Set);
}
- | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
- $$ = parser->createFloatingSelector();
+ | '[' maybe_space IDENT maybe_space match maybe_space ident_or_string maybe_space attrib_flags ']' {
+ $$ = new CSSParserSelector;
$$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), parser->m_context.isHTMLDocument);
- $$->setMatch((CSSSelector::Match)$4);
- $$->setValue($6);
+ $$->setMatch($5);
+ $$->setValue($7);
+ $$->setAttributeValueMatchingIsCaseInsensitive($9);
}
- | '[' maybe_space namespace_selector attr_name ']' {
- $$ = parser->createFloatingSelector();
+ | '[' maybe_space namespace_selector IDENT maybe_space ']' {
+ $$ = new CSSParserSelector;
$$->setAttribute(parser->determineNameInNamespace($3, $4), parser->m_context.isHTMLDocument);
$$->setMatch(CSSSelector::Set);
}
- | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
- $$ = parser->createFloatingSelector();
+ | '[' maybe_space namespace_selector IDENT maybe_space match maybe_space ident_or_string maybe_space attrib_flags ']' {
+ $$ = new CSSParserSelector;
$$->setAttribute(parser->determineNameInNamespace($3, $4), parser->m_context.isHTMLDocument);
- $$->setMatch((CSSSelector::Match)$5);
- $$->setValue($7);
+ $$->setMatch($6);
+ $$->setValue($8);
+ $$->setAttributeValueMatchingIsCaseInsensitive($10);
}
;
+attrib_flags:
+ IDENT maybe_space {
+ if (UNLIKELY($1.length() != 1 || !isASCIIAlphaCaselessEqual($1[0], 'i')))
+ YYERROR;
+ $$ = true;
+ }
+ |
+ /* empty */ {
+ $$ = false;
+ }
+
match:
'=' {
$$ = CSSSelector::Exact;
@@ -1397,55 +1322,39 @@ match:
}
;
-ident_or_string:
- IDENT
- | STRING
- ;
+ident_or_string: IDENT | STRING ;
pseudo_page:
':' IDENT {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PagePseudoClass);
- $2.lower();
- $$->setValue($2);
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type == CSSSelector::PseudoUnknown)
- $$ = 0;
+ $$ = CSSParserSelector::parsePagePseudoSelector($2);
}
+nth_selector_ending:
+ ')' {
+ $$ = nullptr;
+ }
+ | space ')' {
+ $$ = nullptr;
+ }
+ | space NTHCHILDSELECTORSEPARATOR space nested_selector_list maybe_space ')' {
+ if ($4)
+ $$ = $4;
+ else
+ YYERROR;
+ }
+ ;
+
pseudo:
':' IDENT {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoClass);
- $2.lower();
- $$->setValue($2);
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type == CSSSelector::PseudoUnknown)
- $$ = 0;
+ $$ = CSSParserSelector::parsePseudoClassAndCompatibilityElementSelector($2);
}
| ':' ':' IDENT {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoElement);
- $3.lower();
- $$->setValue($3);
- // FIXME: This call is needed to force selector to compute the pseudoType early enough.
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type == CSSSelector::PseudoUnknown)
- $$ = 0;
+ $$ = CSSParserSelector::parsePseudoElementSelector($3);
}
#if ENABLE_VIDEO_TRACK
// used by ::cue(:past/:future)
| ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space ')' {
- if ($5) {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoClass);
- $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($5));
- $$->setValue($3);
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type != CSSSelector::PseudoCue)
- $$ = 0;
- } else
- $$ = 0;
+ $$ = CSSParserSelector::parsePseudoElementCueFunctionSelector($3, $5);
}
#endif
// use by :-webkit-any.
@@ -1454,93 +1363,170 @@ pseudo:
// 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 ')' {
+ $$ = nullptr;
if ($4) {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoClass);
- $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
- $2.lower();
- $$->setValue($2);
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type != CSSSelector::PseudoAny)
- $$ = 0;
- } else
- $$ = 0;
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->adoptSelectorVector(*std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>>($4));
+ selector->setPseudoClassValue($2);
+ if (selector->pseudoClassType() == CSSSelector::PseudoClassAny)
+ $$ = selector.release();
+ }
+ }
+ | ':' MATCHESFUNCTION maybe_space nested_selector_list maybe_space ')' {
+ $$ = nullptr;
+ if ($4) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->adoptSelectorVector(*std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>>($4));
+ selector->setPseudoClassValue($2);
+ if (selector->pseudoClassType() == CSSSelector::PseudoClassMatches)
+ $$ = selector.release();
+ }
+ }
+ | ':' LANGFUNCTION maybe_space comma_separated_lang_ranges maybe_space ')' {
+ $$ = nullptr;
+ if ($4) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setLangArgumentList(*std::unique_ptr<Vector<CSSParserString>>($4));
+ selector->setPseudoClassValue($2);
+ if (selector->pseudoClassType() == CSSSelector::PseudoClassLang)
+ $$ = selector.release();
+ }
+ }
+
+#if ENABLE_CSS_SELECTORS_LEVEL4
+ | ':' DIRFUNCTION maybe_space IDENT maybe_space ')' {
+ $$ = nullptr;
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument($4);
+ selector->setPseudoClassValue($2);
+ if (selector->pseudoClassType() == CSSSelector::PseudoClassDir)
+ $$ = selector.release();
}
+
+ | ':' ROLEFUNCTION maybe_space IDENT maybe_space ')' {
+ $$ = nullptr;
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument($4);
+ selector->setPseudoClassValue($2);
+ if (selector->pseudoClassType() == CSSSelector::PseudoClassRole)
+ $$ = selector.release();
+ }
+#endif
+
+ // Definition of :nth-child().
+ | ':' NTHCHILDFUNCTIONS maybe_space NTH nth_selector_ending {
+ $$ = nullptr;
+ 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;
+ 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;
+ 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();
+ }
+ }
+
// used by :nth-*(ax+b)
| ':' FUNCTION maybe_space NTH maybe_space ')' {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoClass);
- $$->setArgument($4);
- $$->setValue($2);
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type == CSSSelector::PseudoUnknown)
- $$ = 0;
+ $$ = nullptr;
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument($4);
+ selector->setPseudoClassValue($2);
+ if (selector->pseudoClassType() != CSSSelector::PseudoClassUnknown)
+ $$ = selector.release();
}
// used by :nth-*
| ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space ')' {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoClass);
- $$->setArgument(String::number($4 * $5));
- $$->setValue($2);
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type == CSSSelector::PseudoUnknown)
- $$ = 0;
+ $$ = nullptr;
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument(AtomicString::number($4 * $5));
+ selector->setPseudoClassValue($2);
+ if (selector->pseudoClassType() != CSSSelector::PseudoClassUnknown)
+ $$ = selector.release();
}
// used by :nth-*(odd/even) and :lang
| ':' FUNCTION maybe_space IDENT maybe_space ')' {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoClass);
- $$->setArgument($4);
- $2.lower();
- $$->setValue($2);
- CSSSelector::PseudoType type = $$->pseudoType();
- if (type == CSSSelector::PseudoUnknown)
- $$ = 0;
- else if (type == CSSSelector::PseudoNthChild ||
- type == CSSSelector::PseudoNthOfType ||
- type == CSSSelector::PseudoNthLastChild ||
- type == CSSSelector::PseudoNthLastOfType) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setArgument($4);
+ selector->setPseudoClassValue($2);
+ CSSSelector::PseudoClassType type = selector->pseudoClassType();
+ if (type == CSSSelector::PseudoClassUnknown)
+ selector = nullptr;
+ else if (type == CSSSelector::PseudoClassNthChild ||
+ type == CSSSelector::PseudoClassNthOfType ||
+ type == CSSSelector::PseudoClassNthLastChild ||
+ type == CSSSelector::PseudoClassNthLastOfType) {
if (!isValidNthToken($4))
- $$ = 0;
+ selector = nullptr;
}
+ $$ = selector.release();
}
- // used by :not
- | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
- if (!$4 || !$4->isSimple())
- $$ = 0;
- else {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoClass);
-
- Vector<OwnPtr<CSSParserSelector> > selectorVector;
- selectorVector.append(parser->sinkFloatingSelector($4));
- $$->adoptSelectorVector(selectorVector);
-
- $2.lower();
- $$->setValue($2);
+ // Definition of :not().
+ | ':' NOTFUNCTION maybe_space nested_selector_list maybe_space ')' {
+ $$ = nullptr;
+ if ($4) {
+ std::unique_ptr<Vector<std::unique_ptr<CSSParserSelector>>> list($4);
+ if (selectorListDoesNotMatchAnyPseudoElement(list.get())) {
+ auto selector = std::make_unique<CSSParserSelector>();
+ selector->setMatch(CSSSelector::PseudoClass);
+ selector->setPseudoClassValue($2);
+ selector->adoptSelectorVector(*list);
+ if (selector->pseudoClassType() == CSSSelector::PseudoClassNot)
+ $$ = selector.release();
+ }
}
}
;
declaration_list:
/* empty */ { $$ = false; }
- | declaration {
- $$ = $1;
- }
- | decl_list declaration {
- $$ = $1;
- if ( $2 )
- $$ = $2;
- }
- | decl_list {
- $$ = $1;
- }
- | decl_list_recovery {
- $$ = false;
- }
- | decl_list decl_list_recovery {
- $$ = $1;
- }
+ | declaration
+ | decl_list declaration { $$ = $1 || $2; }
+ | decl_list
+ | decl_list_recovery { $$ = false; }
+ | decl_list decl_list_recovery
;
decl_list:
@@ -1571,23 +1557,15 @@ decl_list_recovery:
;
declaration:
- VAR_DEFINITION maybe_space ':' maybe_space expr prio {
-#if ENABLE_CSS_VARIABLES
- parser->storeVariableDeclaration($1, parser->sinkFloatingValueList($5), $6);
- $$ = true;
- parser->markPropertyEnd($6, true);
-#else
- $$ = false;
-#endif
- }
- |
- property ':' maybe_space expr prio {
+ CUSTOM_PROPERTY maybe_space ':' whitespace_or_expr priority {
$$ = false;
bool isPropertyParsed = false;
- if ($1 && $4) {
- parser->m_valueList = parser->sinkFloatingValueList($4);
+ std::unique_ptr<CSSParserValueList> propertyValue($4);
+ if (propertyValue) {
+ parser->m_valueList = WTFMove(propertyValue);
int oldParsedProperties = parser->m_parsedProperties.size();
- $$ = parser->parseValue(static_cast<CSSPropertyID>($1), $5);
+ parser->setCustomPropertyName($1);
+ $$ = parser->parseValue(CSSPropertyCustom, $5);
if (!$$)
parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
else
@@ -1596,59 +1574,105 @@ declaration:
}
parser->markPropertyEnd($5, isPropertyParsed);
}
- |
- property declaration_recovery {
+ | property ':' maybe_space expr priority {
$$ = false;
+ bool isPropertyParsed = false;
+ std::unique_ptr<CSSParserValueList> propertyValue($4);
+ if ($1 && propertyValue) {
+ parser->m_valueList = WTFMove(propertyValue);
+ int oldParsedProperties = parser->m_parsedProperties.size();
+ $$ = parser->parseValue($1, $5);
+ if (!$$)
+ parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
+ else
+ isPropertyParsed = true;
+ parser->m_valueList = nullptr;
+ }
+ parser->markPropertyEnd($5, isPropertyParsed);
}
- |
- property ':' maybe_space expr prio declaration_recovery {
- /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
+ | property declaration_recovery { $$ = false; }
+ | property ':' maybe_space expr priority declaration_recovery {
+ // When we encounter something like p {color: red !important fail;} we should drop the declaration.
parser->markPropertyEnd(false, false);
+ delete $4;
$$ = false;
}
- |
- IMPORTANT_SYM maybe_space declaration_recovery {
- /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
+ | IMPORTANT_SYM maybe_space declaration_recovery {
+ // Handle this case -- div { text-align: center; !important } -- by just reducing away the stray !important.
$$ = false;
}
- |
- property ':' maybe_space declaration_recovery {
- /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
+ | property ':' maybe_space declaration_recovery {
+ // If we come across rules with invalid values like this case: p { weight: *; }, just discard the rule.
parser->markPropertyEnd(false, false);
$$ = false;
}
;
-declaration_recovery:
- error error_location error_recovery {
- parser->syntaxError($2);
- }
- ;
+declaration_recovery: error error_location error_recovery { parser->syntaxError($2); } ;
+
+property: IDENT maybe_space { $$ = cssPropertyID($1); } ;
+
+priority: IMPORTANT_SYM maybe_space { $$ = true; } | /* empty */ { $$ = false; } ;
-property:
+#if ENABLE_CSS_GRID_LAYOUT
+
+ident_list:
IDENT maybe_space {
- $$ = cssPropertyID($1);
+ $$ = new CSSParserValueList;
+ $$->addValue(makeIdentValue($1));
}
- ;
+ | ident_list IDENT maybe_space {
+ $$ = $1;
+ $$->addValue(makeIdentValue($2));
+ }
+ ;
-prio:
- IMPORTANT_SYM maybe_space { $$ = true; }
- | /* empty */ { $$ = false; }
+track_names_list:
+ '[' maybe_space closing_bracket {
+ $$.setFromValueList(std::make_unique<CSSParserValueList>());
+ }
+ | '[' maybe_space ident_list closing_bracket {
+ $$.setFromValueList(std::unique_ptr<CSSParserValueList>($3));
+ }
+ | '[' maybe_space expr_recovery closing_bracket {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
+ YYERROR;
+ }
;
-expr:
- valid_expr
- | valid_expr expr_recovery { $$ = 0; }
- ;
+#endif
+
+whitespace_or_expr:
+ WHITESPACE maybe_expr {
+ if ($2)
+ $$ = $2;
+ else {
+ CSSParserValue val;
+ val.id = CSSValueInvalid;
+ val.unit = CSSPrimitiveValue::CSS_PARSER_WHITESPACE;
+ val.string.init(emptyString());
+ $$ = new CSSParserValueList;
+ $$->addValue(val);
+ }
+ }
+ | maybe_space expr { $$ = $2; }
+ ;
+
+maybe_expr: /* empty */ { $$ = nullptr; } | expr { $$ = $1; };
+
+expr: valid_expr | valid_expr expr_recovery { $$ = nullptr; delete $1; } ;
valid_expr:
term {
- $$ = parser->createFloatingValueList();
- $$->addValue(parser->sinkFloatingValue($1));
+ $$ = new CSSParserValueList;
+ $$->addValue($1);
}
| valid_expr operator term {
$$ = $1;
- if ($$) {
+ if (!$$)
+ destroy($3);
+ else {
if ($2) {
CSSParserValue v;
v.id = CSSValueInvalid;
@@ -1656,36 +1680,20 @@ valid_expr:
v.iValue = $2;
$$->addValue(v);
}
- $$->addValue(parser->sinkFloatingValue($3));
+ $$->addValue($3);
}
}
;
-expr_recovery:
- error error_location error_recovery
- ;
+expr_recovery: error error_location error_recovery ;
-operator:
- '/' maybe_space {
- $$ = '/';
- }
- | ',' maybe_space {
- $$ = ',';
- }
- | /* empty */ {
- $$ = 0;
- }
- ;
+operator: '/' maybe_space { $$ = '/'; } | ',' maybe_space { $$ = ','; } | /* empty */ { $$ = 0; } ;
term:
- unary_term maybe_space { $$ = $1; }
+ unary_term maybe_space
| unary_operator unary_term maybe_space { $$ = $2; $$.fValue *= $1; }
| STRING maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
- | IDENT maybe_space {
- $$.id = cssValueKeywordID($1);
- $$.unit = CSSPrimitiveValue::CSS_IDENT;
- $$.string = $1;
- }
+ | IDENT maybe_space { $$ = makeIdentValue($1); }
/* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
| DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
| unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
@@ -1693,26 +1701,17 @@ term:
| UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
| HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
| '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
- | VARFUNCTION maybe_space IDENT closing_parenthesis maybe_space {
-#if ENABLE_CSS_VARIABLES
- $$.id = CSSValueInvalid;
- $$.string = $3;
- $$.unit = CSSPrimitiveValue::CSS_VARIABLE_NAME;
-#endif
- }
/* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
- | function maybe_space {
- $$ = $1;
- }
- | calc_function maybe_space {
- $$ = $1;
- }
- | min_or_max_function maybe_space {
- $$ = $1;
- }
+ | function maybe_space
+ | calc_function maybe_space
+ | variable_function maybe_space
+ | min_or_max_function maybe_space
| '%' maybe_space { /* Handle width: %; */
$$.id = CSSValueInvalid; $$.unit = 0;
}
+#if ENABLE_CSS_GRID_LAYOUT
+ | track_names_list maybe_space
+#endif
;
unary_term:
@@ -1741,7 +1740,7 @@ unary_term:
$$.fValue = $1;
$$.unit = CSSPrimitiveValue::CSS_REMS;
if (parser->m_styleSheet)
- parser->m_styleSheet->parserSetUsesRemUnits(true);
+ parser->m_styleSheet->parserSetUsesRemUnits();
}
| CHS { $$.id = CSSValueInvalid; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CHS; }
| VW { $$.id = CSSValueInvalid; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_VW; }
@@ -1751,28 +1750,28 @@ unary_term:
| DPPX { $$.id = CSSValueInvalid; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DPPX; }
| DPI { $$.id = CSSValueInvalid; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DPI; }
| DPCM { $$.id = CSSValueInvalid; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DPCM; }
+ | FR { $$.id = CSSValueInvalid; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_FR; }
;
function:
FUNCTION maybe_space expr closing_parenthesis {
- CSSParserFunction* f = parser->createFloatingFunction();
+ CSSParserFunction* f = new CSSParserFunction;
f->name = $1;
- f->args = parser->sinkFloatingValueList($3);
+ f->args = std::unique_ptr<CSSParserValueList>($3);
$$.id = CSSValueInvalid;
$$.unit = CSSParserValue::Function;
$$.function = f;
} |
FUNCTION maybe_space closing_parenthesis {
- CSSParserFunction* f = parser->createFloatingFunction();
+ CSSParserFunction* f = new CSSParserFunction;
f->name = $1;
- CSSParserValueList* valueList = parser->createFloatingValueList();
- f->args = parser->sinkFloatingValueList(valueList);
+ f->args = std::unique_ptr<CSSParserValueList>(new CSSParserValueList);
$$.id = CSSValueInvalid;
$$.unit = CSSParserValue::Function;
$$.function = f;
} |
FUNCTION maybe_space expr_recovery closing_parenthesis {
- CSSParserFunction* f = parser->createFloatingFunction();
+ CSSParserFunction* f = new CSSParserFunction;
f->name = $1;
f->args = nullptr;
$$.id = CSSValueInvalid;
@@ -1781,23 +1780,79 @@ function:
}
;
+variable_function:
+ VARFUNCTION maybe_space CUSTOM_PROPERTY maybe_space closing_parenthesis {
+ CSSParserVariable* var = new CSSParserVariable;
+ var->name = $3;
+ var->args = nullptr;
+ $$.id = CSSValueInvalid;
+ $$.unit = CSSParserValue::Variable;
+ $$.variable = var;
+ }
+ | VARFUNCTION maybe_space CUSTOM_PROPERTY maybe_space ',' maybe_space expr closing_parenthesis {
+ CSSParserVariable* var = new CSSParserVariable;
+ var->name = $3;
+ var->args = std::unique_ptr<CSSParserValueList>($7);
+ $$.id = CSSValueInvalid;
+ $$.unit = CSSParserValue::Variable;
+ $$.variable = var;
+ }
+ | VARFUNCTION maybe_space CUSTOM_PROPERTY maybe_space ',' maybe_space closing_parenthesis {
+ CSSParserVariable* var = new CSSParserVariable;
+ var->name = $3;
+ var->args = std::unique_ptr<CSSParserValueList>(new CSSParserValueList());
+ $$.id = CSSValueInvalid;
+ $$.unit = CSSParserValue::Variable;
+ $$.variable = var;
+ }
+ // Error handling cases
+ | VARFUNCTION maybe_space CUSTOM_PROPERTY maybe_space ',' closing_parenthesis {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
+ YYERROR;
+ }
+ | VARFUNCTION maybe_space CUSTOM_PROPERTY maybe_space ',' maybe_space invalid_var_fallback maybe_space closing_parenthesis {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
+ YYERROR;
+ }
+ | VARFUNCTION maybe_space CUSTOM_PROPERTY maybe_space ',' maybe_space priority closing_parenthesis {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
+ YYERROR;
+ }
+ | VARFUNCTION maybe_space expr closing_parenthesis {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
+ delete $3;
+ YYERROR;
+ }
+ | VARFUNCTION maybe_space expr_recovery closing_parenthesis {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
+ YYERROR;
+ }
+ ;
+
+invalid_var_fallback:
+ '!' | ';';
+
calc_func_term:
- unary_term { $$ = $1; }
- | VARFUNCTION maybe_space IDENT closing_parenthesis {
-#if ENABLE_CSS_VARIABLES
- $$.id = CSSValueInvalid;
- $$.string = $3;
- $$.unit = CSSPrimitiveValue::CSS_VARIABLE_NAME;
-#endif
- }
+ unary_term
+ | variable_function { $$ = $1; }
| unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
;
+/*
+ * The grammar requires spaces around binary ‘+’ and ‘-’ operators.
+ * The '*' and '/' operators do not require spaces.
+ * http://www.w3.org/TR/css3-values/#calc-syntax
+ */
calc_func_operator:
- WHITESPACE '+' WHITESPACE {
+ space '+' space {
$$ = '+';
}
- | WHITESPACE '-' WHITESPACE {
+ | space '-' space {
$$ = '-';
}
| calc_maybe_space '*' maybe_space {
@@ -1808,13 +1863,11 @@ calc_func_operator:
}
;
-calc_maybe_space:
- /* empty */
- | WHITESPACE
- ;
+calc_maybe_space: /* empty */ | WHITESPACE ;
calc_func_paren_expr:
'(' maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
+ $$ = nullptr;
if ($3) {
$$ = $3;
CSSParserValue v;
@@ -1824,168 +1877,128 @@ calc_func_paren_expr:
$$->insertValueAt(0, v);
v.iValue = ')';
$$->addValue(v);
- } else
- $$ = 0;
+ }
}
;
-calc_func_expr:
- valid_calc_func_expr
- | valid_calc_func_expr expr_recovery { $$ = 0; }
- ;
+calc_func_expr: valid_calc_func_expr | valid_calc_func_expr expr_recovery { $$ = nullptr; delete $1; } ;
valid_calc_func_expr:
calc_func_term {
- $$ = parser->createFloatingValueList();
- $$->addValue(parser->sinkFloatingValue($1));
+ $$ = new CSSParserValueList;
+ $$->addValue($1);
}
| calc_func_expr calc_func_operator calc_func_term {
- if ($1 && $2) {
- $$ = $1;
+ std::unique_ptr<CSSParserValueList> expression($1);
+ $$ = nullptr;
+ if (expression && $2) {
+ $$ = expression.release();
CSSParserValue v;
v.id = CSSValueInvalid;
v.unit = CSSParserValue::Operator;
v.iValue = $2;
$$->addValue(v);
- $$->addValue(parser->sinkFloatingValue($3));
- } else
- $$ = 0;
+ $$->addValue($3);
+ } else {
+ destroy($3);
+ }
}
| calc_func_expr calc_func_operator calc_func_paren_expr {
- if ($1 && $2 && $3) {
- $$ = $1;
+ std::unique_ptr<CSSParserValueList> left($1);
+ std::unique_ptr<CSSParserValueList> right($3);
+ $$ = nullptr;
+ if (left && $2 && right) {
CSSParserValue v;
v.id = CSSValueInvalid;
v.unit = CSSParserValue::Operator;
v.iValue = $2;
- $$->addValue(v);
- $$->extend(*($3));
- } else
- $$ = 0;
+ left->addValue(v);
+ left->extend(*right);
+ $$ = left.release();
+ }
}
| calc_func_paren_expr
;
calc_func_expr_list:
- calc_func_expr calc_maybe_space {
- $$ = $1;
- }
+ calc_func_expr calc_maybe_space
| calc_func_expr_list ',' maybe_space calc_func_expr calc_maybe_space {
- if ($1 && $4) {
- $$ = $1;
+ std::unique_ptr<CSSParserValueList> list($1);
+ std::unique_ptr<CSSParserValueList> expression($4);
+ $$ = nullptr;
+ if (list && expression) {
+ $$ = list.release();
CSSParserValue v;
v.id = CSSValueInvalid;
v.unit = CSSParserValue::Operator;
v.iValue = ',';
$$->addValue(v);
- $$->extend(*($4));
- } else
- $$ = 0;
+ $$->extend(*expression);
+ }
}
;
calc_function:
CALCFUNCTION maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
- CSSParserFunction* f = parser->createFloatingFunction();
+ CSSParserFunction* f = new CSSParserFunction;
f->name = $1;
- f->args = parser->sinkFloatingValueList($3);
+ f->args = std::unique_ptr<CSSParserValueList>($3);
$$.id = CSSValueInvalid;
$$.unit = CSSParserValue::Function;
$$.function = f;
}
| CALCFUNCTION maybe_space expr_recovery closing_parenthesis {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
YYERROR;
}
;
-min_or_max:
- MINFUNCTION {
- $$ = $1;
- }
- | MAXFUNCTION {
- $$ = $1;
- }
- ;
+min_or_max: MINFUNCTION | MAXFUNCTION ;
min_or_max_function:
min_or_max maybe_space calc_func_expr_list closing_parenthesis {
- CSSParserFunction* f = parser->createFloatingFunction();
+ CSSParserFunction* f = new CSSParserFunction;
f->name = $1;
- f->args = parser->sinkFloatingValueList($3);
+ f->args = std::unique_ptr<CSSParserValueList>($3);
$$.id = CSSValueInvalid;
$$.unit = CSSParserValue::Function;
$$.function = f;
- }
+ }
| min_or_max maybe_space expr_recovery closing_parenthesis {
+ $$.id = CSSValueInvalid;
+ $$.unit = 0;
YYERROR;
}
;
/* error handling rules */
-save_block:
- closing_brace {
- $$ = 0;
- }
- | error closing_brace {
- $$ = 0;
- }
- ;
-
-invalid_at:
- ATKEYWORD error invalid_block {
- $$ = 0;
- }
- | ATKEYWORD error ';' {
- $$ = 0;
- }
- ;
-
-invalid_rule:
- error invalid_block {
- $$ = 0;
- }
+save_block: closing_brace | error closing_brace ;
-/*
- Seems like the two rules below are trying too much and violating
- http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
+invalid_at: ATKEYWORD error invalid_block | ATKEYWORD error ';' ;
- | error ';' {
- $$ = 0;
- }
- | error '}' {
- $$ = 0;
- }
-*/
- ;
+invalid_rule: error invalid_block ;
-invalid_block:
- '{' error_recovery closing_brace {
- parser->invalidBlockHit();
- }
- ;
+invalid_block: '{' error_recovery closing_brace { parser->invalidBlockHit(); } ;
-invalid_square_brackets_block:
- '[' error_recovery ']'
- | '[' error_recovery TOKEN_EOF
- ;
+invalid_square_brackets_block: '[' error_recovery closing_bracket ;
-invalid_parentheses_block:
- opening_parenthesis error_recovery closing_parenthesis;
+invalid_parentheses_block: opening_parenthesis error_recovery closing_parenthesis;
opening_parenthesis:
- '(' | FUNCTION | CALCFUNCTION | VARFUNCTION | MINFUNCTION | MAXFUNCTION | ANYFUNCTION | NOTFUNCTION
+ '(' | FUNCTION | VARFUNCTION | CALCFUNCTION | MATCHESFUNCTION | MAXFUNCTION | MINFUNCTION | ANYFUNCTION | NOTFUNCTION | LANGFUNCTION
+#if ENABLE_CSS_SELECTORS_LEVEL4
+ | DIRFUNCTION | ROLEFUNCTION
+#endif
#if ENABLE_VIDEO_TRACK
| CUEFUNCTION
#endif
;
-error_location: {
- $$ = parser->currentLocation();
- }
- ;
+error_location: { $$ = parser->currentLocation(); } ;
error_recovery:
/* empty */
@@ -1996,4 +2009,3 @@ error_recovery:
;
%%
-