parser 2.3.0.2 → 2.3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/doc/AST_FORMAT.md +1 -1
- data/lib/parser/lexer.rl +82 -96
- data/lib/parser/lexer/literal.rb +5 -5
- data/lib/parser/source/buffer.rb +39 -12
- data/lib/parser/source/comment/associator.rb +17 -11
- data/lib/parser/source/range.rb +22 -12
- data/lib/parser/source/rewriter.rb +214 -59
- data/lib/parser/version.rb +1 -1
- data/test/parse_helper.rb +36 -26
- data/test/test_lexer.rb +1181 -1147
- data/test/test_parser.rb +12 -0
- data/test/test_source_comment_associator.rb +17 -0
- data/test/test_source_range.rb +20 -0
- data/test/test_source_rewriter.rb +269 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32b8e79e47ae5063bd6a4451c47b337f43d5a2a2
|
4
|
+
data.tar.gz: c8d08375dca4b4089fa0dade5d77f13284498852
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 039b018cd53937074f6a0eb1b366c5d83c0de6ed104a3ca63597b265c695f010e2ae85fdee74bc9c00418510e386e9fc7e2ff44dd9dc9ead2ddef5cc3ef0ec1e
|
7
|
+
data.tar.gz: 4b8b8b3497d1034e4662aa8ad3cf85c57cd65cb73e038bf7737c63db832d719714aa2bafd2fef5dcdb85d2ee4342ef3c4c8ceb5d26f3abc5cfed67e4c6902aff
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
17
|
+
v2.3.0.3 (2016-01-16)
|
12
18
|
---------------------
|
13
19
|
|
14
20
|
v2.3.0.1 (2016-01-14)
|
data/doc/AST_FORMAT.md
CHANGED
data/lib/parser/lexer.rl
CHANGED
@@ -82,15 +82,12 @@ class Parser::Lexer
|
|
82
82
|
# %
|
83
83
|
|
84
84
|
ESCAPES = {
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
703
|
-
@escape = ESCAPES
|
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(
|
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+$/,
|
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.*$/,
|
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
|
-
|
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 =
|
1187
|
-
[?!]
|
1188
|
-
'
|
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 =
|
1192
|
-
ambiguous_fid_suffix
|
1193
|
-
'='
|
1194
|
-
'=='
|
1195
|
-
'=~'
|
1196
|
-
'=>'
|
1197
|
-
'==='
|
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 =
|
1189
|
+
ambiguous_symbol_suffix = # actual parsed
|
1201
1190
|
ambiguous_ident_suffix |
|
1202
|
-
'==>'
|
1191
|
+
'==>' %{ tm = p - 2 } # :a==>b :a= => b
|
1203
1192
|
;
|
1204
1193
|
|
1205
1194
|
# Ambiguous with 1.9 hash labels.
|
1206
|
-
ambiguous_const_suffix =
|
1207
|
-
'::'
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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 =
|
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
|
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 =
|
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
|
-
|
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,
|
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,
|
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,
|
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?
|
2030
|
-
diagnostic :error, :trailing_in_number, { :character =>
|
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 =
|
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,
|
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 {
|