ruby_parser 3.14.2 → 3.15.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +35 -0
- data/Manifest.txt +2 -0
- data/Rakefile +28 -9
- data/bin/ruby_parse_extract_error +8 -3
- data/compare/normalize.rb +43 -3
- data/debugging.md +39 -0
- data/lib/ruby20_parser.rb +2722 -2702
- data/lib/ruby20_parser.y +91 -58
- data/lib/ruby21_parser.rb +2603 -2576
- data/lib/ruby21_parser.y +91 -58
- data/lib/ruby22_parser.rb +2729 -2715
- data/lib/ruby22_parser.y +91 -58
- data/lib/ruby23_parser.rb +2698 -2686
- data/lib/ruby23_parser.y +91 -58
- data/lib/ruby24_parser.rb +2699 -2670
- data/lib/ruby24_parser.y +91 -58
- data/lib/ruby25_parser.rb +2699 -2670
- data/lib/ruby25_parser.y +91 -58
- data/lib/ruby26_parser.rb +2699 -2670
- data/lib/ruby26_parser.y +91 -58
- data/lib/ruby27_parser.rb +7224 -0
- data/lib/ruby27_parser.y +2657 -0
- data/lib/ruby_lexer.rb +72 -40
- data/lib/ruby_lexer.rex +5 -6
- data/lib/ruby_lexer.rex.rb +6 -8
- data/lib/ruby_parser.rb +2 -0
- data/lib/ruby_parser.yy +93 -58
- data/lib/ruby_parser_extras.rb +49 -16
- data/test/test_ruby_lexer.rb +32 -16
- data/test/test_ruby_parser.rb +204 -3
- data/tools/munge.rb +9 -4
- metadata +12 -7
- metadata.gz.sig +0 -0
data/lib/ruby_lexer.rb
CHANGED
@@ -25,12 +25,6 @@ class RubyLexer
|
|
25
25
|
|
26
26
|
HAS_ENC = "".respond_to? :encoding
|
27
27
|
|
28
|
-
IDENT_CHAR = if HAS_ENC then
|
29
|
-
/[\w\u0080-\u{10ffff}]/u
|
30
|
-
else
|
31
|
-
/[\w\x80-\xFF]/n
|
32
|
-
end
|
33
|
-
|
34
28
|
TOKENS = {
|
35
29
|
"!" => :tBANG,
|
36
30
|
"!=" => :tNEQ,
|
@@ -162,7 +156,7 @@ class RubyLexer
|
|
162
156
|
indent = func =~ STR_FUNC_INDENT ? "[ \t]*" : nil
|
163
157
|
expand = func =~ STR_FUNC_EXPAND
|
164
158
|
eol = last_line && last_line.end_with?("\r\n") ? "\r\n" : "\n"
|
165
|
-
eos_re = /#{indent}#{Regexp.escape eos}(
|
159
|
+
eos_re = /#{indent}#{Regexp.escape eos}(\r*\n|\z)/
|
166
160
|
err_msg = "can't match #{eos_re.inspect} anywhere in "
|
167
161
|
|
168
162
|
rb_compile_error err_msg if end_of_stream?
|
@@ -177,10 +171,15 @@ class RubyLexer
|
|
177
171
|
|
178
172
|
if expand then
|
179
173
|
case
|
180
|
-
when scan(/#[
|
181
|
-
|
174
|
+
when scan(/#(?=\$(-.|[a-zA-Z_0-9~\*\$\?!@\/\\;,\.=:<>\"\&\`\'+]))/) then
|
175
|
+
# TODO: !ISASCII
|
176
|
+
# ?! see parser_peek_variable_name
|
177
|
+
return :tSTRING_DVAR, matched
|
178
|
+
when scan(/#(?=\@\@?[a-zA-Z_])/) then
|
179
|
+
# TODO: !ISASCII
|
182
180
|
return :tSTRING_DVAR, matched
|
183
181
|
when scan(/#[{]/) then
|
182
|
+
self.command_start = true
|
184
183
|
return :tSTRING_DBEG, matched
|
185
184
|
when scan(/#/) then
|
186
185
|
string_buffer << "#"
|
@@ -320,6 +319,11 @@ class RubyLexer
|
|
320
319
|
lpar_beg && lpar_beg == paren_nest
|
321
320
|
end
|
322
321
|
|
322
|
+
def is_local_id id
|
323
|
+
# maybe just make this false for now
|
324
|
+
self.parser.env[id.to_sym] == :lvar # HACK: this isn't remotely right
|
325
|
+
end
|
326
|
+
|
323
327
|
def lvar_defined? id
|
324
328
|
# TODO: (dyna_in_block? && dvar_defined?(id)) || local_id?(id)
|
325
329
|
self.parser.env[id.to_sym] == :lvar
|
@@ -338,9 +342,9 @@ class RubyLexer
|
|
338
342
|
|
339
343
|
if scan(/[a-z0-9]{1,2}/i) then # Long-hand (e.g. %Q{}).
|
340
344
|
rb_compile_error "unknown type of %string" if ss.matched_size == 2
|
341
|
-
c, beg, short_hand = matched,
|
345
|
+
c, beg, short_hand = matched, getch, false
|
342
346
|
else # Short-hand (e.g. %{, %., %!, etc)
|
343
|
-
c, beg, short_hand = "Q",
|
347
|
+
c, beg, short_hand = "Q", getch, true
|
344
348
|
end
|
345
349
|
|
346
350
|
if end_of_stream? or c == RubyLexer::EOF or beg == RubyLexer::EOF then
|
@@ -457,7 +461,7 @@ class RubyLexer
|
|
457
461
|
if text =~ check then
|
458
462
|
content.gsub(ESC) { unescape $1 }
|
459
463
|
else
|
460
|
-
content.gsub(/\\\\/, "\\").gsub(
|
464
|
+
content.gsub(/\\\\/, "\\").gsub(/\\\'/, "'")
|
461
465
|
end
|
462
466
|
end
|
463
467
|
|
@@ -495,16 +499,19 @@ class RubyLexer
|
|
495
499
|
end
|
496
500
|
|
497
501
|
def process_brace_close text
|
498
|
-
# matching compare/parse23.y:8561
|
499
|
-
cond.lexpop
|
500
|
-
cmdarg.lexpop
|
501
|
-
|
502
502
|
case matched
|
503
503
|
when "}" then
|
504
504
|
self.brace_nest -= 1
|
505
|
-
self.lex_state = ruby24minus? ? EXPR_ENDARG : EXPR_END
|
506
|
-
|
507
505
|
return :tSTRING_DEND, matched if brace_nest < 0
|
506
|
+
end
|
507
|
+
|
508
|
+
# matching compare/parse26.y:8099
|
509
|
+
cond.pop
|
510
|
+
cmdarg.pop
|
511
|
+
|
512
|
+
case matched
|
513
|
+
when "}" then
|
514
|
+
self.lex_state = ruby24minus? ? EXPR_ENDARG : EXPR_END
|
508
515
|
return :tRCURLY, matched
|
509
516
|
when "]" then
|
510
517
|
self.paren_nest -= 1
|
@@ -605,7 +612,7 @@ class RubyLexer
|
|
605
612
|
end
|
606
613
|
|
607
614
|
def process_label text
|
608
|
-
symbol = possibly_escape_string text,
|
615
|
+
symbol = possibly_escape_string text, /^\"/
|
609
616
|
|
610
617
|
result EXPR_LAB, :tLABEL, [symbol, self.lineno]
|
611
618
|
end
|
@@ -619,7 +626,7 @@ class RubyLexer
|
|
619
626
|
text = text[0..-2]
|
620
627
|
end
|
621
628
|
|
622
|
-
result EXPR_END, :tSTRING, text[1..-2].gsub(/\\\\/, "\\").gsub(
|
629
|
+
result EXPR_END, :tSTRING, text[1..-2].gsub(/\\\\/, "\\").gsub(/\\\'/, "\'")
|
623
630
|
end
|
624
631
|
|
625
632
|
def process_lchevron text
|
@@ -791,12 +798,22 @@ class RubyLexer
|
|
791
798
|
c = if scan(/\\/) then
|
792
799
|
self.read_escape
|
793
800
|
else
|
794
|
-
|
801
|
+
getch
|
795
802
|
end
|
796
803
|
|
797
804
|
result EXPR_END, :tSTRING, c
|
798
805
|
end
|
799
806
|
|
807
|
+
def process_simple_string text
|
808
|
+
replacement = text[1..-2].gsub(ESC) {
|
809
|
+
unescape($1).b.force_encoding Encoding::UTF_8
|
810
|
+
}
|
811
|
+
|
812
|
+
replacement = replacement.b unless replacement.valid_encoding?
|
813
|
+
|
814
|
+
result EXPR_END, :tSTRING, replacement
|
815
|
+
end
|
816
|
+
|
800
817
|
def process_slash text
|
801
818
|
if is_beg? then
|
802
819
|
string STR_REGEXP
|
@@ -870,16 +887,16 @@ class RubyLexer
|
|
870
887
|
|
871
888
|
if [:tSTRING_END, :tREGEXP_END, :tLABEL_END].include? token_type then
|
872
889
|
self.lex_strterm = nil
|
873
|
-
self.lex_state = (token_type == :tLABEL_END) ? EXPR_PAR :
|
890
|
+
self.lex_state = (token_type == :tLABEL_END) ? EXPR_PAR : EXPR_LIT
|
874
891
|
end
|
875
892
|
|
876
893
|
return token
|
877
894
|
end
|
878
895
|
|
879
896
|
def process_symbol text
|
880
|
-
symbol = possibly_escape_string text,
|
897
|
+
symbol = possibly_escape_string text, /^:\"/ # stupid emacs
|
881
898
|
|
882
|
-
result
|
899
|
+
result EXPR_LIT, :tSYMBOL, symbol
|
883
900
|
end
|
884
901
|
|
885
902
|
def process_token text
|
@@ -928,6 +945,8 @@ class RubyLexer
|
|
928
945
|
EXPR_END
|
929
946
|
end
|
930
947
|
|
948
|
+
tok_id = :tIDENTIFIER if tok_id == :tCONSTANT && is_local_id(token)
|
949
|
+
|
931
950
|
if last_state !~ EXPR_DOT|EXPR_FNAME and
|
932
951
|
(tok_id == :tIDENTIFIER) and # not EXPR_FNAME, not attrasgn
|
933
952
|
lvar_defined?(token) then
|
@@ -951,18 +970,16 @@ class RubyLexer
|
|
951
970
|
self.command_start = true if lex_state =~ EXPR_BEG
|
952
971
|
|
953
972
|
case
|
954
|
-
when keyword.id0 == :kDO then
|
973
|
+
when keyword.id0 == :kDO then # parse26.y line 7591
|
955
974
|
case
|
956
975
|
when lambda_beginning? then
|
957
976
|
self.lpar_beg = nil # lambda_beginning? == FALSE in the body of "-> do ... end"
|
958
|
-
self.paren_nest -= 1
|
977
|
+
self.paren_nest -= 1 # TODO: question this?
|
959
978
|
result lex_state, :kDO_LAMBDA, value
|
960
979
|
when cond.is_in_state then
|
961
980
|
result lex_state, :kDO_COND, value
|
962
981
|
when cmdarg.is_in_state && state != EXPR_CMDARG then
|
963
982
|
result lex_state, :kDO_BLOCK, value
|
964
|
-
when state =~ EXPR_BEG|EXPR_ENDARG then
|
965
|
-
result lex_state, :kDO_BLOCK, value
|
966
983
|
else
|
967
984
|
result lex_state, :kDO, value
|
968
985
|
end
|
@@ -979,9 +996,9 @@ class RubyLexer
|
|
979
996
|
ss.unscan # put back "_"
|
980
997
|
|
981
998
|
if beginning_of_line? && scan(/\__END__(\r?\n|\Z)/) then
|
982
|
-
|
983
|
-
elsif scan(
|
984
|
-
|
999
|
+
[RubyLexer::EOF, RubyLexer::EOF]
|
1000
|
+
elsif scan(/#{IDENT_CHAR}+/) then
|
1001
|
+
process_token matched
|
985
1002
|
end
|
986
1003
|
end
|
987
1004
|
|
@@ -1018,7 +1035,7 @@ class RubyLexer
|
|
1018
1035
|
when scan(/x([0-9a-fA-F]{1,2})/) then # hex constant
|
1019
1036
|
# TODO: force encode everything to UTF-8?
|
1020
1037
|
ss[1].to_i(16).chr.force_encoding Encoding::UTF_8
|
1021
|
-
when check(/M
|
1038
|
+
when check(/M-\\./) then
|
1022
1039
|
scan(/M-\\/) # eat it
|
1023
1040
|
c = self.read_escape
|
1024
1041
|
c[0] = (c[0].ord | 0x80).chr
|
@@ -1032,6 +1049,11 @@ class RubyLexer
|
|
1032
1049
|
c = self.read_escape
|
1033
1050
|
c[0] = (c[0].ord & 0x9f).chr
|
1034
1051
|
c
|
1052
|
+
when check(/(C-|c)\\(?!u|\\)/) then
|
1053
|
+
scan(/(C-|c)\\/) # eat it
|
1054
|
+
c = read_escape
|
1055
|
+
c[0] = (c[0].ord & 0x9f).chr
|
1056
|
+
c
|
1035
1057
|
when scan(/C-\?|c\?/) then
|
1036
1058
|
127.chr
|
1037
1059
|
when scan(/(C-|c)(.)/) then
|
@@ -1040,17 +1062,25 @@ class RubyLexer
|
|
1040
1062
|
c
|
1041
1063
|
when scan(/^[89]/i) then # bad octal or hex... MRI ignores them :(
|
1042
1064
|
matched
|
1043
|
-
when scan(/u(
|
1044
|
-
[ss[1].
|
1045
|
-
when scan(/u(
|
1065
|
+
when scan(/u(\h{4})/) then
|
1066
|
+
[ss[1].to_i(16)].pack("U")
|
1067
|
+
when scan(/u(\h{1,3})/) then
|
1046
1068
|
rb_compile_error "Invalid escape character syntax"
|
1069
|
+
when scan(/u\{(\h+(?:\s+\h+)*)\}/) then
|
1070
|
+
ss[1].split.map { |s| s.to_i(16) }.pack("U*")
|
1047
1071
|
when scan(/[McCx0-9]/) || end_of_stream? then
|
1048
1072
|
rb_compile_error("Invalid escape character syntax")
|
1049
1073
|
else
|
1050
|
-
|
1074
|
+
getch
|
1051
1075
|
end.dup
|
1052
1076
|
end
|
1053
1077
|
|
1078
|
+
def getch
|
1079
|
+
c = ss.getch
|
1080
|
+
c = ss.getch if c == "\r" && ss.peek(1) == "\n"
|
1081
|
+
c
|
1082
|
+
end
|
1083
|
+
|
1054
1084
|
def regx_options # TODO: rewrite / remove
|
1055
1085
|
good, bad = [], []
|
1056
1086
|
|
@@ -1274,10 +1304,12 @@ class RubyLexer
|
|
1274
1304
|
s
|
1275
1305
|
when /^[McCx0-9]/ then
|
1276
1306
|
rb_compile_error("Invalid escape character syntax")
|
1277
|
-
when /u(
|
1307
|
+
when /u(\h{4})/ then
|
1278
1308
|
[$1.delete("{}").to_i(16)].pack("U")
|
1279
|
-
when /u(
|
1309
|
+
when /u(\h{1,3})/ then
|
1280
1310
|
rb_compile_error("Invalid escape character syntax")
|
1311
|
+
when /u\{(\h+(?:\s+\h+)*)\}/ then
|
1312
|
+
$1.split.map { |s| s.to_i(16) }.pack("U*")
|
1281
1313
|
else
|
1282
1314
|
s
|
1283
1315
|
end
|
@@ -1355,11 +1387,11 @@ class RubyLexer
|
|
1355
1387
|
# extra fake lex_state names to make things a bit cleaner
|
1356
1388
|
|
1357
1389
|
EXPR_LAB = EXPR_ARG|EXPR_LABELED
|
1358
|
-
|
1390
|
+
EXPR_LIT = EXPR_END|EXPR_ENDARG
|
1359
1391
|
EXPR_PAR = EXPR_BEG|EXPR_LABEL
|
1360
1392
|
EXPR_PAD = EXPR_BEG|EXPR_LABELED
|
1361
1393
|
|
1362
|
-
|
1394
|
+
EXPR_NUM = EXPR_LIT
|
1363
1395
|
|
1364
1396
|
expr_names.merge!(EXPR_NONE => "EXPR_NONE",
|
1365
1397
|
EXPR_BEG => "EXPR_BEG",
|
data/lib/ruby_lexer.rex
CHANGED
@@ -6,9 +6,9 @@ class RubyLexer
|
|
6
6
|
|
7
7
|
macro
|
8
8
|
|
9
|
-
|
9
|
+
IDENT_CHAR /[a-zA-Z0-9_[:^ascii:]]/
|
10
10
|
|
11
|
-
ESC /\\((?>[0-7]{1,3}|x
|
11
|
+
ESC /\\((?>[0-7]{1,3}|x\h{1,2}|M-[^\\]|(C-|c)[^\\]|u\h{1,4}|u\{\h+(?:\s+\h+)*\}|[^0-7xMCc]))/
|
12
12
|
SIMPLE_STRING /((#{ESC}|\#(#{ESC}|[^\{\#\@\$\"\\])|[^\"\\\#])*)/o
|
13
13
|
SSTRING /((\\.|[^\'])*)/
|
14
14
|
|
@@ -62,7 +62,7 @@ rule
|
|
62
62
|
| /\=(?=begin\b)/ { result arg_state, TOKENS[text], text }
|
63
63
|
|
64
64
|
ruby22_label? /\"#{SIMPLE_STRING}\":/o process_label
|
65
|
-
/\"(#{SIMPLE_STRING})\"/o
|
65
|
+
/\"(#{SIMPLE_STRING})\"/o process_simple_string
|
66
66
|
/\"/ { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
|
67
67
|
|
68
68
|
/\@\@?\d/ { rb_compile_error "`#{text}` is not allowed as a variable name" }
|
@@ -164,13 +164,12 @@ was_label? /\'#{SSTRING}\':?/o process_label_or_string
|
|
164
164
|
| in_fname? /\$([1-9]\d*)/ process_gvar
|
165
165
|
| /\$([1-9]\d*)/ process_nthref
|
166
166
|
| /\$0/ process_gvar
|
167
|
-
|
|
167
|
+
| /\$#{IDENT_CHAR}+/ process_gvar
|
168
168
|
| /\$\W|\$\z/ process_gvar_oddity
|
169
|
-
| /\$\w+/ process_gvar
|
170
169
|
|
171
170
|
/\_/ process_underscore
|
172
171
|
|
173
|
-
/#{
|
172
|
+
/#{IDENT_CHAR}+/o process_token
|
174
173
|
|
175
174
|
/\004|\032|\000|\Z/ { [RubyLexer::EOF, RubyLexer::EOF] }
|
176
175
|
|
data/lib/ruby_lexer.rex.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
#--
|
3
3
|
# This file is automatically generated. Do not modify it.
|
4
|
-
# Generated by: oedipus_lex version 2.5.
|
4
|
+
# Generated by: oedipus_lex version 2.5.2.
|
5
5
|
# Source: lib/ruby_lexer.rex
|
6
6
|
#++
|
7
7
|
|
@@ -16,8 +16,8 @@ class RubyLexer
|
|
16
16
|
require 'strscan'
|
17
17
|
|
18
18
|
# :stopdoc:
|
19
|
-
|
20
|
-
ESC = /\\((?>[0-7]{1,3}|x
|
19
|
+
IDENT_CHAR = /[a-zA-Z0-9_[:^ascii:]]/
|
20
|
+
ESC = /\\((?>[0-7]{1,3}|x\h{1,2}|M-[^\\]|(C-|c)[^\\]|u\h{1,4}|u\{\h+(?:\s+\h+)*\}|[^0-7xMCc]))/
|
21
21
|
SIMPLE_STRING = /((#{ESC}|\#(#{ESC}|[^\{\#\@\$\"\\])|[^\"\\\#])*)/o
|
22
22
|
SSTRING = /((\\.|[^\'])*)/
|
23
23
|
INT_DEC = /[+]?(?:(?:[1-9][\d_]*|0)(?!\.\d)(ri|r|i)?\b|0d[0-9_]+)(ri|r|i)?/i
|
@@ -160,7 +160,7 @@ class RubyLexer
|
|
160
160
|
when ruby22_label? && (text = ss.scan(/\"#{SIMPLE_STRING}\":/o)) then
|
161
161
|
process_label text
|
162
162
|
when text = ss.scan(/\"(#{SIMPLE_STRING})\"/o) then
|
163
|
-
|
163
|
+
process_simple_string text
|
164
164
|
when text = ss.scan(/\"/) then
|
165
165
|
action { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
|
166
166
|
when text = ss.scan(/\@\@?\d/) then
|
@@ -328,16 +328,14 @@ class RubyLexer
|
|
328
328
|
process_nthref text
|
329
329
|
when text = ss.scan(/\$0/) then
|
330
330
|
process_gvar text
|
331
|
-
when text = ss.scan(
|
331
|
+
when text = ss.scan(/\$#{IDENT_CHAR}+/) then
|
332
332
|
process_gvar text
|
333
333
|
when text = ss.scan(/\$\W|\$\z/) then
|
334
334
|
process_gvar_oddity text
|
335
|
-
when text = ss.scan(/\$\w+/) then
|
336
|
-
process_gvar text
|
337
335
|
end # group /\$/
|
338
336
|
when text = ss.scan(/\_/) then
|
339
337
|
process_underscore text
|
340
|
-
when text = ss.scan(/#{
|
338
|
+
when text = ss.scan(/#{IDENT_CHAR}+/o) then
|
341
339
|
process_token text
|
342
340
|
when ss.skip(/\004|\032|\000|\Z/) then
|
343
341
|
action { [RubyLexer::EOF, RubyLexer::EOF] }
|
data/lib/ruby_parser.rb
CHANGED
@@ -78,10 +78,12 @@ require "ruby23_parser"
|
|
78
78
|
require "ruby24_parser"
|
79
79
|
require "ruby25_parser"
|
80
80
|
require "ruby26_parser"
|
81
|
+
require "ruby27_parser"
|
81
82
|
|
82
83
|
class RubyParser # HACK
|
83
84
|
VERSIONS.clear # also a HACK caused by racc namespace issues
|
84
85
|
|
86
|
+
class V27 < ::Ruby27Parser; end
|
85
87
|
class V26 < ::Ruby26Parser; end
|
86
88
|
class V25 < ::Ruby25Parser; end
|
87
89
|
class V24 < ::Ruby24Parser; end
|
data/lib/ruby_parser.yy
CHANGED
@@ -14,6 +14,8 @@ class Ruby24Parser
|
|
14
14
|
class Ruby25Parser
|
15
15
|
#elif V == 26
|
16
16
|
class Ruby26Parser
|
17
|
+
#elif V == 27
|
18
|
+
class Ruby27Parser
|
17
19
|
#else
|
18
20
|
fail "version not specified or supported on code generation"
|
19
21
|
#endif
|
@@ -286,13 +288,15 @@ rule
|
|
286
288
|
}
|
287
289
|
| primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
|
288
290
|
{
|
289
|
-
|
290
|
-
|
291
|
+
lhs1, _, lhs2, op, rhs = val
|
292
|
+
|
293
|
+
result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
|
291
294
|
}
|
292
295
|
| primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
|
293
296
|
{
|
294
|
-
|
295
|
-
|
297
|
+
lhs1, _, lhs2, op, rhs = val
|
298
|
+
|
299
|
+
result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
|
296
300
|
}
|
297
301
|
| backref tOP_ASGN command_rhs
|
298
302
|
{
|
@@ -1078,12 +1082,39 @@ rule
|
|
1078
1082
|
}
|
1079
1083
|
|
1080
1084
|
command_args: {
|
1081
|
-
|
1085
|
+
# parse26.y line 2200
|
1086
|
+
|
1087
|
+
# If call_args starts with a open paren '(' or
|
1088
|
+
# '[', look-ahead reading of the letters calls
|
1089
|
+
# CMDARG_PUSH(0), but the push must be done
|
1090
|
+
# after CMDARG_PUSH(1). So this code makes them
|
1091
|
+
# consistent by first cancelling the premature
|
1092
|
+
# CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
|
1093
|
+
# finally redoing CMDARG_PUSH(0).
|
1094
|
+
|
1095
|
+
result = yychar = self.last_token_type.first
|
1096
|
+
lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
|
1097
|
+
lexer.cmdarg.pop if lookahead
|
1098
|
+
lexer.cmdarg.push true
|
1099
|
+
lexer.cmdarg.push false if lookahead
|
1082
1100
|
}
|
1083
1101
|
call_args
|
1084
1102
|
{
|
1085
|
-
|
1086
|
-
|
1103
|
+
yychar, args = val
|
1104
|
+
|
1105
|
+
# call_args can be followed by tLBRACE_ARG (that
|
1106
|
+
# does CMDARG_PUSH(0) in the lexer) but the push
|
1107
|
+
# must be done after CMDARG_POP() in the parser.
|
1108
|
+
# So this code does CMDARG_POP() to pop 0 pushed
|
1109
|
+
# by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
|
1110
|
+
# by command_args, and CMDARG_PUSH(0) to restore
|
1111
|
+
# back the flag set by tLBRACE_ARG.
|
1112
|
+
|
1113
|
+
lookahead = [:tLBRACE_ARG].include?(yychar)
|
1114
|
+
lexer.cmdarg.pop if lookahead
|
1115
|
+
lexer.cmdarg.pop
|
1116
|
+
lexer.cmdarg.push false if lookahead
|
1117
|
+
result = args
|
1087
1118
|
}
|
1088
1119
|
|
1089
1120
|
block_arg: tAMPER arg_value
|
@@ -1101,8 +1132,9 @@ rule
|
|
1101
1132
|
args: arg_value
|
1102
1133
|
{
|
1103
1134
|
arg, = val
|
1135
|
+
lineno = arg.line || lexer.lineno # HACK
|
1104
1136
|
|
1105
|
-
result = s(:array, arg).line
|
1137
|
+
result = s(:array, arg).line lineno
|
1106
1138
|
}
|
1107
1139
|
| tSTAR arg_value
|
1108
1140
|
{
|
@@ -1114,9 +1146,11 @@ rule
|
|
1114
1146
|
args, _, id = val
|
1115
1147
|
result = self.list_append args, id
|
1116
1148
|
}
|
1117
|
-
| args tCOMMA tSTAR
|
1149
|
+
| args tCOMMA tSTAR arg_value
|
1118
1150
|
{
|
1119
|
-
|
1151
|
+
# TODO: the line number from tSTAR has been dropped
|
1152
|
+
args, _, _, id = val
|
1153
|
+
line = lexer.lineno
|
1120
1154
|
result = self.list_append args, s(:splat, id).line(line)
|
1121
1155
|
}
|
1122
1156
|
|
@@ -1137,7 +1171,6 @@ rule
|
|
1137
1171
|
}
|
1138
1172
|
| args tCOMMA tSTAR arg_value
|
1139
1173
|
{
|
1140
|
-
# FIX: bad shift/reduce conflict with rhs' comma star prod
|
1141
1174
|
# TODO: make all tXXXX terminals include lexer.lineno
|
1142
1175
|
arg, _, _, splat = val
|
1143
1176
|
result = self.arg_concat arg, splat
|
@@ -1165,21 +1198,13 @@ rule
|
|
1165
1198
|
}
|
1166
1199
|
| k_begin
|
1167
1200
|
{
|
1201
|
+
lexer.cmdarg.push false
|
1168
1202
|
result = self.lexer.lineno
|
1169
|
-
# TODO:
|
1170
|
-
# $<val>1 = cmdarg_stack;
|
1171
|
-
# CMDARG_SET(0);
|
1172
1203
|
}
|
1173
1204
|
bodystmt k_end
|
1174
1205
|
{
|
1175
|
-
|
1176
|
-
|
1177
|
-
result = s(:nil)
|
1178
|
-
else
|
1179
|
-
result = s(:begin, val[2])
|
1180
|
-
end
|
1181
|
-
|
1182
|
-
result.line = val[1]
|
1206
|
+
lexer.cmdarg.pop
|
1207
|
+
result = new_begin val
|
1183
1208
|
}
|
1184
1209
|
| tLPAREN_ARG
|
1185
1210
|
{
|
@@ -1192,18 +1217,14 @@ rule
|
|
1192
1217
|
result = s(:begin).line line
|
1193
1218
|
}
|
1194
1219
|
| tLPAREN_ARG
|
1195
|
-
{
|
1196
|
-
result = lexer.cmdarg.store false
|
1197
|
-
}
|
1198
1220
|
stmt
|
1199
1221
|
{
|
1200
1222
|
lexer.lex_state = EXPR_ENDARG
|
1201
1223
|
}
|
1202
1224
|
rparen
|
1203
1225
|
{
|
1204
|
-
_,
|
1205
|
-
warning "(...) interpreted as grouped expression"
|
1206
|
-
lexer.cmdarg.restore cmdarg
|
1226
|
+
_, stmt, _, _, = val
|
1227
|
+
# warning "(...) interpreted as grouped expression"
|
1207
1228
|
result = stmt
|
1208
1229
|
}
|
1209
1230
|
| tLPAREN compstmt tRPAREN
|
@@ -1386,48 +1407,61 @@ rule
|
|
1386
1407
|
}
|
1387
1408
|
| k_def fname
|
1388
1409
|
{
|
1389
|
-
result =
|
1410
|
+
result = self.in_def
|
1390
1411
|
|
1391
|
-
self.
|
1392
|
-
self.in_def = true
|
1412
|
+
self.in_def = true # group = local_push
|
1393
1413
|
self.env.extend
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1414
|
+
lexer.cmdarg.push false
|
1415
|
+
lexer.cond.push false
|
1416
|
+
|
1417
|
+
self.comments.push self.lexer.comments
|
1397
1418
|
}
|
1398
1419
|
f_arglist bodystmt { result = lexer.lineno } k_end
|
1399
1420
|
{
|
1400
|
-
in_def
|
1421
|
+
in_def = val[2]
|
1401
1422
|
|
1402
1423
|
result = new_defn val
|
1403
1424
|
|
1404
|
-
lexer.
|
1425
|
+
lexer.cond.pop # group = local_pop
|
1426
|
+
lexer.cmdarg.pop
|
1405
1427
|
self.env.unextend
|
1406
1428
|
self.in_def = in_def
|
1429
|
+
|
1407
1430
|
self.lexer.comments # we don't care about comments in the body
|
1408
1431
|
}
|
1409
1432
|
| k_def singleton dot_or_colon
|
1410
1433
|
{
|
1411
|
-
self.comments.push self.lexer.comments
|
1412
1434
|
lexer.lex_state = EXPR_FNAME
|
1413
1435
|
}
|
1414
1436
|
fname
|
1415
1437
|
{
|
1416
|
-
self.
|
1438
|
+
result = [self.in_def, lexer.lineno]
|
1439
|
+
|
1440
|
+
self.in_single += 1 # TODO: remove?
|
1441
|
+
|
1442
|
+
self.in_def = true # local_push
|
1417
1443
|
self.env.extend
|
1418
|
-
lexer.
|
1419
|
-
|
1420
|
-
|
1444
|
+
lexer.cmdarg.push false
|
1445
|
+
lexer.cond.push false
|
1446
|
+
|
1447
|
+
lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
|
1448
|
+
self.comments.push self.lexer.comments
|
1421
1449
|
}
|
1422
1450
|
f_arglist bodystmt k_end
|
1423
1451
|
{
|
1424
|
-
_,
|
1425
|
-
result = new_defs val
|
1452
|
+
_, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
|
1426
1453
|
|
1427
|
-
|
1454
|
+
result = new_defs val
|
1428
1455
|
|
1456
|
+
lexer.cond.pop # group = local_pop
|
1457
|
+
lexer.cmdarg.pop
|
1429
1458
|
self.env.unextend
|
1459
|
+
self.in_def = in_def
|
1460
|
+
|
1430
1461
|
self.in_single -= 1
|
1462
|
+
|
1463
|
+
# TODO: restore cur_arg ? what's cur_arg?
|
1464
|
+
|
1431
1465
|
self.lexer.comments # we don't care about comments in the body
|
1432
1466
|
}
|
1433
1467
|
| kBREAK
|
@@ -1712,20 +1746,19 @@ opt_block_args_tail: tCOMMA block_args_tail
|
|
1712
1746
|
}
|
1713
1747
|
f_larglist
|
1714
1748
|
{
|
1715
|
-
|
1749
|
+
lexer.cmdarg.push false
|
1716
1750
|
}
|
1717
1751
|
lambda_body
|
1718
1752
|
{
|
1719
|
-
(line, lpar), args,
|
1753
|
+
(line, lpar), args, _cmdarg, body = val
|
1720
1754
|
lexer.lpar_beg = lpar
|
1721
1755
|
|
1722
|
-
lexer.cmdarg.
|
1723
|
-
lexer.cmdarg.lexpop
|
1756
|
+
lexer.cmdarg.pop
|
1724
1757
|
|
1725
1758
|
call = s(:lambda).line line
|
1726
1759
|
result = new_iter call, args, body
|
1727
1760
|
result.line = line
|
1728
|
-
self.env.unextend
|
1761
|
+
self.env.unextend # TODO: dynapush & dynapop
|
1729
1762
|
}
|
1730
1763
|
|
1731
1764
|
f_larglist: tLPAREN2 f_args opt_bv_decl rparen
|
@@ -1878,7 +1911,7 @@ opt_block_args_tail: tCOMMA block_args_tail
|
|
1878
1911
|
}
|
1879
1912
|
|
1880
1913
|
do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
|
1881
|
-
{
|
1914
|
+
{ lexer.cmdarg.push false }
|
1882
1915
|
opt_block_param
|
1883
1916
|
#if V >= 25
|
1884
1917
|
bodystmt
|
@@ -1886,11 +1919,11 @@ opt_block_args_tail: tCOMMA block_args_tail
|
|
1886
1919
|
compstmt
|
1887
1920
|
#endif
|
1888
1921
|
{
|
1889
|
-
line,
|
1922
|
+
line, _cmdarg, param, cmpstmt = val
|
1890
1923
|
|
1891
1924
|
result = new_do_body param, cmpstmt, line
|
1925
|
+
lexer.cmdarg.pop
|
1892
1926
|
self.env.unextend
|
1893
|
-
lexer.cmdarg.restore cmdarg
|
1894
1927
|
}
|
1895
1928
|
|
1896
1929
|
case_body: k_when
|
@@ -1990,7 +2023,7 @@ opt_block_args_tail: tCOMMA block_args_tail
|
|
1990
2023
|
|
1991
2024
|
xstring: tXSTRING_BEG xstring_contents tSTRING_END
|
1992
2025
|
{
|
1993
|
-
result = new_xstring val
|
2026
|
+
result = new_xstring val
|
1994
2027
|
# TODO: dedent?!?! SERIOUSLY?!?
|
1995
2028
|
}
|
1996
2029
|
|
@@ -2132,12 +2165,13 @@ regexp_contents: none
|
|
2132
2165
|
result = [lexer.lex_strterm,
|
2133
2166
|
lexer.brace_nest,
|
2134
2167
|
lexer.string_nest, # TODO: remove
|
2135
|
-
lexer.cond.store,
|
2136
|
-
lexer.cmdarg.store,
|
2137
2168
|
lexer.lex_state,
|
2138
2169
|
lexer.lineno,
|
2139
2170
|
]
|
2140
2171
|
|
2172
|
+
lexer.cmdarg.push false
|
2173
|
+
lexer.cond.push false
|
2174
|
+
|
2141
2175
|
lexer.lex_strterm = nil
|
2142
2176
|
lexer.brace_nest = 0
|
2143
2177
|
lexer.string_nest = 0
|
@@ -2149,14 +2183,15 @@ regexp_contents: none
|
|
2149
2183
|
{
|
2150
2184
|
_, memo, stmt, _ = val
|
2151
2185
|
|
2152
|
-
lex_strterm, brace_nest, string_nest,
|
2186
|
+
lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
|
2187
|
+
# TODO: heredoc_indent
|
2153
2188
|
|
2154
2189
|
lexer.lex_strterm = lex_strterm
|
2155
2190
|
lexer.brace_nest = brace_nest
|
2156
2191
|
lexer.string_nest = string_nest
|
2157
2192
|
|
2158
|
-
lexer.
|
2159
|
-
lexer.
|
2193
|
+
lexer.cmdarg.pop
|
2194
|
+
lexer.cond.pop
|
2160
2195
|
|
2161
2196
|
lexer.lex_state = oldlex_state
|
2162
2197
|
|