parser 2.6.3.0 → 2.6.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -10
- data/CHANGELOG.md +24 -2
- data/doc/AST_FORMAT.md +45 -3
- data/lib/parser.rb +1 -0
- data/lib/parser/ast/processor.rb +24 -1
- data/lib/parser/builders/default.rb +64 -12
- data/lib/parser/context.rb +8 -0
- data/lib/parser/current.rb +3 -3
- data/lib/parser/lexer.rl +84 -3
- data/lib/parser/lexer/max_numparam_stack.rb +42 -0
- data/lib/parser/messages.rb +26 -20
- data/lib/parser/meta.rb +1 -0
- data/lib/parser/ruby25.y +1 -1
- data/lib/parser/ruby27.y +65 -31
- data/lib/parser/runner/ruby_parse.rb +2 -2
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +1 -1
- data/test/test_lexer.rb +75 -0
- data/test/test_parser.rb +382 -3
- data/test/test_runner_parse.rb +35 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e113f6f42c44591674f288ebda60f8c4f17f5b6aee601d1cc5c2e20c50ef2e6
|
4
|
+
data.tar.gz: '08cf94385ef5cd8f211de395e1c272e5b7950e155463160e327cda2eb047dfad'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25fd7715c94cf32eb097e8c0049d48f7b8185bef6ea4dafe21f0f7013c13892ff6d929e2e45f18480903f081ed9738aa8f0059287dd528cdb63feb94a47fd42e
|
7
|
+
data.tar.gz: 8dfe6966704a8b5b662f99a2ee15d525f6d4cd3d74b62b0c3946f01933c86f50075572cf32a81de3bfe2fe96a07d8197a55a11906f870b80daa2d81e50987944
|
data/.travis.yml
CHANGED
@@ -11,14 +11,14 @@ matrix:
|
|
11
11
|
- name: 2.3.8 / Parser tests
|
12
12
|
rvm: 2.3.8
|
13
13
|
script: bundle exec rake test_cov
|
14
|
-
- name: 2.4.
|
15
|
-
rvm: 2.4.
|
14
|
+
- name: 2.4.7 / Parser tests
|
15
|
+
rvm: 2.4.7
|
16
16
|
script: bundle exec rake test_cov
|
17
|
-
- name: 2.5.
|
18
|
-
rvm: 2.5.
|
17
|
+
- name: 2.5.6 / Parser tests
|
18
|
+
rvm: 2.5.6
|
19
19
|
script: bundle exec rake test_cov
|
20
|
-
- name: 2.6.
|
21
|
-
rvm: 2.6.
|
20
|
+
- name: 2.6.4 / Parser tests
|
21
|
+
rvm: 2.6.4
|
22
22
|
script: bundle exec rake test_cov
|
23
23
|
- name: ruby-head / Parser tests
|
24
24
|
rvm: ruby-head
|
@@ -29,11 +29,11 @@ matrix:
|
|
29
29
|
- name: rbx-2 / Parser tests
|
30
30
|
rvm: rbx-2
|
31
31
|
script: bundle exec rake test_cov
|
32
|
-
- name: 2.5.
|
33
|
-
rvm: 2.5.
|
32
|
+
- name: 2.5.6 / Rubocop tests
|
33
|
+
rvm: 2.5.6
|
34
34
|
script: ./ci/run_rubocop_specs
|
35
|
-
- name: 2.6.
|
36
|
-
rvm: 2.6.
|
35
|
+
- name: 2.6.4 / Rubocop tests
|
36
|
+
rvm: 2.6.4
|
37
37
|
script: ./ci/run_rubocop_specs
|
38
38
|
allow_failures:
|
39
39
|
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,30 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
v2.6.4.0 (2019-08-30)
|
5
|
+
---------------------
|
6
|
+
|
7
|
+
API modifications:
|
8
|
+
* Added specs for heredocs with mixed encoding. (#581) (Ilya Bylich)
|
9
|
+
|
10
|
+
Features implemented:
|
11
|
+
* ruby27.y: Revert "pipeline operator" (#601) (Koichi ITO)
|
12
|
+
* ruby27.y: Fix parsing of mutiple assignment with rescue modifier (#600) (Koichi ITO)
|
13
|
+
* ruby27.y: hoisted out f_rest_marg. (#594) (Ilya Bylich)
|
14
|
+
* ruby27.y: added pipeline operator. (#592) (Ilya Bylich)
|
15
|
+
* ruby27.y: reject safe navigator in LHS of mass-assignment. (#586) (Ilya Bylich)
|
16
|
+
* lexer.rl: reject whitespaces in meta and control chars. (#585) (Ilya Bylich)
|
17
|
+
* lexer.rl: Reject numparams as symbol literals. (#582) (Ilya Bylich)
|
18
|
+
* ruby27.y: Added numbered parameters support. (#565) (Ilya Bylich)
|
19
|
+
* lexer.rl: Reject \n and \r in heredoc identifiers starting from 2.7. (#575) (Ilya Bylich)
|
20
|
+
|
21
|
+
Bugs fixed:
|
22
|
+
* ruby-parse: print empty string when --emit-json and empty input are given. (#590) (Ilya Bylich)
|
23
|
+
* AST_FORMAT: fixed documentation of the string with interpolation. (#589) (Ilya Bylich)
|
24
|
+
* builder.rb, processor.rb: Changed format of the procarg0 node. (#587) (Ilya Bylich)
|
25
|
+
|
26
|
+
v2.6.3.0 (2019-04-28)
|
27
|
+
---------------------
|
6
28
|
|
7
29
|
Features implemented:
|
8
30
|
* ruby27.y: Added beginless ranges support. (#570) (Ilya Bylich)
|
data/doc/AST_FORMAT.md
CHANGED
@@ -102,10 +102,13 @@ Format:
|
|
102
102
|
Format:
|
103
103
|
|
104
104
|
~~~
|
105
|
-
(dstr (str "foo") (lvar bar) (str "baz"))
|
105
|
+
(dstr (str "foo") (begin (lvar bar)) (str "baz"))
|
106
106
|
'"foo#{bar}baz"'
|
107
107
|
^ begin ^ end
|
108
108
|
~~~~~~~~~~~~~~ expression
|
109
|
+
^^ begin (begin)
|
110
|
+
^ end (begin)
|
111
|
+
^^^^^^ expression (begin)
|
109
112
|
~~~
|
110
113
|
|
111
114
|
#### Here document
|
@@ -933,10 +936,15 @@ the sole argument (e.g. `|foo,|`).
|
|
933
936
|
Format:
|
934
937
|
|
935
938
|
~~~
|
936
|
-
(procarg0 :foo)
|
939
|
+
(procarg0 (arg :foo))
|
937
940
|
"|foo|"
|
938
941
|
~~~ expression
|
939
|
-
|
942
|
+
|
943
|
+
(procarg0 (arg :foo) (arg :bar))
|
944
|
+
"|(foo, bar)|"
|
945
|
+
~ begin
|
946
|
+
~ end
|
947
|
+
~~~~~~~~~~ expression
|
940
948
|
~~~
|
941
949
|
|
942
950
|
### Expression arguments
|
@@ -1083,6 +1091,40 @@ However, the following code results in a parse error:
|
|
1083
1091
|
def f(*a: b); end
|
1084
1092
|
~~~
|
1085
1093
|
|
1094
|
+
## Numbered parameters
|
1095
|
+
|
1096
|
+
### Block with numbered parameters
|
1097
|
+
|
1098
|
+
Ruby 2.7 introduced a feature called "numbered parameters".
|
1099
|
+
Numbered and ordinal parameters are mutually exclusive, so if the block
|
1100
|
+
has only numbered parameters it also has a different AST node.
|
1101
|
+
|
1102
|
+
Note that the second child represents a total number of numbered parameters.
|
1103
|
+
|
1104
|
+
Format:
|
1105
|
+
|
1106
|
+
~~~
|
1107
|
+
s(:numblock,
|
1108
|
+
s(:send, nil, :proc), 3,
|
1109
|
+
s(:send,
|
1110
|
+
s(:numparam, 1), :+,
|
1111
|
+
s(:numparam, 3)))
|
1112
|
+
"proc { @1 + @3 }"
|
1113
|
+
~ begin ~ end
|
1114
|
+
~~~~~~~~~~~~~~~~ expression
|
1115
|
+
~~~
|
1116
|
+
|
1117
|
+
### Numbered parameter
|
1118
|
+
|
1119
|
+
Format:
|
1120
|
+
|
1121
|
+
~~~
|
1122
|
+
(numparam 10)
|
1123
|
+
"@10"
|
1124
|
+
~~~ name
|
1125
|
+
~~~ expression
|
1126
|
+
~~~
|
1127
|
+
|
1086
1128
|
## Send
|
1087
1129
|
|
1088
1130
|
### To self
|
data/lib/parser.rb
CHANGED
data/lib/parser/ast/processor.rb
CHANGED
@@ -124,7 +124,22 @@ module Parser
|
|
124
124
|
alias on_kwarg process_argument_node
|
125
125
|
alias on_kwoptarg process_argument_node
|
126
126
|
alias on_kwrestarg process_argument_node
|
127
|
-
|
127
|
+
|
128
|
+
def on_procarg0(node)
|
129
|
+
if node.children[0].is_a?(Symbol)
|
130
|
+
# This branch gets executed when the builder
|
131
|
+
# is not configured to emit and 'arg' inside 'procarg0', i.e. when
|
132
|
+
# Parser::Builders::Default.emit_arg_inside_procarg0
|
133
|
+
# is set to false.
|
134
|
+
#
|
135
|
+
# If this flag is set to true this branch is unreachable.
|
136
|
+
# s(:procarg0, :a)
|
137
|
+
on_argument(node)
|
138
|
+
else
|
139
|
+
# s(:procarg0, s(:arg, :a), s(:arg, :b))
|
140
|
+
process_regular_node(node)
|
141
|
+
end
|
142
|
+
end
|
128
143
|
|
129
144
|
alias on_arg_expr process_regular_node
|
130
145
|
alias on_restarg_expr process_regular_node
|
@@ -173,6 +188,14 @@ module Parser
|
|
173
188
|
alias on_block process_regular_node
|
174
189
|
alias on_lambda process_regular_node
|
175
190
|
|
191
|
+
def on_numblock(node)
|
192
|
+
method_call, max_numparam, body = *node
|
193
|
+
|
194
|
+
node.updated(nil, [
|
195
|
+
process(method_call), max_numparam, process(body)
|
196
|
+
])
|
197
|
+
end
|
198
|
+
|
176
199
|
alias on_while process_regular_node
|
177
200
|
alias on_while_post process_regular_node
|
178
201
|
alias on_until process_regular_node
|
@@ -80,6 +80,21 @@ module Parser
|
|
80
80
|
attr_accessor :emit_index
|
81
81
|
end
|
82
82
|
|
83
|
+
class << self
|
84
|
+
##
|
85
|
+
# AST compatibility attribute; causes a single non-mlhs
|
86
|
+
# block argument to be wrapped in s(:procarg0).
|
87
|
+
#
|
88
|
+
# If set to false (the default), block arguments `|a|` are emitted as
|
89
|
+
# `s(:args, s(:procarg0, :a))`
|
90
|
+
#
|
91
|
+
# If set to true, block arguments `|a|` are emitted as
|
92
|
+
# `s(:args, s(:procarg0, s(:arg, :a))`
|
93
|
+
#
|
94
|
+
# @return [Boolean]
|
95
|
+
attr_accessor :emit_arg_inside_procarg0
|
96
|
+
end
|
97
|
+
|
83
98
|
@emit_index = false
|
84
99
|
|
85
100
|
class << self
|
@@ -90,6 +105,7 @@ module Parser
|
|
90
105
|
@emit_procarg0 = true
|
91
106
|
@emit_encoding = true
|
92
107
|
@emit_index = true
|
108
|
+
@emit_arg_inside_procarg0 = true
|
93
109
|
end
|
94
110
|
end
|
95
111
|
|
@@ -437,6 +453,11 @@ module Parser
|
|
437
453
|
variable_map(token))
|
438
454
|
end
|
439
455
|
|
456
|
+
def numparam(token)
|
457
|
+
n(:numparam, [ value(token).to_i ],
|
458
|
+
variable_map(token))
|
459
|
+
end
|
460
|
+
|
440
461
|
def back_ref(token)
|
441
462
|
n(:back_ref, [ value(token).to_sym ],
|
442
463
|
token_map(token))
|
@@ -663,6 +684,10 @@ module Parser
|
|
663
684
|
collection_map(begin_t, args, end_t))
|
664
685
|
end
|
665
686
|
|
687
|
+
def numargs(max_numparam)
|
688
|
+
n(:numargs, [ max_numparam ], nil)
|
689
|
+
end
|
690
|
+
|
666
691
|
def arg(name_t)
|
667
692
|
n(:arg, [ value(name_t).to_sym ],
|
668
693
|
variable_map(name_t))
|
@@ -717,7 +742,12 @@ module Parser
|
|
717
742
|
|
718
743
|
def procarg0(arg)
|
719
744
|
if self.class.emit_procarg0
|
720
|
-
arg.
|
745
|
+
if arg.type == :arg && self.class.emit_arg_inside_procarg0
|
746
|
+
n(:procarg0, [ arg ],
|
747
|
+
Source::Map::Collection.new(nil, nil, arg.location.expression))
|
748
|
+
else
|
749
|
+
arg.updated(:procarg0)
|
750
|
+
end
|
721
751
|
else
|
722
752
|
arg
|
723
753
|
end
|
@@ -835,15 +865,23 @@ module Parser
|
|
835
865
|
diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
|
836
866
|
end
|
837
867
|
|
868
|
+
|
869
|
+
if args.type == :numargs
|
870
|
+
block_type = :numblock
|
871
|
+
args = args.children[0]
|
872
|
+
else
|
873
|
+
block_type = :block
|
874
|
+
end
|
875
|
+
|
838
876
|
if [:send, :csend, :index, :super, :zsuper, :lambda].include?(method_call.type)
|
839
|
-
n(
|
877
|
+
n(block_type, [ method_call, args, body ],
|
840
878
|
block_map(method_call.loc.expression, begin_t, end_t))
|
841
879
|
else
|
842
880
|
# Code like "return foo 1 do end" is reduced in a weird sequence.
|
843
881
|
# Here, method_call is actually (return).
|
844
882
|
actual_send, = *method_call
|
845
883
|
block =
|
846
|
-
n(
|
884
|
+
n(block_type, [ actual_send, args, body ],
|
847
885
|
block_map(actual_send.loc.expression, begin_t, end_t))
|
848
886
|
|
849
887
|
n(method_call.type, [ block ],
|
@@ -1215,18 +1253,18 @@ module Parser
|
|
1215
1253
|
case this_arg.type
|
1216
1254
|
when :arg, :optarg, :restarg, :blockarg,
|
1217
1255
|
:kwarg, :kwoptarg, :kwrestarg,
|
1218
|
-
:shadowarg
|
1256
|
+
:shadowarg
|
1219
1257
|
|
1220
|
-
|
1258
|
+
check_duplicate_arg(this_arg, map)
|
1221
1259
|
|
1222
|
-
|
1223
|
-
that_name, = *that_arg
|
1260
|
+
when :procarg0
|
1224
1261
|
|
1225
|
-
if
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1262
|
+
if this_arg.children[0].is_a?(Symbol)
|
1263
|
+
# s(:procarg0, :a)
|
1264
|
+
check_duplicate_arg(this_arg, map)
|
1265
|
+
else
|
1266
|
+
# s(:procarg0, s(:arg, :a), ...)
|
1267
|
+
check_duplicate_args(this_arg.children, map)
|
1230
1268
|
end
|
1231
1269
|
|
1232
1270
|
when :mlhs
|
@@ -1235,6 +1273,20 @@ module Parser
|
|
1235
1273
|
end
|
1236
1274
|
end
|
1237
1275
|
|
1276
|
+
def check_duplicate_arg(this_arg, map={})
|
1277
|
+
this_name, = *this_arg
|
1278
|
+
|
1279
|
+
that_arg = map[this_name]
|
1280
|
+
that_name, = *that_arg
|
1281
|
+
|
1282
|
+
if that_arg.nil?
|
1283
|
+
map[this_name] = this_arg
|
1284
|
+
elsif arg_name_collides?(this_name, that_name)
|
1285
|
+
diagnostic :error, :duplicate_argument, nil,
|
1286
|
+
this_arg.loc.name, [ that_arg.loc.name ]
|
1287
|
+
end
|
1288
|
+
end
|
1289
|
+
|
1238
1290
|
def arg_name_collides?(this_name, that_name)
|
1239
1291
|
case @parser.version
|
1240
1292
|
when 18
|
data/lib/parser/context.rb
CHANGED
@@ -47,5 +47,13 @@ module Parser
|
|
47
47
|
end
|
48
48
|
alias module_definition_allowed? class_definition_allowed?
|
49
49
|
alias dynamic_const_definition_allowed? class_definition_allowed?
|
50
|
+
|
51
|
+
def in_block?
|
52
|
+
@stack.last == :block
|
53
|
+
end
|
54
|
+
|
55
|
+
def in_lambda?
|
56
|
+
@stack.last == :lambda
|
57
|
+
end
|
50
58
|
end
|
51
59
|
end
|
data/lib/parser/current.rb
CHANGED
@@ -48,7 +48,7 @@ module Parser
|
|
48
48
|
CurrentRuby = Ruby23
|
49
49
|
|
50
50
|
when /^2\.4\./
|
51
|
-
current_version = '2.4.
|
51
|
+
current_version = '2.4.7'
|
52
52
|
if RUBY_VERSION != current_version
|
53
53
|
warn_syntax_deviation 'parser/ruby24', current_version
|
54
54
|
end
|
@@ -57,7 +57,7 @@ module Parser
|
|
57
57
|
CurrentRuby = Ruby24
|
58
58
|
|
59
59
|
when /^2\.5\./
|
60
|
-
current_version = '2.5.
|
60
|
+
current_version = '2.5.6'
|
61
61
|
if RUBY_VERSION != current_version
|
62
62
|
warn_syntax_deviation 'parser/ruby25', current_version
|
63
63
|
end
|
@@ -66,7 +66,7 @@ module Parser
|
|
66
66
|
CurrentRuby = Ruby25
|
67
67
|
|
68
68
|
when /^2\.6\./
|
69
|
-
current_version = '2.6.
|
69
|
+
current_version = '2.6.4'
|
70
70
|
if RUBY_VERSION != current_version
|
71
71
|
warn_syntax_deviation 'parser/ruby26', current_version
|
72
72
|
end
|
data/lib/parser/lexer.rl
CHANGED
@@ -89,7 +89,10 @@ class Parser::Lexer
|
|
89
89
|
|
90
90
|
REGEXP_META_CHARACTERS = Regexp.union(*"\\$()*+.<>?[]^{|}".chars).freeze
|
91
91
|
|
92
|
+
NUMPARAM_MAX = 100
|
93
|
+
|
92
94
|
attr_reader :source_buffer
|
95
|
+
attr_reader :max_numparam_stack
|
93
96
|
|
94
97
|
attr_accessor :diagnostics
|
95
98
|
attr_accessor :static_env
|
@@ -176,6 +179,9 @@ class Parser::Lexer
|
|
176
179
|
|
177
180
|
# State before =begin / =end block comment
|
178
181
|
@cs_before_block_comment = self.class.lex_en_line_begin
|
182
|
+
|
183
|
+
# Maximum numbered parameters stack
|
184
|
+
@max_numparam_stack = MaxNumparamStack.new
|
179
185
|
end
|
180
186
|
|
181
187
|
def source_buffer=(source_buffer)
|
@@ -249,6 +255,10 @@ class Parser::Lexer
|
|
249
255
|
@cond = @cond_stack.pop
|
250
256
|
end
|
251
257
|
|
258
|
+
def max_numparam
|
259
|
+
@max_numparam_stack.top
|
260
|
+
end
|
261
|
+
|
252
262
|
def dedent_level
|
253
263
|
# We erase @dedent_level as a precaution to avoid accidentally
|
254
264
|
# using a stale value.
|
@@ -705,6 +715,14 @@ class Parser::Lexer
|
|
705
715
|
diagnostic :fatal, :invalid_escape
|
706
716
|
}
|
707
717
|
|
718
|
+
action read_post_meta_or_ctrl_char {
|
719
|
+
@escape = @source_buffer.slice(p - 1).chr
|
720
|
+
|
721
|
+
if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord))
|
722
|
+
diagnostic :fatal, :invalid_escape
|
723
|
+
end
|
724
|
+
}
|
725
|
+
|
708
726
|
action slash_c_char {
|
709
727
|
@escape = encode_escape(@escape[0].ord & 0x9f)
|
710
728
|
}
|
@@ -715,13 +733,13 @@ class Parser::Lexer
|
|
715
733
|
|
716
734
|
maybe_escaped_char = (
|
717
735
|
'\\' c_any %unescape_char
|
718
|
-
| ( c_any - [\\] ) %
|
736
|
+
| ( c_any - [\\] ) %read_post_meta_or_ctrl_char
|
719
737
|
);
|
720
738
|
|
721
739
|
maybe_escaped_ctrl_char = ( # why?!
|
722
740
|
'\\' c_any %unescape_char %slash_c_char
|
723
741
|
| '?' % { @escape = "\x7f" }
|
724
|
-
| ( c_any - [\\?] ) %
|
742
|
+
| ( c_any - [\\?] ) %read_post_meta_or_ctrl_char %slash_c_char
|
725
743
|
);
|
726
744
|
|
727
745
|
escape = (
|
@@ -1301,6 +1319,36 @@ class Parser::Lexer
|
|
1301
1319
|
fnext *stack_pop; fbreak;
|
1302
1320
|
};
|
1303
1321
|
|
1322
|
+
'@' [0-9]+
|
1323
|
+
=> {
|
1324
|
+
if @version < 27
|
1325
|
+
diagnostic :error, :ivar_name, { :name => tok }
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
value = tok[1..-1]
|
1329
|
+
|
1330
|
+
if value[0] == '0'
|
1331
|
+
diagnostic :error, :leading_zero_in_numparam, nil, range(@ts, @te)
|
1332
|
+
end
|
1333
|
+
|
1334
|
+
if value.to_i > NUMPARAM_MAX
|
1335
|
+
diagnostic :error, :too_large_numparam, nil, range(@ts, @te)
|
1336
|
+
end
|
1337
|
+
|
1338
|
+
if !@context.in_block? && !@context.in_lambda?
|
1339
|
+
diagnostic :error, :numparam_outside_block, nil, range(@ts, @te)
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
if !@max_numparam_stack.can_have_numparams?
|
1343
|
+
diagnostic :error, :ordinary_param_defined, nil, range(@ts, @te)
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
@max_numparam_stack.register(value.to_i)
|
1347
|
+
|
1348
|
+
emit(:tNUMPARAM, tok[1..-1])
|
1349
|
+
fnext *stack_pop; fbreak;
|
1350
|
+
};
|
1351
|
+
|
1304
1352
|
instance_var_v
|
1305
1353
|
=> {
|
1306
1354
|
if tok =~ /^@[0-9]/
|
@@ -1733,7 +1781,11 @@ class Parser::Lexer
|
|
1733
1781
|
type = $3.empty? ? '<<"'.freeze : ('<<'.freeze + $3)
|
1734
1782
|
delimiter = $4
|
1735
1783
|
|
1736
|
-
if @version >=
|
1784
|
+
if @version >= 27
|
1785
|
+
if delimiter.count("\n") > 0 || delimiter.count("\r") > 0
|
1786
|
+
diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1)
|
1787
|
+
end
|
1788
|
+
elsif @version >= 24
|
1737
1789
|
if delimiter.count("\n") > 0
|
1738
1790
|
if delimiter.end_with?("\n")
|
1739
1791
|
diagnostic :warning, :heredoc_id_ends_with_nl, nil, range(@ts, @ts + 1)
|
@@ -1756,6 +1808,21 @@ class Parser::Lexer
|
|
1756
1808
|
end
|
1757
1809
|
};
|
1758
1810
|
|
1811
|
+
# Escaped unterminated heredoc start
|
1812
|
+
# <<'END | <<"END | <<`END |
|
1813
|
+
# <<-'END | <<-"END | <<-`END |
|
1814
|
+
# <<~'END | <<~"END | <<~`END
|
1815
|
+
#
|
1816
|
+
# If the heredoc is terminated the rule above should handle it
|
1817
|
+
'<<' [~\-]?
|
1818
|
+
('"' (any - c_nl - '"')*
|
1819
|
+
|"'" (any - c_nl - "'")*
|
1820
|
+
|"`" (any - c_nl - "`")
|
1821
|
+
)
|
1822
|
+
=> {
|
1823
|
+
diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1)
|
1824
|
+
};
|
1825
|
+
|
1759
1826
|
#
|
1760
1827
|
# SYMBOL LITERALS
|
1761
1828
|
#
|
@@ -1796,6 +1863,20 @@ class Parser::Lexer
|
|
1796
1863
|
fnext expr_end; fbreak;
|
1797
1864
|
};
|
1798
1865
|
|
1866
|
+
':' ( '@' %{ tm = p - 1; diag_msg = :ivar_name }
|
1867
|
+
| '@@' %{ tm = p - 2; diag_msg = :cvar_name }
|
1868
|
+
) [0-9]*
|
1869
|
+
=> {
|
1870
|
+
if @version >= 27
|
1871
|
+
diagnostic :error, diag_msg, { name: tok(tm, @te) }, range(tm, @te)
|
1872
|
+
else
|
1873
|
+
emit(:tCOLON, tok(@ts, @ts + 1), @ts, @ts + 1)
|
1874
|
+
p = @ts
|
1875
|
+
end
|
1876
|
+
|
1877
|
+
fnext expr_end; fbreak;
|
1878
|
+
};
|
1879
|
+
|
1799
1880
|
#
|
1800
1881
|
# AMBIGUOUS TERNARY OPERATOR
|
1801
1882
|
#
|