|
3 | 3 | grammar CSSGrammar {
|
4 | 4 | # builtin: ident (we use cssident), alpha
|
5 | 5 |
|
6 |
| - token TOP { ^ <import>* <css>* $ || <.panic: "CSS parsing failed"> }; |
7 |
| - token css { <ruleset> | <media> | <page> }; |
8 |
| - rule ruleset { <selector> +% ',' <declarations> } |
9 |
| - rule declarations { '{' <declaration> +%% ';' '}' } |
10 |
| - rule selector { <simple_selector> +% <combinator>? }; |
11 |
| - rule simple_selector { <element_name> [ <hcap> ]* | <hcap>+ }; |
12 |
| - token hcap { '#' | <class> | <attrib> | <pseudo> }; |
13 |
| - token class { '.' <cssident> }; |
14 |
| - token element_name { <cssident> | '*' }; |
15 |
| - token attrib { '[' <cssident> [ [ '=' | <INCLUDES> | <DASHMATCH> ] [ <cssident> | <string> ] ]? ']' }; |
16 |
| - token pseudo { ':' [ <cssident> | <FUNCTION> <cssident>? ')' ] }; |
17 |
| - token combinator { '+' | '>' }; |
| 6 | + token TOP { ^ <import>* <css>* $ || <.panic: "CSS parsing failed"> } |
| 7 | + token css { <ruleset> | <media> | <page> } |
| 8 | + rule ruleset { <selector> +% ',' '{' ~ '}' <declarations> } |
| 9 | + rule declarations { <declaration> +%% ';' } |
| 10 | + rule selector { <simple_selector> +% <combinator>? } |
| 11 | + rule simple_selector { <element_name> [ <hcap> ]* | <hcap>+ } |
| 12 | + token hcap { '#' | <class> | '[' ~ ']' <attrib> | <pseudo> } |
| 13 | + token class { '.' <cssident> } |
| 14 | + token element_name { <cssident> | '*' } |
| 15 | + token attrib { <cssident> [ [ '=' | <INCLUDES> | <DASHMATCH> ] [ <cssident> | <string> ] ]? } |
| 16 | + token pseudo { ':' [ <FUNCTION> ~ ')' <cssident>? | <cssident> ] } |
| 17 | + token combinator { '+' | '>' } |
18 | 18 |
|
19 |
| - rule declaration { <property> ':' <expr> <prio>? }; |
20 |
| - token property { <cssident> }; |
21 |
| - token prio { <important_sym> }; |
22 |
| - token expr { <term> +% <operator>? }; |
23 |
| - token cssident { '-'?<namestart><namechar>* }; |
| 19 | + rule declaration { <property> ':' <expr> <prio>? } |
| 20 | + token property { <cssident> } |
| 21 | + token prio { <important_sym> } |
| 22 | + token expr { <term> +% <operator>? } |
| 23 | + token cssident { '-'?<namestart><namechar>* } |
24 | 24 | rule term { <unary_operator>?
|
25 |
| - [ <number> | <percentage> | <length> | <ems> | <exs> | <angle> | <time> | <freq> ] |
26 |
| - | <string> | <cssident> | <uri> | <hexcolor> | <function> |
27 |
| - }; |
28 |
| - token operator { '/' | ',' }; |
29 |
| - token function { <FUNCTION> <expr> ')' }; |
30 |
| - token hexcolor { '#' }; |
31 |
| - token namestart { <alpha> | _ }; |
32 |
| - token namechar { \w | '-' }; |
33 |
| - token unary_operator { '-' | '+' }; |
34 |
| - token number { \d+ | \d* '.' \d+ }; |
35 |
| - token percentage { <number> '%' }; |
36 |
| - token length {:i <number> [ px | cm | mm | in | pt | pc ] }; |
37 |
| - token ems {:i <number>? em }; |
38 |
| - token exs {:i <number>? ex }; |
39 |
| - token angle {:i <number> [ deg | rad | grad ] }; |
40 |
| - token time {:i <number> [ ms | s ] }; |
41 |
| - token freq {:i <number> k?hz }; |
42 |
| - token string { ('"' | \') (<- [\n]>|\\ \n)*? $0 }; |
43 |
| - token uri { url '(' [ <string> | <url>] ')'}; |
44 |
| - token url { ( <- [\( \) \' \" \\]> )* }; |
45 |
| - token FUNCTION { <cssident> '(' }; |
46 |
| - token important_sym {:i '!'important }; |
| 25 | + [ <percentage> | <length> | <ems> | <exs> | <angle> | <time> | <freq> | <number> ] |
| 26 | + | <string> | <uri> | <function> | <cssident> | <hexcolor> |
| 27 | + } |
| 28 | + token operator { '/' | ',' } |
| 29 | + token function { <FUNCTION> ~ ')' <expr> } |
| 30 | + token hexcolor { '#' } |
| 31 | + token namestart { <alpha> | _ } |
| 32 | + token namechar { \w | '-' } |
| 33 | + token unary_operator { '-' | '+' } |
| 34 | + token number { \d+ | \d* '.' \d+ } |
| 35 | + token percentage { <number> '%' } |
| 36 | + token length {:i <number> [ px | cm | mm | in | pt | pc ] } |
| 37 | + token ems {:i <number>? em } |
| 38 | + token exs {:i <number>? ex } |
| 39 | + token angle {:i <number> [ deg | rad | grad ] } |
| 40 | + token time {:i <number> [ ms | s ] } |
| 41 | + token freq {:i <number> k?hz } |
| 42 | + token string { ('"' | \') (<- nl>|\\ \n)*? $0 } |
| 43 | + token uri { url '(' ~ ')' [ <string> | <url>] } |
| 44 | + token url { ( <- [\( \) \' \" \\]> )* } |
| 45 | + token FUNCTION { <cssident> '(' } |
| 46 | + token INCLUDES { '~=' } |
| 47 | + token DASHMATCH { '|=' } |
| 48 | + |
| 49 | + token important_sym {:i '!'important } |
47 | 50 |
|
48 | 51 | rule import {:i'@import' [<string>|<uri>] <media_list>? ';' }
|
49 | 52 |
|
50 | 53 | rule media {:i'@media' <media_list> <media_rules> }
|
51 |
| - rule media_list {<media_type> [',' <media_type>]*} |
52 |
| - rule media_type {<cssident>} |
53 |
| - rule media_rules { '{' <ruleset>* '}' } |
| 54 | + rule media_list {<media_type> +%','} |
| 55 | + rule media_type { <cssident> } |
| 56 | + rule media_rules { '{' ~ '}' <ruleset>* } |
54 | 57 |
|
55 | 58 | rule page {:i'@page' [':'<cssident>]? <declarations> }
|
56 | 59 |
|
57 | 60 | # Comments and whitespace.
|
58 | 61 | token comment {'<!--' .*? '-->' | '/*' .*? '*/'}
|
59 |
| - # override <ws> builtin. Note: \n matches a logical (platform |
60 |
| - # independent) newline in Perl 6 |
61 |
| - token ws { <!ww> [ \n | "\t" | " " | <comment> ]* } |
| 62 | + token nl {\xA|"\r"\xA|"\r"|"\f"} |
| 63 | + token ws { <!ww> [ nl | "\t" | " " | <comment> ]* } |
62 | 64 |
|
63 | 65 | method panic($e) {die $e;}
|
64 | 66 | }
|
0 commit comments