parser 2.3.0.2 → 2.3.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3cb2802760d71d558e9ab344e63deb18525be110
4
- data.tar.gz: 32edc10c308de0d00030d4b9fbac6bd40bfff36f
3
+ metadata.gz: 32b8e79e47ae5063bd6a4451c47b337f43d5a2a2
4
+ data.tar.gz: c8d08375dca4b4089fa0dade5d77f13284498852
5
5
  SHA512:
6
- metadata.gz: 365c674e6cf6b3fa43f81903a7f46ce787075eb927e4aecce9b59ff05d81b5c47d4304f063f2f31c528f8846faec1983736f7bbd169697e19950e03346b0e52a
7
- data.tar.gz: 1504d14896c1cb0dde7a8bc46aa60b04036e03310b1f097e84e5f14587699f18b086184292fbb5fb1aaff4d201d172cd9c424d1b8bc11de725d2c64567893928
6
+ metadata.gz: 039b018cd53937074f6a0eb1b366c5d83c0de6ed104a3ca63597b265c695f010e2ae85fdee74bc9c00418510e386e9fc7e2ff44dd9dc9ead2ddef5cc3ef0ec1e
7
+ data.tar.gz: 4b8b8b3497d1034e4662aa8ad3cf85c57cd65cb73e038bf7737c63db832d719714aa2bafd2fef5dcdb85d2ee4342ef3c4c8ceb5d26f3abc5cfed67e4c6902aff
@@ -1,6 +1,12 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ v2.3.0.3 (2016-02-06)
5
+ ---------------------
6
+
7
+ API modifications:
8
+ * lexer.rl: "a?=b": lex via tCHARACTER (closes #255). (whitequark)
9
+
4
10
  v2.3.0.2 (2016-01-24)
5
11
  ---------------------
6
12
 
@@ -8,7 +14,7 @@ Bugs fixed:
8
14
  * Add :csend to Parser::Meta::NODE_TYPES (Markus Schirp)
9
15
  * lexer/dedenter: "\<\<x\n y\\n z\nx": don't dedent after escaped newline. (whitequark)
10
16
 
11
- v2.3.0.2 (2016-01-16)
17
+ v2.3.0.3 (2016-01-16)
12
18
  ---------------------
13
19
 
14
20
  v2.3.0.1 (2016-01-14)
@@ -795,7 +795,7 @@ Format:
795
795
  Format:
796
796
 
797
797
  ~~~
798
- (defs (self) (args) nil)
798
+ (defs (self) :foo (args) nil)
799
799
  "def self.foo; end"
800
800
  ~~~ keyword
801
801
  ~~~ name
@@ -82,15 +82,12 @@ class Parser::Lexer
82
82
  # %
83
83
 
84
84
  ESCAPES = {
85
- 'a' => "\a", 'b' => "\b", 'e' => "\e", 'f' => "\f",
86
- 'n' => "\n", 'r' => "\r", 's' => "\s", 't' => "\t",
87
- 'v' => "\v", '\\' => "\\"
88
- }
85
+ ?a.ord => "\a", ?b.ord => "\b", ?e.ord => "\e", ?f.ord => "\f",
86
+ ?n.ord => "\n", ?r.ord => "\r", ?s.ord => "\s", ?t.ord => "\t",
87
+ ?v.ord => "\v", ?\\.ord => "\\"
88
+ }.freeze
89
89
 
90
- BLANK_STRING = ''.freeze
91
- ESCAPED_NEXT_LINE = "\\\n".freeze
92
90
  REGEXP_META_CHARACTERS = Regexp.union(*"\\$()*+.<>?[]^{|}".chars).freeze
93
- UNDERSCORE_STRING = '_'.freeze
94
91
 
95
92
  RBRACE_OR_RBRACK = %w"} ]".freeze
96
93
 
@@ -192,9 +189,7 @@ class Parser::Lexer
192
189
  @source = @source_buffer.source
193
190
  @need_encode = false
194
191
 
195
- if @has_encode
196
- @encoding = @source.encoding
197
- end
192
+ @encoding = @source.encoding if @has_encode
198
193
 
199
194
  if @has_encode && @source.encoding == Encoding::UTF_8
200
195
  @source_pts = @source.unpack('U*')
@@ -315,10 +310,10 @@ class Parser::Lexer
315
310
  if @token_queue.any?
316
311
  @token_queue.shift
317
312
  elsif @cs == klass.lex_error
318
- [ false, [ '$error', range(p - 1, p) ] ]
313
+ [ false, [ '$error'.freeze, range(p - 1, p) ] ]
319
314
  else
320
315
  eof = @source_pts.size + 1
321
- [ false, [ '$eof', range(eof, eof) ] ]
316
+ [ false, [ '$eof'.freeze, range(eof, eof) ] ]
322
317
  end
323
318
  end
324
319
 
@@ -332,11 +327,6 @@ class Parser::Lexer
332
327
  versions.include?(@version)
333
328
  end
334
329
 
335
- def stack_pop
336
- @top -= 1
337
- @stack[@top]
338
- end
339
-
340
330
  if "".respond_to?(:encode)
341
331
  def encode_escape(ord)
342
332
  ord.chr.force_encoding(@encoding)
@@ -379,11 +369,11 @@ class Parser::Lexer
379
369
 
380
370
  def emit_do(do_block=false)
381
371
  if @cond.active?
382
- emit(:kDO_COND)
372
+ emit(:kDO_COND, 'do'.freeze)
383
373
  elsif @cmdarg.active? || do_block
384
- emit(:kDO_BLOCK)
374
+ emit(:kDO_BLOCK, 'do'.freeze)
385
375
  else
386
- emit(:kDO)
376
+ emit(:kDO, 'do'.freeze)
387
377
  end
388
378
  end
389
379
 
@@ -699,8 +689,8 @@ class Parser::Lexer
699
689
  }
700
690
 
701
691
  action unescape_char {
702
- char = @source[p - 1].chr
703
- @escape = ESCAPES.fetch(char, char)
692
+ codepoint = @source_pts[p - 1]
693
+ @escape = ESCAPES[codepoint] || encode_escape(codepoint)
704
694
  }
705
695
 
706
696
  action invalid_complex_escape {
@@ -847,7 +837,6 @@ class Parser::Lexer
847
837
 
848
838
  action extend_string {
849
839
  string = tok
850
- string = string.encode(@encoding) if @need_encode
851
840
 
852
841
  # tLABEL_END is only possible in non-cond context on >= 2.2
853
842
  if @version >= 22 && !@cond.active?
@@ -899,7 +888,7 @@ class Parser::Lexer
899
888
  if current_literal.regexp?
900
889
  # Regular expressions should include escape sequences in their
901
890
  # escaped form. On the other hand, escaped newlines are removed.
902
- current_literal.extend_string(tok.gsub(ESCAPED_NEXT_LINE, BLANK_STRING), @ts, @te)
891
+ current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
903
892
  else
904
893
  current_literal.extend_string(@escape || tok, @ts, @te)
905
894
  end
@@ -917,11 +906,11 @@ class Parser::Lexer
917
906
  end
918
907
 
919
908
  if current_literal.heredoc?
920
- line = tok(@herebody_s, @ts).gsub(/\r+$/, BLANK_STRING)
909
+ line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze)
921
910
 
922
911
  if version?(18, 19, 20)
923
912
  # See ruby:c48b4209c
924
- line = line.gsub(/\r.*$/, BLANK_STRING)
913
+ line = line.gsub(/\r.*$/, ''.freeze)
925
914
  end
926
915
 
927
916
  # Try ending the heredoc with the complete most recently
@@ -1023,9 +1012,9 @@ class Parser::Lexer
1023
1012
  if current_literal
1024
1013
  if current_literal.end_interp_brace_and_try_closing
1025
1014
  if version?(18, 19)
1026
- emit(:tRCURLY, '}', p - 1, p)
1015
+ emit(:tRCURLY, '}'.freeze, p - 1, p)
1027
1016
  else
1028
- emit(:tSTRING_DEND, '}', p - 1, p)
1017
+ emit(:tSTRING_DEND, '}'.freeze, p - 1, p)
1029
1018
  end
1030
1019
 
1031
1020
  if current_literal.saved_herebody_s
@@ -1033,7 +1022,7 @@ class Parser::Lexer
1033
1022
  end
1034
1023
 
1035
1024
  fhold;
1036
- fnext *stack_pop;
1025
+ fret;
1037
1026
  fbreak;
1038
1027
  end
1039
1028
  end
@@ -1044,7 +1033,7 @@ class Parser::Lexer
1044
1033
  current_literal.flush_string
1045
1034
  current_literal.extend_content
1046
1035
 
1047
- emit(:tSTRING_DBEG, '#{')
1036
+ emit(:tSTRING_DBEG, '#{'.freeze)
1048
1037
 
1049
1038
  if current_literal.heredoc?
1050
1039
  current_literal.saved_herebody_s = @herebody_s
@@ -1183,28 +1172,28 @@ class Parser::Lexer
1183
1172
  # The default longest-match scanning does not work here due
1184
1173
  # to sheer ambiguity.
1185
1174
 
1186
- ambiguous_fid_suffix = # actual parsed
1187
- [?!] %{ tm = p } | # a? a?
1188
- '!=' %{ tm = p - 2 } # a!=b a != b
1175
+ ambiguous_fid_suffix = # actual parsed
1176
+ [?!] %{ tm = p } | # a? a?
1177
+ [?!]'=' %{ tm = p - 2 } # a!=b a != b
1189
1178
  ;
1190
1179
 
1191
- ambiguous_ident_suffix = # actual parsed
1192
- ambiguous_fid_suffix |
1193
- '=' %{ tm = p } | # a= a=
1194
- '==' %{ tm = p - 2 } | # a==b a == b
1195
- '=~' %{ tm = p - 2 } | # a=~b a =~ b
1196
- '=>' %{ tm = p - 2 } | # a=>b a => b
1197
- '===' %{ tm = p - 3 } # a===b a === b
1180
+ ambiguous_ident_suffix = # actual parsed
1181
+ ambiguous_fid_suffix |
1182
+ '=' %{ tm = p } | # a= a=
1183
+ '==' %{ tm = p - 2 } | # a==b a == b
1184
+ '=~' %{ tm = p - 2 } | # a=~b a =~ b
1185
+ '=>' %{ tm = p - 2 } | # a=>b a => b
1186
+ '===' %{ tm = p - 3 } # a===b a === b
1198
1187
  ;
1199
1188
 
1200
- ambiguous_symbol_suffix = # actual parsed
1189
+ ambiguous_symbol_suffix = # actual parsed
1201
1190
  ambiguous_ident_suffix |
1202
- '==>' %{ tm = p - 2 } # :a==>b :a= => b
1191
+ '==>' %{ tm = p - 2 } # :a==>b :a= => b
1203
1192
  ;
1204
1193
 
1205
1194
  # Ambiguous with 1.9 hash labels.
1206
- ambiguous_const_suffix = # actual parsed
1207
- '::' %{ tm = p - 2 } # A::B A :: B
1195
+ ambiguous_const_suffix = # actual parsed
1196
+ '::' %{ tm = p - 2 } # A::B A :: B
1208
1197
  ;
1209
1198
 
1210
1199
  # Resolving kDO/kDO_COND/kDO_BLOCK ambiguity requires embedding
@@ -1252,7 +1241,7 @@ class Parser::Lexer
1252
1241
  emit(:tGVAR)
1253
1242
  end
1254
1243
 
1255
- fnext *stack_pop; fbreak;
1244
+ fret; fbreak;
1256
1245
  };
1257
1246
 
1258
1247
  class_var_v
@@ -1262,7 +1251,7 @@ class Parser::Lexer
1262
1251
  end
1263
1252
 
1264
1253
  emit(:tCVAR)
1265
- fnext *stack_pop; fbreak;
1254
+ fret; fbreak;
1266
1255
  };
1267
1256
 
1268
1257
  instance_var_v
@@ -1272,7 +1261,7 @@ class Parser::Lexer
1272
1261
  end
1273
1262
 
1274
1263
  emit(:tIVAR)
1275
- fnext *stack_pop; fbreak;
1264
+ fret; fbreak;
1276
1265
  };
1277
1266
  *|;
1278
1267
 
@@ -1388,10 +1377,10 @@ class Parser::Lexer
1388
1377
  w_space+ e_lparen
1389
1378
  => {
1390
1379
  if version?(18)
1391
- emit(:tLPAREN2, '(', @te - 1, @te)
1380
+ emit(:tLPAREN2, '('.freeze, @te - 1, @te)
1392
1381
  fnext expr_value; fbreak;
1393
1382
  else
1394
- emit(:tLPAREN_ARG, '(', @te - 1, @te)
1383
+ emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te)
1395
1384
  fnext expr_beg; fbreak;
1396
1385
  end
1397
1386
  };
@@ -1399,13 +1388,13 @@ class Parser::Lexer
1399
1388
  # meth(1 + 2)
1400
1389
  # Regular method call.
1401
1390
  e_lparen
1402
- => { emit(:tLPAREN2)
1391
+ => { emit(:tLPAREN2, '('.freeze)
1403
1392
  fnext expr_beg; fbreak; };
1404
1393
 
1405
1394
  # meth [...]
1406
1395
  # Array argument. Compare with indexing `meth[...]`.
1407
1396
  w_space+ e_lbrack
1408
- => { emit(:tLBRACK, '[', @te - 1, @te)
1397
+ => { emit(:tLBRACK, '['.freeze, @te - 1, @te)
1409
1398
  fnext expr_beg; fbreak; };
1410
1399
 
1411
1400
  # cmd {}
@@ -1416,7 +1405,7 @@ class Parser::Lexer
1416
1405
  p = @ts - 1
1417
1406
  fgoto expr_end;
1418
1407
  else
1419
- emit(:tLCURLY, '{', @te - 1, @te)
1408
+ emit(:tLCURLY, '{'.freeze, @te - 1, @te)
1420
1409
  fnext expr_value; fbreak;
1421
1410
  end
1422
1411
  };
@@ -1447,7 +1436,7 @@ class Parser::Lexer
1447
1436
  | '<<'
1448
1437
  )
1449
1438
  => {
1450
- if tok(tm, tm + 1) == '/'
1439
+ if tok(tm, tm + 1) == '/'.freeze
1451
1440
  # Ambiguous regexp literal.
1452
1441
  diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1)
1453
1442
  end
@@ -1524,7 +1513,7 @@ class Parser::Lexer
1524
1513
  expr_cmdarg := |*
1525
1514
  w_space+ e_lparen
1526
1515
  => {
1527
- emit(:tLPAREN_ARG, '(', @te - 1, @te)
1516
+ emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te)
1528
1517
  if version?(18)
1529
1518
  fnext expr_value; fbreak;
1530
1519
  else
@@ -1535,9 +1524,9 @@ class Parser::Lexer
1535
1524
  w_space* 'do'
1536
1525
  => {
1537
1526
  if @cond.active?
1538
- emit(:kDO_COND, 'do', @te - 2, @te)
1527
+ emit(:kDO_COND, 'do'.freeze, @te - 2, @te)
1539
1528
  else
1540
- emit(:kDO, 'do', @te - 2, @te)
1529
+ emit(:kDO, 'do'.freeze, @te - 2, @te)
1541
1530
  end
1542
1531
  fnext expr_value; fbreak;
1543
1532
  };
@@ -1569,7 +1558,7 @@ class Parser::Lexer
1569
1558
  # `do` (as `kDO_BLOCK` in `expr_beg`).
1570
1559
  expr_endarg := |*
1571
1560
  e_lbrace
1572
- => { emit(:tLBRACE_ARG)
1561
+ => { emit(:tLBRACE_ARG, '{'.freeze)
1573
1562
  fnext expr_value; };
1574
1563
 
1575
1564
  'do'
@@ -1622,15 +1611,15 @@ class Parser::Lexer
1622
1611
  [+\-][0-9]
1623
1612
  => {
1624
1613
  fhold;
1625
- if tok.start_with? '-'
1626
- emit(:tUMINUS_NUM, '-', @ts, @ts + 1)
1614
+ if tok.start_with? '-'.freeze
1615
+ emit(:tUMINUS_NUM, '-'.freeze, @ts, @ts + 1)
1627
1616
  fnext expr_end; fbreak;
1628
1617
  end
1629
1618
  };
1630
1619
 
1631
1620
  # splat *a
1632
1621
  '*'
1633
- => { emit(:tSTAR)
1622
+ => { emit(:tSTAR, '*'.freeze)
1634
1623
  fbreak; };
1635
1624
 
1636
1625
  #
@@ -1641,7 +1630,7 @@ class Parser::Lexer
1641
1630
  # /=/ (disambiguation with /=)
1642
1631
  '/' c_any
1643
1632
  => {
1644
- type = delimiter = @source[@ts].chr
1633
+ type = delimiter = tok[0].chr
1645
1634
  fhold; fgoto *push_literal(type, delimiter, @ts);
1646
1635
  };
1647
1636
 
@@ -1655,7 +1644,7 @@ class Parser::Lexer
1655
1644
  # %w(we are the people)
1656
1645
  '%' [A-Za-z]+ c_any
1657
1646
  => {
1658
- type, delimiter = @source[@ts...(@te - 1)], @source[@te - 1].chr
1647
+ type, delimiter = tok[0..-2], tok[-1].chr
1659
1648
  fgoto *push_literal(type, delimiter, @ts);
1660
1649
  };
1661
1650
 
@@ -1672,27 +1661,24 @@ class Parser::Lexer
1672
1661
  ( '"' ( c_line - '"' )* '"'
1673
1662
  | "'" ( c_line - "'" )* "'"
1674
1663
  | "`" ( c_line - "`" )* "`"
1675
- | bareword ) % { heredoc_e = p }
1664
+ | bareword ) % { heredoc_e = p }
1676
1665
  c_line* c_nl % { new_herebody_s = p }
1677
1666
  => {
1678
1667
  tok(@ts, heredoc_e) =~ /^<<(-?)(~?)(["'`]?)(.*)\3$/
1679
1668
 
1680
1669
  indent = !$1.empty? || !$2.empty?
1681
1670
  dedent_body = !$2.empty?
1682
- type = '<<' + ($3.empty? ? '"' : $3)
1671
+ type = $3.empty? ? '<<"'.freeze : ('<<'.freeze + $3)
1683
1672
  delimiter = $4
1684
1673
 
1685
1674
  if dedent_body && version?(18, 19, 20, 21, 22)
1686
- emit(:tLSHFT, '<<', @ts, @ts + 2)
1675
+ emit(:tLSHFT, '<<'.freeze, @ts, @ts + 2)
1687
1676
  p = @ts + 1
1688
1677
  fnext expr_beg; fbreak;
1689
1678
  else
1690
1679
  fnext *push_literal(type, delimiter, @ts, heredoc_e, indent, dedent_body);
1691
1680
 
1692
- if @herebody_s.nil?
1693
- @herebody_s = new_herebody_s
1694
- end
1695
-
1681
+ @herebody_s ||= new_herebody_s
1696
1682
  p = @herebody_s - 1
1697
1683
  end
1698
1684
  };
@@ -1704,7 +1690,7 @@ class Parser::Lexer
1704
1690
  # :"bar", :'baz'
1705
1691
  ':' ['"] # '
1706
1692
  => {
1707
- type, delimiter = tok, @source[@te - 1].chr
1693
+ type, delimiter = tok, tok[-1].chr
1708
1694
  fgoto *push_literal(type, delimiter, @ts);
1709
1695
  };
1710
1696
 
@@ -1774,21 +1760,21 @@ class Parser::Lexer
1774
1760
  => {
1775
1761
  if @lambda_stack.last == @paren_nest
1776
1762
  @lambda_stack.pop
1777
- emit(:tLAMBEG)
1763
+ emit(:tLAMBEG, '{'.freeze)
1778
1764
  else
1779
- emit(:tLBRACE)
1765
+ emit(:tLBRACE, '{'.freeze)
1780
1766
  end
1781
1767
  fbreak;
1782
1768
  };
1783
1769
 
1784
1770
  # a([1, 2])
1785
1771
  e_lbrack
1786
- => { emit(:tLBRACK)
1772
+ => { emit(:tLBRACK, '['.freeze)
1787
1773
  fbreak; };
1788
1774
 
1789
1775
  # a()
1790
1776
  e_lparen
1791
- => { emit(:tLPAREN)
1777
+ => { emit(:tLPAREN, '('.freeze)
1792
1778
  fbreak; };
1793
1779
 
1794
1780
  # a(+b)
@@ -1799,7 +1785,7 @@ class Parser::Lexer
1799
1785
  # rescue Exception => e: Block rescue.
1800
1786
  # Special because it should transition to expr_mid.
1801
1787
  'rescue' %{ tm = p } '=>'?
1802
- => { emit(:kRESCUE, tok(@ts, tm), @ts, tm)
1788
+ => { emit(:kRESCUE, 'rescue'.freeze, @ts, tm)
1803
1789
  p = tm - 1
1804
1790
  fnext expr_mid; fbreak; };
1805
1791
 
@@ -1929,7 +1915,7 @@ class Parser::Lexer
1929
1915
 
1930
1916
  '->'
1931
1917
  => {
1932
- emit(:tLAMBDA, tok(@ts, @ts + 2), @ts, @ts + 2)
1918
+ emit(:tLAMBDA, '->'.freeze, @ts, @ts + 2)
1933
1919
 
1934
1920
  @lambda_stack.push @paren_nest
1935
1921
  fnext expr_endfn; fbreak;
@@ -1940,14 +1926,14 @@ class Parser::Lexer
1940
1926
  if @lambda_stack.last == @paren_nest
1941
1927
  @lambda_stack.pop
1942
1928
 
1943
- if tok == '{'
1944
- emit(:tLAMBEG)
1929
+ if tok == '{'.freeze
1930
+ emit(:tLAMBEG, '{'.freeze)
1945
1931
  else # 'do'
1946
- emit(:kDO_LAMBDA)
1932
+ emit(:kDO_LAMBDA, 'do'.freeze)
1947
1933
  end
1948
1934
  else
1949
- if tok == '{'
1950
- emit(:tLCURLY)
1935
+ if tok == '{'.freeze
1936
+ emit(:tLCURLY, '{'.freeze)
1951
1937
  else # 'do'
1952
1938
  emit_do
1953
1939
  end
@@ -1965,8 +1951,8 @@ class Parser::Lexer
1965
1951
  fnext expr_fname; fbreak; };
1966
1952
 
1967
1953
  'class' w_any* '<<'
1968
- => { emit(:kCLASS, 'class', @ts, @ts + 5)
1969
- emit(:tLSHFT, '<<', @te - 2, @te)
1954
+ => { emit(:kCLASS, 'class'.freeze, @ts, @ts + 5)
1955
+ emit(:tLSHFT, '<<'.freeze, @te - 2, @te)
1970
1956
  fnext expr_value; fbreak; };
1971
1957
 
1972
1958
  # a if b:c: Syntax error.
@@ -1987,7 +1973,7 @@ class Parser::Lexer
1987
1973
  => {
1988
1974
  emit_table(KEYWORDS)
1989
1975
 
1990
- if version?(18) && tok == 'not'
1976
+ if version?(18) && tok == 'not'.freeze
1991
1977
  fnext expr_beg; fbreak;
1992
1978
  else
1993
1979
  fnext expr_arg; fbreak;
@@ -2003,7 +1989,7 @@ class Parser::Lexer
2003
1989
  fnext *arg_or_cmdarg;
2004
1990
  end
2005
1991
  else
2006
- emit(:k__ENCODING__)
1992
+ emit(:k__ENCODING__, '__ENCODING__'.freeze)
2007
1993
  end
2008
1994
  fbreak;
2009
1995
  };
@@ -2026,12 +2012,12 @@ class Parser::Lexer
2026
2012
  => {
2027
2013
  digits = tok(@num_digits_s, @num_suffix_s)
2028
2014
 
2029
- if digits.end_with? UNDERSCORE_STRING
2030
- diagnostic :error, :trailing_in_number, { :character => UNDERSCORE_STRING },
2015
+ if digits.end_with? '_'.freeze
2016
+ diagnostic :error, :trailing_in_number, { :character => '_'.freeze },
2031
2017
  range(@te - 1, @te)
2032
2018
  elsif digits.empty? && @num_base == 8 && version?(18)
2033
2019
  # 1.8 did not raise an error on 0o.
2034
- digits = "0"
2020
+ digits = '0'.freeze
2035
2021
  elsif digits.empty?
2036
2022
  diagnostic :error, :empty_numeric
2037
2023
  elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/))
@@ -2041,7 +2027,7 @@ class Parser::Lexer
2041
2027
  end
2042
2028
 
2043
2029
  if version?(18, 19, 20)
2044
- emit(:tINTEGER, digits.to_i(@num_base))
2030
+ emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s)
2045
2031
  p = @num_suffix_s - 1
2046
2032
  else
2047
2033
  @num_xfrm.call(digits.to_i(@num_base))
@@ -2061,7 +2047,7 @@ class Parser::Lexer
2061
2047
  :trailing_in_number, { :character => tok(@te - 1, @te) },
2062
2048
  range(@te - 1, @te)
2063
2049
  else
2064
- emit(:tINTEGER, tok(@ts, @te - 1).to_i)
2050
+ emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1)
2065
2051
  fhold; fbreak;
2066
2052
  end
2067
2053
  };
@@ -2073,7 +2059,7 @@ class Parser::Lexer
2073
2059
  :trailing_in_number, { :character => tok(@te - 1, @te) },
2074
2060
  range(@te - 1, @te)
2075
2061
  else
2076
- emit(:tFLOAT, tok(@ts, @te - 1).to_f)
2062
+ emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1)
2077
2063
  fhold; fbreak;
2078
2064
  end
2079
2065
  };
@@ -2086,7 +2072,7 @@ class Parser::Lexer
2086
2072
  digits = tok(@ts, @num_suffix_s)
2087
2073
 
2088
2074
  if version?(18, 19, 20)
2089
- emit(:tFLOAT, Float(digits))
2075
+ emit(:tFLOAT, Float(digits), @ts, @num_suffix_s)
2090
2076
  p = @num_suffix_s - 1
2091
2077
  else
2092
2078
  @num_xfrm.call(digits)
@@ -2101,7 +2087,7 @@ class Parser::Lexer
2101
2087
  # `echo foo`, "bar", 'baz'
2102
2088
  '`' | ['"] # '
2103
2089
  => {
2104
- type, delimiter = tok, @source[@te - 1].chr
2090
+ type, delimiter = tok, tok[-1].chr
2105
2091
  fgoto *push_literal(type, delimiter, @ts, nil, false, false, true);
2106
2092
  };
2107
2093
 
@@ -2174,11 +2160,11 @@ class Parser::Lexer
2174
2160
  fnext expr_beg; fbreak; };
2175
2161
 
2176
2162
  '?'
2177
- => { emit(:tEH)
2163
+ => { emit(:tEH, '?'.freeze)
2178
2164
  fnext expr_value; fbreak; };
2179
2165
 
2180
2166
  e_lbrack
2181
- => { emit(:tLBRACK2)
2167
+ => { emit(:tLBRACK2, '['.freeze)
2182
2168
  fnext expr_beg; fbreak; };
2183
2169
 
2184
2170
  punctuation_end
@@ -2195,7 +2181,7 @@ class Parser::Lexer
2195
2181
  => { fgoto leading_dot; };
2196
2182
 
2197
2183
  ';'
2198
- => { emit(:tSEMI)
2184
+ => { emit(:tSEMI, ';'.freeze)
2199
2185
  fnext expr_value; fbreak; };
2200
2186
 
2201
2187
  '\\' c_line {