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