File: | blib/lib/CSS/Grammar/CSS21.pm |
Coverage: | 100.0% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package CSS::Grammar::CSS21; | |||||
2 | ||||||
3 | 4 4 4 | 20 8 23 | use strict; | |||
4 | 4 4 4 | 28 13 23 | use warnings; | |||
5 | ||||||
6 | 4 4 4 | 32 11 23 | use base 'CSS::Grammar'; | |||
7 | ||||||
8 | # | |||||
9 | # http://www.w3.org/TR/CSS21/ | |||||
10 | # http://www.w3.org/TR/CSS21/grammar.html | |||||
11 | # http://www.w3.org/TR/CSS21/syndata.html#parsing-errors | |||||
12 | # | |||||
13 | ||||||
14 | sub init { | |||||
15 | 4 | 13 | my ($self) = @_; | |||
16 | ||||||
17 | 4 | 7 | my %rx; | |||
18 | ||||||
19 | ##################################################################################### | |||||
20 | ||||||
21 | 4 | 12 | $self->{case_insensitive} = 1; | |||
22 | ||||||
23 | ||||||
24 | ##################################################################################### | |||||
25 | ||||||
26 | #h [0-9a-f] | |||||
27 | #nonascii [\200-\377] | |||||
28 | #unicode \\{h}{1,6}(\r\n|[ \t\r\n\f])? | |||||
29 | #escape {unicode}|\\[^\r\n\f0-9a-f] | |||||
30 | #s [ \t\r\n\f]+ | |||||
31 | #w {s}? | |||||
32 | #nl \n|\r\n|\r|\f | |||||
33 | ||||||
34 | 4 | 14 | $rx{h} = '[0-9a-f]'; | |||
35 | 4 | 11 | $rx{nonascii} = '[\\x80-\\xff]'; | |||
36 | 4 | 18 | $rx{unicode} = '(\\'.$rx{h}.'{1,6}(\\r\\n|[ \\t\\r\\n\\f])?)'; | |||
37 | 4 | 20 | $rx{escape} = '('.$rx{unicode}.'|\\\\[ -~\\x80-\\xff])'; | |||
38 | 4 | 9 | $rx{s} = '[ \t\r\n\f]'; | |||
39 | 4 | 17 | $rx{w} = "$rx{s}*"; | |||
40 | 4 | 11 | $rx{nl} = '(\\n|\\r\\n|\\r|\\f)'; | |||
41 | ||||||
42 | ||||||
43 | #nmstart [_a-z]|{nonascii}|{escape} | |||||
44 | #nmchar [_a-z0-9-]|{nonascii}|{escape} | |||||
45 | #string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\" | |||||
46 | #string2 \'([^\n\r\f\\']|\\{nl}|{escape})*\' | |||||
47 | ||||||
48 | 4 | 183 | $rx{nmstart} = '([_a-z]|'.$rx{nonascii}.'|'.$rx{escape}.')'; | |||
49 | 4 | 25 | $rx{nmchar} = '([_a-zA-Z0-9-]|'.$rx{nonascii}.'|'.$rx{escape}.')'; | |||
50 | 4 | 28 | $rx{string1} = '("([\\t !#$%&(-~]|\\\\('.$rx{nl}.')|\'|('.$rx{nonascii}.')|('.$rx{escape}.'))*")'; | |||
51 | 4 | 28 | $rx{string2} = '(\'([\\t !#$%&(-~]|\\\\('.$rx{nl}.')|"|('.$rx{nonascii}.')|('.$rx{escape}.'))*\')'; | |||
52 | ||||||
53 | ||||||
54 | #ident -?{nmstart}{nmchar}* | |||||
55 | #name {nmchar}+ | |||||
56 | #num [0-9]+|[0-9]*"."[0-9]+ | |||||
57 | #string {string1}|{string2} | |||||
58 | #url ([!#$%&*-~]|{nonascii}|{escape})* | |||||
59 | ||||||
60 | 4 | 20 | $rx{ident} = "$rx{nmstart}$rx{nmchar}*"; | |||
61 | 4 | 13 | $rx{name} = "$rx{nmchar}+"; | |||
62 | 4 | 12 | $rx{num} = '([0-9]+|[0-9]*\\.[0-9]+)'; | |||
63 | 4 | 24 | $rx{string} = "($rx{string1}|$rx{string2})"; | |||
64 | 4 | 26 | $rx{url} = "(([!#\$%&*-~]|$rx{nonascii}|$rx{escape})*)"; | |||
65 | ||||||
66 | ||||||
67 | # these aren't used in any productions... | |||||
68 | #invalid1 \"([^\n\r\f\\"]|\\{nl}|{escape})* | |||||
69 | #invalid2 \'([^\n\r\f\\']|\\{nl}|{escape})* | |||||
70 | #invalid {invalid1}|{invalid2} | |||||
71 | ||||||
72 | ||||||
73 | #A a|\\0{0,4}(41|61)(\r\n|[ \t\r\n\f])? | |||||
74 | #C c|\\0{0,4}(43|63)(\r\n|[ \t\r\n\f])? | |||||
75 | #D d|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])? | |||||
76 | #E e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])? | |||||
77 | #G g|\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\g | |||||
78 | #H h|\\0{0,4}(48|68)(\r\n|[ \t\r\n\f])?|\\h | |||||
79 | #I i|\\0{0,4}(49|69)(\r\n|[ \t\r\n\f])?|\\i | |||||
80 | #K k|\\0{0,4}(4b|6b)(\r\n|[ \t\r\n\f])?|\\k | |||||
81 | #M m|\\0{0,4}(4d|6d)(\r\n|[ \t\r\n\f])?|\\m | |||||
82 | #N n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n | |||||
83 | #O o|\\0{0,4}(51|71)(\r\n|[ \t\r\n\f])?|\\o | |||||
84 | #P p|\\0{0,4}(50|70)(\r\n|[ \t\r\n\f])?|\\p | |||||
85 | #R r|\\0{0,4}(52|72)(\r\n|[ \t\r\n\f])?|\\r | |||||
86 | #S s|\\0{0,4}(53|73)(\r\n|[ \t\r\n\f])?|\\s | |||||
87 | #T t|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t | |||||
88 | #X x|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\x | |||||
89 | #Z z|\\0{0,4}(5a|7a)(\r\n|[ \t\r\n\f])?|\\z | |||||
90 | ||||||
91 | 4 | 11 | $rx{A} = '(a|\\\\0{0,4}(41|61)(\r\n|[ \t\r\n\f])?)'; | |||
92 | 4 | 13 | $rx{C} = '(c|\\\\0{0,4}(43|63)(\r\n|[ \t\r\n\f])?)'; | |||
93 | 4 | 11 | $rx{D} = '(d|\\\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])?)'; | |||
94 | 4 | 11 | $rx{E} = '(e|\\\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])?)'; | |||
95 | 4 | 11 | $rx{G} = '(g|\\\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\\\g)'; | |||
96 | 4 | 13 | $rx{H} = '(h|\\\\0{0,4}(48|68)(\r\n|[ \t\r\n\f])?|\\\\h)'; | |||
97 | 4 | 11 | $rx{I} = '(i|\\\\0{0,4}(49|69)(\r\n|[ \t\r\n\f])?|\\\\i)'; | |||
98 | 4 | 11 | $rx{K} = '(k|\\\\0{0,4}(4b|6b)(\r\n|[ \t\r\n\f])?|\\\\k)'; | |||
99 | 4 | 11 | $rx{M} = '(m|\\\\0{0,4}(4d|6d)(\r\n|[ \t\r\n\f])?|\\\\m)'; | |||
100 | 4 | 12 | $rx{N} = '(n|\\\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\\\n)'; | |||
101 | 4 | 13 | $rx{O} = '(o|\\\\0{0,4}(51|71)(\r\n|[ \t\r\n\f])?|\\\\o)'; | |||
102 | 4 | 10 | $rx{P} = '(p|\\\\0{0,4}(50|70)(\r\n|[ \t\r\n\f])?|\\\\p)'; | |||
103 | 4 | 12 | $rx{R} = '(r|\\\\0{0,4}(52|72)(\r\n|[ \t\r\n\f])?|\\\\r)'; | |||
104 | 4 | 9 | $rx{S} = '(s|\\\\0{0,4}(53|73)(\r\n|[ \t\r\n\f])?|\\\\s)'; | |||
105 | 4 | 11 | $rx{T} = '(t|\\\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\\\t)'; | |||
106 | 4 | 12 | $rx{X} = '(x|\\\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\\\x)'; | |||
107 | 4 | 18 | $rx{Z} = '(z|\\\\0{0,4}(5a|7a)(\r\n|[ \t\r\n\f])?|\\\\z)'; | |||
108 | ||||||
109 | ||||||
110 | ##################################################################################### | |||||
111 | ||||||
112 | #{s} {return S;} | |||||
113 | #"<!--" {return CDO;} | |||||
114 | #"-->" {return CDC;} | |||||
115 | #"~=" {return INCLUDES;} | |||||
116 | #"|=" {return DASHMATCH;} | |||||
117 | ||||||
118 | 4 | 28 | $self->add_toke_rule('S' , "$rx{s}+"); | |||
119 | 4 | 17 | $self->add_toke_rule('CDO' , '<!--'); | |||
120 | 4 | 15 | $self->add_toke_rule('CDC' , '-->'); | |||
121 | 4 | 15 | $self->add_toke_rule('INCLUDES' , '~='); | |||
122 | 4 | 15 | $self->add_toke_rule('DASHMATCH' , '\\|='); | |||
123 | ||||||
124 | ||||||
125 | #{w}"{" {return LBRACE;} | |||||
126 | #{w}"+" {return PLUS;} | |||||
127 | #{w}">" {return GREATER;} | |||||
128 | #{w}"," {return COMMA;} | |||||
129 | ||||||
130 | 4 | 23 | $self->add_toke_rule('LBRACE' , "$rx{w}\\{"); | |||
131 | 4 | 20 | $self->add_toke_rule('PLUS' , "$rx{w}\\+"); | |||
132 | 4 | 20 | $self->add_toke_rule('GREATER' , "$rx{w}>"); | |||
133 | 4 | 20 | $self->add_toke_rule('COMMA' , "$rx{w},"); | |||
134 | ||||||
135 | ||||||
136 | #{string} {return STRING;} | |||||
137 | #{invalid} {return INVALID; /* unclosed string */} | |||||
138 | #{ident} {return IDENT;} | |||||
139 | #"#"{name} {return HASH;} | |||||
140 | ||||||
141 | 4 | 16 | $self->add_toke_rule('STRING' , $rx{string}); | |||
142 | 4 | 18 | $self->add_toke_rule('IDENT' , $rx{ident}); | |||
143 | 4 | 22 | $self->add_toke_rule('HASH' , "#$rx{name}"); | |||
144 | ||||||
145 | ||||||
146 | #@{I}{M}{P}{O}{R}{T} {return IMPORT_SYM;} | |||||
147 | #@{P}{A}{G}{E} {return PAGE_SYM;} | |||||
148 | #@{M}{E}{D}{I}{A} {return MEDIA_SYM;} | |||||
149 | #@{C}{H}{A}{R}{S}{E}{T} {return CHARSET_SYM;} | |||||
150 | ||||||
151 | #"!"({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T} {return IMPORTANT_SYM;} | |||||
152 | ||||||
153 | 4 | 40 | $self->add_toke_rule('IMPORT_SYM' , "\@$rx{I}$rx{M}$rx{P}$rx{O}$rx{R}$rx{T}"); | |||
154 | 4 | 31 | $self->add_toke_rule('PAGE_SYM' , "\@$rx{P}$rx{A}$rx{G}$rx{E}"); | |||
155 | 4 | 35 | $self->add_toke_rule('MEDIA_SYM' , "\@$rx{M}$rx{E}$rx{D}$rx{I}$rx{A}"); | |||
156 | 4 | 43 | $self->add_toke_rule('CHARSET_SYM' , "\@$rx{C}$rx{H}$rx{A}$rx{R}$rx{S}$rx{E}$rx{T}"); | |||
157 | ||||||
158 | 4 | 56 | $self->add_toke_rule('IMPORTANT_SYM' , "!$rx{w}$rx{I}$rx{M}$rx{P}$rx{O}$rx{R}$rx{T}$rx{A}$rx{N}$rx{T}"); | |||
159 | ||||||
160 | ||||||
161 | #{num}{E}{M} {return EMS;} | |||||
162 | #{num}{E}{X} {return EXS;} | |||||
163 | #{num}{P}{X} {return LENGTH;} | |||||
164 | #{num}{C}{M} {return LENGTH;} | |||||
165 | #{num}{M}{M} {return LENGTH;} | |||||
166 | #{num}{I}{N} {return LENGTH;} | |||||
167 | #{num}{P}{T} {return LENGTH;} | |||||
168 | #{num}{P}{C} {return LENGTH;} | |||||
169 | #{num}{D}{E}{G} {return ANGLE;} | |||||
170 | #{num}{R}{A}{D} {return ANGLE;} | |||||
171 | #{num}{G}{R}{A}{D} {return ANGLE;} | |||||
172 | #{num}{M}{S} {return TIME;} | |||||
173 | #{num}{S} {return TIME;} | |||||
174 | #{num}{H}{Z} {return FREQ;} | |||||
175 | #{num}{K}{H}{Z} {return FREQ;} | |||||
176 | #{num}{ident} {return DIMENSION;} | |||||
177 | ||||||
178 | #{num}% {return PERCENTAGE;} | |||||
179 | #{num} {return NUMBER;} | |||||
180 | ||||||
181 | 4 | 28 | $self->add_toke_rule('EMS' , "$rx{num}$rx{E}$rx{M}"); | |||
182 | 4 | 27 | $self->add_toke_rule('EXS' , "$rx{num}$rx{E}$rx{X}"); | |||
183 | 4 | 119 | $self->add_toke_rule('LENGTH' , "$rx{num}($rx{P}$rx{X}|$rx{C}$rx{M}|$rx{M}$rx{M}|$rx{I}$rx{N}|$rx{P}$rx{T}|$rx{P}$rx{C})"); | |||
184 | 4 | 61 | $self->add_toke_rule('ANGLE' , "$rx{num}($rx{D}$rx{E}$rx{G}|$rx{R}$rx{A}$rx{D}|$rx{G}$rx{R}$rx{A}$rx{D})"); | |||
185 | 4 | 33 | $self->add_toke_rule('TIME' , "$rx{num}($rx{M}$rx{S}|$rx{S})"); | |||
186 | 4 | 41 | $self->add_toke_rule('FREQ' , "$rx{num}($rx{H}$rx{Z}|$rx{K}$rx{H}$rx{Z})"); | |||
187 | 4 | 25 | $self->add_toke_rule('DIMEN' , "$rx{num}$rx{ident}"); | |||
188 | 4 | 20 | $self->add_toke_rule('PERCENTAGE' , "$rx{num}%"); | |||
189 | 4 | 72 | $self->add_toke_rule('NUMBER' , "$rx{num}"); | |||
190 | ||||||
191 | ||||||
192 | #"url("{w}{string}{w}")" {return URI;} | |||||
193 | #"url("{w}{url}{w}")" {return URI;} | |||||
194 | #{ident}"(" {return FUNCTION;} | |||||
195 | ||||||
196 | 4 | 40 | $self->add_toke_rule('URI' , "url\\($rx{w}($rx{string}|$rx{url})$rx{w}\\)"); | |||
197 | 4 | 20 | $self->add_toke_rule('FUNCTION' , "$rx{ident}\\("); | |||
198 | ||||||
199 | ||||||
200 | ##################################################################################### | |||||
201 | ||||||
202 | 4 | 15 | $self->add_toke_rule('_SEMICOLON' , ';'); | |||
203 | 4 | 15 | $self->add_toke_rule('_BRACE_CLOSE' , '}'); | |||
204 | 4 | 14 | $self->add_toke_rule('_COLON' , ':'); | |||
205 | 4 | 16 | $self->add_toke_rule('_SLASH' , '/'); | |||
206 | 4 | 16 | $self->add_toke_rule('_MINUS' , '-'); | |||
207 | 4 | 16 | $self->add_toke_rule('_PERIOD' , '\\.'); | |||
208 | 4 | 16 | $self->add_toke_rule('_STAR' , '\\*'); | |||
209 | 4 | 15 | $self->add_toke_rule('_SQUARE_OPEN' , '\\['); | |||
210 | 4 | 14 | $self->add_toke_rule('_SQUARE_CLOSE' , '\\]'); | |||
211 | 4 | 15 | $self->add_toke_rule('_EQUALS' , '='); | |||
212 | 4 | 15 | $self->add_toke_rule('_ROUND_CLOSE' , '\\)'); | |||
213 | ||||||
214 | ||||||
215 | ##################################################################################### | |||||
216 | ||||||
217 | #stylesheet | |||||
218 | # : [ CHARSET_SYM STRING ';' ]? | |||||
219 | # [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* | |||||
220 | # [ [ ruleset | media | page ] [S|CDO|CDC]* ]* | |||||
221 | # ; | |||||
222 | #import | |||||
223 | # : IMPORT_SYM S* | |||||
224 | # [STRING|URI] S* [ medium [ COMMA S* medium]* ]? ';' S* | |||||
225 | # ; | |||||
226 | #media | |||||
227 | # : MEDIA_SYM S* medium [ COMMA S* medium ]* LBRACE S* ruleset* '}' S* | |||||
228 | # ; | |||||
229 | ||||||
230 | 4 | 26 | $self->add_lex_rule('stylesheet', '[ CHARSET_SYM S* STRING S* _SEMICOLON ]? [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* '. | |||
231 | '[ [ ruleset | media | page ] [S|CDO|CDC]* ]*'); | |||||
232 | 4 | 16 | $self->add_lex_rule('import', 'IMPORT_SYM S* [STRING|URI] S* [ medium [ COMMA S* medium]* ]? _SEMICOLON S*'); | |||
233 | 4 | 15 | $self->add_lex_rule('media', 'MEDIA_SYM S* medium [ COMMA S* medium ]* LBRACE S* ruleset* _BRACE_CLOSE S*'); | |||
234 | ||||||
235 | ||||||
236 | #medium | |||||
237 | # : IDENT S* | |||||
238 | # ; | |||||
239 | #page | |||||
240 | # : PAGE_SYM S* pseudo_page? S* | |||||
241 | # LBRACE S* declaration [ ';' S* declaration ]* '}' S* | |||||
242 | # ; | |||||
243 | #pseudo_page | |||||
244 | # : ':' IDENT | |||||
245 | # ; | |||||
246 | #operator | |||||
247 | # : '/' S* | COMMA S* | /* empty */ | |||||
248 | # ; | |||||
249 | ||||||
250 | 4 | 15 | $self->add_lex_rule('medium', 'IDENT S*'); | |||
251 | 4 | 18 | $self->add_lex_rule('page', 'PAGE_SYM S* pseudo_page? S* LBRACE S* declaration [ _SEMICOLON S* declaration ]* _BRACE_CLOSE S*'); | |||
252 | 4 | 15 | $self->add_lex_rule('pseudo_page', '_COLON IDENT'); | |||
253 | 4 | 16 | $self->add_lex_rule('operator', '_SLASH S* | COMMA S* | '); | |||
254 | ||||||
255 | ||||||
256 | #combinator | |||||
257 | # : PLUS S* | |||||
258 | # | GREATER S* | |||||
259 | # | S | |||||
260 | # ; | |||||
261 | #unary_operator | |||||
262 | # : '-' | PLUS | |||||
263 | # ; | |||||
264 | #property | |||||
265 | # : IDENT S* | |||||
266 | # ; | |||||
267 | #ruleset | |||||
268 | # : selector [ COMMA S* selector ]* | |||||
269 | # LBRACE S* declaration [ ';' S* declaration ]* '}' S* | |||||
270 | # ; | |||||
271 | ||||||
272 | 4 | 15 | $self->add_lex_rule('combinator', 'PLUS S* | GREATER S* | S+'); | |||
273 | 4 | 17 | $self->add_lex_rule('unary_operator', '_MINUS | PLUS'); | |||
274 | 4 | 16 | $self->add_lex_rule('property', 'IDENT S*'); | |||
275 | 4 | 17 | $self->add_lex_rule('ruleset', 'selector [ COMMA S* selector ]* S* LBRACE S* declaration [ _SEMICOLON S* declaration ]* _BRACE_CLOSE S*'); | |||
276 | ||||||
277 | ||||||
278 | #selector | |||||
279 | # : simple_selector [ combinator simple_selector ]* | |||||
280 | # ; | |||||
281 | #simple_selector | |||||
282 | # : element_name [ HASH | class | attrib | pseudo ]* | |||||
283 | # | [ HASH | class | attrib | pseudo ]+ | |||||
284 | # ; | |||||
285 | #class | |||||
286 | # : '.' IDENT | |||||
287 | # ; | |||||
288 | #element_name | |||||
289 | # : IDENT | '*' | |||||
290 | # ; | |||||
291 | ||||||
292 | 4 | 15 | $self->add_lex_rule('selector', 'simple_selector [ combinator simple_selector ]*'); | |||
293 | 4 | 15 | $self->add_lex_rule('simple_selector', 'element_name [ HASH | class | attrib | pseudo ]* | [ HASH | class | attrib | pseudo ]+'); | |||
294 | 4 | 16 | $self->add_lex_rule('class', '_PERIOD IDENT'); | |||
295 | 4 | 16 | $self->add_lex_rule('element_name', 'IDENT | _STAR'); | |||
296 | ||||||
297 | ||||||
298 | #attrib | |||||
299 | # : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S* | |||||
300 | # [ IDENT | STRING ] S* ]? ']' | |||||
301 | # ; | |||||
302 | #pseudo | |||||
303 | # : ':' [ IDENT | FUNCTION S* IDENT? S* ')' ] | |||||
304 | # ; | |||||
305 | #declaration | |||||
306 | # : property ':' S* expr prio? | |||||
307 | # | /* empty */ | |||||
308 | # ; | |||||
309 | #prio | |||||
310 | # : IMPORTANT_SYM S* | |||||
311 | # ; | |||||
312 | ||||||
313 | 4 | 16 | $self->add_lex_rule('attrib', '_SQUARE_OPEN S* IDENT S* [ [ _EQUALS | INCLUDES | DASHMATCH ] S* [ IDENT | STRING ] S* ]? _SQUARE_CLOSE'); | |||
314 | 4 | 17 | $self->add_lex_rule('pseudo', '_COLON [ IDENT | FUNCTION S* IDENT? S* _ROUND_CLOSE ]'); | |||
315 | 4 | 16 | $self->add_lex_rule('declaration', 'property _COLON S* expr prio? | '); | |||
316 | 4 | 15 | $self->add_lex_rule('prio', 'IMPORTANT_SYM S*'); | |||
317 | ||||||
318 | ||||||
319 | ##expr | |||||
320 | # : term [ operator term ]* | |||||
321 | # ; | |||||
322 | #term | |||||
323 | # : unary_operator? | |||||
324 | # [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | | |||||
325 | # TIME S* | FREQ S* ] | |||||
326 | # | STRING S* | IDENT S* | URI S* | hexcolor | function | |||||
327 | # ; | |||||
328 | #function | |||||
329 | # : FUNCTION S* expr ')' S* | |||||
330 | # ; | |||||
331 | #hexcolor | |||||
332 | # : HASH S* | |||||
333 | # ; | |||||
334 | ||||||
335 | 4 | 16 | $self->add_lex_rule('expr', 'term [ operator term ]*'); | |||
336 | 4 | 18 | $self->add_lex_rule('term', 'unary_operator? [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | TIME S* | FREQ S* ] '. | |||
337 | '| STRING S* | IDENT S* | URI S* | hexcolor | function'); | |||||
338 | 4 | 16 | $self->add_lex_rule('function', 'FUNCTION S* expr _ROUND_CLOSE S*'); | |||
339 | 4 | 16 | $self->add_lex_rule('hexcolor', 'HASH S*'); | |||
340 | ||||||
341 | ||||||
342 | ##################################################################################### | |||||
343 | ||||||
344 | 4 | 33 | $self->set_base('stylesheet'); | |||
345 | } | |||||
346 | ||||||
347 | sub toke { | |||||
348 | 3 | 19 | my ($self, $input) = @_; | |||
349 | ||||||
350 | # strip comments first | |||||
351 | 3 | 9 | $input =~ s!/\*[^*]*\*+([^/*][^*]*\*+)*/! !g; | |||
352 | ||||||
353 | 3 | 27 | $self->SUPER::toke($input); | |||
354 | } | |||||
355 | ||||||
356 | 1; |