fabiokung-ruby_parser 2.0.2

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.
@@ -0,0 +1,1738 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require "test/unit"
4
+ require "ruby_lexer"
5
+
6
+ class TestRubyLexer < Test::Unit::TestCase
7
+ def deny cond, msg = nil
8
+ assert ! cond, msg
9
+ end
10
+
11
+ def setup
12
+ p = RubyParser.new
13
+ @lex = p.lexer
14
+ @lex.src = "blah blah"
15
+ @lex.lex_state = :expr_beg
16
+ end
17
+
18
+ def test_advance
19
+ assert @lex.advance # blah
20
+ assert @lex.advance # blah
21
+ deny @lex.advance # nada
22
+ end
23
+
24
+ def test_read_escape
25
+ util_escape "\\", "\\"
26
+ util_escape "\n", "n"
27
+ util_escape "\t", "t"
28
+ util_escape "\r", "r"
29
+ util_escape "\f", "f"
30
+ util_escape "\13", "v"
31
+ util_escape "\0", "0"
32
+ util_escape "\07", "a"
33
+ util_escape "\007", "a"
34
+ util_escape "\033", "e"
35
+ util_escape "\377", "377"
36
+ util_escape "\377", "xff"
37
+ util_escape "\010", "b"
38
+ util_escape " ", "s"
39
+ util_escape "q", "q" # plain vanilla escape
40
+ end
41
+
42
+ def test_read_escape_c
43
+ util_escape "\030", "C-x"
44
+ util_escape "\030", "cx"
45
+ util_escape "\230", 'C-\M-x'
46
+ util_escape "\230", 'c\M-x'
47
+
48
+ util_escape "\177", "C-?"
49
+ util_escape "\177", "c?"
50
+ end
51
+
52
+ def test_read_escape_errors
53
+ util_escape_bad ""
54
+
55
+ util_escape_bad "M"
56
+ util_escape_bad "M-"
57
+ util_escape_bad "Mx"
58
+
59
+ util_escape_bad "Cx"
60
+ util_escape_bad "C"
61
+ util_escape_bad "C-"
62
+
63
+ util_escape_bad "c"
64
+ end
65
+
66
+ def test_read_escape_m
67
+ util_escape "\370", "M-x"
68
+ util_escape "\230", 'M-\C-x'
69
+ util_escape "\230", 'M-\cx'
70
+ end
71
+
72
+ def test_yylex_ambiguous_uminus
73
+ util_lex_token("m -3",
74
+ :tIDENTIFIER, "m",
75
+ :tUMINUS_NUM, "-",
76
+ :tINTEGER, 3)
77
+ # TODO: verify warning
78
+ end
79
+
80
+ def test_yylex_ambiguous_uplus
81
+ util_lex_token("m +3",
82
+ :tIDENTIFIER, "m",
83
+ :tINTEGER, 3)
84
+ # TODO: verify warning
85
+ end
86
+
87
+ def test_yylex_and
88
+ util_lex_token "&", :tAMPER, "&"
89
+ end
90
+
91
+ def test_yylex_and2
92
+ util_lex_token "&&", :tANDOP, "&&"
93
+ end
94
+
95
+ def test_yylex_and2_equals
96
+ util_lex_token "&&=", :tOP_ASGN, "&&"
97
+ end
98
+
99
+ def test_yylex_and_arg
100
+ @lex.lex_state = :expr_arg
101
+
102
+ util_lex_token(" &y",
103
+ :tAMPER, "&",
104
+ :tIDENTIFIER, "y")
105
+ end
106
+
107
+ def test_yylex_and_equals
108
+ util_lex_token "&=", :tOP_ASGN, "&"
109
+ end
110
+
111
+ def test_yylex_and_expr
112
+ @lex.lex_state = :expr_arg
113
+
114
+ util_lex_token("x & y",
115
+ :tIDENTIFIER, "x",
116
+ :tAMPER2, "&",
117
+ :tIDENTIFIER, "y")
118
+ end
119
+
120
+ def test_yylex_and_meth
121
+ util_lex_fname "&", :tAMPER2
122
+ end
123
+
124
+ def test_yylex_assoc
125
+ util_lex_token "=>", :tASSOC, "=>"
126
+ end
127
+
128
+ def test_yylex_back_ref
129
+ util_lex_token("[$&, $`, $', $+]",
130
+ :tLBRACK, "[",
131
+ :tBACK_REF, :"&", :tCOMMA, ",",
132
+ :tBACK_REF, :"`", :tCOMMA, ",",
133
+ :tBACK_REF, :"'", :tCOMMA, ",",
134
+ :tBACK_REF, :"+",
135
+ :tRBRACK, "]")
136
+ end
137
+
138
+ def test_yylex_backslash
139
+ util_lex_token("1 \\\n+ 2",
140
+ :tINTEGER, 1,
141
+ :tPLUS, "+",
142
+ :tINTEGER, 2)
143
+ end
144
+
145
+ def test_yylex_backslash_bad
146
+ util_bad_token("1 \\ + 2",
147
+ :tINTEGER, 1)
148
+ end
149
+
150
+ def test_yylex_backtick
151
+ util_lex_token("`ls`",
152
+ :tXSTRING_BEG, "`",
153
+ :tSTRING_CONTENT, "ls",
154
+ :tSTRING_END, "`")
155
+ end
156
+
157
+ def test_yylex_backtick_cmdarg
158
+ @lex.lex_state = :expr_dot
159
+ util_lex_token("\n`", :tBACK_REF2, "`") # \n ensures expr_cmd
160
+
161
+ assert_equal :expr_cmdarg, @lex.lex_state
162
+ end
163
+
164
+ def test_yylex_backtick_dot
165
+ @lex.lex_state = :expr_dot
166
+ util_lex_token("a.`(3)",
167
+ :tIDENTIFIER, "a",
168
+ :tDOT, ".",
169
+ :tBACK_REF2, "`",
170
+ :tLPAREN2, "(",
171
+ :tINTEGER, 3,
172
+ :tRPAREN, ")")
173
+ end
174
+
175
+ def test_yylex_backtick_method
176
+ @lex.lex_state = :expr_fname
177
+ util_lex_token("`", :tBACK_REF2, "`")
178
+ assert_equal :expr_end, @lex.lex_state
179
+ end
180
+
181
+ def test_yylex_bad_char
182
+ util_bad_token(" \010 ")
183
+ end
184
+
185
+ def test_yylex_bang
186
+ util_lex_token "!", :tBANG, "!"
187
+ end
188
+
189
+ def test_yylex_bang_equals
190
+ util_lex_token "!=", :tNEQ, "!="
191
+ end
192
+
193
+ def test_yylex_bang_tilde
194
+ util_lex_token "!~", :tNMATCH, "!~"
195
+ end
196
+
197
+ def test_yylex_carat
198
+ util_lex_token "^", :tCARET, "^"
199
+ end
200
+
201
+ def test_yylex_carat_equals
202
+ util_lex_token "^=", :tOP_ASGN, "^"
203
+ end
204
+
205
+ def test_yylex_colon2
206
+ util_lex_token("A::B",
207
+ :tCONSTANT, "A",
208
+ :tCOLON2, "::",
209
+ :tCONSTANT, "B")
210
+ end
211
+
212
+ def test_yylex_colon3
213
+ util_lex_token("::Array",
214
+ :tCOLON3, "::",
215
+ :tCONSTANT, "Array")
216
+ end
217
+
218
+ def test_yylex_comma
219
+ util_lex_token ",", :tCOMMA, ","
220
+ end
221
+
222
+ def test_yylex_comment
223
+ util_lex_token("1 # one\n# two\n2",
224
+ :tINTEGER, 1,
225
+ :tNL, nil,
226
+ :tINTEGER, 2)
227
+ assert_equal "# one\n# two\n", @lex.comments
228
+ end
229
+
230
+ def test_yylex_comment_begin
231
+ util_lex_token("=begin\nblah\nblah\n=end\n42",
232
+ :tINTEGER, 42)
233
+ assert_equal "=begin\nblah\nblah\n=end\n", @lex.comments
234
+ end
235
+
236
+ def test_yylex_comment_begin_bad
237
+ util_bad_token("=begin\nblah\nblah\n")
238
+ assert_equal "", @lex.comments
239
+ end
240
+
241
+ def test_yylex_comment_begin_not_comment
242
+ util_lex_token("beginfoo = 5\np x \\\n=beginfoo",
243
+ :tIDENTIFIER, "beginfoo",
244
+ :tEQL, "=",
245
+ :tINTEGER, 5,
246
+ :tNL, nil,
247
+ :tIDENTIFIER, "p",
248
+ :tIDENTIFIER, "x",
249
+ :tEQL, "=",
250
+ :tIDENTIFIER, "beginfoo")
251
+ end
252
+
253
+ def test_yylex_comment_begin_space
254
+ util_lex_token("=begin blah\nblah\n=end\n")
255
+ assert_equal "=begin blah\nblah\n=end\n", @lex.comments
256
+ end
257
+
258
+ def test_yylex_comment_eos
259
+ util_lex_token("# comment")
260
+ end
261
+
262
+ def test_yylex_constant
263
+ util_lex_token("ArgumentError",
264
+ :tCONSTANT, "ArgumentError")
265
+ end
266
+
267
+ def test_yylex_constant_semi
268
+ util_lex_token("ArgumentError;",
269
+ :tCONSTANT, "ArgumentError",
270
+ :tSEMI, ";")
271
+ end
272
+
273
+ def test_yylex_cvar
274
+ util_lex_token "@@blah", :tCVAR, "@@blah"
275
+ end
276
+
277
+ def test_yylex_cvar_bad
278
+ assert_raises SyntaxError do
279
+ util_lex_token "@@1"
280
+ end
281
+ end
282
+
283
+ def test_yylex_def_bad_name
284
+ @lex.lex_state = :expr_fname
285
+ util_bad_token("def [ ", :kDEF, "def")
286
+ end
287
+
288
+ def test_yylex_div
289
+ util_lex_token("a / 2",
290
+ :tIDENTIFIER, "a",
291
+ :tDIVIDE, "/",
292
+ :tINTEGER, 2)
293
+ end
294
+
295
+ def test_yylex_div_equals
296
+ util_lex_token("a /= 2",
297
+ :tIDENTIFIER, "a",
298
+ :tOP_ASGN, "/",
299
+ :tINTEGER, 2)
300
+ end
301
+
302
+ def test_yylex_do
303
+ util_lex_token("x do 42 end",
304
+ :tIDENTIFIER, "x",
305
+ :kDO, "do",
306
+ :tINTEGER, 42,
307
+ :kEND, "end")
308
+ end
309
+
310
+ def test_yylex_do_block
311
+ @lex.lex_state = :expr_endarg
312
+ @lex.cmdarg.push true
313
+
314
+ util_lex_token("x.y do 42 end",
315
+ :tIDENTIFIER, "x",
316
+ :tDOT, ".",
317
+ :tIDENTIFIER, "y",
318
+ :kDO_BLOCK, "do",
319
+ :tINTEGER, 42,
320
+ :kEND, "end")
321
+ end
322
+
323
+ def test_yylex_do_block2
324
+ @lex.lex_state = :expr_endarg
325
+
326
+ util_lex_token("do 42 end",
327
+ :kDO_BLOCK, "do",
328
+ :tINTEGER, 42,
329
+ :kEND, "end")
330
+ end
331
+
332
+ def test_yylex_do_cond
333
+ @lex.cond.push true
334
+
335
+ util_lex_token("x do 42 end",
336
+ :tIDENTIFIER, "x",
337
+ :kDO_COND, "do",
338
+ :tINTEGER, 42,
339
+ :kEND, "end")
340
+ end
341
+
342
+ def test_yylex_dollar
343
+ util_lex_token("$", "$", "$") # FIX: wtf is this?!?
344
+ end
345
+
346
+ def test_yylex_dot # HINT message sends
347
+ util_lex_token ".", :tDOT, "."
348
+ end
349
+
350
+ def test_yylex_dot2
351
+ util_lex_token "..", :tDOT2, ".."
352
+ end
353
+
354
+ def test_yylex_dot3
355
+ util_lex_token "...", :tDOT3, "..."
356
+ end
357
+
358
+ def test_yylex_equals
359
+ util_lex_token "=", :tEQL, "=" # FIX: this sucks
360
+ end
361
+
362
+ def test_yylex_equals2
363
+ util_lex_token "==", :tEQ, "=="
364
+ end
365
+
366
+ def test_yylex_equals3
367
+ util_lex_token "===", :tEQQ, "==="
368
+ end
369
+
370
+ def test_yylex_equals_tilde
371
+ util_lex_token "=~", :tMATCH, "=~"
372
+ end
373
+
374
+ def test_yylex_float
375
+ util_lex_token "1.0", :tFLOAT, 1.0
376
+ end
377
+
378
+ def test_yylex_float_bad_no_underscores
379
+ util_bad_token "1__0.0"
380
+ end
381
+
382
+ def test_yylex_float_bad_no_zero_leading
383
+ util_bad_token ".0"
384
+ end
385
+
386
+ def test_yylex_float_bad_trailing_underscore
387
+ util_bad_token "123_.0"
388
+ end
389
+
390
+ def test_yylex_float_call
391
+ util_lex_token("1.0.to_s",
392
+ :tFLOAT, 1.0,
393
+ :tDOT, ".",
394
+ :tIDENTIFIER, "to_s")
395
+ end
396
+
397
+ def test_yylex_float_dot_E
398
+ util_lex_token "1.0E10", :tFLOAT, 1.0e10
399
+ end
400
+
401
+ def test_yylex_float_dot_E_neg
402
+ util_lex_token("-1.0E10",
403
+ :tUMINUS_NUM, "-",
404
+ :tFLOAT, 1.0e10)
405
+ end
406
+
407
+ def test_yylex_float_dot_e
408
+ util_lex_token "1.0e10", :tFLOAT, 1.0e10
409
+ end
410
+
411
+ def test_yylex_float_dot_e_neg
412
+ util_lex_token("-1.0e10",
413
+ :tUMINUS_NUM, "-",
414
+ :tFLOAT, 1.0e10)
415
+ end
416
+
417
+ def test_yylex_float_e
418
+ util_lex_token "1e10", :tFLOAT, 1e10
419
+ end
420
+
421
+ def test_yylex_float_e_bad_double_e
422
+ util_bad_token "1e2e3"
423
+ end
424
+
425
+ def test_yylex_float_e_bad_trailing_underscore
426
+ util_bad_token "123_e10"
427
+ end
428
+
429
+ def test_yylex_float_e_minus
430
+ util_lex_token "1e-10", :tFLOAT, 1e-10
431
+ end
432
+
433
+ def test_yylex_float_e_neg
434
+ util_lex_token("-1e10",
435
+ :tUMINUS_NUM, "-",
436
+ :tFLOAT, 1e10)
437
+ end
438
+
439
+ def test_yylex_float_e_neg_minus
440
+ util_lex_token("-1e-10",
441
+ :tUMINUS_NUM, "-",
442
+ :tFLOAT, 1e-10)
443
+ end
444
+
445
+ def test_yylex_float_e_neg_plus
446
+ util_lex_token("-1e+10",
447
+ :tUMINUS_NUM, "-",
448
+ :tFLOAT, 1e10)
449
+ end
450
+
451
+ def test_yylex_float_e_plus
452
+ util_lex_token "1e+10", :tFLOAT, 1e10
453
+ end
454
+
455
+ def test_yylex_float_e_zero
456
+ util_lex_token "0e0", :tFLOAT, 0e0
457
+ end
458
+
459
+ def test_yylex_float_neg
460
+ util_lex_token("-1.0",
461
+ :tUMINUS_NUM, "-",
462
+ :tFLOAT, 1.0)
463
+ end
464
+
465
+ def test_yylex_ge
466
+ util_lex_token("a >= 2",
467
+ :tIDENTIFIER, "a",
468
+ :tGEQ, ">=",
469
+ :tINTEGER, 2)
470
+ end
471
+
472
+ def test_yylex_global
473
+ util_lex_token("$blah", :tGVAR, "$blah")
474
+ end
475
+
476
+ def test_yylex_global_backref
477
+ @lex.lex_state = :expr_fname
478
+ util_lex_token("$`", :tGVAR, "$`")
479
+ end
480
+
481
+ def test_yylex_global_dash_nothing
482
+ util_lex_token("$- ", :tGVAR, "$-")
483
+ end
484
+
485
+ def test_yylex_global_dash_something
486
+ util_lex_token("$-x", :tGVAR, "$-x")
487
+ end
488
+
489
+ def test_yylex_global_number
490
+ @lex.lex_state = :expr_fname
491
+ util_lex_token("$1", :tGVAR, "$1")
492
+ end
493
+
494
+ def test_yylex_global_number_big
495
+ @lex.lex_state = :expr_fname
496
+ util_lex_token("$1234", :tGVAR, "$1234")
497
+ end
498
+
499
+ def test_yylex_global_other
500
+ util_lex_token("[$~, $*, $$, $?, $!, $@, $/, $\\, $;, $,, $., $=, $:, $<, $>, $\"]",
501
+ :tLBRACK, "[",
502
+ :tGVAR, "$~", :tCOMMA, ",",
503
+ :tGVAR, "$*", :tCOMMA, ",",
504
+ :tGVAR, "$$", :tCOMMA, ",",
505
+ :tGVAR, "$\?", :tCOMMA, ",",
506
+ :tGVAR, "$!", :tCOMMA, ",",
507
+ :tGVAR, "$@", :tCOMMA, ",",
508
+ :tGVAR, "$/", :tCOMMA, ",",
509
+ :tGVAR, "$\\", :tCOMMA, ",",
510
+ :tGVAR, "$;", :tCOMMA, ",",
511
+ :tGVAR, "$,", :tCOMMA, ",",
512
+ :tGVAR, "$.", :tCOMMA, ",",
513
+ :tGVAR, "$=", :tCOMMA, ",",
514
+ :tGVAR, "$:", :tCOMMA, ",",
515
+ :tGVAR, "$<", :tCOMMA, ",",
516
+ :tGVAR, "$>", :tCOMMA, ",",
517
+ :tGVAR, "$\"",
518
+ :tRBRACK, "]")
519
+ end
520
+
521
+ def test_yylex_global_underscore
522
+ util_lex_token("$_",
523
+ :tGVAR, "$_")
524
+ end
525
+
526
+ def test_yylex_global_wierd
527
+ util_lex_token("$__blah",
528
+ :tGVAR, "$__blah")
529
+ end
530
+
531
+ def test_yylex_global_zero
532
+ util_lex_token("$0", :tGVAR, "$0")
533
+ end
534
+
535
+ def test_yylex_gt
536
+ util_lex_token("a > 2",
537
+ :tIDENTIFIER, "a",
538
+ :tGT, ">",
539
+ :tINTEGER, 2)
540
+ end
541
+
542
+ def test_yylex_heredoc_backtick
543
+ util_lex_token("a = <<`EOF`\n blah blah\nEOF\n",
544
+ :tIDENTIFIER, "a",
545
+ :tEQL, "=",
546
+ :tXSTRING_BEG, "`",
547
+ :tSTRING_CONTENT, " blah blah\n",
548
+ :tSTRING_END, "EOF",
549
+ :tNL, nil)
550
+ end
551
+
552
+ def test_yylex_heredoc_double
553
+ util_lex_token("a = <<\"EOF\"\n blah blah\nEOF\n",
554
+ :tIDENTIFIER, "a",
555
+ :tEQL, "=",
556
+ :tSTRING_BEG, "\"",
557
+ :tSTRING_CONTENT, " blah blah\n",
558
+ :tSTRING_END, "EOF",
559
+ :tNL, nil)
560
+ end
561
+
562
+ def test_yylex_heredoc_double_dash
563
+ util_lex_token("a = <<-\"EOF\"\n blah blah\n EOF\n",
564
+ :tIDENTIFIER, "a",
565
+ :tEQL, "=",
566
+ :tSTRING_BEG, "\"",
567
+ :tSTRING_CONTENT, " blah blah\n",
568
+ :tSTRING_END, "EOF",
569
+ :tNL, nil)
570
+ end
571
+
572
+ def test_yylex_heredoc_double_eos
573
+ util_bad_token("a = <<\"EOF\"\nblah",
574
+ :tIDENTIFIER, "a",
575
+ :tEQL, "=",
576
+ :tSTRING_BEG, "\"")
577
+ end
578
+
579
+ def test_yylex_heredoc_double_eos_nl
580
+ util_bad_token("a = <<\"EOF\"\nblah\n",
581
+ :tIDENTIFIER, "a",
582
+ :tEQL, "=",
583
+ :tSTRING_BEG, "\"")
584
+ end
585
+
586
+ def test_yylex_heredoc_double_interp
587
+ util_lex_token("a = <<\"EOF\"\n#x a \#@a b \#$b c \#{3} \nEOF\n",
588
+ :tIDENTIFIER, "a",
589
+ :tEQL, "=",
590
+ :tSTRING_BEG, "\"",
591
+ :tSTRING_CONTENT, "#x a ",
592
+ :tSTRING_DVAR, "\#@",
593
+ :tSTRING_CONTENT, "@a b ", # HUH?
594
+ :tSTRING_DVAR, "\#$",
595
+ :tSTRING_CONTENT, "$b c ", # HUH?
596
+ :tSTRING_DBEG, "\#{",
597
+ :tSTRING_CONTENT, "3} \n", # HUH?
598
+ :tSTRING_END, "EOF",
599
+ :tNL, nil)
600
+ end
601
+
602
+ def test_yylex_heredoc_none
603
+ util_lex_token("a = <<EOF\nblah\nblah\nEOF",
604
+ :tIDENTIFIER, "a",
605
+ :tEQL, "=",
606
+ :tSTRING_BEG, "\"",
607
+ :tSTRING_CONTENT, "blah\nblah\n",
608
+ :tSTRING_CONTENT, "",
609
+ :tSTRING_END, "EOF",
610
+ :tNL, nil)
611
+ end
612
+
613
+ def test_yylex_heredoc_none_bad_eos
614
+ util_bad_token("a = <<EOF",
615
+ :tIDENTIFIER, "a",
616
+ :tEQL, "=",
617
+ :tSTRING_BEG, "\"")
618
+ end
619
+
620
+ def test_yylex_heredoc_none_dash
621
+ util_lex_token("a = <<-EOF\nblah\nblah\n EOF",
622
+ :tIDENTIFIER, "a",
623
+ :tEQL, "=",
624
+ :tSTRING_BEG, "\"",
625
+ :tSTRING_CONTENT, "blah\nblah\n",
626
+ :tSTRING_CONTENT, "",
627
+ :tSTRING_END, "EOF",
628
+ :tNL, nil)
629
+ end
630
+
631
+ def test_yylex_heredoc_single
632
+ util_lex_token("a = <<'EOF'\n blah blah\nEOF\n",
633
+ :tIDENTIFIER, "a",
634
+ :tEQL, "=",
635
+ :tSTRING_BEG, "\"",
636
+ :tSTRING_CONTENT, " blah blah\n",
637
+ :tSTRING_END, "EOF",
638
+ :tNL, nil)
639
+ end
640
+
641
+ def test_yylex_heredoc_single_bad_eos_body
642
+ util_bad_token("a = <<'EOF'\nblah",
643
+ :tIDENTIFIER, "a",
644
+ :tEQL, "=",
645
+ :tSTRING_BEG, "\"")
646
+ end
647
+
648
+ def test_yylex_heredoc_single_bad_eos_empty
649
+ util_bad_token("a = <<''\n",
650
+ :tIDENTIFIER, "a",
651
+ :tEQL, "=",
652
+ :tSTRING_BEG, "\"")
653
+ end
654
+
655
+ def test_yylex_heredoc_single_bad_eos_term
656
+ util_bad_token("a = <<'EOF",
657
+ :tIDENTIFIER, "a",
658
+ :tEQL, "=",
659
+ :tSTRING_BEG, "\"")
660
+ end
661
+
662
+ def test_yylex_heredoc_single_bad_eos_term_nl
663
+ util_bad_token("a = <<'EOF\ns = 'blah blah'",
664
+ :tIDENTIFIER, "a",
665
+ :tEQL, "=",
666
+ :tSTRING_BEG, "\"")
667
+ end
668
+
669
+ def test_yylex_heredoc_single_dash
670
+ util_lex_token("a = <<-'EOF'\n blah blah\n EOF\n",
671
+ :tIDENTIFIER, "a",
672
+ :tEQL, "=",
673
+ :tSTRING_BEG, "\"",
674
+ :tSTRING_CONTENT, " blah blah\n",
675
+ :tSTRING_END, "EOF",
676
+ :tNL, nil)
677
+ end
678
+
679
+ def test_yylex_identifier
680
+ util_lex_token("identifier", :tIDENTIFIER, "identifier")
681
+ end
682
+
683
+ def test_yylex_identifier_bang
684
+ util_lex_token("identifier!", :tFID, "identifier!")
685
+ end
686
+
687
+ def test_yylex_identifier_cmp
688
+ util_lex_fname "<=>", :tCMP
689
+ end
690
+
691
+ def test_yylex_identifier_def
692
+ util_lex_fname "identifier", :tIDENTIFIER, :expr_end
693
+ end
694
+
695
+ def test_yylex_identifier_eh
696
+ util_lex_token("identifier?", :tFID, "identifier?")
697
+ end
698
+
699
+ def test_yylex_identifier_equals_arrow
700
+ @lex.lex_state = :expr_fname
701
+ util_lex_token(":blah==>",
702
+ :tSYMBOL, "blah=",
703
+ :tASSOC, "=>")
704
+ end
705
+
706
+ def test_yylex_identifier_equals_caret
707
+ util_lex_fname "^", :tCARET
708
+ end
709
+
710
+ def test_yylex_identifier_equals_def
711
+ util_lex_fname "identifier=", :tIDENTIFIER, :expr_end
712
+ end
713
+
714
+ def test_yylex_identifier_equals_def2
715
+ util_lex_fname "==", :tEQ
716
+ end
717
+
718
+ def test_yylex_identifier_equals_expr
719
+ @lex.lex_state = :expr_dot
720
+ util_lex_token("y = arg",
721
+ :tIDENTIFIER, "y",
722
+ :tEQL, "=",
723
+ :tIDENTIFIER, "arg")
724
+
725
+ assert_equal :expr_arg, @lex.lex_state
726
+ end
727
+
728
+ def test_yylex_identifier_equals_or
729
+ util_lex_fname "|", :tPIPE
730
+ end
731
+
732
+ def test_yylex_identifier_equals_slash
733
+ util_lex_fname "/", :tDIVIDE
734
+ end
735
+
736
+ def test_yylex_identifier_equals_tilde
737
+ @lex.lex_state = :expr_fname # can only set via parser's defs
738
+ util_lex_token("identifier=~",
739
+ :tIDENTIFIER, "identifier",
740
+ :tMATCH, "=~")
741
+ end
742
+
743
+ def test_yylex_identifier_gt
744
+ util_lex_fname ">", :tGT
745
+ end
746
+
747
+ def test_yylex_identifier_le
748
+ util_lex_fname "<=", :tLEQ
749
+ end
750
+
751
+ def test_yylex_identifier_lt
752
+ util_lex_fname "<", :tLT
753
+ end
754
+
755
+ def test_yylex_identifier_tilde
756
+ util_lex_fname "~", :tTILDE
757
+ end
758
+
759
+ def test_yylex_index
760
+ util_lex_fname "[]", :tAREF
761
+ end
762
+
763
+ def test_yylex_index_equals
764
+ util_lex_fname "[]=", :tASET
765
+ end
766
+
767
+ def test_yylex_integer
768
+ util_lex_token "42", :tINTEGER, 42
769
+ end
770
+
771
+ def test_yylex_integer_bin
772
+ util_lex_token "0b101010", :tINTEGER, 42
773
+ end
774
+
775
+ def test_yylex_integer_bin_bad_none
776
+ util_bad_token "0b "
777
+ end
778
+
779
+ def test_yylex_integer_bin_bad_underscores
780
+ util_bad_token "0b10__01"
781
+ end
782
+
783
+ def test_yylex_integer_dec
784
+ util_lex_token "42", :tINTEGER, 42
785
+ end
786
+
787
+ def test_yylex_integer_dec_bad_underscores
788
+ util_bad_token "42__24"
789
+ end
790
+
791
+ def test_yylex_integer_dec_d
792
+ util_lex_token "0d42", :tINTEGER, 42
793
+ end
794
+
795
+ def test_yylex_integer_dec_d_bad_none
796
+ util_bad_token "0d"
797
+ end
798
+
799
+ def test_yylex_integer_dec_d_bad_underscores
800
+ util_bad_token "0d42__24"
801
+ end
802
+
803
+ def test_yylex_integer_eh_a
804
+ util_lex_token '?a', :tINTEGER, 97
805
+ end
806
+
807
+ def test_yylex_integer_eh_escape_M_escape_C
808
+ util_lex_token '?\M-\C-a', :tINTEGER, 129
809
+ end
810
+
811
+ def test_yylex_integer_hex
812
+ util_lex_token "0x2a", :tINTEGER, 42
813
+ end
814
+
815
+ def test_yylex_integer_hex_bad_none
816
+ util_bad_token "0x "
817
+ end
818
+
819
+ def test_yylex_integer_hex_bad_underscores
820
+ util_bad_token "0xab__cd"
821
+ end
822
+
823
+ def test_yylex_integer_oct
824
+ util_lex_token "052", :tINTEGER, 42
825
+ end
826
+
827
+ def test_yylex_integer_oct_bad_range
828
+ util_bad_token "08"
829
+ end
830
+
831
+ def test_yylex_integer_oct_bad_underscores
832
+ util_bad_token "01__23"
833
+ end
834
+
835
+ def test_yylex_integer_oct_o
836
+ util_lex_token "0o52", :tINTEGER, 42
837
+ end
838
+
839
+ def test_yylex_integer_oct_o_bad_range
840
+ util_bad_token "0o8"
841
+ end
842
+
843
+ def test_yylex_integer_oct_o_bad_underscores
844
+ util_bad_token "0o1__23"
845
+ end
846
+
847
+ def test_yylex_integer_oct_o_not_bad_none
848
+ util_lex_token "0o ", :tINTEGER, 0
849
+ end
850
+
851
+ def test_yylex_integer_trailing
852
+ util_lex_token("1.to_s",
853
+ :tINTEGER, 1,
854
+ :tDOT, '.',
855
+ :tIDENTIFIER, 'to_s')
856
+ end
857
+
858
+ def test_yylex_integer_underscore
859
+ util_lex_token "4_2", :tINTEGER, 42
860
+ end
861
+
862
+ def test_yylex_integer_underscore_bad
863
+ util_bad_token "4__2"
864
+ end
865
+
866
+ def test_yylex_integer_zero
867
+ util_lex_token "0", :tINTEGER, 0
868
+ end
869
+
870
+ def test_yylex_ivar
871
+ util_lex_token "@blah", :tIVAR, "@blah"
872
+ end
873
+
874
+ def test_yylex_ivar_bad
875
+ util_bad_token "@1"
876
+ end
877
+
878
+ def test_yylex_keyword_expr
879
+ @lex.lex_state = :expr_endarg
880
+
881
+ util_lex_token("if", :kIF_MOD, "if")
882
+
883
+ assert_equal :expr_beg, @lex.lex_state
884
+ end
885
+
886
+ def test_yylex_lt
887
+ util_lex_token "<", :tLT, "<"
888
+ end
889
+
890
+ def test_yylex_lt2
891
+ util_lex_token("a <\< b",
892
+ :tIDENTIFIER, "a",
893
+ :tLSHFT, "<\<",
894
+ :tIDENTIFIER, "b")
895
+
896
+ end
897
+
898
+ def test_yylex_lt2_equals
899
+ util_lex_token("a <\<= b",
900
+ :tIDENTIFIER, "a",
901
+ :tOP_ASGN, "<\<",
902
+ :tIDENTIFIER, "b")
903
+ end
904
+
905
+ def test_yylex_lt_equals
906
+ util_lex_token "<=", :tLEQ, "<="
907
+ end
908
+
909
+ def test_yylex_minus
910
+ util_lex_token("1 - 2",
911
+ :tINTEGER, 1,
912
+ :tMINUS, "-",
913
+ :tINTEGER, 2)
914
+ end
915
+
916
+ def test_yylex_minus_equals
917
+ util_lex_token "-=", :tOP_ASGN, "-"
918
+ end
919
+
920
+ def test_yylex_minus_method
921
+ @lex.lex_state = :expr_fname
922
+ util_lex_token "-", :tMINUS, "-"
923
+ end
924
+
925
+ def test_yylex_minus_unary_method
926
+ @lex.lex_state = :expr_fname
927
+ util_lex_token "-@", :tUMINUS, "-@"
928
+ end
929
+
930
+ def test_yylex_minus_unary_number
931
+ util_lex_token("-42",
932
+ :tUMINUS_NUM, "-",
933
+ :tINTEGER, 42)
934
+ end
935
+
936
+ def test_yylex_nth_ref
937
+ util_lex_token('[$1, $2, $3, $4, $5, $6, $7, $8, $9]',
938
+ :tLBRACK, "[",
939
+ :tNTH_REF, 1, :tCOMMA, ",",
940
+ :tNTH_REF, 2, :tCOMMA, ",",
941
+ :tNTH_REF, 3, :tCOMMA, ",",
942
+ :tNTH_REF, 4, :tCOMMA, ",",
943
+ :tNTH_REF, 5, :tCOMMA, ",",
944
+ :tNTH_REF, 6, :tCOMMA, ",",
945
+ :tNTH_REF, 7, :tCOMMA, ",",
946
+ :tNTH_REF, 8, :tCOMMA, ",",
947
+ :tNTH_REF, 9,
948
+ :tRBRACK, "]")
949
+ end
950
+
951
+ def test_yylex_open_bracket
952
+ util_lex_token("(", :tLPAREN, "(")
953
+ end
954
+
955
+ def test_yylex_open_bracket_cmdarg
956
+ @lex.lex_state = :expr_cmdarg
957
+ util_lex_token(" (", :tLPAREN_ARG, "(")
958
+ end
959
+
960
+ def test_yylex_open_bracket_exprarg
961
+ @lex.lex_state = :expr_arg
962
+ util_lex_token(" (", :tLPAREN2, "(")
963
+ end
964
+
965
+ def test_yylex_open_curly_bracket
966
+ util_lex_token("{",
967
+ :tLBRACE, "{")
968
+ end
969
+
970
+ def test_yylex_open_curly_bracket_arg
971
+ @lex.lex_state = :expr_arg
972
+ util_lex_token("m { 3 }",
973
+ :tIDENTIFIER, "m",
974
+ :tLCURLY, "{",
975
+ :tINTEGER, 3,
976
+ :tRCURLY, "}")
977
+ end
978
+
979
+ def test_yylex_open_curly_bracket_block
980
+ @lex.lex_state = :expr_endarg # seen m(3)
981
+ util_lex_token("{ 4 }",
982
+ :tLBRACE_ARG, "{",
983
+ :tINTEGER, 4,
984
+ :tRCURLY, "}")
985
+ end
986
+
987
+ def test_yylex_open_square_bracket_arg
988
+ @lex.lex_state = :expr_arg
989
+ util_lex_token("m [ 3 ]",
990
+ :tIDENTIFIER, "m",
991
+ :tLBRACK, "[",
992
+ :tINTEGER, 3,
993
+ :tRBRACK, "]")
994
+ end
995
+
996
+ def test_yylex_open_square_bracket_ary
997
+ util_lex_token("[1, 2, 3]",
998
+ :tLBRACK, "[",
999
+ :tINTEGER, 1,
1000
+ :tCOMMA, ",",
1001
+ :tINTEGER, 2,
1002
+ :tCOMMA, ",",
1003
+ :tINTEGER, 3,
1004
+ :tRBRACK, "]")
1005
+ end
1006
+
1007
+ def test_yylex_open_square_bracket_meth
1008
+ util_lex_token("m[3]",
1009
+ :tIDENTIFIER, "m",
1010
+ "[", "[",
1011
+ :tINTEGER, 3,
1012
+ :tRBRACK, "]")
1013
+ end
1014
+
1015
+ def test_yylex_or
1016
+ util_lex_token "|", :tPIPE, "|"
1017
+ end
1018
+
1019
+ def test_yylex_or2
1020
+ util_lex_token "||", :tOROP, "||"
1021
+ end
1022
+
1023
+ def test_yylex_or2_equals
1024
+ util_lex_token "||=", :tOP_ASGN, "||"
1025
+ end
1026
+
1027
+ def test_yylex_or_equals
1028
+ util_lex_token "|=", :tOP_ASGN, "|"
1029
+ end
1030
+
1031
+ def test_yylex_percent
1032
+ util_lex_token("a % 2",
1033
+ :tIDENTIFIER, "a",
1034
+ :tPERCENT, "%",
1035
+ :tINTEGER, 2)
1036
+ end
1037
+
1038
+ def test_yylex_percent_equals
1039
+ util_lex_token("a %= 2",
1040
+ :tIDENTIFIER, "a",
1041
+ :tOP_ASGN, "%",
1042
+ :tINTEGER, 2)
1043
+ end
1044
+
1045
+ def test_yylex_plus
1046
+ util_lex_token("1 + 1", # TODO lex_state?
1047
+ :tINTEGER, 1,
1048
+ :tPLUS, "+",
1049
+ :tINTEGER, 1)
1050
+ end
1051
+
1052
+ def test_yylex_plus_equals
1053
+ util_lex_token "+=", :tOP_ASGN, "+"
1054
+ end
1055
+
1056
+ def test_yylex_plus_method
1057
+ @lex.lex_state = :expr_fname
1058
+ util_lex_token "+", :tPLUS, "+"
1059
+ end
1060
+
1061
+ def test_yylex_plus_unary_method
1062
+ @lex.lex_state = :expr_fname
1063
+ util_lex_token "+@", :tUPLUS, "+@"
1064
+ end
1065
+
1066
+ def test_yylex_plus_unary_number
1067
+ util_lex_token("+42",
1068
+ :tINTEGER, 42)
1069
+ end
1070
+
1071
+ def test_yylex_question
1072
+ util_lex_token "?*", :tINTEGER, 42
1073
+ end
1074
+
1075
+ def test_yylex_question_bad_eos
1076
+ util_bad_token "?"
1077
+ end
1078
+
1079
+ def test_yylex_question_ws
1080
+ util_lex_token "? ", :tEH, "?"
1081
+ util_lex_token "?\n", :tEH, "?"
1082
+ util_lex_token "?\t", :tEH, "?"
1083
+ util_lex_token "?\v", :tEH, "?"
1084
+ util_lex_token "?\r", :tEH, "?"
1085
+ util_lex_token "?\f", :tEH, "?"
1086
+ end
1087
+
1088
+ def test_yylex_question_ws_backslashed
1089
+ @lex.lex_state = :expr_beg
1090
+ util_lex_token "?\\ ", :tINTEGER, 32
1091
+ @lex.lex_state = :expr_beg
1092
+ util_lex_token "?\\n", :tINTEGER, 10
1093
+ @lex.lex_state = :expr_beg
1094
+ util_lex_token "?\\t", :tINTEGER, 9
1095
+ @lex.lex_state = :expr_beg
1096
+ util_lex_token "?\\v", :tINTEGER, 11
1097
+ @lex.lex_state = :expr_beg
1098
+ util_lex_token "?\\r", :tINTEGER, 13
1099
+ @lex.lex_state = :expr_beg
1100
+ util_lex_token "?\\f", :tINTEGER, 12
1101
+ end
1102
+
1103
+ def test_yylex_rbracket
1104
+ util_lex_token "]", :tRBRACK, "]"
1105
+ end
1106
+
1107
+ def test_yylex_rcurly
1108
+ util_lex_token "}", :tRCURLY, "}"
1109
+ end
1110
+
1111
+ def test_yylex_regexp
1112
+ util_lex_token("/regexp/",
1113
+ :tREGEXP_BEG, "/",
1114
+ :tSTRING_CONTENT, "regexp",
1115
+ :tREGEXP_END, "")
1116
+ end
1117
+
1118
+ def test_yylex_regexp_ambiguous
1119
+ util_lex_token("method /regexp/",
1120
+ :tIDENTIFIER, "method",
1121
+ :tREGEXP_BEG, "/",
1122
+ :tSTRING_CONTENT, "regexp",
1123
+ :tREGEXP_END, "")
1124
+ end
1125
+
1126
+ def test_yylex_regexp_bad
1127
+ util_bad_token("/.*/xyz",
1128
+ :tREGEXP_BEG, "/",
1129
+ :tSTRING_CONTENT, ".*")
1130
+ end
1131
+
1132
+ def test_yylex_regexp_escape_C
1133
+ util_lex_token('/regex\\C-x/',
1134
+ :tREGEXP_BEG, "/",
1135
+ :tSTRING_CONTENT, "regex\\C-x",
1136
+ :tREGEXP_END, "")
1137
+ end
1138
+
1139
+ def test_yylex_regexp_escape_C_M
1140
+ util_lex_token('/regex\\C-\\M-x/',
1141
+ :tREGEXP_BEG, "/",
1142
+ :tSTRING_CONTENT, "regex\\C-\\M-x",
1143
+ :tREGEXP_END, "")
1144
+ end
1145
+
1146
+ def test_yylex_regexp_escape_C_M_craaaazy
1147
+ util_lex_token("/regex\\C-\\\n\\M-x/",
1148
+ :tREGEXP_BEG, "/",
1149
+ :tSTRING_CONTENT, "regex\\C-\\M-x",
1150
+ :tREGEXP_END, "")
1151
+ end
1152
+
1153
+ def test_yylex_regexp_escape_C_bad_dash
1154
+ util_bad_token '/regex\\Cx/', :tREGEXP_BEG, "/"
1155
+ end
1156
+
1157
+ def test_yylex_regexp_escape_C_bad_dash_eos
1158
+ util_bad_token '/regex\\C-/', :tREGEXP_BEG, "/"
1159
+ end
1160
+
1161
+ def test_yylex_regexp_escape_C_bad_dash_eos2
1162
+ util_bad_token '/regex\\C-', :tREGEXP_BEG, "/"
1163
+ end
1164
+
1165
+ def test_yylex_regexp_escape_C_bad_eos
1166
+ util_bad_token '/regex\\C/', :tREGEXP_BEG, "/"
1167
+ end
1168
+
1169
+ def test_yylex_regexp_escape_C_bad_eos2
1170
+ util_bad_token '/regex\\c', :tREGEXP_BEG, "/"
1171
+ end
1172
+
1173
+ def test_yylex_regexp_escape_M
1174
+ util_lex_token('/regex\\M-x/',
1175
+ :tREGEXP_BEG, "/",
1176
+ :tSTRING_CONTENT, "regex\\M-x",
1177
+ :tREGEXP_END, "")
1178
+ end
1179
+
1180
+ def test_yylex_regexp_escape_M_C
1181
+ util_lex_token('/regex\\M-\\C-x/',
1182
+ :tREGEXP_BEG, "/",
1183
+ :tSTRING_CONTENT, "regex\\M-\\C-x",
1184
+ :tREGEXP_END, "")
1185
+ end
1186
+
1187
+ def test_yylex_regexp_escape_M_bad_dash
1188
+ util_bad_token '/regex\\Mx/', :tREGEXP_BEG, "/"
1189
+ end
1190
+
1191
+ def test_yylex_regexp_escape_M_bad_dash_eos
1192
+ util_bad_token '/regex\\M-/', :tREGEXP_BEG, "/"
1193
+ end
1194
+
1195
+ def test_yylex_regexp_escape_M_bad_dash_eos2
1196
+ util_bad_token '/regex\\M-', :tREGEXP_BEG, "/"
1197
+ end
1198
+
1199
+ def test_yylex_regexp_escape_M_bad_eos
1200
+ util_bad_token '/regex\\M/', :tREGEXP_BEG, "/"
1201
+ end
1202
+
1203
+ def test_yylex_regexp_escape_backslash_slash
1204
+ util_lex_token('/\\//',
1205
+ :tREGEXP_BEG, "/",
1206
+ :tSTRING_CONTENT, '\\/',
1207
+ :tREGEXP_END, "")
1208
+ end
1209
+
1210
+ def test_yylex_regexp_escape_backslash_terminator
1211
+ util_lex_token('%r%blah\\%blah%',
1212
+ :tREGEXP_BEG, "%r\000", # FIX ?!?
1213
+ :tSTRING_CONTENT, "blah\\%blah",
1214
+ :tREGEXP_END, "")
1215
+ end
1216
+
1217
+ def test_yylex_regexp_escape_backslash_terminator_meta1
1218
+ util_lex_token('%r{blah\\}blah}',
1219
+ :tREGEXP_BEG, "%r{", # FIX ?!?
1220
+ :tSTRING_CONTENT, "blah\\}blah",
1221
+ :tREGEXP_END, "")
1222
+ end
1223
+
1224
+ def test_yylex_regexp_escape_backslash_terminator_meta2
1225
+ util_lex_token('%r/blah\\/blah/',
1226
+ :tREGEXP_BEG, "%r\000", # FIX ?!?
1227
+ :tSTRING_CONTENT, "blah\\/blah",
1228
+ :tREGEXP_END, "")
1229
+ end
1230
+
1231
+ def test_yylex_regexp_escape_backslash_terminator_meta3
1232
+ util_lex_token('%r/blah\\%blah/',
1233
+ :tREGEXP_BEG, "%r\000", # FIX ?!?
1234
+ :tSTRING_CONTENT, "blah\\%blah",
1235
+ :tREGEXP_END, "")
1236
+ end
1237
+
1238
+ def test_yylex_regexp_escape_bad_eos
1239
+ util_bad_token '/regex\\', :tREGEXP_BEG, "/"
1240
+ end
1241
+
1242
+ def test_yylex_regexp_escape_bs
1243
+ util_lex_token('/regex\\\\regex/',
1244
+ :tREGEXP_BEG, "/",
1245
+ :tSTRING_CONTENT, "regex\\\\regex",
1246
+ :tREGEXP_END, "")
1247
+ end
1248
+
1249
+ def test_yylex_regexp_escape_c
1250
+ util_lex_token('/regex\\cxxx/',
1251
+ :tREGEXP_BEG, "/",
1252
+ :tSTRING_CONTENT, "regex\\cxxx",
1253
+ :tREGEXP_END, "")
1254
+ end
1255
+
1256
+ def test_yylex_regexp_escape_c_backslash
1257
+ util_lex_token('/regex\\c\\n/',
1258
+ :tREGEXP_BEG, "/",
1259
+ :tSTRING_CONTENT, "regex\\c\\n",
1260
+ :tREGEXP_END, "")
1261
+ end
1262
+
1263
+ def test_yylex_regexp_escape_chars
1264
+ util_lex_token('/re\\tge\\nxp/',
1265
+ :tREGEXP_BEG, "/",
1266
+ :tSTRING_CONTENT, "re\\tge\\nxp",
1267
+ :tREGEXP_END, "")
1268
+ end
1269
+
1270
+ def test_yylex_regexp_escape_double_backslash
1271
+ regexp = '/[\\/\\\\]$/'
1272
+ util_lex_token(regexp,
1273
+ :tREGEXP_BEG, "/",
1274
+ :tSTRING_CONTENT, regexp[1..-2],
1275
+ :tREGEXP_END, "")
1276
+ end
1277
+
1278
+ def test_yylex_regexp_escape_hex
1279
+ util_lex_token('/regex\\x61xp/',
1280
+ :tREGEXP_BEG, "/",
1281
+ :tSTRING_CONTENT, "regex\\x61xp",
1282
+ :tREGEXP_END, "")
1283
+ end
1284
+
1285
+ def test_yylex_regexp_escape_hex_one
1286
+ util_lex_token('/^[\\xd\\xa]{2}/on',
1287
+ :tREGEXP_BEG, '/',
1288
+ :tSTRING_CONTENT, '^[\\xd\\xa]{2}',
1289
+ :tREGEXP_END, 'on')
1290
+ end
1291
+
1292
+ def test_yylex_regexp_escape_hex_bad
1293
+ util_bad_token '/regex\\xzxp/', :tREGEXP_BEG, "/"
1294
+ end
1295
+
1296
+ def test_yylex_regexp_escape_oct1
1297
+ util_lex_token('/regex\\0xp/',
1298
+ :tREGEXP_BEG, "/",
1299
+ :tSTRING_CONTENT, "regex\\0xp",
1300
+ :tREGEXP_END, "")
1301
+ end
1302
+
1303
+ def test_yylex_regexp_escape_oct2
1304
+ util_lex_token('/regex\\07xp/',
1305
+ :tREGEXP_BEG, "/",
1306
+ :tSTRING_CONTENT, "regex\\07xp",
1307
+ :tREGEXP_END, "")
1308
+ end
1309
+
1310
+ def test_yylex_regexp_escape_oct3
1311
+ util_lex_token('/regex\\10142/',
1312
+ :tREGEXP_BEG, "/",
1313
+ :tSTRING_CONTENT, "regex\\10142",
1314
+ :tREGEXP_END, "")
1315
+ end
1316
+
1317
+ def test_yylex_regexp_escape_return
1318
+ util_lex_token("/regex\\\nregex/",
1319
+ :tREGEXP_BEG, "/",
1320
+ :tSTRING_CONTENT, "regexregex",
1321
+ :tREGEXP_END, "")
1322
+ end
1323
+
1324
+ def test_yylex_regexp_nm
1325
+ util_lex_token("/.*/nm",
1326
+ :tREGEXP_BEG, "/",
1327
+ :tSTRING_CONTENT, ".*",
1328
+ :tREGEXP_END, "nm")
1329
+ end
1330
+
1331
+ def test_yylex_rparen
1332
+ util_lex_token ")", :tRPAREN, ")"
1333
+ end
1334
+
1335
+ def test_yylex_rshft
1336
+ util_lex_token("a >> 2",
1337
+ :tIDENTIFIER, "a",
1338
+ :tRSHFT, ">>",
1339
+ :tINTEGER, 2)
1340
+ end
1341
+
1342
+ def test_yylex_rshft_equals
1343
+ util_lex_token("a >>= 2",
1344
+ :tIDENTIFIER, "a",
1345
+ :tOP_ASGN, ">>",
1346
+ :tINTEGER, 2)
1347
+ end
1348
+
1349
+ def test_yylex_star
1350
+ util_lex_token("a * ",
1351
+ :tIDENTIFIER, "a",
1352
+ :tSTAR2, "*")
1353
+
1354
+ assert_equal :expr_beg, @lex.lex_state
1355
+ end
1356
+
1357
+ def test_yylex_star2
1358
+ util_lex_token("a ** ",
1359
+ :tIDENTIFIER, "a",
1360
+ :tPOW, "**")
1361
+
1362
+ assert_equal :expr_beg, @lex.lex_state
1363
+ end
1364
+
1365
+ def test_yylex_star2_equals
1366
+ util_lex_token("a **= ",
1367
+ :tIDENTIFIER, "a",
1368
+ :tOP_ASGN, "**")
1369
+
1370
+ assert_equal :expr_beg, @lex.lex_state
1371
+ end
1372
+
1373
+ def test_yylex_star_arg
1374
+ @lex.lex_state = :expr_arg
1375
+
1376
+ util_lex_token(" *a",
1377
+ :tSTAR, "*",
1378
+ :tIDENTIFIER, "a")
1379
+
1380
+ assert_equal :expr_arg, @lex.lex_state
1381
+ end
1382
+
1383
+ def test_yylex_star_arg_beg
1384
+ @lex.lex_state = :expr_beg
1385
+
1386
+ util_lex_token("*a",
1387
+ :tSTAR, "*",
1388
+ :tIDENTIFIER, "a")
1389
+
1390
+ assert_equal :expr_arg, @lex.lex_state
1391
+ end
1392
+
1393
+ def test_yylex_star_arg_beg_fname
1394
+ @lex.lex_state = :expr_fname
1395
+
1396
+ util_lex_token("*a",
1397
+ :tSTAR2, "*",
1398
+ :tIDENTIFIER, "a")
1399
+
1400
+ assert_equal :expr_arg, @lex.lex_state
1401
+ end
1402
+
1403
+ def test_yylex_star_equals
1404
+ util_lex_token("a *= ",
1405
+ :tIDENTIFIER, "a",
1406
+ :tOP_ASGN, "*")
1407
+
1408
+ assert_equal :expr_beg, @lex.lex_state
1409
+ end
1410
+
1411
+ def test_yylex_string_bad_eos
1412
+ util_bad_token('%',
1413
+ :tSTRING_BEG, '%')
1414
+ end
1415
+
1416
+ def test_yylex_string_bad_eos_quote
1417
+ util_bad_token('%{nest',
1418
+ :tSTRING_BEG, '%}')
1419
+ end
1420
+
1421
+ def test_yylex_string_double
1422
+ util_lex_token('"string"',
1423
+ :tSTRING, "string")
1424
+ end
1425
+
1426
+ def test_yylex_string_double_escape_M
1427
+ util_lex_token('"\\M-g"',
1428
+ :tSTRING, "\347")
1429
+ end
1430
+
1431
+ def test_yylex_string_escape_x_single
1432
+ util_lex_token('"\\x0"',
1433
+ :tSTRING, "\000")
1434
+ end
1435
+
1436
+ def test_yylex_string_double_escape_chars
1437
+ util_lex_token('"s\\tri\\ng"',
1438
+ :tSTRING, "s\tri\ng")
1439
+ end
1440
+
1441
+ def test_yylex_string_double_escape_hex
1442
+ util_lex_token('"n = \\x61\\x62\\x63"',
1443
+ :tSTRING, "n = abc")
1444
+ end
1445
+
1446
+ def test_yylex_string_double_escape_bs1
1447
+ util_lex_token('"a\\a\\a"',
1448
+ :tSTRING, "a\a\a")
1449
+ end
1450
+
1451
+ def test_yylex_string_double_escape_bs2
1452
+ util_lex_token('"a\\\\a"',
1453
+ :tSTRING, "a\\a")
1454
+ end
1455
+
1456
+ def test_yylex_string_double_escape_octal
1457
+ util_lex_token('"n = \\101\\102\\103"',
1458
+ :tSTRING, "n = ABC")
1459
+ end
1460
+
1461
+ def test_yylex_string_double_interp
1462
+ util_lex_token("\"blah #x a \#@a b \#$b c \#{3} # \"",
1463
+ :tSTRING_BEG, "\"",
1464
+ :tSTRING_CONTENT, "blah #x a ",
1465
+ :tSTRING_DVAR, nil,
1466
+ :tSTRING_CONTENT, "@a b ",
1467
+ :tSTRING_DVAR, nil,
1468
+ :tSTRING_CONTENT, "$b c ",
1469
+ :tSTRING_DBEG, nil,
1470
+ :tSTRING_CONTENT, "3} # ",
1471
+ :tSTRING_END, "\"")
1472
+ end
1473
+
1474
+ def test_yylex_string_double_nested_curlies
1475
+ util_lex_token('%{nest{one{two}one}nest}',
1476
+ :tSTRING_BEG, '%}',
1477
+ :tSTRING_CONTENT, "nest{one{two}one}nest",
1478
+ :tSTRING_END, '}')
1479
+ end
1480
+
1481
+ def test_yylex_string_double_no_interp
1482
+ util_lex_token("\"# blah\"", # pound first
1483
+ :tSTRING, "# blah")
1484
+
1485
+ util_lex_token("\"blah # blah\"", # pound not first
1486
+ :tSTRING, "blah # blah")
1487
+ end
1488
+
1489
+ def test_yylex_string_pct_Q
1490
+ util_lex_token("%Q[s1 s2]",
1491
+ :tSTRING_BEG, "%Q[",
1492
+ :tSTRING_CONTENT, "s1 s2",
1493
+ :tSTRING_END, "]")
1494
+ end
1495
+
1496
+ def test_yylex_string_pct_W
1497
+ util_lex_token("%W[s1 s2\ns3]", # TODO: add interpolation to these
1498
+ :tWORDS_BEG, "%W[",
1499
+ :tSTRING_CONTENT, "s1",
1500
+ :tSPACE, nil,
1501
+ :tSTRING_CONTENT, "s2",
1502
+ :tSPACE, nil,
1503
+ :tSTRING_CONTENT, "s3",
1504
+ :tSPACE, nil,
1505
+ :tSTRING_END, nil)
1506
+ end
1507
+
1508
+ def test_yylex_string_pct_W_bs_nl
1509
+ util_lex_token("%W[s1 \\\ns2]", # TODO: add interpolation to these
1510
+ :tWORDS_BEG, "%W[",
1511
+ :tSTRING_CONTENT, "s1",
1512
+ :tSPACE, nil,
1513
+ :tSTRING_CONTENT, "\ns2",
1514
+ :tSPACE, nil,
1515
+ :tSTRING_END, nil)
1516
+ end
1517
+
1518
+ def test_yylex_string_pct_angle
1519
+ util_lex_token("%<blah>",
1520
+ :tSTRING_BEG, "%>",
1521
+ :tSTRING_CONTENT, "blah",
1522
+ :tSTRING_END, ">")
1523
+ end
1524
+
1525
+ def test_yylex_string_pct_other
1526
+ util_lex_token("%%blah%",
1527
+ :tSTRING_BEG, "%%",
1528
+ :tSTRING_CONTENT, "blah",
1529
+ :tSTRING_END, "%")
1530
+ end
1531
+
1532
+ def test_yylex_string_pct_w
1533
+ util_bad_token("%w[s1 s2 ",
1534
+ :tAWORDS_BEG, "%w[",
1535
+ :tSTRING_CONTENT, "s1",
1536
+ :tSPACE, nil,
1537
+ :tSTRING_CONTENT, "s2",
1538
+ :tSPACE, nil)
1539
+ end
1540
+
1541
+ def test_yylex_string_pct_w_bs_nl
1542
+ util_lex_token("%w[s1 \\\ns2]",
1543
+ :tAWORDS_BEG, "%w[",
1544
+ :tSTRING_CONTENT, "s1",
1545
+ :tSPACE, nil,
1546
+ :tSTRING_CONTENT, "\ns2",
1547
+ :tSPACE, nil,
1548
+ :tSTRING_END, nil)
1549
+ end
1550
+
1551
+ def test_yylex_string_pct_w_bs_sp
1552
+ util_lex_token("%w[s\\ 1 s\\ 2]",
1553
+ :tAWORDS_BEG, "%w[",
1554
+ :tSTRING_CONTENT, "s 1",
1555
+ :tSPACE, nil,
1556
+ :tSTRING_CONTENT, "s 2",
1557
+ :tSPACE, nil,
1558
+ :tSTRING_END, nil)
1559
+ end
1560
+
1561
+ def test_yylex_string_single
1562
+ util_lex_token("'string'",
1563
+ :tSTRING, "string")
1564
+ end
1565
+
1566
+ def test_yylex_string_single_escape_chars
1567
+ util_lex_token("'s\\tri\\ng'",
1568
+ :tSTRING, "s\\tri\\ng")
1569
+ end
1570
+
1571
+ def test_yylex_string_single_nl
1572
+ util_lex_token("'blah\\\nblah'",
1573
+ :tSTRING, "blah\\\nblah")
1574
+ end
1575
+
1576
+ def test_yylex_symbol
1577
+ util_lex_token(":symbol",
1578
+ :tSYMBOL, "symbol")
1579
+ end
1580
+
1581
+ def test_yylex_symbol_bad_zero
1582
+ util_bad_token(":\"blah\0\"",
1583
+ :tSYMBEG, ":")
1584
+ end
1585
+
1586
+ def test_yylex_symbol_double
1587
+ util_lex_token(":\"symbol\"",
1588
+ :tSYMBEG, ":",
1589
+ :tSTRING_CONTENT, "symbol",
1590
+ :tSTRING_END, '"')
1591
+ end
1592
+
1593
+ def test_yylex_symbol_single
1594
+ util_lex_token(":'symbol'",
1595
+ :tSYMBEG, ":",
1596
+ :tSTRING_CONTENT, "symbol",
1597
+ :tSTRING_END, "'")
1598
+ end
1599
+
1600
+ def test_yylex_ternary
1601
+ util_lex_token("a ? b : c",
1602
+ :tIDENTIFIER, "a",
1603
+ :tEH, "?",
1604
+ :tIDENTIFIER, "b",
1605
+ :tCOLON, ":",
1606
+ :tIDENTIFIER, "c")
1607
+
1608
+ util_lex_token("a ?bb : c", # GAH! MATZ!!!
1609
+ :tIDENTIFIER, "a",
1610
+ :tEH, "?",
1611
+ :tIDENTIFIER, "bb",
1612
+ :tCOLON, ":",
1613
+ :tIDENTIFIER, "c")
1614
+
1615
+ util_lex_token("42 ?", # 42 forces expr_end
1616
+ :tINTEGER, 42,
1617
+ :tEH, "?")
1618
+ end
1619
+
1620
+ def test_yylex_tilde
1621
+ util_lex_token "~", :tTILDE, "~"
1622
+ end
1623
+
1624
+ def test_yylex_tilde_unary
1625
+ @lex.lex_state = :expr_fname
1626
+ util_lex_token "~@", :tTILDE, "~"
1627
+ end
1628
+
1629
+ def test_yylex_uminus
1630
+ util_lex_token("-blah",
1631
+ :tUMINUS, "-",
1632
+ :tIDENTIFIER, "blah")
1633
+ end
1634
+
1635
+ def test_yylex_underscore
1636
+ util_lex_token("_var", :tIDENTIFIER, "_var")
1637
+ end
1638
+
1639
+ def test_yylex_underscore_end
1640
+ @lex.src = "__END__\n"
1641
+ deny @lex.advance
1642
+ end
1643
+
1644
+ def test_yylex_uplus
1645
+ util_lex_token("+blah",
1646
+ :tUPLUS, "+",
1647
+ :tIDENTIFIER, "blah")
1648
+ end
1649
+
1650
+ def test_zbug_float_in_decl
1651
+ util_lex_token("def initialize(u = ",
1652
+ :kDEF, "def",
1653
+ :tIDENTIFIER, "initialize",
1654
+ :tLPAREN2, "(",
1655
+ :tIDENTIFIER, "u",
1656
+ :tEQL, "=")
1657
+
1658
+ assert_equal :expr_beg, @lex.lex_state
1659
+
1660
+ util_lex_token("0.0, s = 0.0",
1661
+ :tFLOAT, 0.0,
1662
+ :tCOMMA, ',',
1663
+ :tIDENTIFIER, "s",
1664
+ :tEQL, "=",
1665
+ :tFLOAT, 0.0)
1666
+ end
1667
+
1668
+ def test_zbug_id_equals
1669
+ util_lex_token("a =",
1670
+ :tIDENTIFIER, "a",
1671
+ :tEQL, "=")
1672
+
1673
+ assert_equal :expr_beg, @lex.lex_state
1674
+
1675
+ util_lex_token("0.0",
1676
+ :tFLOAT, 0.0)
1677
+ end
1678
+
1679
+ def test_zbug_no_spaces_in_decl
1680
+ util_lex_token("def initialize(u=",
1681
+ :kDEF, "def",
1682
+ :tIDENTIFIER, "initialize",
1683
+ :tLPAREN2, "(",
1684
+ :tIDENTIFIER, "u",
1685
+ :tEQL, "=")
1686
+
1687
+ assert_equal :expr_beg, @lex.lex_state
1688
+
1689
+ util_lex_token("0.0,s=0.0",
1690
+ :tFLOAT, 0.0,
1691
+ :tCOMMA, ",",
1692
+ :tIDENTIFIER, "s",
1693
+ :tEQL, "=",
1694
+ :tFLOAT, 0.0)
1695
+ end
1696
+
1697
+ ############################################################
1698
+
1699
+ def util_bad_token s, *args
1700
+ assert_raises SyntaxError do
1701
+ util_lex_token s, *args
1702
+ end
1703
+ end
1704
+
1705
+ def util_escape expected, input
1706
+ @lex.src = input
1707
+ assert_equal expected, @lex.read_escape
1708
+ end
1709
+
1710
+ def util_escape_bad input
1711
+ @lex.src = input
1712
+ assert_raises SyntaxError do
1713
+ @lex.read_escape
1714
+ end
1715
+ end
1716
+
1717
+ def util_lex_fname name, type, end_state = :expr_arg
1718
+ @lex.lex_state = :expr_fname # can only set via parser's defs
1719
+
1720
+ util_lex_token("def #{name} ", :kDEF, "def", type, name)
1721
+
1722
+ assert_equal end_state, @lex.lex_state
1723
+ end
1724
+
1725
+ def util_lex_token input, *args
1726
+ @lex.src = input
1727
+
1728
+ until args.empty? do
1729
+ token = args.shift
1730
+ value = args.shift
1731
+ assert @lex.advance, "no more tokens"
1732
+ assert_equal [token, value], [@lex.token, @lex.yacc_value]
1733
+ end
1734
+
1735
+ deny @lex.advance, "must be empty, but had #{[@lex.token, @lex.yacc_value].inspect}"
1736
+ end
1737
+ end
1738
+