racc 1.4.14-java → 1.4.15-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Manifest.txt +50 -0
- data/ext/racc/com/headius/racc/Cparse.java +66 -23
- data/ext/racc/cparse.c +1 -1
- data/ext/racc/depend +1 -1
- data/lib/racc/cparse-jruby.jar +0 -0
- data/lib/racc/info.rb +2 -2
- data/test/assets/bibtex.y +141 -0
- data/test/assets/cadenza.y +170 -0
- data/test/assets/cast.y +926 -0
- data/test/assets/csspool.y +729 -0
- data/test/assets/edtf.y +583 -0
- data/test/assets/huia.y +318 -0
- data/test/assets/journey.y +47 -0
- data/test/assets/liquor.y +313 -0
- data/test/assets/machete.y +423 -0
- data/test/assets/macruby.y +2197 -0
- data/test/assets/mediacloth.y +599 -0
- data/test/assets/mof.y +649 -0
- data/test/assets/namae.y +302 -0
- data/test/assets/nasl.y +626 -0
- data/test/assets/nokogiri-css.y +255 -0
- data/test/assets/opal.y +1807 -0
- data/test/assets/php_serialization.y +98 -0
- data/test/assets/rdblockparser.y +576 -0
- data/test/assets/rdinlineparser.y +561 -0
- data/test/assets/riml.y +665 -0
- data/test/assets/ruby18.y +1943 -0
- data/test/assets/ruby19.y +2174 -0
- data/test/assets/ruby20.y +2350 -0
- data/test/assets/ruby21.y +2359 -0
- data/test/assets/ruby22.y +2381 -0
- data/test/assets/tp_plus.y +622 -0
- data/test/assets/twowaysql.y +278 -0
- data/test/helper.rb +50 -34
- data/test/regress/bibtex +474 -0
- data/test/regress/cadenza +796 -0
- data/test/regress/cast +3425 -0
- data/test/regress/csspool +2318 -0
- data/test/regress/edtf +1794 -0
- data/test/regress/huia +1392 -0
- data/test/regress/journey +222 -0
- data/test/regress/liquor +885 -0
- data/test/regress/machete +833 -0
- data/test/regress/mediacloth +1463 -0
- data/test/regress/mof +1368 -0
- data/test/regress/namae +634 -0
- data/test/regress/nasl +2058 -0
- data/test/regress/nokogiri-css +836 -0
- data/test/regress/opal +6429 -0
- data/test/regress/php_serialization +336 -0
- data/test/regress/rdblockparser +1061 -0
- data/test/regress/rdinlineparser +1243 -0
- data/test/regress/riml +3297 -0
- data/test/regress/ruby18 +6351 -0
- data/test/regress/ruby22 +7456 -0
- data/test/regress/tp_plus +1933 -0
- data/test/regress/twowaysql +556 -0
- data/test/test_racc_command.rb +177 -0
- metadata +80 -25
- data/.gemtest +0 -0
@@ -0,0 +1,729 @@
|
|
1
|
+
class CSSPool::CSS::Parser
|
2
|
+
|
3
|
+
token CHARSET_SYM IMPORT_SYM STRING SEMI IDENT S COMMA LBRACE RBRACE STAR HASH
|
4
|
+
token LSQUARE RSQUARE EQUAL INCLUDES DASHMATCH LPAREN RPAREN FUNCTION GREATER PLUS
|
5
|
+
token SLASH NUMBER MINUS LENGTH PERCENTAGE ANGLE TIME FREQ URI
|
6
|
+
token IMPORTANT_SYM MEDIA_SYM NOT ONLY AND NTH_PSEUDO_CLASS
|
7
|
+
token DOCUMENT_QUERY_SYM FUNCTION_NO_QUOTE
|
8
|
+
token TILDE
|
9
|
+
token PREFIXMATCH SUFFIXMATCH SUBSTRINGMATCH
|
10
|
+
token NOT_PSEUDO_CLASS
|
11
|
+
token KEYFRAMES_SYM
|
12
|
+
token MATCHES_PSEUDO_CLASS
|
13
|
+
token NAMESPACE_SYM
|
14
|
+
token MOZ_PSEUDO_ELEMENT
|
15
|
+
token RESOLUTION
|
16
|
+
token COLON
|
17
|
+
token SUPPORTS_SYM
|
18
|
+
token OR
|
19
|
+
token VARIABLE_NAME
|
20
|
+
token CALC_SYM
|
21
|
+
token FONTFACE_SYM
|
22
|
+
token UNICODE_RANGE
|
23
|
+
token RATIO
|
24
|
+
|
25
|
+
rule
|
26
|
+
document
|
27
|
+
: { @handler.start_document }
|
28
|
+
stylesheet
|
29
|
+
{ @handler.end_document }
|
30
|
+
;
|
31
|
+
stylesheet
|
32
|
+
: charset stylesheet
|
33
|
+
| import stylesheet
|
34
|
+
| namespace stylesheet
|
35
|
+
| charset
|
36
|
+
| import
|
37
|
+
| namespace
|
38
|
+
| body
|
39
|
+
|
|
40
|
+
;
|
41
|
+
charset
|
42
|
+
: CHARSET_SYM STRING SEMI { @handler.charset interpret_string(val[1]), {} }
|
43
|
+
;
|
44
|
+
import
|
45
|
+
: IMPORT_SYM import_location medium SEMI {
|
46
|
+
@handler.import_style val[2], val[1]
|
47
|
+
}
|
48
|
+
| IMPORT_SYM import_location SEMI {
|
49
|
+
@handler.import_style [], val[1]
|
50
|
+
}
|
51
|
+
;
|
52
|
+
import_location
|
53
|
+
: import_location S
|
54
|
+
| STRING { result = Terms::String.new interpret_string val.first }
|
55
|
+
| URI { result = Terms::URI.new interpret_uri val.first }
|
56
|
+
;
|
57
|
+
namespace
|
58
|
+
: NAMESPACE_SYM ident import_location SEMI {
|
59
|
+
@handler.namespace val[1], val[2]
|
60
|
+
}
|
61
|
+
| NAMESPACE_SYM import_location SEMI {
|
62
|
+
@handler.namespace nil, val[1]
|
63
|
+
}
|
64
|
+
;
|
65
|
+
medium
|
66
|
+
: medium COMMA IDENT {
|
67
|
+
result = val[0] << MediaType.new(val[2])
|
68
|
+
}
|
69
|
+
| IDENT {
|
70
|
+
result = [MediaType.new(val[0])]
|
71
|
+
}
|
72
|
+
;
|
73
|
+
media_query_list
|
74
|
+
: media_query { result = MediaQueryList.new([ val[0] ]) }
|
75
|
+
| media_query_list COMMA media_query { result = val[0] << val[2] }
|
76
|
+
| { result = MediaQueryList.new }
|
77
|
+
;
|
78
|
+
media_query
|
79
|
+
: optional_only_or_not media_type optional_and_exprs { result = MediaQuery.new(val[0], val[1], val[2]) }
|
80
|
+
| media_expr optional_and_exprs { result = MediaQuery.new(nil, val[0], val[1]) }
|
81
|
+
;
|
82
|
+
optional_only_or_not
|
83
|
+
: ONLY { result = :only }
|
84
|
+
| NOT { result = :not }
|
85
|
+
| { result = nil }
|
86
|
+
;
|
87
|
+
media_type
|
88
|
+
: IDENT { result = MediaType.new(val[0]) }
|
89
|
+
;
|
90
|
+
media_expr
|
91
|
+
: LPAREN optional_space IDENT optional_space RPAREN { result = MediaType.new(val[2]) }
|
92
|
+
| LPAREN optional_space IDENT optional_space COLON optional_space expr RPAREN { result = MediaFeature.new(val[2], val[6][0]) }
|
93
|
+
;
|
94
|
+
optional_space
|
95
|
+
: S { result = val[0] }
|
96
|
+
| { result = nil }
|
97
|
+
;
|
98
|
+
optional_and_exprs
|
99
|
+
: optional_and_exprs AND media_expr { result = val[0] << val[2] }
|
100
|
+
| { result = [] }
|
101
|
+
;
|
102
|
+
resolution
|
103
|
+
: RESOLUTION {
|
104
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
105
|
+
number = numeric(val.first)
|
106
|
+
result = Terms::Resolution.new(number, unit)
|
107
|
+
}
|
108
|
+
;
|
109
|
+
body
|
110
|
+
: ruleset body
|
111
|
+
| conditional_rule body
|
112
|
+
| keyframes_rule body
|
113
|
+
| fontface_rule body
|
114
|
+
| ruleset
|
115
|
+
| conditional_rule
|
116
|
+
| keyframes_rule
|
117
|
+
| fontface_rule
|
118
|
+
;
|
119
|
+
conditional_rule
|
120
|
+
: media
|
121
|
+
| document_query
|
122
|
+
| supports
|
123
|
+
;
|
124
|
+
body_in_media
|
125
|
+
: body
|
126
|
+
| empty_ruleset
|
127
|
+
;
|
128
|
+
media
|
129
|
+
: start_media body_in_media RBRACE { @handler.end_media val.first }
|
130
|
+
;
|
131
|
+
start_media
|
132
|
+
: MEDIA_SYM media_query_list LBRACE {
|
133
|
+
result = val[1]
|
134
|
+
@handler.start_media result
|
135
|
+
}
|
136
|
+
;
|
137
|
+
document_query
|
138
|
+
: start_document_query body RBRACE { @handler.end_document_query(before_pos(val), after_pos(val)) }
|
139
|
+
| start_document_query RBRACE { @handler.end_document_query(before_pos(val), after_pos(val)) }
|
140
|
+
;
|
141
|
+
start_document_query
|
142
|
+
: start_document_query_pos url_match_fns LBRACE {
|
143
|
+
@handler.start_document_query(val[1], after_pos(val))
|
144
|
+
}
|
145
|
+
;
|
146
|
+
start_document_query_pos
|
147
|
+
: DOCUMENT_QUERY_SYM {
|
148
|
+
@handler.node_start_pos = before_pos(val)
|
149
|
+
}
|
150
|
+
;
|
151
|
+
url_match_fns
|
152
|
+
: url_match_fn COMMA url_match_fns {
|
153
|
+
result = [val[0], val[2]].flatten
|
154
|
+
}
|
155
|
+
| url_match_fn {
|
156
|
+
result = val
|
157
|
+
}
|
158
|
+
;
|
159
|
+
url_match_fn
|
160
|
+
: function_no_quote
|
161
|
+
| function
|
162
|
+
| uri
|
163
|
+
;
|
164
|
+
supports
|
165
|
+
: start_supports body RBRACE { @handler.end_supports }
|
166
|
+
| start_supports RBRACE { @handler.end_supports }
|
167
|
+
;
|
168
|
+
start_supports
|
169
|
+
: SUPPORTS_SYM supports_condition_root LBRACE {
|
170
|
+
@handler.start_supports val[1]
|
171
|
+
}
|
172
|
+
;
|
173
|
+
supports_condition_root
|
174
|
+
: supports_negation { result = val.join('') }
|
175
|
+
| supports_conjunction_or_disjunction { result = val.join('') }
|
176
|
+
| supports_condition_in_parens { result = val.join('') }
|
177
|
+
;
|
178
|
+
supports_condition
|
179
|
+
: supports_negation { result = val.join('') }
|
180
|
+
| supports_conjunction_or_disjunction { result = val.join('') }
|
181
|
+
| supports_condition_in_parens { result = val.join('') }
|
182
|
+
;
|
183
|
+
supports_condition_in_parens
|
184
|
+
: LPAREN supports_condition RPAREN { result = val.join('') }
|
185
|
+
| supports_declaration_condition { result = val.join('') }
|
186
|
+
;
|
187
|
+
supports_negation
|
188
|
+
: NOT supports_condition_in_parens { result = val.join('') }
|
189
|
+
;
|
190
|
+
supports_conjunction_or_disjunction
|
191
|
+
: supports_conjunction
|
192
|
+
| supports_disjunction
|
193
|
+
;
|
194
|
+
supports_conjunction
|
195
|
+
: supports_condition_in_parens AND supports_condition_in_parens { result = val.join('') }
|
196
|
+
| supports_conjunction_or_disjunction AND supports_condition_in_parens { result = val.join('') }
|
197
|
+
;
|
198
|
+
supports_disjunction
|
199
|
+
: supports_condition_in_parens OR supports_condition_in_parens { result = val.join('') }
|
200
|
+
| supports_conjunction_or_disjunction OR supports_condition_in_parens { result = val.join('') }
|
201
|
+
;
|
202
|
+
supports_declaration_condition
|
203
|
+
: LPAREN declaration_internal RPAREN { result = val.join('') }
|
204
|
+
| LPAREN S declaration_internal RPAREN { result = val.join('') }
|
205
|
+
;
|
206
|
+
keyframes_rule
|
207
|
+
: start_keyframes_rule keyframes_blocks RBRACE
|
208
|
+
| start_keyframes_rule RBRACE
|
209
|
+
;
|
210
|
+
start_keyframes_rule
|
211
|
+
: KEYFRAMES_SYM IDENT LBRACE {
|
212
|
+
@handler.start_keyframes_rule val[1]
|
213
|
+
}
|
214
|
+
;
|
215
|
+
keyframes_blocks
|
216
|
+
: keyframes_block keyframes_blocks
|
217
|
+
| keyframes_block
|
218
|
+
;
|
219
|
+
keyframes_block
|
220
|
+
: start_keyframes_block declarations RBRACE { @handler.end_keyframes_block }
|
221
|
+
| start_keyframes_block RBRACE { @handler.end_keyframes_block }
|
222
|
+
;
|
223
|
+
start_keyframes_block
|
224
|
+
: keyframes_selectors LBRACE {
|
225
|
+
@handler.start_keyframes_block val[0]
|
226
|
+
}
|
227
|
+
;
|
228
|
+
keyframes_selectors
|
229
|
+
| keyframes_selector COMMA keyframes_selectors {
|
230
|
+
result = val[0] + ', ' + val[2]
|
231
|
+
}
|
232
|
+
| keyframes_selector
|
233
|
+
;
|
234
|
+
keyframes_selector
|
235
|
+
: IDENT
|
236
|
+
| PERCENTAGE { result = val[0].strip }
|
237
|
+
;
|
238
|
+
fontface_rule
|
239
|
+
: start_fontface_rule declarations RBRACE { @handler.end_fontface_rule }
|
240
|
+
| start_fontface_rule RBRACE { @handler.end_fontface_rule }
|
241
|
+
;
|
242
|
+
start_fontface_rule
|
243
|
+
: FONTFACE_SYM LBRACE {
|
244
|
+
@handler.start_fontface_rule
|
245
|
+
}
|
246
|
+
;
|
247
|
+
ruleset
|
248
|
+
: start_selector declarations RBRACE {
|
249
|
+
@handler.end_selector val.first
|
250
|
+
}
|
251
|
+
| start_selector RBRACE {
|
252
|
+
@handler.end_selector val.first
|
253
|
+
}
|
254
|
+
;
|
255
|
+
empty_ruleset
|
256
|
+
: optional_space {
|
257
|
+
start = @handler.start_selector([])
|
258
|
+
@handler.end_selector(start)
|
259
|
+
}
|
260
|
+
;
|
261
|
+
start_selector
|
262
|
+
: S start_selector { result = val.last }
|
263
|
+
| selectors LBRACE {
|
264
|
+
@handler.start_selector val.first
|
265
|
+
}
|
266
|
+
;
|
267
|
+
selectors
|
268
|
+
: selector COMMA selectors
|
269
|
+
{
|
270
|
+
sel = Selector.new(val.first, {})
|
271
|
+
result = [sel].concat(val[2])
|
272
|
+
}
|
273
|
+
| selector
|
274
|
+
{
|
275
|
+
result = [Selector.new(val.first, {})]
|
276
|
+
}
|
277
|
+
;
|
278
|
+
selector
|
279
|
+
: simple_selector combinator selector
|
280
|
+
{
|
281
|
+
val.flatten!
|
282
|
+
val[2].combinator = val.delete_at 1
|
283
|
+
result = val
|
284
|
+
}
|
285
|
+
| simple_selector
|
286
|
+
;
|
287
|
+
combinator
|
288
|
+
: S { result = :s }
|
289
|
+
| GREATER { result = :> }
|
290
|
+
| PLUS { result = :+ }
|
291
|
+
| TILDE { result = :~ }
|
292
|
+
;
|
293
|
+
simple_selector
|
294
|
+
: element_name hcap {
|
295
|
+
selector = val.first
|
296
|
+
selector.additional_selectors = val.last
|
297
|
+
result = [selector]
|
298
|
+
}
|
299
|
+
| element_name { result = val }
|
300
|
+
| hcap
|
301
|
+
{
|
302
|
+
ss = Selectors::Simple.new nil, nil
|
303
|
+
ss.additional_selectors = val.flatten
|
304
|
+
result = [ss]
|
305
|
+
}
|
306
|
+
;
|
307
|
+
simple_selectors
|
308
|
+
: simple_selector COMMA simple_selectors { result = [val[0], val[2]].flatten }
|
309
|
+
| simple_selector
|
310
|
+
;
|
311
|
+
ident_with_namespace
|
312
|
+
: IDENT { result = [interpret_identifier(val[0]), nil] }
|
313
|
+
| IDENT '|' IDENT { result = [interpret_identifier(val[2]), interpret_identifier(val[0])] }
|
314
|
+
| '|' IDENT { result = [interpret_identifier(val[1]), nil] }
|
315
|
+
| STAR '|' IDENT { result = [interpret_identifier(val[2]), '*'] }
|
316
|
+
;
|
317
|
+
element_name
|
318
|
+
: ident_with_namespace { result = Selectors::Type.new val.first[0], nil, val.first[1] }
|
319
|
+
| STAR { result = Selectors::Universal.new val.first }
|
320
|
+
| '|' STAR { result = Selectors::Universal.new val[1] }
|
321
|
+
| STAR '|' STAR { result = Selectors::Universal.new val[2], nil, val[0] }
|
322
|
+
| IDENT '|' STAR { result = Selectors::Universal.new val[2], nil, interpret_identifier(val[0]) }
|
323
|
+
;
|
324
|
+
hcap
|
325
|
+
: hash { result = val }
|
326
|
+
| class { result = val }
|
327
|
+
| attrib { result = val }
|
328
|
+
| pseudo { result = val }
|
329
|
+
| hash hcap { result = val.flatten }
|
330
|
+
| class hcap { result = val.flatten }
|
331
|
+
| attrib hcap { result = val.flatten }
|
332
|
+
| pseudo hcap { result = val.flatten }
|
333
|
+
;
|
334
|
+
hash
|
335
|
+
: HASH {
|
336
|
+
result = Selectors::Id.new interpret_identifier val.first.sub(/^#/, '')
|
337
|
+
}
|
338
|
+
class
|
339
|
+
: '.' IDENT {
|
340
|
+
result = Selectors::Class.new interpret_identifier val.last
|
341
|
+
}
|
342
|
+
;
|
343
|
+
attrib
|
344
|
+
: LSQUARE ident_with_namespace EQUAL IDENT RSQUARE {
|
345
|
+
result = Selectors::Attribute.new(
|
346
|
+
val[1][0],
|
347
|
+
interpret_identifier(val[3]),
|
348
|
+
Selectors::Attribute::EQUALS,
|
349
|
+
val[1][1]
|
350
|
+
)
|
351
|
+
}
|
352
|
+
| LSQUARE ident_with_namespace EQUAL STRING RSQUARE {
|
353
|
+
result = Selectors::Attribute.new(
|
354
|
+
val[1][0],
|
355
|
+
interpret_string(val[3]),
|
356
|
+
Selectors::Attribute::EQUALS,
|
357
|
+
val[1][1]
|
358
|
+
)
|
359
|
+
}
|
360
|
+
| LSQUARE ident_with_namespace INCLUDES STRING RSQUARE {
|
361
|
+
result = Selectors::Attribute.new(
|
362
|
+
val[1][0],
|
363
|
+
interpret_string(val[3]),
|
364
|
+
Selectors::Attribute::INCLUDES,
|
365
|
+
val[1][1]
|
366
|
+
)
|
367
|
+
}
|
368
|
+
| LSQUARE ident_with_namespace INCLUDES IDENT RSQUARE {
|
369
|
+
result = Selectors::Attribute.new(
|
370
|
+
val[1][0],
|
371
|
+
interpret_identifier(val[3]),
|
372
|
+
Selectors::Attribute::INCLUDES,
|
373
|
+
val[1][1]
|
374
|
+
)
|
375
|
+
}
|
376
|
+
| LSQUARE ident_with_namespace DASHMATCH IDENT RSQUARE {
|
377
|
+
result = Selectors::Attribute.new(
|
378
|
+
val[1][0],
|
379
|
+
interpret_identifier(val[3]),
|
380
|
+
Selectors::Attribute::DASHMATCH,
|
381
|
+
val[1][1]
|
382
|
+
)
|
383
|
+
}
|
384
|
+
| LSQUARE ident_with_namespace DASHMATCH STRING RSQUARE {
|
385
|
+
result = Selectors::Attribute.new(
|
386
|
+
val[1][0],
|
387
|
+
interpret_string(val[3]),
|
388
|
+
Selectors::Attribute::DASHMATCH,
|
389
|
+
val[1][1]
|
390
|
+
)
|
391
|
+
}
|
392
|
+
| LSQUARE ident_with_namespace PREFIXMATCH IDENT RSQUARE {
|
393
|
+
result = Selectors::Attribute.new(
|
394
|
+
val[1][0],
|
395
|
+
interpret_identifier(val[3]),
|
396
|
+
Selectors::Attribute::PREFIXMATCH,
|
397
|
+
val[1][1]
|
398
|
+
)
|
399
|
+
}
|
400
|
+
| LSQUARE ident_with_namespace PREFIXMATCH STRING RSQUARE {
|
401
|
+
result = Selectors::Attribute.new(
|
402
|
+
val[1][0],
|
403
|
+
interpret_string(val[3]),
|
404
|
+
Selectors::Attribute::PREFIXMATCH,
|
405
|
+
val[1][1]
|
406
|
+
)
|
407
|
+
}
|
408
|
+
| LSQUARE ident_with_namespace SUFFIXMATCH IDENT RSQUARE {
|
409
|
+
result = Selectors::Attribute.new(
|
410
|
+
val[1][0],
|
411
|
+
interpret_identifier(val[3]),
|
412
|
+
Selectors::Attribute::SUFFIXMATCH,
|
413
|
+
val[1][1]
|
414
|
+
)
|
415
|
+
}
|
416
|
+
| LSQUARE ident_with_namespace SUFFIXMATCH STRING RSQUARE {
|
417
|
+
result = Selectors::Attribute.new(
|
418
|
+
val[1][0],
|
419
|
+
interpret_string(val[3]),
|
420
|
+
Selectors::Attribute::SUFFIXMATCH,
|
421
|
+
val[1][1]
|
422
|
+
)
|
423
|
+
}
|
424
|
+
| LSQUARE ident_with_namespace SUBSTRINGMATCH IDENT RSQUARE {
|
425
|
+
result = Selectors::Attribute.new(
|
426
|
+
val[1][0],
|
427
|
+
interpret_identifier(val[3]),
|
428
|
+
Selectors::Attribute::SUBSTRINGMATCH,
|
429
|
+
val[1][1]
|
430
|
+
)
|
431
|
+
}
|
432
|
+
| LSQUARE ident_with_namespace SUBSTRINGMATCH STRING RSQUARE {
|
433
|
+
result = Selectors::Attribute.new(
|
434
|
+
val[1][0],
|
435
|
+
interpret_string(val[3]),
|
436
|
+
Selectors::Attribute::SUBSTRINGMATCH,
|
437
|
+
val[1][1]
|
438
|
+
)
|
439
|
+
}
|
440
|
+
| LSQUARE ident_with_namespace RSQUARE {
|
441
|
+
result = Selectors::Attribute.new(
|
442
|
+
val[1][0],
|
443
|
+
nil,
|
444
|
+
Selectors::Attribute::SET,
|
445
|
+
val[1][1]
|
446
|
+
)
|
447
|
+
}
|
448
|
+
;
|
449
|
+
pseudo
|
450
|
+
: COLON IDENT {
|
451
|
+
result = Selectors::pseudo interpret_identifier(val[1])
|
452
|
+
}
|
453
|
+
| COLON COLON IDENT {
|
454
|
+
result = Selectors::PseudoElement.new(
|
455
|
+
interpret_identifier(val[2])
|
456
|
+
)
|
457
|
+
}
|
458
|
+
| COLON FUNCTION RPAREN {
|
459
|
+
result = Selectors::PseudoClass.new(
|
460
|
+
interpret_identifier(val[1].sub(/\($/, '')),
|
461
|
+
''
|
462
|
+
)
|
463
|
+
}
|
464
|
+
| COLON FUNCTION IDENT RPAREN {
|
465
|
+
result = Selectors::PseudoClass.new(
|
466
|
+
interpret_identifier(val[1].sub(/\($/, '')),
|
467
|
+
interpret_identifier(val[2])
|
468
|
+
)
|
469
|
+
}
|
470
|
+
| COLON NOT_PSEUDO_CLASS simple_selector RPAREN {
|
471
|
+
result = Selectors::PseudoClass.new(
|
472
|
+
'not',
|
473
|
+
val[2].first.to_s
|
474
|
+
)
|
475
|
+
}
|
476
|
+
| COLON NTH_PSEUDO_CLASS {
|
477
|
+
result = Selectors::PseudoClass.new(
|
478
|
+
interpret_identifier(val[1].sub(/\(.*/, '')),
|
479
|
+
interpret_identifier(val[1].sub(/.*\(/, '').sub(/\).*/, ''))
|
480
|
+
)
|
481
|
+
}
|
482
|
+
| COLON MATCHES_PSEUDO_CLASS simple_selectors RPAREN {
|
483
|
+
result = Selectors::PseudoClass.new(
|
484
|
+
val[1].split('(').first.strip,
|
485
|
+
val[2].join(', ')
|
486
|
+
)
|
487
|
+
}
|
488
|
+
| COLON MOZ_PSEUDO_ELEMENT optional_space any_number_of_idents optional_space RPAREN {
|
489
|
+
result = Selectors::PseudoElement.new(
|
490
|
+
interpret_identifier(val[1].sub(/\($/, ''))
|
491
|
+
)
|
492
|
+
}
|
493
|
+
| COLON COLON MOZ_PSEUDO_ELEMENT optional_space any_number_of_idents optional_space RPAREN {
|
494
|
+
result = Selectors::PseudoElement.new(
|
495
|
+
interpret_identifier(val[2].sub(/\($/, ''))
|
496
|
+
)
|
497
|
+
}
|
498
|
+
;
|
499
|
+
any_number_of_idents
|
500
|
+
:
|
501
|
+
| multiple_idents
|
502
|
+
;
|
503
|
+
multiple_idents
|
504
|
+
: IDENT
|
505
|
+
| IDENT COMMA multiple_idents
|
506
|
+
;
|
507
|
+
# declarations can be separated by one *or more* semicolons. semi-colons at the start or end of a ruleset are also allowed
|
508
|
+
one_or_more_semis
|
509
|
+
: SEMI
|
510
|
+
| SEMI one_or_more_semis
|
511
|
+
;
|
512
|
+
declarations
|
513
|
+
: declaration one_or_more_semis declarations
|
514
|
+
| one_or_more_semis declarations
|
515
|
+
| declaration one_or_more_semis
|
516
|
+
| declaration
|
517
|
+
| one_or_more_semis
|
518
|
+
;
|
519
|
+
declaration
|
520
|
+
: declaration_internal { @handler.property val.first }
|
521
|
+
;
|
522
|
+
declaration_internal
|
523
|
+
: property COLON expr prio
|
524
|
+
{ result = Declaration.new(val.first, val[2], val[3]) }
|
525
|
+
| property COLON S expr prio
|
526
|
+
{ result = Declaration.new(val.first, val[3], val[4]) }
|
527
|
+
| property S COLON expr prio
|
528
|
+
{ result = Declaration.new(val.first, val[3], val[4]) }
|
529
|
+
| property S COLON S expr prio
|
530
|
+
{ result = Declaration.new(val.first, val[4], val[5]) }
|
531
|
+
;
|
532
|
+
prio
|
533
|
+
: IMPORTANT_SYM { result = true }
|
534
|
+
| { result = false }
|
535
|
+
;
|
536
|
+
property
|
537
|
+
: IDENT { result = interpret_identifier val[0] }
|
538
|
+
| STAR IDENT { result = interpret_identifier val.join }
|
539
|
+
| VARIABLE_NAME { result = interpret_identifier val[0] }
|
540
|
+
;
|
541
|
+
operator
|
542
|
+
: COMMA
|
543
|
+
| SLASH
|
544
|
+
| EQUAL
|
545
|
+
;
|
546
|
+
expr
|
547
|
+
: term operator expr {
|
548
|
+
result = [val.first, val.last].flatten
|
549
|
+
val.last.first.operator = val[1]
|
550
|
+
}
|
551
|
+
| term expr { result = val.flatten }
|
552
|
+
| term { result = val }
|
553
|
+
;
|
554
|
+
term
|
555
|
+
: ident
|
556
|
+
| ratio
|
557
|
+
| numeric
|
558
|
+
| string
|
559
|
+
| uri
|
560
|
+
| hexcolor
|
561
|
+
| calc
|
562
|
+
| function
|
563
|
+
| resolution
|
564
|
+
| VARIABLE_NAME
|
565
|
+
| uranges
|
566
|
+
;
|
567
|
+
function
|
568
|
+
: function S { result = val.first }
|
569
|
+
| FUNCTION expr RPAREN {
|
570
|
+
name = interpret_identifier val.first.sub(/\($/, '')
|
571
|
+
if name == 'rgb'
|
572
|
+
result = Terms::Rgb.new(*val[1])
|
573
|
+
else
|
574
|
+
result = Terms::Function.new name, val[1]
|
575
|
+
end
|
576
|
+
}
|
577
|
+
| FUNCTION RPAREN {
|
578
|
+
name = interpret_identifier val.first.sub(/\($/, '')
|
579
|
+
result = Terms::Function.new name
|
580
|
+
}
|
581
|
+
;
|
582
|
+
function_no_quote
|
583
|
+
: function_no_quote S { result = val.first }
|
584
|
+
| FUNCTION_NO_QUOTE {
|
585
|
+
parts = val.first.split('(')
|
586
|
+
name = interpret_identifier parts.first
|
587
|
+
result = Terms::Function.new(name, [Terms::String.new(interpret_string_no_quote(parts.last))])
|
588
|
+
}
|
589
|
+
;
|
590
|
+
uranges
|
591
|
+
: UNICODE_RANGE COMMA uranges
|
592
|
+
| UNICODE_RANGE
|
593
|
+
;
|
594
|
+
calc
|
595
|
+
: CALC_SYM calc_sum RPAREN optional_space {
|
596
|
+
result = Terms::Math.new(val.first.split('(').first, val[1])
|
597
|
+
}
|
598
|
+
;
|
599
|
+
# plus and minus are supposed to have whitespace around them, per http://dev.w3.org/csswg/css-values/#calc-syntax, but the numbers are eating trailing whitespace, so we inject it back in
|
600
|
+
calc_sum
|
601
|
+
: calc_product
|
602
|
+
| calc_product PLUS calc_sum { val.insert(1, ' '); result = val.join('') }
|
603
|
+
| calc_product MINUS calc_sum { val.insert(1, ' '); result = val.join('') }
|
604
|
+
;
|
605
|
+
calc_product
|
606
|
+
: calc_value
|
607
|
+
| calc_value optional_space STAR calc_value { result = val.join('') }
|
608
|
+
| calc_value optional_space SLASH calc_value { result = val.join('') }
|
609
|
+
;
|
610
|
+
calc_value
|
611
|
+
: numeric { result = val.join('') }
|
612
|
+
| function { result = val.join('') } # for var() variable references
|
613
|
+
| LPAREN calc_sum RPAREN { result = val.join('') }
|
614
|
+
;
|
615
|
+
hexcolor
|
616
|
+
: hexcolor S { result = val.first }
|
617
|
+
| HASH { result = Terms::Hash.new val.first.sub(/^#/, '') }
|
618
|
+
;
|
619
|
+
uri
|
620
|
+
: uri S { result = val.first }
|
621
|
+
| URI { result = Terms::URI.new interpret_uri val.first }
|
622
|
+
;
|
623
|
+
string
|
624
|
+
: string S { result = val.first }
|
625
|
+
| STRING { result = Terms::String.new interpret_string val.first }
|
626
|
+
;
|
627
|
+
numeric
|
628
|
+
: unary_operator numeric {
|
629
|
+
result = val[1]
|
630
|
+
val[1].unary_operator = val.first
|
631
|
+
}
|
632
|
+
| NUMBER {
|
633
|
+
result = Terms::Number.new numeric val.first
|
634
|
+
}
|
635
|
+
| PERCENTAGE {
|
636
|
+
result = Terms::Number.new numeric(val.first), nil, '%'
|
637
|
+
}
|
638
|
+
| LENGTH {
|
639
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
640
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
641
|
+
}
|
642
|
+
| ANGLE {
|
643
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
644
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
645
|
+
}
|
646
|
+
| TIME {
|
647
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
648
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
649
|
+
}
|
650
|
+
| FREQ {
|
651
|
+
unit = val.first.gsub(/[\s\d.]/, '')
|
652
|
+
result = Terms::Number.new numeric(val.first), nil, unit
|
653
|
+
}
|
654
|
+
;
|
655
|
+
ratio
|
656
|
+
: RATIO {
|
657
|
+
result = Terms::Ratio.new(val[0], val[1])
|
658
|
+
}
|
659
|
+
;
|
660
|
+
unary_operator
|
661
|
+
: MINUS { result = :minus }
|
662
|
+
| PLUS { result = :plus }
|
663
|
+
;
|
664
|
+
ident
|
665
|
+
: ident S { result = val.first }
|
666
|
+
| IDENT { result = Terms::Ident.new interpret_identifier val.first }
|
667
|
+
;
|
668
|
+
|
669
|
+
---- inner
|
670
|
+
|
671
|
+
def numeric thing
|
672
|
+
thing = thing.gsub(/[^\d.]/, '')
|
673
|
+
Integer(thing) rescue Float(thing)
|
674
|
+
end
|
675
|
+
|
676
|
+
def interpret_identifier s
|
677
|
+
interpret_escapes s
|
678
|
+
end
|
679
|
+
|
680
|
+
def interpret_uri s
|
681
|
+
interpret_escapes s.match(/^url\((.*)\)$/mui)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
|
682
|
+
end
|
683
|
+
|
684
|
+
def interpret_string_no_quote s
|
685
|
+
interpret_escapes s.match(/^(.*)\)$/mu)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
|
686
|
+
end
|
687
|
+
|
688
|
+
def interpret_string s
|
689
|
+
interpret_escapes s.match(/^(['"])((?:\\.|.)*)\1$/mu)[2]
|
690
|
+
end
|
691
|
+
|
692
|
+
def interpret_escapes s
|
693
|
+
token_exp = /\\(?:([0-9a-fA-F]{1,6}(?:\r\n|\s)?)|(.))/mu
|
694
|
+
return s.gsub(token_exp) do |escape_sequence|
|
695
|
+
if !$1.nil?
|
696
|
+
code = $1.chomp.to_i 16
|
697
|
+
code = 0xFFFD if code > 0x10FFFF
|
698
|
+
next [code].pack('U')
|
699
|
+
end
|
700
|
+
next '' if $2 == "\n"
|
701
|
+
next $2
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
# override racc's on_error so we can have context in our error messages
|
706
|
+
def on_error(t, val, vstack)
|
707
|
+
errcontext = (@ss.pre_match[-10..-1] || @ss.pre_match) +
|
708
|
+
@ss.matched + @ss.post_match[0..9]
|
709
|
+
line_number = @ss.pre_match.lines.count
|
710
|
+
raise ParseError, sprintf("parse error on value %s (%s) " +
|
711
|
+
"on line %s around \"%s\"",
|
712
|
+
val.inspect, token_to_str(t) || '?',
|
713
|
+
line_number, errcontext)
|
714
|
+
end
|
715
|
+
|
716
|
+
def before_pos(val)
|
717
|
+
# don't include leading whitespace
|
718
|
+
return current_pos - val.last.length + val.last[/\A\s*/].size
|
719
|
+
end
|
720
|
+
|
721
|
+
def after_pos(val)
|
722
|
+
# don't include trailing whitespace
|
723
|
+
return current_pos - val.last[/\s*\z/].size
|
724
|
+
end
|
725
|
+
|
726
|
+
# charpos will work with multibyte strings but is not available until ruby 2
|
727
|
+
def current_pos
|
728
|
+
@ss.respond_to?('charpos') ? @ss.charpos : @ss.pos
|
729
|
+
end
|