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.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/Manifest.txt +50 -0
  3. data/ext/racc/com/headius/racc/Cparse.java +66 -23
  4. data/ext/racc/cparse.c +1 -1
  5. data/ext/racc/depend +1 -1
  6. data/lib/racc/cparse-jruby.jar +0 -0
  7. data/lib/racc/info.rb +2 -2
  8. data/test/assets/bibtex.y +141 -0
  9. data/test/assets/cadenza.y +170 -0
  10. data/test/assets/cast.y +926 -0
  11. data/test/assets/csspool.y +729 -0
  12. data/test/assets/edtf.y +583 -0
  13. data/test/assets/huia.y +318 -0
  14. data/test/assets/journey.y +47 -0
  15. data/test/assets/liquor.y +313 -0
  16. data/test/assets/machete.y +423 -0
  17. data/test/assets/macruby.y +2197 -0
  18. data/test/assets/mediacloth.y +599 -0
  19. data/test/assets/mof.y +649 -0
  20. data/test/assets/namae.y +302 -0
  21. data/test/assets/nasl.y +626 -0
  22. data/test/assets/nokogiri-css.y +255 -0
  23. data/test/assets/opal.y +1807 -0
  24. data/test/assets/php_serialization.y +98 -0
  25. data/test/assets/rdblockparser.y +576 -0
  26. data/test/assets/rdinlineparser.y +561 -0
  27. data/test/assets/riml.y +665 -0
  28. data/test/assets/ruby18.y +1943 -0
  29. data/test/assets/ruby19.y +2174 -0
  30. data/test/assets/ruby20.y +2350 -0
  31. data/test/assets/ruby21.y +2359 -0
  32. data/test/assets/ruby22.y +2381 -0
  33. data/test/assets/tp_plus.y +622 -0
  34. data/test/assets/twowaysql.y +278 -0
  35. data/test/helper.rb +50 -34
  36. data/test/regress/bibtex +474 -0
  37. data/test/regress/cadenza +796 -0
  38. data/test/regress/cast +3425 -0
  39. data/test/regress/csspool +2318 -0
  40. data/test/regress/edtf +1794 -0
  41. data/test/regress/huia +1392 -0
  42. data/test/regress/journey +222 -0
  43. data/test/regress/liquor +885 -0
  44. data/test/regress/machete +833 -0
  45. data/test/regress/mediacloth +1463 -0
  46. data/test/regress/mof +1368 -0
  47. data/test/regress/namae +634 -0
  48. data/test/regress/nasl +2058 -0
  49. data/test/regress/nokogiri-css +836 -0
  50. data/test/regress/opal +6429 -0
  51. data/test/regress/php_serialization +336 -0
  52. data/test/regress/rdblockparser +1061 -0
  53. data/test/regress/rdinlineparser +1243 -0
  54. data/test/regress/riml +3297 -0
  55. data/test/regress/ruby18 +6351 -0
  56. data/test/regress/ruby22 +7456 -0
  57. data/test/regress/tp_plus +1933 -0
  58. data/test/regress/twowaysql +556 -0
  59. data/test/test_racc_command.rb +177 -0
  60. metadata +80 -25
  61. data/.gemtest +0 -0
@@ -0,0 +1,583 @@
1
+ # -*- racc -*-
2
+
3
+ # Copyright 2011 Sylvester Keil. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
16
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18
+ # EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
+ # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ #
26
+ # The views and conclusions contained in the software and documentation are
27
+ # those of the authors and should not be interpreted as representing official
28
+ # policies, either expressed or implied, of the copyright holder.
29
+
30
+ class EDTF::Parser
31
+
32
+ token T Z E X U UNKNOWN OPEN LONGYEAR UNMATCHED DOTS UA PUA
33
+
34
+ expect 0
35
+
36
+ rule
37
+
38
+ edtf : level_0_expression
39
+ | level_1_expression
40
+ | level_2_expression
41
+ ;
42
+
43
+ # ---- Level 0 / ISO 8601 Rules ----
44
+
45
+ # NB: level 0 intervals are covered by the level 1 interval rules
46
+ level_0_expression : date
47
+ | date_time
48
+ ;
49
+
50
+ date : positive_date
51
+ | negative_date
52
+ ;
53
+
54
+ positive_date :
55
+ year { result = Date.new(val[0]).year_precision! }
56
+ | year_month { result = Date.new(*val.flatten).month_precision! }
57
+ | year_month_day { result = Date.new(*val.flatten).day_precision! }
58
+ ;
59
+
60
+ negative_date : '-' positive_date { result = -val[1] }
61
+
62
+
63
+ date_time : date T time {
64
+ result = DateTime.new(val[0].year, val[0].month, val[0].day, *val[2])
65
+ result.skip_timezone = (val[2].length == 3)
66
+ }
67
+
68
+ time : base_time
69
+ | base_time zone_offset { result = val.flatten }
70
+
71
+ base_time : hour ':' minute ':' second { result = val.values_at(0, 2, 4) }
72
+ | midnight
73
+
74
+ midnight : '2' '4' ':' '0' '0' ':' '0' '0' { result = [24, 0, 0] }
75
+
76
+ zone_offset : Z { result = 0 }
77
+ | '-' zone_offset_hour { result = -1 * val[1] }
78
+ | '+' positive_zone_offset { result = val[1] }
79
+ ;
80
+
81
+ positive_zone_offset : zone_offset_hour
82
+ | '0' '0' ':' '0' '0' { result = 0 }
83
+ ;
84
+
85
+
86
+ zone_offset_hour : d01_13 ':' minute { result = Rational(val[0] * 60 + val[2], 1440) }
87
+ | '1' '4' ':' '0' '0' { result = Rational(840, 1440) }
88
+ | '0' '0' ':' d01_59 { result = Rational(val[3], 1440) }
89
+ ;
90
+
91
+ year : digit digit digit digit {
92
+ result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
93
+ }
94
+
95
+ month : d01_12
96
+ day : d01_31
97
+
98
+ year_month : year '-' month { result = [val[0], val[2]] }
99
+
100
+ # We raise an exception if there are two many days for the month, but
101
+ # do not consider leap years, as the EDTF BNF did not either.
102
+ # NB: an exception will be raised regardless, because the Ruby Date
103
+ # implementation calculates leap years.
104
+ year_month_day : year_month '-' day {
105
+ result = val[0] << val[2]
106
+ if result[2] > 31 || (result[2] > 30 && [2,4,6,9,11].include?(result[1])) || (result[2] > 29 && result[1] == 2)
107
+ raise ArgumentError, "invalid date (invalid days #{result[2]} for month #{result[1]})"
108
+ end
109
+ }
110
+
111
+ hour : d00_23
112
+ minute : d00_59
113
+ second : d00_59
114
+
115
+ # Completely covered by level_1_interval
116
+ # level_0_interval : date '/' date { result = Interval.new(val[0], val[1]) }
117
+
118
+
119
+ # ---- Level 1 Extension Rules ----
120
+
121
+ # NB: Uncertain/approximate Dates are covered by the Level 2 rules
122
+ level_1_expression : unspecified | level_1_interval | long_year_simple | season
123
+
124
+ # uncertain_or_approximate_date : date UA { result = uoa(val[0], val[1]) }
125
+
126
+ unspecified : unspecified_year
127
+ {
128
+ result = Date.new(val[0][0]).year_precision!
129
+ result.unspecified.year[2,2] = val[0][1]
130
+ }
131
+ | unspecified_month
132
+ | unspecified_day
133
+ | unspecified_day_and_month
134
+ ;
135
+
136
+ unspecified_year :
137
+ digit digit digit U
138
+ {
139
+ result = [val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }, [false,true]]
140
+ }
141
+ | digit digit U U
142
+ {
143
+ result = [val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }, [true, true]]
144
+ }
145
+
146
+ unspecified_month : year '-' U U {
147
+ result = Date.new(val[0]).unspecified!(:month)
148
+ result.precision = :month
149
+ }
150
+
151
+ unspecified_day : year_month '-' U U {
152
+ result = Date.new(*val[0]).unspecified!(:day)
153
+ }
154
+
155
+ unspecified_day_and_month : year '-' U U '-' U U {
156
+ result = Date.new(val[0]).unspecified!([:day,:month])
157
+ }
158
+
159
+
160
+ level_1_interval : level_1_start '/' level_1_end {
161
+ result = Interval.new(val[0], val[2])
162
+ }
163
+
164
+ level_1_start : date | partial_uncertain_or_approximate | unspecified | partial_unspecified | UNKNOWN
165
+
166
+ level_1_end : level_1_start | OPEN
167
+
168
+
169
+ long_year_simple :
170
+ LONGYEAR long_year
171
+ {
172
+ result = Date.new(val[1])
173
+ result.precision = :year
174
+ }
175
+ | LONGYEAR '-' long_year
176
+ {
177
+ result = Date.new(-1 * val[2])
178
+ result.precision = :year
179
+ }
180
+ ;
181
+
182
+ long_year :
183
+ positive_digit digit digit digit digit {
184
+ result = val.zip([10000,1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
185
+ }
186
+ | long_year digit { result = 10 * val[0] + val[1] }
187
+ ;
188
+
189
+
190
+ season : year '-' season_number ua {
191
+ result = Season.new(val[0], val[2])
192
+ val[3].each { |ua| result.send(ua) }
193
+ }
194
+
195
+ season_number : '2' '1' { result = 21 }
196
+ | '2' '2' { result = 22 }
197
+ | '2' '3' { result = 23 }
198
+ | '2' '4' { result = 24 }
199
+ ;
200
+
201
+
202
+ # ---- Level 2 Extension Rules ----
203
+
204
+ # NB: Level 2 Intervals are covered by the Level 1 Interval rules.
205
+ level_2_expression : season_qualified
206
+ | partial_uncertain_or_approximate
207
+ | partial_unspecified
208
+ | choice_list
209
+ | inclusive_list
210
+ | masked_precision
211
+ | date_and_calendar
212
+ | long_year_scientific
213
+ ;
214
+
215
+
216
+ season_qualified : season '^' { result = val[0]; result.qualifier = val[1] }
217
+
218
+
219
+ long_year_scientific :
220
+ long_year_simple E integer
221
+ {
222
+ result = Date.new(val[0].year * 10 ** val[2]).year_precision!
223
+ }
224
+ | LONGYEAR int1_4 E integer
225
+ {
226
+ result = Date.new(val[1] * 10 ** val[3]).year_precision!
227
+ }
228
+ | LONGYEAR '-' int1_4 E integer
229
+ {
230
+ result = Date.new(-1 * val[2] * 10 ** val[4]).year_precision!
231
+ }
232
+ ;
233
+
234
+
235
+ date_and_calendar : date '^' { result = val[0]; result.calendar = val[1] }
236
+
237
+
238
+ masked_precision :
239
+ digit digit digit X
240
+ {
241
+ d = val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }
242
+ result = EDTF::Decade.new(d)
243
+ }
244
+ | digit digit X X
245
+ {
246
+ d = val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }
247
+ result = EDTF::Century.new(d)
248
+ }
249
+ ;
250
+
251
+
252
+ choice_list : '[' list ']' { result = val[1].choice! }
253
+
254
+ inclusive_list : '{' list '}' { result = val[1] }
255
+
256
+ list : earlier { result = EDTF::Set.new(val[0]).earlier! }
257
+ | earlier ',' list_elements ',' later { result = EDTF::Set.new([val[0]] + val[2] + [val[4]]).earlier!.later! }
258
+ | earlier ',' list_elements { result = EDTF::Set.new([val[0]] + val[2]).earlier! }
259
+ | earlier ',' later { result = EDTF::Set.new([val[0]] + [val[2]]).earlier!.later! }
260
+ | list_elements ',' later { result = EDTF::Set.new(val[0] + [val[2]]).later! }
261
+ | list_elements { result = EDTF::Set.new(*val[0]) }
262
+ | later { result = EDTF::Set.new(val[0]).later! }
263
+ ;
264
+
265
+ list_elements : list_element { result = [val[0]].flatten }
266
+ | list_elements ',' list_element { result = val[0] + [val[2]].flatten }
267
+ ;
268
+
269
+ list_element : atomic
270
+ | consecutives
271
+ ;
272
+
273
+ atomic : date
274
+ | partial_uncertain_or_approximate
275
+ | unspecified
276
+ ;
277
+
278
+ earlier : DOTS date { result = val[1] }
279
+
280
+ later : year_month_day DOTS { result = Date.new(*val[0]).year_precision! }
281
+ | year_month DOTS { result = Date.new(*val[0]).month_precision! }
282
+ | year DOTS { result = Date.new(val[0]).year_precision! }
283
+ ;
284
+
285
+ consecutives : year_month_day DOTS year_month_day { result = (Date.new(val[0]).day_precision! .. Date.new(val[2]).day_precision!) }
286
+ | year_month DOTS year_month { result = (Date.new(val[0]).month_precision! .. Date.new(val[2]).month_precision!) }
287
+ | year DOTS year { result = (Date.new(val[0]).year_precision! .. Date.new(val[2]).year_precision!) }
288
+ ;
289
+
290
+ partial_unspecified :
291
+ unspecified_year '-' month '-' day
292
+ {
293
+ result = Date.new(val[0][0], val[2], val[4])
294
+ result.unspecified.year[2,2] = val[0][1]
295
+ }
296
+ | unspecified_year '-' U U '-' day
297
+ {
298
+ result = Date.new(val[0][0], 1, val[5])
299
+ result.unspecified.year[2,2] = val[0][1]
300
+ result.unspecified!(:month)
301
+ }
302
+ | unspecified_year '-' U U '-' U U
303
+ {
304
+ result = Date.new(val[0][0], 1, 1)
305
+ result.unspecified.year[2,2] = val[0][1]
306
+ result.unspecified!([:month, :day])
307
+ }
308
+ | unspecified_year '-' month '-' U U
309
+ {
310
+ result = Date.new(val[0][0], val[2], 1)
311
+ result.unspecified.year[2,2] = val[0][1]
312
+ result.unspecified!(:day)
313
+ }
314
+ | year '-' U U '-' day
315
+ {
316
+ result = Date.new(val[0], 1, val[5])
317
+ result.unspecified!(:month)
318
+ }
319
+ ;
320
+
321
+
322
+ partial_uncertain_or_approximate : pua_base
323
+ | '(' pua_base ')' UA { result = uoa(val[1], val[3]) }
324
+
325
+ pua_base :
326
+ pua_year { result = val[0].year_precision! }
327
+ | pua_year_month { result = val[0][0].month_precision! }
328
+ | pua_year_month_day { result = val[0].day_precision! }
329
+
330
+ pua_year : year UA { result = uoa(Date.new(val[0]), val[1], :year) }
331
+
332
+ pua_year_month :
333
+ pua_year '-' month ua {
334
+ result = [uoa(val[0].change(:month => val[2]), val[3], [:month, :year])]
335
+ }
336
+ | year '-' month UA {
337
+ result = [uoa(Date.new(val[0], val[2]), val[3], [:year, :month])]
338
+ }
339
+ | year '-(' month ')' UA {
340
+ result = [uoa(Date.new(val[0], val[2]), val[4], [:month]), true]
341
+ }
342
+ | pua_year '-(' month ')' UA {
343
+ result = [uoa(val[0].change(:month => val[2]), val[4], [:month]), true]
344
+ }
345
+ ;
346
+
347
+ pua_year_month_day :
348
+ pua_year_month '-' day ua {
349
+ result = uoa(val[0][0].change(:day => val[2]), val[3], val[0][1] ? [:day] : nil)
350
+ }
351
+ | pua_year_month '-(' day ')' UA {
352
+ result = uoa(val[0][0].change(:day => val[2]), val[4], [:day])
353
+ }
354
+ | year '-(' month ')' UA day ua {
355
+ result = uoa(uoa(Date.new(val[0], val[2], val[5]), val[4], :month), val[6], :day)
356
+ }
357
+ | year_month '-' day UA {
358
+ result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[3])
359
+ }
360
+ | year_month '-(' day ')' UA {
361
+ result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[4], [:day])
362
+ }
363
+ | year '-(' month '-' day ')' UA {
364
+ result = uoa(Date.new(val[0], val[2], val[4]), val[6], [:month, :day])
365
+ }
366
+ | year '-(' month '-(' day ')' UA ')' UA {
367
+ result = Date.new(val[0], val[2], val[4])
368
+ result = uoa(result, val[6], [:day])
369
+ result = uoa(result, val[8], [:month, :day])
370
+ }
371
+ | pua_year '-(' month '-' day ')' UA {
372
+ result = val[0].change(:month => val[2], :day => val[4])
373
+ result = uoa(result, val[6], [:month, :day])
374
+ }
375
+ | pua_year '-(' month '-(' day ')' UA ')' UA {
376
+ result = val[0].change(:month => val[2], :day => val[4])
377
+ result = uoa(result, val[6], [:day])
378
+ result = uoa(result, val[8], [:month, :day])
379
+ }
380
+ # | '(' pua_year '-(' month ')' UA ')' UA '-' day ua {
381
+ # result = val[1].change(:month => val[3], :day => val[9])
382
+ # result = uoa(result, val[5], [:month])
383
+ # result = [uoa(result, val[7], [:year]), true]
384
+ # }
385
+ ;
386
+
387
+ ua : { result = [] } | UA
388
+
389
+ # ---- Auxiliary Rules ----
390
+
391
+ digit : '0' { result = 0 }
392
+ | positive_digit
393
+ ;
394
+
395
+ positive_digit : '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
396
+
397
+ d01_12 : '0' positive_digit { result = val[1] }
398
+ | '1' '0' { result = 10 }
399
+ | '1' '1' { result = 11 }
400
+ | '1' '2' { result = 12 }
401
+ ;
402
+
403
+ d01_13 : d01_12
404
+ | '1' '3' { result = 13 }
405
+ ;
406
+
407
+ d01_23 : '0' positive_digit { result = val[1] }
408
+ | '1' digit { result = 10 + val[1] }
409
+ | '2' '0' { result = 20 }
410
+ | '2' '1' { result = 21 }
411
+ | '2' '2' { result = 22 }
412
+ | '2' '3' { result = 23 }
413
+ ;
414
+
415
+ d00_23 : '0' '0'
416
+ | d01_23
417
+ ;
418
+
419
+ d01_29 : d01_23
420
+ | '2' '4' { result = 24 }
421
+ | '2' '5' { result = 25 }
422
+ | '2' '6' { result = 26 }
423
+ | '2' '7' { result = 27 }
424
+ | '2' '8' { result = 28 }
425
+ | '2' '9' { result = 29 }
426
+ ;
427
+
428
+ d01_30 : d01_29
429
+ | '3' '0' { result = 30 }
430
+ ;
431
+
432
+ d01_31 : d01_30
433
+ | '3' '1' { result = 31 }
434
+ ;
435
+
436
+ d01_59 : d01_29
437
+ | '3' digit { result = 30 + val[1] }
438
+ | '4' digit { result = 40 + val[1] }
439
+ | '5' digit { result = 50 + val[1] }
440
+ ;
441
+
442
+ d00_59 : '0' '0'
443
+ | d01_59
444
+ ;
445
+
446
+ int1_4 : positive_digit { result = val[0] }
447
+ | positive_digit digit { result = 10 * val[0] + val[1] }
448
+ | positive_digit digit digit
449
+ {
450
+ result = val.zip([100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
451
+ }
452
+ | positive_digit digit digit digit
453
+ {
454
+ result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
455
+ }
456
+ ;
457
+
458
+ integer : positive_digit { result = val[0] }
459
+ | integer digit { result = 10 * val[0] + val[1] }
460
+ ;
461
+
462
+
463
+
464
+ ---- header
465
+ require 'strscan'
466
+
467
+ ---- inner
468
+
469
+ @defaults = {
470
+ :level => 2,
471
+ :debug => false
472
+ }.freeze
473
+
474
+ class << self; attr_reader :defaults; end
475
+
476
+ attr_reader :options
477
+
478
+ def initialize(options = {})
479
+ @options = Parser.defaults.merge(options)
480
+ end
481
+
482
+ def debug?
483
+ !!(options[:debug] || ENV['DEBUG'])
484
+ end
485
+
486
+ def parse(input)
487
+ parse!(input)
488
+ rescue => e
489
+ warn e.message if debug?
490
+ nil
491
+ end
492
+
493
+ def parse!(input)
494
+ @yydebug = debug?
495
+ @src = StringScanner.new(input)
496
+ do_parse
497
+ end
498
+
499
+ def on_error(tid, value, stack)
500
+ raise ArgumentError,
501
+ "failed to parse date: unexpected '#{value}' at #{stack.inspect}"
502
+ end
503
+
504
+ def apply_uncertainty(date, uncertainty, scope = nil)
505
+ uncertainty.each do |u|
506
+ scope.nil? ? date.send(u) : date.send(u, scope)
507
+ end
508
+ date
509
+ end
510
+
511
+ alias uoa apply_uncertainty
512
+
513
+ def next_token
514
+ case
515
+ when @src.eos?
516
+ nil
517
+ # when @src.scan(/\s+/)
518
+ # ignore whitespace
519
+ when @src.scan(/\(/)
520
+ ['(', @src.matched]
521
+ # when @src.scan(/\)\?~-/)
522
+ # [:PUA, [:uncertain!, :approximate!]]
523
+ # when @src.scan(/\)\?-/)
524
+ # [:PUA, [:uncertain!]]
525
+ # when @src.scan(/\)~-/)
526
+ # [:PUA, [:approximate!]]
527
+ when @src.scan(/\)/)
528
+ [')', @src.matched]
529
+ when @src.scan(/\[/)
530
+ ['[', @src.matched]
531
+ when @src.scan(/\]/)
532
+ [']', @src.matched]
533
+ when @src.scan(/\{/)
534
+ ['{', @src.matched]
535
+ when @src.scan(/\}/)
536
+ ['}', @src.matched]
537
+ when @src.scan(/T/)
538
+ [:T, @src.matched]
539
+ when @src.scan(/Z/)
540
+ [:Z, @src.matched]
541
+ when @src.scan(/\?~/)
542
+ [:UA, [:uncertain!, :approximate!]]
543
+ when @src.scan(/\?/)
544
+ [:UA, [:uncertain!]]
545
+ when @src.scan(/~/)
546
+ [:UA, [:approximate!]]
547
+ when @src.scan(/open/i)
548
+ [:OPEN, :open]
549
+ when @src.scan(/unkn?own/i) # matches 'unkown' typo too
550
+ [:UNKNOWN, :unknown]
551
+ when @src.scan(/u/)
552
+ [:U, @src.matched]
553
+ when @src.scan(/x/i)
554
+ [:X, @src.matched]
555
+ when @src.scan(/y/)
556
+ [:LONGYEAR, @src.matched]
557
+ when @src.scan(/e/)
558
+ [:E, @src.matched]
559
+ when @src.scan(/\+/)
560
+ ['+', @src.matched]
561
+ when @src.scan(/-\(/)
562
+ ['-(', @src.matched]
563
+ when @src.scan(/-/)
564
+ ['-', @src.matched]
565
+ when @src.scan(/:/)
566
+ [':', @src.matched]
567
+ when @src.scan(/\//)
568
+ ['/', @src.matched]
569
+ when @src.scan(/\s*\.\.\s*/)
570
+ [:DOTS, '..']
571
+ when @src.scan(/\s*,\s*/)
572
+ [',', ',']
573
+ when @src.scan(/\^\w+/)
574
+ ['^', @src.matched[1..-1]]
575
+ when @src.scan(/\d/)
576
+ [@src.matched, @src.matched.to_i]
577
+ else @src.scan(/./)
578
+ [:UNMATCHED, @src.rest]
579
+ end
580
+ end
581
+
582
+
583
+ # -*- racc -*-