Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / parser / CSSGrammar.y
1 %{
2
3 /*
4  *  Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
5  *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
6  *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7  *  Copyright (C) 2008 Eric Seidel <eric@webkit.org>
8  *  Copyright (C) 2012 Intel Corporation. All rights reserved.
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25
26 #include "config.h"
27
28 #include "CSSPropertyNames.h"
29 #include "HTMLNames.h"
30 #include "core/css/CSSKeyframeRule.h"
31 #include "core/css/CSSKeyframesRule.h"
32 #include "core/css/parser/BisonCSSParser.h"
33 #include "core/css/parser/CSSParserMode.h"
34 #include "core/css/CSSPrimitiveValue.h"
35 #include "core/css/CSSSelector.h"
36 #include "core/css/CSSSelectorList.h"
37 #include "core/css/MediaList.h"
38 #include "core/css/MediaQueryExp.h"
39 #include "core/css/StyleRule.h"
40 #include "core/css/StyleSheetContents.h"
41 #include "core/dom/Document.h"
42 #include "core/frame/UseCounter.h"
43 #include "wtf/FastMalloc.h"
44 #include <stdlib.h>
45 #include <string.h>
46
47 using namespace blink;
48 using namespace HTMLNames;
49
50 #define YYMALLOC fastMalloc
51 #define YYFREE fastFree
52
53 #define YYENABLE_NLS 0
54 #define YYLTYPE_IS_TRIVIAL 1
55 #define YYMAXDEPTH 10000
56 #define YYDEBUG 0
57
58 #if YYDEBUG > 0
59 #define YYPRINT(File,Type,Value) if (isCSSTokenAString(Type)) YYFPRINTF(File, "%s", String((Value).string).utf8().data())
60 #endif
61
62 %}
63
64 %pure-parser
65
66 %parse-param { BisonCSSParser* parser }
67 %lex-param { BisonCSSParser* parser }
68
69 %union {
70     bool boolean;
71     char character;
72     int integer;
73     double number;
74     CSSParserString string;
75
76     StyleRuleBase* rule;
77     // The content of the three below HeapVectors are guaranteed to be kept alive by
78     // the corresponding m_parsedRules, m_floatingMediaQueryExpList, and m_parsedKeyFrames
79     // lists in BisonCSSParser.h.
80     WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >* ruleList;
81     WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* mediaQueryExpList;
82     WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* keyframeRuleList;
83     CSSParserSelector* selector;
84     Vector<OwnPtr<CSSParserSelector> >* selectorList;
85     CSSSelector::MarginBoxType marginBox;
86     CSSSelector::Relation relation;
87     CSSSelector::AttributeMatchType attributeMatchType;
88     MediaQuerySet* mediaList;
89     MediaQuery* mediaQuery;
90     MediaQuery::Restrictor mediaQueryRestrictor;
91     MediaQueryExp* mediaQueryExp;
92     CSSParserValue value;
93     CSSParserValueList* valueList;
94     StyleKeyframe* keyframe;
95     float val;
96     CSSPropertyID id;
97     CSSParserLocation location;
98 }
99
100 %{
101
102 static inline int cssyyerror(void*, const char*)
103 {
104     return 1;
105 }
106
107 #if YYDEBUG > 0
108 static inline bool isCSSTokenAString(int yytype)
109 {
110     switch (yytype) {
111     case IDENT:
112     case STRING:
113     case NTH:
114     case HEX:
115     case IDSEL:
116     case DIMEN:
117     case INVALIDDIMEN:
118     case URI:
119     case FUNCTION:
120     case ANYFUNCTION:
121     case HOSTFUNCTION:
122     case HOSTCONTEXTFUNCTION:
123     case NOTFUNCTION:
124     case CALCFUNCTION:
125     case UNICODERANGE:
126         return true;
127     default:
128         return false;
129     }
130 }
131 #endif
132
133 inline static CSSParserValue makeOperatorValue(int value)
134 {
135     CSSParserValue v;
136     v.id = CSSValueInvalid;
137     v.isInt = false;
138     v.unit = CSSParserValue::Operator;
139     v.iValue = value;
140     return v;
141 }
142
143 inline static CSSParserValue makeIdentValue(CSSParserString string)
144 {
145     CSSParserValue v;
146     v.id = cssValueKeywordID(string);
147     v.isInt = false;
148     v.unit = CSSPrimitiveValue::CSS_IDENT;
149     v.string = string;
150     return v;
151 }
152
153 %}
154
155 %expect 0
156
157 %nonassoc LOWEST_PREC
158
159 %left UNIMPORTANT_TOK
160
161 %token WHITESPACE SGML_CD
162 %token TOKEN_EOF 0
163
164 %token INCLUDES
165 %token DASHMATCH
166 %token BEGINSWITH
167 %token ENDSWITH
168 %token CONTAINS
169
170 %token <string> STRING
171 %right <string> IDENT
172 %token <string> NTH
173
174 %nonassoc <string> HEX
175 %nonassoc <string> IDSEL
176 %nonassoc ':'
177 %nonassoc '.'
178 %nonassoc '['
179 %nonassoc <string> '*'
180 %nonassoc error
181 %left '|'
182
183 %token IMPORT_SYM
184 %token PAGE_SYM
185 %token MEDIA_SYM
186 %token SUPPORTS_SYM
187 %token FONT_FACE_SYM
188 %token CHARSET_SYM
189 %token NAMESPACE_SYM
190 %token VIEWPORT_RULE_SYM
191 %token INTERNAL_DECLS_SYM
192 %token INTERNAL_RULE_SYM
193 %token INTERNAL_SELECTOR_SYM
194 %token INTERNAL_VALUE_SYM
195 %token INTERNAL_KEYFRAME_RULE_SYM
196 %token INTERNAL_KEYFRAME_KEY_LIST_SYM
197 %token INTERNAL_SUPPORTS_CONDITION_SYM
198 %token KEYFRAMES_SYM
199 %token WEBKIT_KEYFRAMES_SYM
200 %token <marginBox> TOPLEFTCORNER_SYM
201 %token <marginBox> TOPLEFT_SYM
202 %token <marginBox> TOPCENTER_SYM
203 %token <marginBox> TOPRIGHT_SYM
204 %token <marginBox> TOPRIGHTCORNER_SYM
205 %token <marginBox> BOTTOMLEFTCORNER_SYM
206 %token <marginBox> BOTTOMLEFT_SYM
207 %token <marginBox> BOTTOMCENTER_SYM
208 %token <marginBox> BOTTOMRIGHT_SYM
209 %token <marginBox> BOTTOMRIGHTCORNER_SYM
210 %token <marginBox> LEFTTOP_SYM
211 %token <marginBox> LEFTMIDDLE_SYM
212 %token <marginBox> LEFTBOTTOM_SYM
213 %token <marginBox> RIGHTTOP_SYM
214 %token <marginBox> RIGHTMIDDLE_SYM
215 %token <marginBox> RIGHTBOTTOM_SYM
216
217 %token ATKEYWORD
218
219 %token IMPORTANT_SYM
220 %token MEDIA_ONLY
221 %token MEDIA_NOT
222 %token MEDIA_AND
223 %token MEDIA_OR
224
225 %token SUPPORTS_NOT
226 %token SUPPORTS_AND
227 %token SUPPORTS_OR
228
229 %token <number> REMS
230 %token <number> CHS
231 %token <number> QEMS
232 %token <number> EMS
233 %token <number> EXS
234 %token <number> PXS
235 %token <number> CMS
236 %token <number> MMS
237 %token <number> INS
238 %token <number> PTS
239 %token <number> PCS
240 %token <number> DEGS
241 %token <number> RADS
242 %token <number> GRADS
243 %token <number> TURNS
244 %token <number> MSECS
245 %token <number> SECS
246 %token <number> HERTZ
247 %token <number> KHERTZ
248 %token <string> DIMEN
249 %token <string> INVALIDDIMEN
250 %token <number> PERCENTAGE
251 %token <number> FLOATTOKEN
252 %token <number> INTEGER
253 %token <number> VW
254 %token <number> VH
255 %token <number> VMIN
256 %token <number> VMAX
257 %token <number> DPPX
258 %token <number> DPI
259 %token <number> DPCM
260 %token <number> FR
261
262 %token <string> URI
263 %token <string> FUNCTION
264 %token <string> ANYFUNCTION
265 %token <string> CUEFUNCTION
266 %token <string> NOTFUNCTION
267 %token <string> DISTRIBUTEDFUNCTION
268 %token <string> CALCFUNCTION
269 %token <string> HOSTFUNCTION
270 %token <string> HOSTCONTEXTFUNCTION
271
272 %token <string> UNICODERANGE
273
274 %type <relation> combinator
275
276 %type <rule> ruleset
277 %type <rule> media
278 %type <rule> import
279 %type <rule> namespace
280 %type <rule> page
281 %type <rule> margin_box
282 %type <rule> font_face
283 %type <rule> keyframes
284 %type <rule> rule
285 %type <rule> valid_rule
286 %type <ruleList> block_rule_body
287 %type <ruleList> block_rule_list
288 %type <rule> block_rule
289 %type <rule> block_valid_rule
290 %type <rule> supports
291 %type <rule> viewport
292 %type <boolean> keyframes_rule_start
293
294 %type <string> maybe_ns_prefix
295
296 %type <string> namespace_selector
297
298 %type <string> string_or_uri
299 %type <string> ident_or_string
300 %type <string> medium
301 %type <marginBox> margin_sym
302
303 %type <mediaList> media_list
304 %type <mediaList> maybe_media_list
305 %type <mediaList> mq_list
306 %type <mediaQuery> media_query
307 %type <mediaQuery> valid_media_query
308 %type <mediaQueryRestrictor> maybe_media_restrictor
309 %type <valueList> maybe_media_value
310 %type <mediaQueryExp> media_query_exp
311 %type <mediaQueryExpList> media_query_exp_list
312 %type <mediaQueryExpList> maybe_and_media_query_exp_list
313
314 %type <boolean> supports_condition
315 %type <boolean> supports_condition_in_parens
316 %type <boolean> supports_negation
317 %type <boolean> supports_conjunction
318 %type <boolean> supports_disjunction
319 %type <boolean> supports_declaration_condition
320
321 %type <string> keyframe_name
322 %type <keyframe> keyframe_rule
323 %type <keyframeRuleList> keyframes_rule
324 %type <keyframeRuleList> keyframe_rule_list
325 %type <valueList> key_list
326 %type <value> key
327
328 %type <id> property
329
330 %type <selector> specifier
331 %type <selector> specifier_list
332 %type <selector> simple_selector
333 %type <selector> selector
334 %type <selectorList> selector_list
335 %type <selectorList> simple_selector_list
336 %type <selector> class
337 %type <selector> attrib
338 %type <selector> pseudo
339 %type <selector> pseudo_page
340 %type <selector> page_selector
341
342 %type <boolean> declaration_list
343 %type <boolean> decl_list
344 %type <boolean> declaration
345 %type <boolean> declarations_and_margins
346
347 %type <boolean> prio
348
349 %type <integer> match
350 %type <integer> unary_operator
351 %type <integer> maybe_unary_operator
352 %type <character> operator
353
354 %type <valueList> expr
355 %type <value> term
356 %type <value> unary_term
357 %type <value> function
358 %type <value> calc_func_term
359 %type <character> calc_func_operator
360 %type <valueList> calc_func_expr
361 %type <valueList> calc_func_paren_expr
362 %type <value> calc_function
363
364 %type <string> element_name
365 %type <string> attr_name
366
367 %type <attributeMatchType> attr_match_type
368 %type <attributeMatchType> maybe_attr_match_type
369
370 %type <location> error_location
371
372 %type <valueList> ident_list
373 %type <value> track_names_list
374
375 %%
376
377 stylesheet:
378     maybe_charset maybe_sgml rule_list
379   | internal_decls
380   | internal_rule
381   | internal_selector
382   | internal_value
383   | internal_keyframe_rule
384   | internal_keyframe_key_list
385   | internal_supports_condition
386   ;
387
388 internal_rule:
389     INTERNAL_RULE_SYM maybe_space valid_rule maybe_space TOKEN_EOF {
390         parser->m_rule = $3;
391     }
392 ;
393
394 internal_keyframe_rule:
395     INTERNAL_KEYFRAME_RULE_SYM maybe_space keyframe_rule maybe_space TOKEN_EOF {
396         parser->m_keyframe = $3;
397     }
398 ;
399
400 internal_keyframe_key_list:
401     INTERNAL_KEYFRAME_KEY_LIST_SYM maybe_space key_list TOKEN_EOF {
402         parser->m_valueList = parser->sinkFloatingValueList($3);
403     }
404 ;
405
406 internal_decls:
407     INTERNAL_DECLS_SYM maybe_space_before_declaration declaration_list TOKEN_EOF {
408         /* can be empty */
409     }
410 ;
411
412 internal_value:
413     INTERNAL_VALUE_SYM maybe_space expr TOKEN_EOF {
414         parser->m_valueList = parser->sinkFloatingValueList($3);
415         parser->parseValue(parser->m_id, parser->m_important);
416         parser->m_valueList = nullptr;
417     }
418 ;
419
420 internal_selector:
421     INTERNAL_SELECTOR_SYM maybe_space selector_list TOKEN_EOF {
422         if (parser->m_selectorListForParseSelector)
423             parser->m_selectorListForParseSelector->adoptSelectorVector(*$3);
424     }
425 ;
426
427 internal_supports_condition:
428     INTERNAL_SUPPORTS_CONDITION_SYM maybe_space supports_condition TOKEN_EOF {
429         parser->m_supportsCondition = $3;
430     }
431 ;
432
433 space:
434     WHITESPACE
435   | space WHITESPACE
436   ;
437
438 maybe_space:
439     /* empty */ %prec UNIMPORTANT_TOK
440   | space
441   ;
442
443 maybe_sgml:
444     /* empty */
445   | maybe_sgml SGML_CD
446   | maybe_sgml WHITESPACE
447   ;
448
449 closing_brace:
450     '}'
451   | %prec LOWEST_PREC TOKEN_EOF
452   ;
453
454 closing_parenthesis:
455     ')'
456   | %prec LOWEST_PREC TOKEN_EOF
457   ;
458
459 closing_square_bracket:
460     ']'
461   | %prec LOWEST_PREC TOKEN_EOF
462   ;
463
464 semi_or_eof:
465     ';'
466   | TOKEN_EOF
467   ;
468
469 before_charset_rule:
470   /* empty */ {
471       parser->startRule();
472       parser->startRuleHeader(CSSRuleSourceData::CHARSET_RULE);
473   }
474
475 maybe_charset:
476     /* empty */
477   | before_charset_rule CHARSET_SYM maybe_space STRING maybe_space semi_or_eof {
478        if (parser->m_styleSheet)
479            parser->m_styleSheet->parserSetEncodingFromCharsetRule($4);
480        parser->endRuleHeader();
481        parser->startRuleBody();
482        parser->endRule(true);
483     }
484   | before_charset_rule CHARSET_SYM at_rule_recovery {
485        parser->endRule(false);
486   }
487   ;
488
489 rule_list:
490    /* empty */
491  | rule_list rule maybe_sgml {
492      if ($2 && parser->m_styleSheet)
493          parser->m_styleSheet->parserAppendRule($2);
494  }
495  ;
496
497 valid_rule:
498     ruleset
499   | media
500   | page
501   | font_face
502   | keyframes
503   | namespace
504   | import
505   | supports
506   | viewport
507   ;
508
509 before_rule:
510     /* empty */ {
511         parser->startRule();
512     }
513   ;
514
515 rule:
516     before_rule valid_rule {
517         $$ = $2;
518         parser->m_hadSyntacticallyValidCSSRule = true;
519         parser->endRule(!!$$);
520     }
521   | before_rule invalid_rule {
522         $$ = 0;
523         parser->endRule(false);
524     }
525   ;
526
527 block_rule_body:
528     block_rule_list
529   | block_rule_list block_rule_recovery
530     ;
531
532 block_rule_list:
533     /* empty */ { $$ = 0; }
534   | block_rule_list block_rule maybe_sgml {
535       $$ = parser->appendRule($1, $2);
536     }
537     ;
538
539 block_rule_recovery:
540     before_rule invalid_rule_header {
541         parser->endRule(false);
542     }
543   ;
544
545 block_valid_rule:
546     ruleset
547   | page
548   | font_face
549   | media
550   | keyframes
551   | supports
552   | viewport
553   | namespace
554   ;
555
556 block_rule:
557     before_rule block_valid_rule {
558         $$ = $2;
559         parser->endRule(!!$$);
560     }
561   | before_rule invalid_rule {
562         $$ = 0;
563         parser->endRule(false);
564     }
565   ;
566
567 before_import_rule:
568     /* empty */ {
569         parser->startRuleHeader(CSSRuleSourceData::IMPORT_RULE);
570     }
571     ;
572
573 import_rule_start:
574     before_import_rule IMPORT_SYM maybe_space {
575         parser->endRuleHeader();
576         parser->startRuleBody();
577     }
578   ;
579
580 import:
581     import_rule_start string_or_uri maybe_space location_label maybe_media_list semi_or_eof {
582         $$ = parser->createImportRule($2, $5);
583     }
584   | import_rule_start string_or_uri maybe_space location_label maybe_media_list invalid_block {
585         $$ = 0;
586     }
587   ;
588
589 namespace:
590     NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space semi_or_eof {
591         parser->addNamespace($3, $4);
592         $$ = 0;
593     }
594   ;
595
596 maybe_ns_prefix:
597 /* empty */ { $$.clear(); }
598 | IDENT maybe_space
599 ;
600
601 string_or_uri:
602 STRING
603 | URI
604 ;
605
606 before_media_value_expr:
607     /* empty */ {
608         parser->startMediaValue();
609     }
610     ;
611
612 maybe_media_value:
613     /*empty*/ {
614         $$ = 0;
615     }
616     | ':' maybe_space before_media_value_expr expr {
617         $$ = $4;
618         parser->endMediaValue();
619     }
620     ;
621
622 media_query_exp:
623     '(' maybe_space IDENT maybe_space maybe_media_value closing_parenthesis {
624         parser->tokenToLowerCase($3);
625         $$ = parser->createFloatingMediaQueryExp($3, $5);
626         if (!$$)
627             YYERROR;
628     }
629     | '(' error error_recovery closing_parenthesis {
630         YYERROR;
631     }
632     ;
633
634 media_query_exp_list:
635     media_query_exp {
636         $$ = parser->createFloatingMediaQueryExpList();
637         $$->append(parser->sinkFloatingMediaQueryExp($1));
638     }
639     | media_query_exp_list maybe_space MEDIA_AND maybe_space media_query_exp {
640         $$ = $1;
641         $$->append(parser->sinkFloatingMediaQueryExp($5));
642     }
643     ;
644
645 maybe_and_media_query_exp_list:
646     maybe_space {
647         $$ = parser->createFloatingMediaQueryExpList();
648     }
649     | maybe_space MEDIA_AND maybe_space media_query_exp_list maybe_space {
650         $$ = $4;
651     }
652     ;
653
654 maybe_media_restrictor:
655     /*empty*/ {
656         $$ = MediaQuery::None;
657     }
658     | MEDIA_ONLY maybe_space {
659         $$ = MediaQuery::Only;
660     }
661     | MEDIA_NOT maybe_space {
662         $$ = MediaQuery::Not;
663     }
664     ;
665
666 before_media_query:
667     /* empty */ {
668         parser->startMediaQuery();
669     }
670     ;
671
672 valid_media_query:
673     before_media_query media_query_exp_list maybe_space {
674         $$ = parser->createFloatingMediaQuery(parser->sinkFloatingMediaQueryExpList($2));
675     }
676     | before_media_query maybe_media_restrictor medium maybe_and_media_query_exp_list {
677         parser->tokenToLowerCase($3);
678         $$ = parser->createFloatingMediaQuery($2, $3, parser->sinkFloatingMediaQueryExpList($4));
679     }
680     ;
681
682 media_query:
683     valid_media_query
684     | valid_media_query error error_location rule_error_recovery {
685         parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
686         $$ = parser->createFloatingNotAllQuery();
687     }
688     | error error_location rule_error_recovery {
689         parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
690         $$ = parser->createFloatingNotAllQuery();
691     }
692     ;
693
694 maybe_media_list:
695     /* empty */ {
696         $$ = parser->createMediaQuerySet();
697     }
698     | media_list
699     ;
700
701 media_list:
702     media_query {
703         $$ = parser->createMediaQuerySet();
704         $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
705     }
706     | mq_list media_query {
707         $$ = $1;
708         $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
709     }
710     | mq_list {
711         $$ = $1;
712         $$->addMediaQuery(parser->sinkFloatingMediaQuery(parser->createFloatingNotAllQuery()));
713     }
714     ;
715
716 mq_list:
717     media_query ',' maybe_space location_label {
718         $$ = parser->createMediaQuerySet();
719         $$->addMediaQuery(parser->sinkFloatingMediaQuery($1));
720     }
721     | mq_list media_query ',' maybe_space location_label {
722         $$ = $1;
723         $$->addMediaQuery(parser->sinkFloatingMediaQuery($2));
724     }
725     ;
726
727 at_rule_body_start:
728     /* empty */ {
729         parser->startRuleBody();
730     }
731     ;
732
733 before_media_rule:
734     /* empty */ {
735         parser->startRuleHeader(CSSRuleSourceData::MEDIA_RULE);
736     }
737     ;
738
739 at_rule_header_end_maybe_space:
740     maybe_space {
741         parser->endRuleHeader();
742     }
743     ;
744
745 media_rule_start:
746     before_media_rule MEDIA_SYM maybe_space;
747
748 media:
749     media_rule_start maybe_media_list '{' at_rule_header_end at_rule_body_start maybe_space block_rule_body closing_brace {
750         $$ = parser->createMediaRule($2, $7);
751     }
752     ;
753
754 medium:
755   IDENT
756   ;
757
758 supports:
759     before_supports_rule SUPPORTS_SYM maybe_space supports_condition at_supports_rule_header_end '{' at_rule_body_start maybe_space block_rule_body closing_brace {
760         $$ = parser->createSupportsRule($4, $9);
761     }
762     ;
763
764 before_supports_rule:
765     /* empty */ {
766         parser->startRuleHeader(CSSRuleSourceData::SUPPORTS_RULE);
767         parser->markSupportsRuleHeaderStart();
768     }
769     ;
770
771 at_supports_rule_header_end:
772     /* empty */ {
773         parser->endRuleHeader();
774         parser->markSupportsRuleHeaderEnd();
775     }
776     ;
777
778 supports_condition:
779     supports_condition_in_parens
780     | supports_negation
781     | supports_conjunction
782     | supports_disjunction
783     ;
784
785 supports_negation:
786     SUPPORTS_NOT maybe_space supports_condition_in_parens {
787         $$ = !$3;
788     }
789     ;
790
791 supports_conjunction:
792     supports_condition_in_parens SUPPORTS_AND maybe_space supports_condition_in_parens {
793         $$ = $1 && $4;
794     }
795     | supports_conjunction SUPPORTS_AND maybe_space supports_condition_in_parens {
796         $$ = $1 && $4;
797     }
798     ;
799
800 supports_disjunction:
801     supports_condition_in_parens SUPPORTS_OR maybe_space supports_condition_in_parens {
802         $$ = $1 || $4;
803     }
804     | supports_disjunction SUPPORTS_OR maybe_space supports_condition_in_parens {
805         $$ = $1 || $4;
806     }
807     ;
808
809 supports_condition_in_parens:
810     '(' maybe_space supports_condition closing_parenthesis maybe_space {
811         $$ = $3;
812     }
813     | supports_declaration_condition
814     | '(' error error_location error_recovery closing_parenthesis maybe_space {
815         parser->reportError($3, InvalidSupportsConditionCSSError);
816         $$ = false;
817     }
818     ;
819
820 supports_declaration_condition:
821     '(' maybe_space IDENT maybe_space ':' maybe_space expr prio closing_parenthesis maybe_space {
822         $$ = false;
823         CSSPropertyID id = cssPropertyID($3);
824         if (id != CSSPropertyInvalid) {
825             parser->m_valueList = parser->sinkFloatingValueList($7);
826             int oldParsedProperties = parser->m_parsedProperties.size();
827             $$ = parser->parseValue(id, $8);
828             // We just need to know if the declaration is supported as it is written. Rollback any additions.
829             if ($$)
830                 parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
831         }
832         parser->m_valueList = nullptr;
833         parser->endProperty($8, false);
834     }
835     | '(' maybe_space IDENT maybe_space ':' maybe_space error error_recovery closing_parenthesis maybe_space {
836         $$ = false;
837         parser->endProperty(false, false, GeneralCSSError);
838     }
839     ;
840
841 before_keyframes_rule:
842     /* empty */ {
843         parser->startRuleHeader(CSSRuleSourceData::KEYFRAMES_RULE);
844     }
845     ;
846
847 keyframes_rule_start:
848     before_keyframes_rule KEYFRAMES_SYM maybe_space {
849         $$ = false;
850     }
851   | before_keyframes_rule WEBKIT_KEYFRAMES_SYM maybe_space {
852         $$ = true;
853     }
854     ;
855
856 keyframes:
857     keyframes_rule_start keyframe_name at_rule_header_end_maybe_space '{' at_rule_body_start maybe_space location_label keyframes_rule closing_brace {
858         $$ = parser->createKeyframesRule($2, parser->sinkFloatingKeyframeVector($8), $1 /* isPrefixed */);
859     }
860     ;
861
862 keyframe_name:
863     IDENT
864     | STRING {
865         if (parser->m_context.useCounter())
866             parser->m_context.useCounter()->count(UseCounter::QuotedKeyframesRule);
867     }
868     ;
869
870 keyframes_rule:
871     keyframe_rule_list
872     | keyframe_rule_list keyframes_error_recovery {
873         parser->clearProperties();
874     };
875
876 keyframe_rule_list:
877     /* empty */ {
878         $$ = parser->createFloatingKeyframeVector();
879         parser->resumeErrorLogging();
880     }
881     |  keyframe_rule_list keyframe_rule maybe_space location_label {
882         $$ = $1;
883         $$->append($2);
884     }
885     | keyframe_rule_list keyframes_error_recovery invalid_block maybe_space location_label {
886         parser->clearProperties();
887         parser->resumeErrorLogging();
888     }
889     ;
890
891 keyframe_rule:
892     key_list '{' maybe_space declaration_list closing_brace {
893         $$ = parser->createKeyframe($1);
894     }
895     ;
896
897 key_list:
898     key maybe_space {
899         $$ = parser->createFloatingValueList();
900         $$->addValue(parser->sinkFloatingValue($1));
901     }
902     | key_list ',' maybe_space key maybe_space {
903         $$ = $1;
904         $$->addValue(parser->sinkFloatingValue($4));
905     }
906     ;
907
908 key:
909     maybe_unary_operator PERCENTAGE {
910         $$.setFromNumber($1 * $2);
911     }
912     | IDENT {
913         if ($1.equalIgnoringCase("from"))
914             $$.setFromNumber(0);
915         else if ($1.equalIgnoringCase("to"))
916             $$.setFromNumber(100);
917         else {
918             YYERROR;
919         }
920     }
921     ;
922
923 keyframes_error_recovery:
924     error rule_error_recovery {
925         parser->reportError(parser->lastLocationLabel(), InvalidKeyframeSelectorCSSError);
926     }
927     ;
928
929 before_page_rule:
930     /* empty */ {
931         parser->startRuleHeader(CSSRuleSourceData::PAGE_RULE);
932     }
933     ;
934
935 page:
936     before_page_rule PAGE_SYM maybe_space page_selector at_rule_header_end
937     '{' at_rule_body_start maybe_space_before_declaration declarations_and_margins closing_brace {
938         if ($4)
939             $$ = parser->createPageRule(parser->sinkFloatingSelector($4));
940         else {
941             // Clear properties in the invalid @page rule.
942             parser->clearProperties();
943             // Also clear margin at-rules here once we fully implement margin at-rules parsing.
944             $$ = 0;
945         }
946     }
947     ;
948
949 page_selector:
950     IDENT maybe_space {
951         $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
952         $$->setForPage();
953     }
954     | IDENT pseudo_page maybe_space {
955         $$ = $2;
956         $$->prependTagSelector(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
957         $$->setForPage();
958     }
959     | pseudo_page maybe_space {
960         $$ = $1;
961         $$->setForPage();
962     }
963     | /* empty */ {
964         $$ = parser->createFloatingSelector();
965         $$->setForPage();
966     }
967     ;
968
969 declarations_and_margins:
970     declaration_list
971     | declarations_and_margins margin_box maybe_space declaration_list
972     ;
973
974 margin_box:
975     margin_sym {
976         parser->startDeclarationsForMarginBox();
977     } maybe_space '{' maybe_space declaration_list closing_brace {
978         $$ = parser->createMarginAtRule($1);
979     }
980     ;
981
982 margin_sym :
983     TOPLEFTCORNER_SYM {
984         $$ = CSSSelector::TopLeftCornerMarginBox;
985     }
986     | TOPLEFT_SYM {
987         $$ = CSSSelector::TopLeftMarginBox;
988     }
989     | TOPCENTER_SYM {
990         $$ = CSSSelector::TopCenterMarginBox;
991     }
992     | TOPRIGHT_SYM {
993         $$ = CSSSelector::TopRightMarginBox;
994     }
995     | TOPRIGHTCORNER_SYM {
996         $$ = CSSSelector::TopRightCornerMarginBox;
997     }
998     | BOTTOMLEFTCORNER_SYM {
999         $$ = CSSSelector::BottomLeftCornerMarginBox;
1000     }
1001     | BOTTOMLEFT_SYM {
1002         $$ = CSSSelector::BottomLeftMarginBox;
1003     }
1004     | BOTTOMCENTER_SYM {
1005         $$ = CSSSelector::BottomCenterMarginBox;
1006     }
1007     | BOTTOMRIGHT_SYM {
1008         $$ = CSSSelector::BottomRightMarginBox;
1009     }
1010     | BOTTOMRIGHTCORNER_SYM {
1011         $$ = CSSSelector::BottomRightCornerMarginBox;
1012     }
1013     | LEFTTOP_SYM {
1014         $$ = CSSSelector::LeftTopMarginBox;
1015     }
1016     | LEFTMIDDLE_SYM {
1017         $$ = CSSSelector::LeftMiddleMarginBox;
1018     }
1019     | LEFTBOTTOM_SYM {
1020         $$ = CSSSelector::LeftBottomMarginBox;
1021     }
1022     | RIGHTTOP_SYM {
1023         $$ = CSSSelector::RightTopMarginBox;
1024     }
1025     | RIGHTMIDDLE_SYM {
1026         $$ = CSSSelector::RightMiddleMarginBox;
1027     }
1028     | RIGHTBOTTOM_SYM {
1029         $$ = CSSSelector::RightBottomMarginBox;
1030     }
1031     ;
1032
1033 before_font_face_rule:
1034     /* empty */ {
1035         parser->startRuleHeader(CSSRuleSourceData::FONT_FACE_RULE);
1036     }
1037     ;
1038
1039 font_face:
1040     before_font_face_rule FONT_FACE_SYM at_rule_header_end_maybe_space
1041     '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1042         $$ = parser->createFontFaceRule();
1043     }
1044     ;
1045
1046 before_viewport_rule:
1047     /* empty */ {
1048         parser->markViewportRuleBodyStart();
1049         parser->startRuleHeader(CSSRuleSourceData::VIEWPORT_RULE);
1050     }
1051     ;
1052
1053 viewport:
1054     before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_end_maybe_space
1055     '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1056         $$ = parser->createViewportRule();
1057         parser->markViewportRuleBodyEnd();
1058     }
1059 ;
1060
1061 combinator:
1062     '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
1063     | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
1064     | '>' maybe_space { $$ = CSSSelector::Child; }
1065     | '/' IDENT '/' maybe_space {
1066         if ($2.equalIgnoringCase("deep"))
1067             $$ = CSSSelector::ShadowDeep;
1068         else
1069             YYERROR;
1070     }
1071     ;
1072
1073 maybe_unary_operator:
1074     unary_operator
1075     | /* empty */ { $$ = 1; }
1076     ;
1077
1078 unary_operator:
1079     '-' { $$ = -1; }
1080   | '+' { $$ = 1; }
1081   ;
1082
1083 maybe_space_before_declaration:
1084     maybe_space {
1085         parser->startProperty();
1086     }
1087   ;
1088
1089 before_selector_list:
1090     /* empty */ {
1091         parser->startRuleHeader(CSSRuleSourceData::STYLE_RULE);
1092         parser->startSelector();
1093     }
1094   ;
1095
1096 at_rule_header_end:
1097     /* empty */ {
1098         parser->endRuleHeader();
1099     }
1100   ;
1101
1102 at_selector_end:
1103     /* empty */ {
1104         parser->endSelector();
1105     }
1106   ;
1107
1108 ruleset:
1109     before_selector_list selector_list at_selector_end at_rule_header_end '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
1110         $$ = parser->createStyleRule($2);
1111     }
1112   ;
1113
1114 before_selector_group_item:
1115     /* empty */ {
1116         parser->startSelector();
1117     }
1118
1119 selector_list:
1120     selector %prec UNIMPORTANT_TOK {
1121         $$ = parser->reusableSelectorVector();
1122         $$->shrink(0);
1123         $$->append(parser->sinkFloatingSelector($1));
1124     }
1125     | selector_list at_selector_end ',' maybe_space before_selector_group_item selector %prec UNIMPORTANT_TOK {
1126         $$ = $1;
1127         $$->append(parser->sinkFloatingSelector($6));
1128     }
1129    ;
1130
1131 selector:
1132     simple_selector
1133     | selector WHITESPACE
1134     | selector WHITESPACE simple_selector
1135     {
1136         $$ = $3;
1137         CSSParserSelector* end = $$;
1138         while (end->tagHistory())
1139             end = end->tagHistory();
1140         end->setRelation(CSSSelector::Descendant);
1141         if ($1->isContentPseudoElement())
1142             end->setRelationIsAffectedByPseudoContent();
1143         end->setTagHistory(parser->sinkFloatingSelector($1));
1144     }
1145     | selector combinator simple_selector {
1146         $$ = $3;
1147         CSSParserSelector* end = $$;
1148         while (end->tagHistory())
1149             end = end->tagHistory();
1150         end->setRelation($2);
1151         if ($1->isContentPseudoElement())
1152             end->setRelationIsAffectedByPseudoContent();
1153         end->setTagHistory(parser->sinkFloatingSelector($1));
1154     }
1155     ;
1156
1157 namespace_selector:
1158     /* empty */ '|' { $$.clear(); }
1159     | '*' '|' { static const LChar star = '*'; $$.init(&star, 1); }
1160     | IDENT '|'
1161     ;
1162
1163 simple_selector:
1164     element_name {
1165         $$ = parser->createFloatingSelectorWithTagName(QualifiedName(nullAtom, $1, parser->m_defaultNamespace));
1166     }
1167     | element_name specifier_list {
1168         $$ = parser->rewriteSpecifiersWithElementName(nullAtom, $1, $2);
1169         if (!$$)
1170             YYERROR;
1171     }
1172     | specifier_list {
1173         $$ = parser->rewriteSpecifiersWithNamespaceIfNeeded($1);
1174         if (!$$)
1175             YYERROR;
1176     }
1177     | namespace_selector element_name {
1178         $$ = parser->createFloatingSelectorWithTagName(parser->determineNameInNamespace($1, $2));
1179         if (!$$)
1180             YYERROR;
1181     }
1182     | namespace_selector element_name specifier_list {
1183         $$ = parser->rewriteSpecifiersWithElementName($1, $2, $3);
1184         if (!$$)
1185             YYERROR;
1186     }
1187     | namespace_selector specifier_list {
1188         $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $2);
1189         if (!$$)
1190             YYERROR;
1191     }
1192   ;
1193
1194 simple_selector_list:
1195     simple_selector %prec UNIMPORTANT_TOK {
1196         $$ = parser->createFloatingSelectorVector();
1197         $$->append(parser->sinkFloatingSelector($1));
1198     }
1199     | simple_selector_list maybe_space ',' maybe_space simple_selector %prec UNIMPORTANT_TOK {
1200         $$ = $1;
1201         $$->append(parser->sinkFloatingSelector($5));
1202     }
1203   ;
1204
1205 element_name:
1206     IDENT {
1207         if (parser->m_context.isHTMLDocument())
1208             parser->tokenToLowerCase($1);
1209         $$ = $1;
1210     }
1211     | '*' {
1212         static const LChar star = '*';
1213         $$.init(&star, 1);
1214     }
1215   ;
1216
1217 specifier_list:
1218     specifier
1219     | specifier_list specifier {
1220         $$ = parser->rewriteSpecifiers($1, $2);
1221     }
1222 ;
1223
1224 specifier:
1225     IDSEL {
1226         $$ = parser->createFloatingSelector();
1227         $$->setMatch(CSSSelector::Id);
1228         if (isQuirksModeBehavior(parser->m_context.mode()))
1229             parser->tokenToLowerCase($1);
1230         $$->setValue($1);
1231     }
1232   | HEX {
1233         if ($1[0] >= '0' && $1[0] <= '9') {
1234             YYERROR;
1235         } else {
1236             $$ = parser->createFloatingSelector();
1237             $$->setMatch(CSSSelector::Id);
1238             if (isQuirksModeBehavior(parser->m_context.mode()))
1239                 parser->tokenToLowerCase($1);
1240             $$->setValue($1);
1241         }
1242     }
1243   | class
1244   | attrib
1245   | pseudo
1246     ;
1247
1248 class:
1249     '.' IDENT {
1250         $$ = parser->createFloatingSelector();
1251         $$->setMatch(CSSSelector::Class);
1252         if (isQuirksModeBehavior(parser->m_context.mode()))
1253             parser->tokenToLowerCase($2);
1254         $$->setValue($2);
1255     }
1256   ;
1257
1258 attr_name:
1259     IDENT maybe_space {
1260         if (parser->m_context.isHTMLDocument())
1261             parser->tokenToLowerCase($1);
1262         $$ = $1;
1263     }
1264     ;
1265
1266 attr_match_type:
1267     IDENT maybe_space {
1268         CSSSelector::AttributeMatchType attrMatchType = CSSSelector::CaseSensitive;
1269         if (!parser->parseAttributeMatchType(attrMatchType, $1))
1270             YYERROR;
1271         $$ = attrMatchType;
1272     }
1273     ;
1274
1275 maybe_attr_match_type:
1276     attr_match_type
1277     | /* empty */ { $$ = CSSSelector::CaseSensitive; }
1278     ;
1279
1280 attrib:
1281     '[' maybe_space attr_name closing_square_bracket {
1282         $$ = parser->createFloatingSelector();
1283         $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), CSSSelector::CaseSensitive);
1284         $$->setMatch(CSSSelector::AttributeSet);
1285     }
1286     | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space maybe_attr_match_type closing_square_bracket {
1287         $$ = parser->createFloatingSelector();
1288         $$->setAttribute(QualifiedName(nullAtom, $3, nullAtom), $8);
1289         $$->setMatch((CSSSelector::Match)$4);
1290         $$->setValue($6);
1291     }
1292     | '[' maybe_space namespace_selector attr_name closing_square_bracket {
1293         $$ = parser->createFloatingSelector();
1294         $$->setAttribute(parser->determineNameInNamespace($3, $4), CSSSelector::CaseSensitive);
1295         $$->setMatch(CSSSelector::AttributeSet);
1296     }
1297     | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space maybe_attr_match_type closing_square_bracket {
1298         $$ = parser->createFloatingSelector();
1299         $$->setAttribute(parser->determineNameInNamespace($3, $4), $9);
1300         $$->setMatch((CSSSelector::Match)$5);
1301         $$->setValue($7);
1302     }
1303     | '[' selector_recovery closing_square_bracket {
1304         YYERROR;
1305     }
1306   ;
1307
1308 match:
1309     '=' {
1310         $$ = CSSSelector::AttributeExact;
1311     }
1312     | INCLUDES {
1313         $$ = CSSSelector::AttributeList;
1314     }
1315     | DASHMATCH {
1316         $$ = CSSSelector::AttributeHyphen;
1317     }
1318     | BEGINSWITH {
1319         $$ = CSSSelector::AttributeBegin;
1320     }
1321     | ENDSWITH {
1322         $$ = CSSSelector::AttributeEnd;
1323     }
1324     | CONTAINS {
1325         $$ = CSSSelector::AttributeContain;
1326     }
1327     ;
1328
1329 ident_or_string:
1330     IDENT
1331   | STRING
1332     ;
1333
1334 pseudo_page:
1335     ':' IDENT {
1336         if ($2.isFunction())
1337             YYERROR;
1338         $$ = parser->createFloatingSelector();
1339         $$->setMatch(CSSSelector::PagePseudoClass);
1340         parser->tokenToLowerCase($2);
1341         $$->setValue($2);
1342         CSSSelector::PseudoType type = $$->pseudoType();
1343         if (type == CSSSelector::PseudoUnknown)
1344             YYERROR;
1345     }
1346
1347 pseudo:
1348     ':' error_location IDENT {
1349         if ($3.isFunction())
1350             YYERROR;
1351         $$ = parser->createFloatingSelector();
1352         $$->setMatch(CSSSelector::PseudoClass);
1353         parser->tokenToLowerCase($3);
1354         $$->setValue($3);
1355         CSSSelector::PseudoType type = $$->pseudoType();
1356         if (type == CSSSelector::PseudoUnknown) {
1357             parser->reportError($2, InvalidSelectorPseudoCSSError);
1358             YYERROR;
1359         }
1360     }
1361     | ':' ':' error_location IDENT {
1362         if ($4.isFunction())
1363             YYERROR;
1364         $$ = parser->createFloatingSelector();
1365         $$->setMatch(CSSSelector::PseudoElement);
1366         parser->tokenToLowerCase($4);
1367         $$->setValue($4);
1368         // FIXME: This call is needed to force selector to compute the pseudoType early enough.
1369         CSSSelector::PseudoType type = $$->pseudoType();
1370         if (type == CSSSelector::PseudoUnknown) {
1371             parser->reportError($3, InvalidSelectorPseudoCSSError);
1372             YYERROR;
1373         }
1374     }
1375     // used by ::cue(:past/:future)
1376     | ':' ':' CUEFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1377         $$ = parser->createFloatingSelector();
1378         $$->setMatch(CSSSelector::PseudoElement);
1379         $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($5));
1380         $$->setValue($3);
1381         CSSSelector::PseudoType type = $$->pseudoType();
1382         if (type != CSSSelector::PseudoCue)
1383             YYERROR;
1384     }
1385     | ':' ':' CUEFUNCTION selector_recovery closing_parenthesis {
1386         YYERROR;
1387     }
1388     // use by :-webkit-any.
1389     // FIXME: should we support generic selectors here or just simple_selectors?
1390     // Use simple_selector_list for now to match -moz-any.
1391     // See http://lists.w3.org/Archives/Public/www-style/2010Sep/0566.html for some
1392     // related discussion with respect to :not.
1393     | ':' ANYFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1394         $$ = parser->createFloatingSelector();
1395         $$->setMatch(CSSSelector::PseudoClass);
1396         $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1397         parser->tokenToLowerCase($2);
1398         $$->setValue($2);
1399         CSSSelector::PseudoType type = $$->pseudoType();
1400         if (type != CSSSelector::PseudoAny)
1401             YYERROR;
1402     }
1403     | ':' ANYFUNCTION selector_recovery closing_parenthesis {
1404         YYERROR;
1405     }
1406     // used by :nth-*(ax+b)
1407     | ':' FUNCTION maybe_space NTH maybe_space closing_parenthesis {
1408         $$ = parser->createFloatingSelector();
1409         $$->setMatch(CSSSelector::PseudoClass);
1410         $$->setArgument($4);
1411         $$->setValue($2);
1412         CSSSelector::PseudoType type = $$->pseudoType();
1413         if (type == CSSSelector::PseudoUnknown)
1414             YYERROR;
1415     }
1416     // used by :nth-*
1417     | ':' FUNCTION maybe_space maybe_unary_operator INTEGER maybe_space closing_parenthesis {
1418         $$ = parser->createFloatingSelector();
1419         $$->setMatch(CSSSelector::PseudoClass);
1420         $$->setArgument(AtomicString::number($4 * $5));
1421         $$->setValue($2);
1422         CSSSelector::PseudoType type = $$->pseudoType();
1423         if (type == CSSSelector::PseudoUnknown)
1424             YYERROR;
1425     }
1426     // used by :nth-*(odd/even) and :lang
1427     | ':' FUNCTION maybe_space IDENT maybe_space closing_parenthesis {
1428         $$ = parser->createFloatingSelector();
1429         $$->setMatch(CSSSelector::PseudoClass);
1430         $$->setArgument($4);
1431         parser->tokenToLowerCase($2);
1432         $$->setValue($2);
1433         CSSSelector::PseudoType type = $$->pseudoType();
1434         if (type == CSSSelector::PseudoUnknown)
1435             YYERROR;
1436         else if (type == CSSSelector::PseudoNthChild ||
1437                  type == CSSSelector::PseudoNthOfType ||
1438                  type == CSSSelector::PseudoNthLastChild ||
1439                  type == CSSSelector::PseudoNthLastOfType) {
1440             if (!isValidNthToken($4))
1441                 YYERROR;
1442         }
1443     }
1444     | ':' FUNCTION selector_recovery closing_parenthesis {
1445         YYERROR;
1446     }
1447     // used by :not
1448     | ':' NOTFUNCTION maybe_space simple_selector maybe_space closing_parenthesis {
1449         if (!$4->isSimple())
1450             YYERROR;
1451         else {
1452             $$ = parser->createFloatingSelector();
1453             $$->setMatch(CSSSelector::PseudoClass);
1454
1455             Vector<OwnPtr<CSSParserSelector> > selectorVector;
1456             selectorVector.append(parser->sinkFloatingSelector($4));
1457             $$->adoptSelectorVector(selectorVector);
1458
1459             parser->tokenToLowerCase($2);
1460             $$->setValue($2);
1461         }
1462     }
1463     | ':' NOTFUNCTION selector_recovery closing_parenthesis {
1464         YYERROR;
1465     }
1466     | ':' HOSTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1467         $$ = parser->createFloatingSelector();
1468         $$->setMatch(CSSSelector::PseudoClass);
1469         $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1470         parser->tokenToLowerCase($2);
1471         $$->setValue($2);
1472         CSSSelector::PseudoType type = $$->pseudoType();
1473         if (type != CSSSelector::PseudoHost)
1474             YYERROR;
1475     }
1476     | ':' HOSTFUNCTION selector_recovery closing_parenthesis {
1477         YYERROR;
1478     }
1479     //  used by :host-context()
1480     | ':' HOSTCONTEXTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
1481         $$ = parser->createFloatingSelector();
1482         $$->setMatch(CSSSelector::PseudoClass);
1483         $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
1484         parser->tokenToLowerCase($2);
1485         $$->setValue($2);
1486         CSSSelector::PseudoType type = $$->pseudoType();
1487         if (type != CSSSelector::PseudoHostContext)
1488             YYERROR;
1489     }
1490     | ':' HOSTCONTEXTFUNCTION selector_recovery closing_parenthesis {
1491         YYERROR;
1492     }
1493   ;
1494
1495 selector_recovery:
1496     error error_location error_recovery;
1497
1498 declaration_list:
1499     /* empty */ { $$ = false; }
1500     | declaration
1501     | decl_list declaration {
1502         $$ = $1 || $2;
1503     }
1504     | decl_list
1505     ;
1506
1507 decl_list:
1508     declaration ';' maybe_space {
1509         parser->startProperty();
1510         $$ = $1;
1511     }
1512     | decl_list declaration ';' maybe_space {
1513         parser->startProperty();
1514         $$ = $1 || $2;
1515     }
1516     ;
1517
1518 declaration:
1519     property ':' maybe_space error_location expr prio {
1520         $$ = false;
1521         bool isPropertyParsed = false;
1522         if ($1 != CSSPropertyInvalid) {
1523             parser->m_valueList = parser->sinkFloatingValueList($5);
1524             $$ = parser->parseValue($1, $6);
1525             if (!$$)
1526                 parser->reportError($4, InvalidPropertyValueCSSError);
1527             else
1528                 isPropertyParsed = true;
1529             parser->m_valueList = nullptr;
1530         }
1531         parser->endProperty($6, isPropertyParsed);
1532     }
1533     |
1534     property ':' maybe_space error_location expr prio error error_recovery {
1535         /* When we encounter something like p {color: red !important fail;} we should drop the declaration */
1536         parser->reportError($4, InvalidPropertyValueCSSError);
1537         parser->endProperty(false, false);
1538         $$ = false;
1539     }
1540     |
1541     property ':' maybe_space error_location error error_recovery {
1542         parser->reportError($4, InvalidPropertyValueCSSError);
1543         parser->endProperty(false, false);
1544         $$ = false;
1545     }
1546     |
1547     property error error_location error_recovery {
1548         parser->reportError($3, PropertyDeclarationCSSError);
1549         parser->endProperty(false, false, GeneralCSSError);
1550         $$ = false;
1551     }
1552     |
1553     error error_location error_recovery {
1554         parser->reportError($2, PropertyDeclarationCSSError);
1555         $$ = false;
1556     }
1557   ;
1558
1559 property:
1560     error_location IDENT maybe_space {
1561         $$ = cssPropertyID($2);
1562         parser->setCurrentProperty($$);
1563         if ($$ == CSSPropertyInvalid)
1564             parser->reportError($1, InvalidPropertyCSSError);
1565     }
1566   ;
1567
1568 prio:
1569     IMPORTANT_SYM maybe_space { $$ = true; }
1570     | /* empty */ { $$ = false; }
1571   ;
1572
1573 ident_list:
1574     IDENT maybe_space {
1575         $$ = parser->createFloatingValueList();
1576         $$->addValue(makeIdentValue($1));
1577     }
1578     | ident_list IDENT maybe_space {
1579         $$ = $1;
1580         $$->addValue(makeIdentValue($2));
1581     }
1582     ;
1583
1584 track_names_list:
1585     '(' maybe_space closing_parenthesis {
1586         $$.setFromValueList(parser->sinkFloatingValueList(parser->createFloatingValueList()));
1587     }
1588     | '(' maybe_space ident_list closing_parenthesis {
1589         $$.setFromValueList(parser->sinkFloatingValueList($3));
1590     }
1591     | '(' maybe_space expr_recovery closing_parenthesis {
1592         YYERROR;
1593     }
1594   ;
1595
1596 expr:
1597     term {
1598         $$ = parser->createFloatingValueList();
1599         $$->addValue(parser->sinkFloatingValue($1));
1600     }
1601     | expr operator term {
1602         $$ = $1;
1603         $$->addValue(makeOperatorValue($2));
1604         $$->addValue(parser->sinkFloatingValue($3));
1605     }
1606     | expr term {
1607         $$ = $1;
1608         $$->addValue(parser->sinkFloatingValue($2));
1609     }
1610   ;
1611
1612 expr_recovery:
1613     error error_location error_recovery {
1614         parser->reportError($2, PropertyDeclarationCSSError);
1615     }
1616   ;
1617
1618 operator:
1619     '/' maybe_space {
1620         $$ = '/';
1621     }
1622   | ',' maybe_space {
1623         $$ = ',';
1624     }
1625   ;
1626
1627 term:
1628   unary_term maybe_space
1629   | unary_operator unary_term maybe_space { $$ = $2; $$.fValue *= $1; }
1630   | STRING maybe_space { $$.id = CSSValueInvalid; $$.isInt = false; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
1631   | IDENT maybe_space { $$ = makeIdentValue($1); }
1632   /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1633   | DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1634   | unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
1635   | URI maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_URI; }
1636   | UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
1637   | HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
1638   | '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
1639   /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1640   | function maybe_space
1641   | calc_function maybe_space
1642   | '%' maybe_space { /* Handle width: %; */
1643       $$.id = CSSValueInvalid; $$.isInt = false; $$.unit = 0;
1644   }
1645   | track_names_list maybe_space
1646   ;
1647
1648 unary_term:
1649   INTEGER { $$.setFromNumber($1); $$.isInt = true; }
1650   | FLOATTOKEN { $$.setFromNumber($1); }
1651   | PERCENTAGE { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PERCENTAGE); }
1652   | PXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PX); }
1653   | CMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CM); }
1654   | MMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MM); }
1655   | INS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_IN); }
1656   | PTS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PT); }
1657   | PCS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_PC); }
1658   | DEGS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DEG); }
1659   | RADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_RAD); }
1660   | GRADS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_GRAD); }
1661   | TURNS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_TURN); }
1662   | MSECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_MS); }
1663   | SECS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_S); }
1664   | HERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_HZ); }
1665   | KHERTZ { $$.setFromNumber($1, CSSPrimitiveValue::CSS_KHZ); }
1666   | EMS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EMS); }
1667   | QEMS { $$.setFromNumber($1, CSSParserValue::Q_EMS); }
1668   | EXS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_EXS); }
1669   | REMS {
1670       $$.setFromNumber($1, CSSPrimitiveValue::CSS_REMS);
1671       if (parser->m_styleSheet)
1672           parser->m_styleSheet->parserSetUsesRemUnits(true);
1673   }
1674   | CHS { $$.setFromNumber($1, CSSPrimitiveValue::CSS_CHS); }
1675   | VW { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VW); }
1676   | VH { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VH); }
1677   | VMIN { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMIN); }
1678   | VMAX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_VMAX); }
1679   | DPPX { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPPX); }
1680   | DPI { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPI); }
1681   | DPCM { $$.setFromNumber($1, CSSPrimitiveValue::CSS_DPCM); }
1682   | FR { $$.setFromNumber($1, CSSPrimitiveValue::CSS_FR); }
1683   ;
1684
1685 function:
1686     FUNCTION maybe_space expr closing_parenthesis {
1687         $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1688     } |
1689     FUNCTION maybe_space closing_parenthesis {
1690         $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList(parser->createFloatingValueList())));
1691     } |
1692     FUNCTION maybe_space expr_recovery closing_parenthesis {
1693         YYERROR;
1694     }
1695   ;
1696
1697 calc_func_term:
1698   unary_term
1699   | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
1700   ;
1701
1702 calc_func_operator:
1703     space '+' space {
1704         $$ = '+';
1705     }
1706     | space '-' space {
1707         $$ = '-';
1708     }
1709     | calc_maybe_space '*' maybe_space {
1710         $$ = '*';
1711     }
1712     | calc_maybe_space '/' maybe_space {
1713         $$ = '/';
1714     }
1715   ;
1716
1717 calc_maybe_space:
1718     /* empty */
1719     | WHITESPACE
1720   ;
1721
1722 calc_func_paren_expr:
1723     '(' maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1724         $$ = $3;
1725         $$->insertValueAt(0, makeOperatorValue('('));
1726         $$->addValue(makeOperatorValue(')'));
1727     }
1728     | '(' maybe_space expr_recovery closing_parenthesis {
1729         YYERROR;
1730     }
1731   ;
1732
1733 calc_func_expr:
1734     calc_func_term {
1735         $$ = parser->createFloatingValueList();
1736         $$->addValue(parser->sinkFloatingValue($1));
1737     }
1738     | calc_func_expr calc_func_operator calc_func_term {
1739         $$ = $1;
1740         $$->addValue(makeOperatorValue($2));
1741         $$->addValue(parser->sinkFloatingValue($3));
1742     }
1743     | calc_func_expr calc_func_operator calc_func_paren_expr {
1744         $$ = $1;
1745         $$->addValue(makeOperatorValue($2));
1746         $$->stealValues(*($3));
1747     }
1748     | calc_func_paren_expr
1749   ;
1750
1751 calc_function:
1752     CALCFUNCTION maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
1753         $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
1754     }
1755     | CALCFUNCTION maybe_space expr_recovery closing_parenthesis {
1756         YYERROR;
1757     }
1758     ;
1759
1760
1761 invalid_at:
1762     ATKEYWORD
1763   | margin_sym
1764     ;
1765
1766 at_rule_recovery:
1767     at_rule_header_recovery at_invalid_rule_header_end at_rule_end
1768     ;
1769
1770 at_rule_header_recovery:
1771     error error_location rule_error_recovery {
1772         parser->reportError($2, InvalidRuleCSSError);
1773     }
1774     ;
1775
1776 at_rule_end:
1777     at_invalid_rule_header_end semi_or_eof
1778   | at_invalid_rule_header_end invalid_block
1779     ;
1780
1781 regular_invalid_at_rule_header:
1782     keyframes_rule_start at_rule_header_recovery
1783   | before_page_rule PAGE_SYM at_rule_header_recovery
1784   | before_font_face_rule FONT_FACE_SYM at_rule_header_recovery
1785   | before_supports_rule SUPPORTS_SYM error error_location rule_error_recovery {
1786         parser->reportError($4, InvalidSupportsConditionCSSError);
1787         parser->popSupportsRuleData();
1788     }
1789   | before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_recovery {
1790         parser->markViewportRuleBodyEnd();
1791     }
1792   | import_rule_start at_rule_header_recovery
1793   | NAMESPACE_SYM at_rule_header_recovery
1794   | error_location invalid_at at_rule_header_recovery {
1795         parser->resumeErrorLogging();
1796         parser->reportError($1, InvalidRuleCSSError);
1797     }
1798   ;
1799
1800 invalid_rule:
1801     error error_location rule_error_recovery at_invalid_rule_header_end invalid_block {
1802         parser->reportError($2, InvalidRuleCSSError);
1803     }
1804   | regular_invalid_at_rule_header at_invalid_rule_header_end ';'
1805   | regular_invalid_at_rule_header at_invalid_rule_header_end invalid_block
1806   | media_rule_start maybe_media_list ';'
1807     ;
1808
1809 invalid_rule_header:
1810     error error_location rule_error_recovery at_invalid_rule_header_end {
1811         parser->reportError($2, InvalidRuleCSSError);
1812     }
1813   | regular_invalid_at_rule_header at_invalid_rule_header_end
1814   | media_rule_start maybe_media_list
1815     ;
1816
1817 at_invalid_rule_header_end:
1818    /* empty */ {
1819        parser->endInvalidRuleHeader();
1820    }
1821    ;
1822
1823 invalid_block:
1824     '{' error_recovery closing_brace {
1825         parser->invalidBlockHit();
1826     }
1827     ;
1828
1829 invalid_square_brackets_block:
1830     '[' error_recovery closing_square_bracket
1831     ;
1832
1833 invalid_parentheses_block:
1834     opening_parenthesis error_recovery closing_parenthesis;
1835
1836 opening_parenthesis:
1837     '(' | FUNCTION | CALCFUNCTION | ANYFUNCTION | NOTFUNCTION | CUEFUNCTION | DISTRIBUTEDFUNCTION | HOSTFUNCTION
1838     ;
1839
1840 error_location: {
1841         $$ = parser->currentLocation();
1842     }
1843     ;
1844
1845 location_label: {
1846         parser->setLocationLabel(parser->currentLocation());
1847     }
1848     ;
1849
1850 error_recovery:
1851     /* empty */
1852   | error_recovery error
1853   | error_recovery invalid_block
1854   | error_recovery invalid_square_brackets_block
1855   | error_recovery invalid_parentheses_block
1856     ;
1857
1858 rule_error_recovery:
1859     /* empty */
1860   | rule_error_recovery error
1861   | rule_error_recovery invalid_square_brackets_block
1862   | rule_error_recovery invalid_parentheses_block
1863     ;
1864
1865 %%