racc 1.4.14-java → 1.4.15-java

Sign up to get free protection for your applications and to get access to all the features.
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 -*-