root/lang/actionscript/ascss/src/css/ASCSS.asy @ 9560

Revision 9560, 38.6 kB (checked in by gyuque, 6 years ago)

ascss: style list

Line 
1%{
2/*
3 *  Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)
4 *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
6 *
7 *  This library is free software; you can redistribute it and/or
8 *  modify it under the terms of the GNU Lesser General Public
9 *  License as published by the Free Software Foundation; either
10 *  version 2 of the License, or (at your option) any later version.
11 *
12 *  This library is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 *  Lesser General Public License for more details.
16 *
17 *  You should have received a copy of the GNU Lesser General Public
18 *  License along with this library; if not, write to the Free Software
19 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 */
22
23package css
24{
25        public class ASCSS
26        {
27                private var mParser:ASCSSParser;
28
29                function ASCSS(aSrc:String)
30                {
31                        var sheet:StyleList = new StyleList(null);
32                        var parser:ASCSSParser = new ASCSSParser(sheet);
33                        var lx:CSSLexer = new CSSLexer(aSrc, parser);
34                        parser.lexer = lx;
35
36                        mParser = parser;
37                }
38
39                public function parse():void
40                {
41                        mParser.yyparse();
42                }
43        }
44}
45%}
46
47%union {
48    bool Boolean;
49    char character;
50    int integer;
51    double number;
52    ParseString string;
53
54    CSSRule* rule;
55    CSSRuleList* ruleList;
56    CSSSelector* selector;
57    CSSSelector::Relation relation;
58    MediaList* mediaList;
59    MediaQuery* mediaQuery;
60    MediaQuery::Restrictor mediaQueryRestrictor;
61    MediaQueryExp* mediaQueryExp;
62    ParseValue value;
63    ValueList* valueList;
64    Vector<MediaQueryExp*>* mediaQueryExpList;
65}
66
67%expect 41
68
69%left UNIMPORTANT_TOK
70
71%token WHITESPACE SGML_CD
72
73%token INCLUDES
74%token DASHMATCH
75%token BEGINSWITH
76%token ENDSWITH
77%token CONTAINS
78
79%token <string> STRING
80%right <string> IDENT
81%token <string> NTH
82
83%nonassoc <string> HEX
84%nonassoc <string> IDSEL
85%nonassoc ':'
86%nonassoc '.'
87%nonassoc '['
88%nonassoc <string> '*'
89%nonassoc error
90%left '|'
91
92%token IMPORT_SYM
93%token PAGE_SYM
94%token MEDIA_SYM
95%token FONT_FACE_SYM
96%token CHARSET_SYM
97%token NAMESPACE_SYM
98%token WEBKIT_RULE_SYM
99%token WEBKIT_DECLS_SYM
100%token WEBKIT_VALUE_SYM
101%token WEBKIT_MEDIAQUERY_SYM
102
103%token IMPORTANT_SYM
104%token MEDIA_ONLY
105%token MEDIA_NOT
106%token MEDIA_AND
107
108%token <number> QEMS
109%token <number> EMS
110%token <number> EXS
111%token <number> PXS
112%token <number> CMS
113%token <number> MMS
114%token <number> INS
115%token <number> PTS
116%token <number> PCS
117%token <number> DEGS
118%token <number> RADS
119%token <number> GRADS
120%token <number> MSECS
121%token <number> SECS
122%token <number> HERZ
123%token <number> KHERZ
124%token <string> DIMEN
125%token <number> PERCENTAGE
126%token <number> FLOATTOKEN
127%token <number> INTEGER
128
129%token <string> URI
130%token <string> FUNCTION
131%token <string> NOTFUNCTION
132
133%token <string> UNICODERANGE
134
135%type <relation> combinator
136
137%type <rule> charset
138%type <rule> ruleset
139%type <rule> valid_rule_or_import
140%type <rule> media
141%type <rule> import
142%type <rule> page
143%type <rule> font_face
144%type <rule> invalid_rule
145%type <rule> invalid_at
146%type <rule> invalid_import
147%type <rule> rule
148%type <rule> valid_rule
149
150%type <string> maybe_ns_prefix
151
152%type <string> namespace_selector
153
154%type <string> string_or_uri
155%type <string> ident_or_string
156%type <string> medium
157%type <string> hexcolor
158
159%type <string> media_feature
160%type <mediaList> media_list
161%type <mediaList> maybe_media_list
162%type <mediaQuery> media_query
163%type <mediaQueryRestrictor> maybe_media_restrictor
164%type <valueList> maybe_media_value
165%type <mediaQueryExp> media_query_exp
166%type <mediaQueryExpList> media_query_exp_list
167%type <mediaQueryExpList> maybe_media_query_exp_list
168
169%type <ruleList> ruleset_list
170
171%type <integer> property
172
173%type <selector> specifier
174%type <selector> specifier_list
175%type <selector> simple_selector
176%type <selector> selector
177%type <selector> selector_list
178%type <selector> selector_with_trailing_whitespace
179%type <selector> class
180%type <selector> attrib
181%type <selector> pseudo
182
183%type <boolean> declaration_list
184%type <boolean> decl_list
185%type <boolean> declaration
186
187%type <boolean> prio
188
189%type <integer> match
190%type <integer> unary_operator
191%type <character> operator
192
193%type <valueList> expr
194%type <value> term
195%type <value> unary_term
196%type <value> function
197
198%type <string> element_name
199%type <string> attr_name
200
201%%
202
203stylesheet:
204    maybe_charset maybe_sgml import_list namespace_list rule_list
205  | webkit_rule maybe_space
206  | webkit_decls maybe_space
207  | webkit_value maybe_space
208  | webkit_mediaquery maybe_space
209  ;
210
211valid_rule_or_import:
212    valid_rule
213  | import
214  ;
215
216webkit_rule:
217    WEBKIT_RULE_SYM '{' maybe_space valid_rule_or_import maybe_space '}' {
218/*
219        static_cast<CSSParser*>(parser)->rule = $4;
220*/
221    }
222;
223
224webkit_decls:
225    WEBKIT_DECLS_SYM '{' maybe_space declaration_list '}' {
226        /* can be empty */
227    }
228;
229
230webkit_value:
231    WEBKIT_VALUE_SYM '{' maybe_space expr '}' {
232/*
233        CSSParser* p = static_cast<CSSParser*>(parser);
234        if ($4) {
235            p->valueList = p->sinkFloatingValueList($4);
236            int oldParsedProperties = p->numParsedProperties;
237            if (!p->parseValue(p->id, p->important))
238                p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
239            delete p->valueList;
240            p->valueList = 0;
241        }
242*/
243    }
244;
245
246webkit_mediaquery:
247     WEBKIT_MEDIAQUERY_SYM WHITESPACE maybe_space media_query '}' {
248/*
249         CSSParser* p = static_cast<CSSParser*>(parser);
250         p->mediaQuery = p->sinkFloatingMediaQuery($4);
251*/
252     }
253;
254
255maybe_space:
256    /* empty */ %prec UNIMPORTANT_TOK
257  | maybe_space WHITESPACE
258  ;
259
260maybe_sgml:
261    /* empty */
262  | maybe_sgml SGML_CD
263  | maybe_sgml WHITESPACE
264  ;
265
266maybe_charset:
267   /* empty */
268  | charset {
269  }
270;
271
272charset:
273  CHARSET_SYM maybe_space STRING maybe_space ';' {
274/*
275
276     CSSParser* p = static_cast<CSSParser*>(parser);
277     $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
278     if ($$ && p->styleElement && p->styleElement->isCSSStyleSheet())
279         p->styleElement->append($$);
280*/
281  }
282  | CHARSET_SYM error invalid_block {
283  }
284  | CHARSET_SYM error ';' {
285  }
286;
287
288import_list:
289 /* empty */
290 | import_list import maybe_sgml {
291/*
292     CSSParser* p = static_cast<CSSParser*>(parser);
293     if ($2 && p->styleElement && p->styleElement->isCSSStyleSheet())
294         p->styleElement->append($2);
295*/
296 }
297 ;
298
299namespace_list:
300/* empty */
301| namespace_list namespace maybe_sgml
302;
303
304rule_list:
305   /* empty */
306 | rule_list rule maybe_sgml {
307        if ($2 != null && styleElement != null /* && styleElement.isCSSStyleSheet() */)
308                styleElement.append($2);
309 }
310 ;
311
312valid_rule:
313    ruleset
314  | media
315  | page
316  | font_face
317  ;
318
319rule:
320    valid_rule
321  | invalid_rule
322  | invalid_at
323  | invalid_import
324  ;
325
326import:
327    IMPORT_SYM maybe_space string_or_uri maybe_space maybe_media_list ';' {
328//        $$ = static_cast<CSSParser*>(parser)->createImportRule($3, $5);
329    }
330  | IMPORT_SYM error invalid_block {
331//        $$ = 0;
332    }
333  | IMPORT_SYM error ';' {
334//        $$ = 0;
335    }
336  ;
337
338namespace:
339NAMESPACE_SYM maybe_space maybe_ns_prefix string_or_uri maybe_space ';' {
340/*
341    CSSParser* p = static_cast<CSSParser*>(parser);
342    if (p->styleElement && p->styleElement->isCSSStyleSheet())
343        static_cast<CSSStyleSheet*>(p->styleElement)->addNamespace(p, $3, $4);
344*/
345}
346| NAMESPACE_SYM error invalid_block
347| NAMESPACE_SYM error ';'
348;
349
350maybe_ns_prefix:
351/* empty */ {
352//      $$.characters = 0;
353}
354| IDENT WHITESPACE {
355// $$ = $1;
356}
357;
358
359string_or_uri:
360STRING
361| URI
362;
363
364media_feature:
365    IDENT maybe_space {
366//        $$ = $1;
367    }
368    ;
369
370maybe_media_value:
371    /*empty*/ {
372//        $$ = 0;
373    }
374    | ':' maybe_space expr maybe_space {
375//        $$ = $3;
376    }
377    ;
378
379media_query_exp:
380    MEDIA_AND maybe_space '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space {
381/*
382        $5.lower();
383        $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExp($5, $7);
384*/
385    }
386    ;
387
388media_query_exp_list:
389    media_query_exp {
390/*
391        CSSParser* p = static_cast<CSSParser*>(parser);
392        $$ = p->createFloatingMediaQueryExpList();
393        $$->append(p->sinkFloatingMediaQueryExp($1));
394*/
395    }
396    | media_query_exp_list media_query_exp {
397/*
398        $$ = $1;
399        $$->append(static_cast<CSSParser*>(parser)->sinkFloatingMediaQueryExp($2));
400*/
401    }
402    ;
403
404maybe_media_query_exp_list:
405    /*empty*/ {
406//        $$ = static_cast<CSSParser*>(parser)->createFloatingMediaQueryExpList();
407    }
408    | media_query_exp_list
409    ;
410
411maybe_media_restrictor:
412    /*empty*/ {
413//        $$ = MediaQuery::None;
414    }
415    | MEDIA_ONLY {
416//        $$ = MediaQuery::Only;
417    }
418    | MEDIA_NOT {
419//        $$ = MediaQuery::Not;
420    }
421    ;
422
423media_query:
424    maybe_media_restrictor maybe_space medium maybe_media_query_exp_list {
425/*
426        CSSParser* p = static_cast<CSSParser*>(parser);
427        $3.lower();
428        $$ = p->createFloatingMediaQuery($1, $3, p->sinkFloatingMediaQueryExpList($4));
429*/
430    }
431    ;
432
433maybe_media_list:
434     /* empty */ {
435//        $$ = static_cast<CSSParser*>(parser)->createMediaList();
436     }
437     | media_list
438     ;
439
440media_list:
441    media_query {
442/*
443        CSSParser* p = static_cast<CSSParser*>(parser);
444        $$ = p->createMediaList();
445        $$->appendMediaQuery(p->sinkFloatingMediaQuery($1));
446*/
447    }
448    | media_list ',' maybe_space media_query {
449/*
450        $$ = $1;
451        if ($$)
452            $$->appendMediaQuery(static_cast<CSSParser*>(parser)->sinkFloatingMediaQuery($4));
453*/
454    }
455    | media_list error {
456/*
457        $$ = 0;
458*/
459    }
460    ;
461
462media:
463    MEDIA_SYM maybe_space media_list '{' maybe_space ruleset_list '}' {
464//        $$ = static_cast<CSSParser*>(parser)->createMediaRule($3, $6);
465    }
466    | MEDIA_SYM maybe_space '{' maybe_space ruleset_list '}' {
467//        $$ = static_cast<CSSParser*>(parser)->createMediaRule(0, $5);
468    }
469    ;
470
471ruleset_list:
472    /* empty */ {
473                $$ = null;
474        }
475    | ruleset_list ruleset maybe_space {
476/*
477        $$ = $1;
478        if ($2) {
479            if (!$$)
480                $$ = static_cast<CSSParser*>(parser)->createRuleList();
481            $$->append($2);
482        }
483*/
484    }
485    ;
486
487medium:
488  IDENT maybe_space {
489//      $$ = $1;
490  }
491  ;
492
493/*
494page:
495    PAGE_SYM maybe_space IDENT? pseudo_page? maybe_space
496    '{' maybe_space declaration [ ';' maybe_space declaration ]* '}' maybe_space
497  ;
498
499pseudo_page
500  : ':' IDENT
501  ;
502*/
503
504page:
505    PAGE_SYM error invalid_block {
506//      $$ = 0;
507    }
508  | PAGE_SYM error ';' {
509//      $$ = 0;
510    }
511    ;
512
513font_face:
514    FONT_FACE_SYM maybe_space
515    '{' maybe_space declaration_list '}'  maybe_space {
516//        $$ = static_cast<CSSParser*>(parser)->createFontFaceRule();
517    }
518    | FONT_FACE_SYM error invalid_block {
519//      $$ = 0;
520    }
521    | FONT_FACE_SYM error ';' {
522//      $$ = 0;
523    }
524;
525
526combinator:
527    '+' maybe_space {
528// $$ = CSSSelector::DirectAdjacent;
529  }
530  | '~' maybe_space {
531// $$ = CSSSelector::IndirectAdjacent;
532  }
533  | '>' maybe_space {
534// $$ = CSSSelector::Child;
535  }
536  ;
537
538unary_operator:
539    '-' {
540 $$ = -1;
541  }
542  | '+' {
543 $$ = 1;
544  }
545  ;
546
547ruleset:
548    selector_list '{' maybe_space declaration_list '}' {
549                $$ = createStyleRule($1);
550//        $$ = static_cast<CSSParser*>(parser)->createStyleRule($1);
551    }
552  ;
553
554selector_list:
555    selector %prec UNIMPORTANT_TOK {
556        $$ = $1;
557    }
558    | selector_list ',' maybe_space selector %prec UNIMPORTANT_TOK {
559        if ($1 != null && $4 != null) {
560            $$ = $1;
561            $$.append($4);
562        } else
563            $$ = null;
564    }
565  | selector_list error {
566        $$ = null;
567    }
568   ;
569
570selector_with_trailing_whitespace:
571    selector WHITESPACE {
572        $$ = $1;
573    }
574    ;
575
576selector:
577    simple_selector {
578        $$ = $1;
579    }
580    | selector_with_trailing_whitespace
581    {
582        $$ = $1;
583    }
584    | selector_with_trailing_whitespace simple_selector
585    {
586/*
587        $$ = $2;
588        if (!$1)
589            $$ = 0;
590        else if ($$) {
591            CSSParser* p = static_cast<CSSParser*>(parser);
592            CSSSelector* end = $$;
593            while (end->m_tagHistory)
594                end = end->m_tagHistory;
595            end->m_relation = CSSSelector::Descendant;
596            end->m_tagHistory = p->sinkFloatingSelector($1);
597            if (Document* doc = p->document())
598                doc->setUsesDescendantRules(true);
599        }
600*/
601    }
602    | selector combinator simple_selector {
603/*
604        $$ = $3;
605        if (!$1)
606            $$ = 0;
607        else if ($$) {
608            CSSParser* p = static_cast<CSSParser*>(parser);
609            CSSSelector* end = $$;
610            while (end->m_tagHistory)
611                end = end->m_tagHistory;
612            end->m_relation = $2;
613            end->m_tagHistory = p->sinkFloatingSelector($1);
614            if ($2 == CSSSelector::Child) {
615                if (Document* doc = p->document())
616                    doc->setUsesDescendantRules(true);
617            } else if ($2 == CSSSelector::DirectAdjacent || $2 == CSSSelector::IndirectAdjacent) {
618                if (Document* doc = p->document())
619                    doc->setUsesSiblingRules(true);
620            }
621        }
622*/
623    }
624    | selector error {
625//        $$ = 0;
626    }
627    ;
628
629namespace_selector:
630    /* empty */ '|' {
631// $$.characters = 0; $$.length = 0;
632    }
633    | '*' '|' {
634// static UChar star = '*'; $$.characters = &star; $$.length = 1;
635    }
636    | IDENT '|' {
637// $$ = $1;
638    }
639;
640   
641simple_selector:
642    element_name {
643                CSSTest.puts("simple_selector: "+$1.dump());
644                $$ = new CSSSelector();
645                $$.mTag = new QualifiedName(null, $1.str, defaultNamespace);
646    }
647    | element_name specifier_list {
648/*
649        $$ = $2;
650        if ($$) {
651            CSSParser* p = static_cast<CSSParser*>(parser);
652            $$->m_tag = QualifiedName(nullAtom, $1, p->defaultNamespace);
653        }
654*/
655    }
656    | specifier_list {
657/*
658        $$ = $1;
659        CSSParser* p = static_cast<CSSParser*>(parser);
660        if ($$ && p->defaultNamespace != starAtom)
661            $$->m_tag = QualifiedName(nullAtom, starAtom, p->defaultNamespace);
662*/
663    }
664    | namespace_selector element_name {
665/*
666        AtomicString namespacePrefix = $1;
667        CSSParser* p = static_cast<CSSParser*>(parser);
668        $$ = p->createFloatingSelector();
669        if (p->styleElement && p->styleElement->isCSSStyleSheet()) {
670            $$->m_tag = QualifiedName(namespacePrefix, $2,
671                                      static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
672        } else // FIXME: Shouldn't this case be an error?
673            $$->m_tag = QualifiedName(nullAtom, $2, p->defaultNamespace);
674*/
675    }
676    | namespace_selector element_name specifier_list {
677/*
678        $$ = $3;
679        if ($$) {
680            AtomicString namespacePrefix = $1;
681            CSSParser* p = static_cast<CSSParser*>(parser);
682            if (p->styleElement && p->styleElement->isCSSStyleSheet()) {
683                $$->m_tag = QualifiedName(namespacePrefix, $2,
684                                          static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
685            } else // FIXME: Shouldn't this case be an error?
686                $$->m_tag = QualifiedName(nullAtom, $2, p->defaultNamespace);
687        }
688*/
689    }
690    | namespace_selector specifier_list {
691/*
692        $$ = $2;
693        if ($$) {
694            AtomicString namespacePrefix = $1;
695            CSSParser* p = static_cast<CSSParser*>(parser);
696            if (p->styleElement && p->styleElement->isCSSStyleSheet())
697                $$->m_tag = QualifiedName(namespacePrefix,
698                                          starAtom,
699                                          static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
700        }
701*/
702    }
703  ;
704
705element_name:
706    IDENT {
707        var str:ParseString = new ParseString($1);
708                if (parsingHTMLDocument)
709            str.lower();
710        $$ = str;
711    }
712    | '*' {
713                $$ = new ParseString("*");
714    }
715  ;
716
717specifier_list:
718    specifier {
719//        $$ = $1;
720    }
721    | specifier_list specifier {
722/*
723        if (!$2)
724            $$ = 0;
725        else if ($1) {
726            $$ = $1;
727            CSSParser* p = static_cast<CSSParser*>(parser);
728            CSSSelector* end = $1;
729            while (end->m_tagHistory)
730                end = end->m_tagHistory;
731            end->m_relation = CSSSelector::SubSelector;
732            end->m_tagHistory = p->sinkFloatingSelector($2);
733        }
734*/
735    }
736    | specifier_list error {
737//        $$ = 0;
738    }
739;
740
741specifier:
742    IDSEL {
743/*
744        CSSParser* p = static_cast<CSSParser*>(parser);
745        $$ = p->createFloatingSelector();
746        $$->m_match = CSSSelector::Id;
747        if (!p->strict)
748            $1.lower();
749        $$->m_attr = idAttr;
750        $$->m_value = $1;
751*/
752    }
753  | HEX {
754/*
755        if ($1.characters[0] >= '0' && $1.characters[0] <= '9') {
756            $$ = 0;
757        } else {
758            CSSParser* p = static_cast<CSSParser*>(parser);
759            $$ = p->createFloatingSelector();
760            $$->m_match = CSSSelector::Id;
761            if (!p->strict)
762                $1.lower();
763            $$->m_attr = idAttr;
764            $$->m_value = $1;
765        }
766*/
767    }
768  | class
769  | attrib
770  | pseudo
771    ;
772
773class:
774    '.' IDENT {
775/*
776        CSSParser* p = static_cast<CSSParser*>(parser);
777        $$ = p->createFloatingSelector();
778        $$->m_match = CSSSelector::Class;
779        if (!p->strict)
780            $2.lower();
781        $$->m_attr = classAttr;
782        $$->m_value = $2;
783*/
784    }
785  ;
786
787attr_name:
788    IDENT maybe_space {
789/*
790        ParseString& str = $1;
791        CSSParser* p = static_cast<CSSParser*>(parser);
792        Document* doc = p->document();
793        if (doc && doc->isHTMLDocument())
794            str.lower();
795        $$ = str;
796*/
797    }
798    ;
799
800attrib:
801    '[' maybe_space attr_name ']' {
802/*
803        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
804        $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
805        $$->m_match = CSSSelector::Set;
806*/
807    }
808    | '[' maybe_space attr_name match maybe_space ident_or_string maybe_space ']' {
809/*
810        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
811        $$->m_attr = QualifiedName(nullAtom, $3, nullAtom);
812        $$->m_match = (CSSSelector::Match)$4;
813        $$->m_value = $6;
814*/
815    }
816    | '[' maybe_space namespace_selector attr_name ']' {
817/*
818        AtomicString namespacePrefix = $3;
819        CSSParser* p = static_cast<CSSParser*>(parser);
820        $$ = p->createFloatingSelector();
821        $$->m_attr = QualifiedName(namespacePrefix, $4,
822                                   static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
823        $$->m_match = CSSSelector::Set;
824*/
825    }
826    | '[' maybe_space namespace_selector attr_name match maybe_space ident_or_string maybe_space ']' {
827/*
828        AtomicString namespacePrefix = $3;
829        CSSParser* p = static_cast<CSSParser*>(parser);
830        $$ = p->createFloatingSelector();
831        $$->m_attr = QualifiedName(namespacePrefix, $4,
832                                   static_cast<CSSStyleSheet*>(p->styleElement)->determineNamespace(namespacePrefix));
833        $$->m_match = (CSSSelector::Match)$5;
834        $$->m_value = $7;
835*/
836    }
837  ;
838
839match:
840    '=' {
841//        $$ = CSSSelector::Exact;
842    }
843    | INCLUDES {
844//        $$ = CSSSelector::List;
845    }
846    | DASHMATCH {
847//        $$ = CSSSelector::Hyphen;
848    }
849    | BEGINSWITH {
850//        $$ = CSSSelector::Begin;
851    }
852    | ENDSWITH {
853//        $$ = CSSSelector::End;
854    }
855    | CONTAINS {
856//        $$ = CSSSelector::Contain;
857    }
858    ;
859
860ident_or_string:
861    IDENT
862  | STRING
863    ;
864
865pseudo:
866    ':' IDENT {
867/*
868        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
869        $$->m_match = CSSSelector::PseudoClass;
870        $2.lower();
871        $$->m_value = $2;
872        CSSSelector::PseudoType type = $$->pseudoType();
873        if (type == CSSSelector::PseudoUnknown)
874            $$ = 0;
875        else if (type == CSSSelector::PseudoEmpty ||
876                 type == CSSSelector::PseudoFirstChild ||
877                 type == CSSSelector::PseudoFirstOfType ||
878                 type == CSSSelector::PseudoLastChild ||
879                 type == CSSSelector::PseudoLastOfType ||
880                 type == CSSSelector::PseudoOnlyChild ||
881                 type == CSSSelector::PseudoOnlyOfType) {
882            CSSParser* p = static_cast<CSSParser*>(parser);
883            Document* doc = p->document();
884            if (doc)
885                doc->setUsesSiblingRules(true);
886        } else if (type == CSSSelector::PseudoFirstLine) {
887            CSSParser* p = static_cast<CSSParser*>(parser);
888            if (Document* doc = p->document())
889                doc->setUsesFirstLineRules(true);
890        }
891*/
892    }
893    | ':' ':' IDENT {
894/*
895        $$ = static_cast<CSSParser*>(parser)->createFloatingSelector();
896        $$->m_match = CSSSelector::PseudoElement;
897        $3.lower();
898        $$->m_value = $3;
899        CSSSelector::PseudoType type = $$->pseudoType();
900        if (type == CSSSelector::PseudoUnknown)
901            $$ = 0;
902        else if (type == CSSSelector::PseudoFirstLine) {
903            CSSParser* p = static_cast<CSSParser*>(parser);
904            if (Document* doc = p->document())
905                doc->setUsesFirstLineRules(true);
906        }
907*/
908    }
909    // used by :nth-*(ax+b)
910    | ':' FUNCTION NTH ')' {
911/*
912        CSSParser *p = static_cast<CSSParser*>(parser);
913        $$ = p->createFloatingSelector();
914        $$->m_match = CSSSelector::PseudoClass;
915        $$->m_argument = $3;
916        $$->m_value = $2;
917        CSSSelector::PseudoType type = $$->pseudoType();
918        if (type == CSSSelector::PseudoUnknown)
919            $$ = 0;
920        else if (type == CSSSelector::PseudoNthChild ||
921                 type == CSSSelector::PseudoNthOfType ||
922                 type == CSSSelector::PseudoNthLastChild ||
923                 type == CSSSelector::PseudoNthLastOfType) {
924            if (p->document())
925                p->document()->setUsesSiblingRules(true);
926        }
927*/
928    }
929    // used by :nth-*
930    | ':' FUNCTION INTEGER ')' {
931/*
932        CSSParser *p = static_cast<CSSParser*>(parser);
933        $$ = p->createFloatingSelector();
934        $$->m_match = CSSSelector::PseudoClass;
935        $$->m_argument = String::number($3);
936        $$->m_value = $2;
937        CSSSelector::PseudoType type = $$->pseudoType();
938        if (type == CSSSelector::PseudoUnknown)
939            $$ = 0;
940        else if (type == CSSSelector::PseudoNthChild ||
941                 type == CSSSelector::PseudoNthOfType ||
942                 type == CSSSelector::PseudoNthLastChild ||
943                 type == CSSSelector::PseudoNthLastOfType) {
944            if (p->document())
945                p->document()->setUsesSiblingRules(true);
946        }
947*/
948    }
949    // used by :nth-*(odd/even) and :lang
950    | ':' FUNCTION IDENT ')' {
951/*
952        CSSParser *p = static_cast<CSSParser*>(parser);
953        $$ = p->createFloatingSelector();
954        $$->m_match = CSSSelector::PseudoClass;
955        $$->m_argument = $3;
956        $2.lower();
957        $$->m_value = $2;
958        CSSSelector::PseudoType type = $$->pseudoType();
959        if (type == CSSSelector::PseudoUnknown)
960            $$ = 0;
961        else if (type == CSSSelector::PseudoNthChild ||
962                 type == CSSSelector::PseudoNthOfType ||
963                 type == CSSSelector::PseudoNthLastChild ||
964                 type == CSSSelector::PseudoNthLastOfType) {
965            if (p->document())
966                p->document()->setUsesSiblingRules(true);
967        }
968*/
969    }
970    // used by :not
971    | ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
972/*
973        if (!$4)
974            $$ = 0;
975        else {
976            CSSParser* p = static_cast<CSSParser*>(parser);
977            $$ = p->createFloatingSelector();
978            $$->m_match = CSSSelector::PseudoClass;
979            $$->m_simpleSelector = p->sinkFloatingSelector($4);
980            $2.lower();
981            $$->m_value = $2;
982        }
983*/
984    }
985  ;
986
987declaration_list:
988    declaration {
989        $$ = $1;
990    }
991    | decl_list declaration {
992        $$ = $1;
993        if ( $2 )
994            $$ = $2;
995    }
996    | decl_list {
997        $$ = $1;
998    }
999    | error invalid_block_list error {
1000        $$ = false;
1001    }
1002    | error {
1003        $$ = false;
1004    }
1005    | decl_list error {
1006        $$ = $1;
1007    }
1008    ;
1009
1010decl_list:
1011    declaration ';' maybe_space {
1012        $$ = $1;
1013    }
1014    | declaration invalid_block_list ';' maybe_space {
1015        $$ = false;
1016    }
1017    | error ';' maybe_space {
1018        $$ = false;
1019    }
1020    | error invalid_block_list error ';' maybe_space {
1021        $$ = false;
1022    }
1023    | decl_list declaration ';' maybe_space {
1024        $$ = $1;
1025        if ($2)
1026            $$ = $2;
1027    }
1028    | decl_list error ';' maybe_space {
1029        $$ = $1;
1030    }
1031    | decl_list error invalid_block_list error ';' maybe_space {
1032        $$ = $1;
1033    }
1034    ;
1035
1036declaration:
1037    property ':' maybe_space expr prio {
1038
1039                $$ = false;
1040                if ($1 && $4)
1041                {
1042                        currentValueList = $4;
1043                        $$ = parseValue($1, $5);
1044                        mValueList = null;
1045                }
1046
1047/*
1048        $$ = false;
1049        CSSParser* p = static_cast<CSSParser*>(parser);
1050        if ($1 && $4) {
1051            p->valueList = p->sinkFloatingValueList($4);
1052            int oldParsedProperties = p->numParsedProperties;
1053            $$ = p->parseValue($1, $5);
1054            if (!$$)
1055                p->rollbackLastProperties(p->numParsedProperties - oldParsedProperties);
1056            delete p->valueList;
1057            p->valueList = 0;
1058        }
1059*/
1060    }
1061    |
1062    property error {
1063//        $$ = false;
1064    }
1065    |
1066    property ':' maybe_space error expr prio {
1067        /* The default movable type template has letter-spacing: .none;  Handle this by looking for
1068        error tokens at the start of an expr, recover the expr and then treat as an error, cleaning
1069        up and deleting the shifted expr.  */
1070//        $$ = false;
1071    }
1072    |
1073    IMPORTANT_SYM maybe_space {
1074        /* Handle this case: div { text-align: center; !important } Just reduce away the stray !important. */
1075//        $$ = false;
1076    }
1077    |
1078    property ':' maybe_space {
1079        /* div { font-family: } Just reduce away this property with no value. */
1080//        $$ = false;
1081    }
1082    |
1083    property ':' maybe_space error {
1084        /* if we come across rules with invalid values like this case: p { weight: *; }, just discard the rule */
1085//        $$ = false;
1086    }
1087  ;
1088
1089property:
1090    IDENT maybe_space {
1091        $$ = cssPropertyID($1);
1092    }
1093  ;
1094
1095prio:
1096    IMPORTANT_SYM maybe_space {
1097      $$ = true;
1098    }
1099    | /* empty */ {
1100      $$ = false;
1101    }
1102  ;
1103
1104expr:
1105    term {
1106                var vallist:ValueList = new ValueList();
1107                vallist.addValue($1)
1108                $$ = vallist;
1109    }
1110    | expr operator term {
1111/*
1112
1113        CSSParser* p = static_cast<CSSParser*>(parser);
1114        $$ = $1;
1115        if ($$) {
1116            if ($2) {
1117                Value v;
1118                v.id = 0;
1119                v.unit = Value::Operator;
1120                v.iValue = $2;
1121                $$->addValue(v);
1122            }
1123            $$->addValue(p->sinkFloatingValue($3));
1124        }
1125*/
1126    }
1127    | expr error {
1128//        $$ = 0;
1129    }
1130  ;
1131
1132operator:
1133    '/' maybe_space {
1134//        $$ = '/';
1135    }
1136  | ',' maybe_space {
1137//        $$ = ',';
1138    }
1139  | /* empty */ {
1140//        $$ = 0;
1141  }
1142  ;
1143
1144term:
1145  unary_term {
1146// $$ = $1;
1147  }
1148  | unary_operator unary_term {
1149// $$ = $2; $$.fValue *= $1;
1150  }
1151  | STRING maybe_space {
1152// $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING;
1153  }
1154  | IDENT maybe_space {
1155        $$ = new ParseValue(cssValueKeywordID($1), CSSPrimitiveValue.CSS_IDENT);
1156        $$.stringVal = new ParseString($1);
1157  }
1158  /* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
1159  | DIMEN maybe_space {
1160// $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION
1161  }
1162  | unary_operator DIMEN maybe_space {
1163// $$.id = 0; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION
1164  }
1165  | URI maybe_space {
1166// $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI;
1167  }
1168  | UNICODERANGE maybe_space {
1169// $$.id = 0; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE
1170  }
1171  | hexcolor {
1172    $$ = new ParseValue(0, CSSPrimitiveValue.CSS_RGBCOLOR);
1173    $$.stringVal = $1
1174  }
1175  | '#' maybe_space {
1176// $$.id = 0; $$.string = ParseString(); $$.unit = CSSPrimitiveValue::CSS_RGBCOLOR;
1177  }
1178  /* Handle error case: "color: #;" */
1179
1180  /* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
1181  | function {
1182//      $$ = $1;
1183  }
1184  | '%' maybe_space {} /* Handle width: %; */
1185  ;
1186
1187unary_term:
1188  INTEGER maybe_space {
1189// $$.id = 0; $$.isInt = true; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER;
1190  }
1191  | FLOATTOKEN maybe_space {
1192// $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER;
1193  }
1194  | PERCENTAGE maybe_space {
1195// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PERCENTAGE;
1196  }
1197  | PXS maybe_space {
1198// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PX;
1199  }
1200  | CMS maybe_space {
1201// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_CM;
1202  }
1203  | MMS maybe_space {
1204// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MM;
1205  }
1206  | INS maybe_space {
1207// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_IN;
1208  }
1209  | PTS maybe_space {
1210// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PT;
1211  }
1212  | PCS maybe_space {
1213// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_PC;
1214  }
1215  | DEGS maybe_space {
1216// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_DEG;
1217  }
1218  | RADS maybe_space {
1219// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_RAD;
1220  }
1221  | GRADS maybe_space {
1222// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_GRAD;
1223  }
1224  | MSECS maybe_space {
1225// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_MS;
1226  }
1227  | SECS maybe_space {
1228// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_S;
1229  }
1230  | HERZ maybe_space {
1231// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_HZ;
1232  }
1233  | KHERZ maybe_space {
1234// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_KHZ;
1235  }
1236  | EMS maybe_space {
1237// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EMS;
1238  }
1239  | QEMS maybe_space {
1240// $$.id = 0; $$.fValue = $1; $$.unit = Value::Q_EMS;
1241  }
1242  | EXS maybe_space {
1243// $$.id = 0; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_EXS;
1244  }
1245  ;
1246
1247
1248function:
1249    FUNCTION maybe_space expr ')' maybe_space {
1250/*
1251        CSSParser* p = static_cast<CSSParser*>(parser);
1252        Function* f = p->createFloatingFunction();
1253        f->name = $1;
1254        f->args = p->sinkFloatingValueList($3);
1255        $$.id = 0;
1256        $$.unit = Value::Function;
1257        $$.function = f;
1258*/
1259    } |
1260    FUNCTION maybe_space error {
1261/*
1262        CSSParser* p = static_cast<CSSParser*>(parser);
1263        Function* f = p->createFloatingFunction();
1264        f->name = $1;
1265        f->args = 0;
1266        $$.id = 0;
1267        $$.unit = Value::Function;
1268        $$.function = f;
1269*/
1270    }
1271    ;
1272/*
1273 * There is a constraint on the color that it must
1274 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
1275 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
1276 */
1277hexcolor:
1278  HEX maybe_space {
1279   $$ = new ParseString($1);
1280  }
1281  | IDSEL maybe_space {
1282// $$ = $1;
1283  }
1284  ;
1285
1286
1287/* error handling rules */
1288
1289invalid_at:
1290    '@' error invalid_block {
1291//        $$ = 0;
1292    }
1293  | '@' error ';' {
1294//        $$ = 0;
1295    }
1296    ;
1297
1298invalid_import:
1299    import {
1300//        $$ = 0;
1301    }
1302    ;
1303
1304invalid_rule:
1305    error invalid_block {
1306//        $$ = 0;
1307    }
1308/*
1309  Seems like the two rules below are trying too much and violating
1310  http://www.hixie.ch/tests/evil/mixed/csserrorhandling.html
1311
1312  | error ';' {
1313        $$ = 0;
1314    }
1315  | error '}' {
1316        $$ = 0;
1317    }
1318*/
1319    ;
1320
1321invalid_block:
1322    '{' error invalid_block_list error '}'
1323  | '{' error '}'
1324    ;
1325
1326invalid_block_list:
1327    invalid_block
1328  | invalid_block_list error invalid_block
1329;
1330
1331
1332%%
1333import css.*;
1334
1335private var mInParseShorthand:int      = 0;
1336private var mCurrentShorthand:int      = 0;
1337private var mImplicitShorthand:Boolean = false;
1338private var mDefaultNamespace:String = '*';
1339private var mLex:CSSLexer;
1340private var mValueList:ValueList;
1341private var mStrict:Boolean = false;
1342private var mParsedProperties:Array = [];
1343private var mStyleElement:StyleList;
1344private var mParsedStyleObjects:Array /* of StyleBase */ = [];
1345
1346function ASCSSParser(aSheet:StyleList)
1347{
1348        mStyleElement = aSheet;
1349}
1350
1351public function set strictParsing(s:Boolean):void
1352{
1353        mStrict = s;
1354}
1355
1356public function set lexer(lx:CSSLexer):void
1357{
1358        mLex = lx;
1359}
1360
1361public function get parsingHTMLDocument():Boolean
1362{
1363        return false;
1364}
1365
1366public function get defaultNamespace():String
1367{
1368        return mDefaultNamespace;
1369}
1370
1371public function set currentValueList(vl:ValueList):void
1372{
1373        mValueList = vl;
1374}
1375
1376public function get styleElement():StyleList
1377{
1378        return mStyleElement;
1379}
1380
1381private function appendStyleObject(o:StyleBase):void
1382{
1383        mParsedStyleObjects.push(o);
1384}
1385
1386private function yylex():int {
1387        var ret:int = mLex.next();
1388        yylval = mLex.tokenBody;
1389
1390        CSSTest.puts("tok: "+ret +"  '"+mLex.tokenBody+"'");
1391       
1392        return ret;
1393}
1394
1395private function yyerror(msg:String):void {
1396        CSSTest.puts(msg);
1397}
1398
1399private function cssPropertyID(name:String):int
1400{
1401        if (CSSPropertyID.MAP[name] || CSSPropertyID.MAP[name] == 0)
1402                return CSSPropertyID.MAP[name];
1403
1404    return -1;
1405}
1406
1407private function parseValue(propId:int, important:Boolean):Boolean
1408{
1409        if (mValueList == null)
1410                return false;
1411
1412        var val:ParseValue = mValueList.currentValue;
1413        if (val == null)
1414                return false;
1415
1416        var id:int   = val.id;
1417        var num:uint = mValueList.length;
1418
1419        var valid_primitive:Boolean = false;
1420        var parsedValue:CSSValue;
1421
1422        switch(propId) {
1423                case CSSPropertyID.CSSPropertyBackgroundColor:     // <color> | inherit
1424                case CSSPropertyID.CSSPropertyBorderTopColor:     // <color> | inherit
1425                case CSSPropertyID.CSSPropertyBorderRightColor:   // <color> | inherit
1426                case CSSPropertyID.CSSPropertyBorderBottomColor:  // <color> | inherit
1427                case CSSPropertyID.CSSPropertyBorderLeftColor:    // <color> | inherit
1428                case CSSPropertyID.CSSPropertyColor:                // <color> | inherit
1429                case CSSPropertyID.CSSPropertyTextLineThroughColor: // CSS3 text decoration colors
1430                case CSSPropertyID.CSSPropertyTextUnderlineColor:
1431                case CSSPropertyID.CSSPropertyTextOverlineColor:
1432                case CSSPropertyID.CSSPropertyWebkitColumnRuleColor:
1433                case CSSPropertyID.CSSPropertyWebkitTextFillColor:
1434                case CSSPropertyID.CSSPropertyWebkitTextStrokeColor:
1435
1436
1437/*
1438                if (id == CSSValueWebkitText)
1439                    valid_primitive = true; // Always allow this, even when strict parsing is on,
1440                                            // since we use this in our UA sheets.
1441                else*/
1442                        if (id >= CSSValueKeywords.CSSValueAqua && id <= CSSValueKeywords.CSSValueWindowtext || id == CSSValueKeywords.CSSValueMenu ||
1443                                        (id >= CSSValueKeywords.CSSValueWebkitFocusRingColor && id < CSSValueKeywords.CSSValueWebkitText && !mStrict))
1444                        {
1445                                valid_primitive = true;
1446                }
1447                        else
1448                        {
1449                    parsedValue = parseColor();
1450                    if (parsedValue != null)
1451                        mValueList.next();
1452                }
1453                break;
1454        }
1455
1456    if (valid_primitive) {
1457        if (id != 0)
1458            parsedValue = CSSPrimitiveValue.newId(id);
1459/*
1460        else if (value->unit == CSSPrimitiveValue::CSS_STRING)
1461            parsedValue = new CSSPrimitiveValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
1462        else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
1463            parsedValue = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
1464        else if (value->unit >= Value::Q_EMS)
1465            parsedValue = new CSSQuirkPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_EMS);
1466*/
1467        mValueList.next();
1468    }
1469
1470        if (parsedValue != null) {
1471                if (mValueList.currentValue == null || inShorthand) {
1472                        addProperty(propId, parsedValue, important);
1473                        return true;
1474                }
1475        }
1476
1477        return false;
1478}
1479
1480private function parseColor(aValue:ParseValue = null):CSSPrimitiveValue
1481{
1482        var c:uint = WKColor.transparent;
1483
1484        var res:Object;
1485        if (null == (res = parseColorFromValue((aValue != null) ? aValue : mValueList.currentValue)))
1486                return null;
1487        else
1488                c = uint(res);
1489
1490        return CSSPrimitiveValue.newColor(c);
1491}
1492
1493private function get inShorthand():Boolean
1494{
1495        return mInParseShorthand != 0;
1496}
1497
1498private function parseColorFromValue(value:ParseValue, svg:Boolean = false):Object
1499{
1500        var res:Object = null;
1501        if (value.unit == CSSPrimitiveValue.CSS_RGBCOLOR) {
1502                if (null == (res = parseColorString(value.stringVal.str, mStrict && value.unit == CSSPrimitiveValue.CSS_IDENT)))
1503                        return null;
1504    }
1505
1506        return res;
1507}
1508
1509private function parseColorString(name:String, strict:Boolean):Object
1510{
1511        var res:Object = null;
1512    if (!strict && (res = WKColor.parseHexColor(name)) != null)
1513        return res;
1514
1515    return null;
1516}
1517
1518private function cssValueKeywordID(name:String):int
1519{
1520        if (CSSValueKeywords.MAP[name] || CSSValueKeywords.MAP[name] == 0)
1521                return CSSValueKeywords.MAP[name];
1522       
1523        return 0;
1524}
1525
1526private function addProperty(propId:int, value:CSSValue, important:Boolean):void
1527{
1528        var p:CSSProperty = new CSSProperty(propId, value, important, mCurrentShorthand, mImplicitShorthand);
1529        mParsedProperties.push(p);
1530        CSSTest.puts("prop "+propId+": "+ ((value==null) ? "null" : value.dump()) );
1531       
1532}
1533
1534private function createStyleRule(sel:CSSSelector):CSSRule
1535{
1536        var rule:CSSStyleRule = null;
1537        if (sel != null)
1538        {
1539                rule = new CSSStyleRule(styleElement);
1540                appendStyleObject(rule);
1541                rule.selector = sel;
1542                rule.declaration = new CSSMutableStyleDeclaration(rule, mParsedProperties);
1543        }
1544
1545        clearProperties();
1546        return rule;
1547}
1548
1549private function clearProperties():void
1550{
1551        for (;mParsedProperties.length > 0;)
1552                mParsedProperties.shift();
1553}
Note: See TracBrowser for help on using the browser.