ruby_parser 3.13.0 → 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/.autotest +18 -29
- data/History.rdoc +123 -0
- data/Manifest.txt +2 -0
- data/README.rdoc +3 -3
- data/Rakefile +41 -24
- data/bin/ruby_parse +3 -1
- data/bin/ruby_parse_extract_error +18 -35
- data/compare/normalize.rb +43 -3
- data/debugging.md +39 -0
- data/lib/rp_extensions.rb +1 -1
- data/lib/ruby20_parser.rb +3654 -3466
- data/lib/ruby20_parser.y +504 -327
- data/lib/ruby21_parser.rb +3643 -3455
- data/lib/ruby21_parser.y +512 -334
- data/lib/ruby22_parser.rb +3669 -3492
- data/lib/ruby22_parser.y +513 -335
- data/lib/ruby23_parser.rb +3692 -3499
- data/lib/ruby23_parser.y +513 -335
- data/lib/ruby24_parser.rb +3685 -3463
- data/lib/ruby24_parser.y +517 -331
- data/lib/ruby25_parser.rb +3685 -3462
- data/lib/ruby25_parser.y +517 -331
- data/lib/ruby26_parser.rb +3696 -3471
- data/lib/ruby26_parser.y +523 -335
- data/lib/ruby27_parser.rb +7224 -0
- data/lib/ruby27_parser.y +2657 -0
- data/lib/ruby_lexer.rb +611 -495
- data/lib/ruby_lexer.rex +27 -28
- data/lib/ruby_lexer.rex.rb +71 -31
- data/lib/ruby_parser.rb +31 -27
- data/lib/ruby_parser.yy +529 -336
- data/lib/ruby_parser_extras.rb +720 -449
- data/test/test_ruby_lexer.rb +1560 -1412
- data/test/test_ruby_parser.rb +2611 -1912
- data/test/test_ruby_parser_extras.rb +39 -4
- data/tools/munge.rb +12 -6
- data/tools/ripper.rb +19 -3
- metadata +25 -18
- metadata.gz.sig +4 -1
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
|
|
@@ -44,18 +44,17 @@ rule
|
|
44
44
|
/[\]\)\}]/ process_brace_close
|
45
45
|
|
46
46
|
: /\!/
|
47
|
-
|
|
47
|
+
| is_after_operator? /\!\@/ { result EXPR_ARG, :tUBANG, "!@" }
|
48
48
|
| /\![=~]?/ { result :arg_state, TOKENS[text], text }
|
49
49
|
|
50
50
|
: /\./
|
51
|
-
| /\.\.\.?/ { result
|
51
|
+
| /\.\.\.?/ { result EXPR_BEG, TOKENS[text], text }
|
52
52
|
| /\.\d/ { rb_compile_error "no .<digit> floating literal anymore put 0 before dot" }
|
53
|
-
| /\./ { self.lex_state =
|
53
|
+
| /\./ { self.lex_state = EXPR_BEG; result EXPR_DOT, :tDOT, "." }
|
54
54
|
|
55
55
|
/\(/ process_paren
|
56
56
|
|
57
|
-
|
58
|
-
/\,/ { result :expr_beg, TOKENS[text], text }
|
57
|
+
/\,/ { result EXPR_PAR, TOKENS[text], text }
|
59
58
|
|
60
59
|
: /=/
|
61
60
|
| /\=\=\=|\=\=|\=~|\=>|\=(?!begin\b)/ { result arg_state, TOKENS[text], text }
|
@@ -63,7 +62,7 @@ rule
|
|
63
62
|
| /\=(?=begin\b)/ { result arg_state, TOKENS[text], text }
|
64
63
|
|
65
64
|
ruby22_label? /\"#{SIMPLE_STRING}\":/o process_label
|
66
|
-
/\"(#{SIMPLE_STRING})\"/o
|
65
|
+
/\"(#{SIMPLE_STRING})\"/o process_simple_string
|
67
66
|
/\"/ { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
|
68
67
|
|
69
68
|
/\@\@?\d/ { rb_compile_error "`#{text}` is not allowed as a variable name" }
|
@@ -76,7 +75,7 @@ ruby22_label? /\"#{SIMPLE_STRING}\":/o process_label
|
|
76
75
|
| /\:\:/ process_colon2
|
77
76
|
| /\:/ process_colon1
|
78
77
|
|
79
|
-
/->/ { result
|
78
|
+
/->/ { result EXPR_ENDFN, :tLAMBDA, nil }
|
80
79
|
|
81
80
|
/[+-]/ process_plus_minus
|
82
81
|
|
@@ -97,57 +96,57 @@ ruby22_label? /\"#{SIMPLE_STRING}\":/o process_label
|
|
97
96
|
was_label? /\'#{SSTRING}\':?/o process_label_or_string
|
98
97
|
|
99
98
|
: /\|/
|
100
|
-
| /\|\|\=/ { result
|
101
|
-
| /\|\|/ { result
|
102
|
-
| /\|\=/ { result
|
103
|
-
| /\|/ { result
|
99
|
+
| /\|\|\=/ { result EXPR_BEG, :tOP_ASGN, "||" }
|
100
|
+
| /\|\|/ { result EXPR_BEG, :tOROP, "||" }
|
101
|
+
| /\|\=/ { result EXPR_BEG, :tOP_ASGN, "|" }
|
102
|
+
| /\|/ { state = is_after_operator? ? EXPR_ARG : EXPR_PAR; result state, :tPIPE, "|" }
|
104
103
|
|
105
104
|
/\{/ process_brace_open
|
106
105
|
|
107
106
|
: /\*/
|
108
|
-
| /\*\*=/ { result
|
107
|
+
| /\*\*=/ { result EXPR_BEG, :tOP_ASGN, "**" }
|
109
108
|
| /\*\*/ { result(:arg_state, space_vs_beginning(:tDSTAR, :tDSTAR, :tPOW), "**") }
|
110
|
-
| /\*\=/ { result(
|
109
|
+
| /\*\=/ { result(EXPR_BEG, :tOP_ASGN, "*") }
|
111
110
|
| /\*/ { result(:arg_state, space_vs_beginning(:tSTAR, :tSTAR, :tSTAR2), "*") }
|
112
111
|
|
113
112
|
# TODO: fix result+process_lchevron to set command_start = true
|
114
113
|
: /</
|
115
114
|
| /\<\=\>/ { result :arg_state, :tCMP, "<=>" }
|
116
115
|
| /\<\=/ { result :arg_state, :tLEQ, "<=" }
|
117
|
-
| /\<\<\=/ { result
|
116
|
+
| /\<\<\=/ { result EXPR_BEG, :tOP_ASGN, "<<" }
|
118
117
|
| /\<\</ process_lchevron
|
119
118
|
| /\</ { result :arg_state, :tLT, "<" }
|
120
119
|
|
121
120
|
: />/
|
122
121
|
| /\>\=/ { result :arg_state, :tGEQ, ">=" }
|
123
|
-
| /\>\>=/ { result
|
122
|
+
| /\>\>=/ { result EXPR_BEG, :tOP_ASGN, ">>" }
|
124
123
|
| /\>\>/ { result :arg_state, :tRSHFT, ">>" }
|
125
124
|
| /\>/ { result :arg_state, :tGT, ">" }
|
126
125
|
|
127
126
|
: /\`/
|
128
|
-
| expr_fname? /\`/ { result(
|
129
|
-
| expr_dot? /\`/ { result((cmd_state ?
|
127
|
+
| expr_fname? /\`/ { result(EXPR_END, :tBACK_REF2, "`") }
|
128
|
+
| expr_dot? /\`/ { result((cmd_state ? EXPR_CMDARG : EXPR_ARG), :tBACK_REF2, "`") }
|
130
129
|
| /\`/ { string STR_XQUOTE, '`'; result(nil, :tXSTRING_BEG, "`") }
|
131
130
|
|
132
131
|
/\?/ process_questionmark
|
133
132
|
|
134
133
|
: /&/
|
135
|
-
| /\&\&\=/ { result(
|
136
|
-
| /\&\&/ { result(
|
137
|
-
| /\&\=/ { result(
|
138
|
-
| /\&\./ { result(
|
134
|
+
| /\&\&\=/ { result(EXPR_BEG, :tOP_ASGN, "&&") }
|
135
|
+
| /\&\&/ { result(EXPR_BEG, :tANDOP, "&&") }
|
136
|
+
| /\&\=/ { result(EXPR_BEG, :tOP_ASGN, "&" ) }
|
137
|
+
| /\&\./ { result(EXPR_DOT, :tLONELY, "&.") }
|
139
138
|
| /\&/ process_amper
|
140
139
|
|
141
140
|
/\// process_slash
|
142
141
|
|
143
142
|
: /\^/
|
144
|
-
| /\^=/ { result(
|
143
|
+
| /\^=/ { result(EXPR_BEG, :tOP_ASGN, "^") }
|
145
144
|
| /\^/ { result(:arg_state, :tCARET, "^") }
|
146
145
|
|
147
|
-
/\;/ { self.command_start = true; result(
|
146
|
+
/\;/ { self.command_start = true; result(EXPR_BEG, :tSEMI, ";") }
|
148
147
|
|
149
148
|
: /~/
|
150
|
-
|
|
149
|
+
| is_after_operator? /\~@/ { result(:arg_state, :tTILDE, "~") }
|
151
150
|
| /\~/ { result(:arg_state, :tTILDE, "~") }
|
152
151
|
|
153
152
|
: /\\/
|
@@ -165,12 +164,12 @@ was_label? /\'#{SSTRING}\':?/o process_label_or_string
|
|
165
164
|
| in_fname? /\$([1-9]\d*)/ process_gvar
|
166
165
|
| /\$([1-9]\d*)/ process_nthref
|
167
166
|
| /\$0/ process_gvar
|
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,18 +1,23 @@
|
|
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
|
|
8
8
|
#
|
9
9
|
# lexical scanner definition for ruby
|
10
10
|
|
11
|
+
|
12
|
+
##
|
13
|
+
# The generated lexer RubyLexer
|
14
|
+
|
11
15
|
class RubyLexer
|
12
16
|
require 'strscan'
|
13
17
|
|
14
|
-
|
15
|
-
|
18
|
+
# :stopdoc:
|
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]))/
|
16
21
|
SIMPLE_STRING = /((#{ESC}|\#(#{ESC}|[^\{\#\@\$\"\\])|[^\"\\\#])*)/o
|
17
22
|
SSTRING = /((\\.|[^\'])*)/
|
18
23
|
INT_DEC = /[+]?(?:(?:[1-9][\d_]*|0)(?!\.\d)(ri|r|i)?\b|0d[0-9_]+)(ri|r|i)?/i
|
@@ -24,30 +29,56 @@ class RubyLexer
|
|
24
29
|
NUM_BAD = /[+]?0[xbd]\b/i
|
25
30
|
INT_OCT_BAD = /[+]?0o?[0-7_]*[89]/i
|
26
31
|
FLOAT_BAD = /[+]?\d[\d_]*_(e|\.)/i
|
27
|
-
|
32
|
+
# :startdoc:
|
33
|
+
# :stopdoc:
|
28
34
|
class LexerError < StandardError ; end
|
29
35
|
class ScanError < LexerError ; end
|
36
|
+
# :startdoc:
|
37
|
+
|
38
|
+
##
|
39
|
+
# The file name / path
|
30
40
|
|
31
41
|
attr_accessor :filename
|
42
|
+
|
43
|
+
##
|
44
|
+
# The StringScanner for this lexer.
|
45
|
+
|
32
46
|
attr_accessor :ss
|
47
|
+
|
48
|
+
##
|
49
|
+
# The current lexical state.
|
50
|
+
|
33
51
|
attr_accessor :state
|
34
52
|
|
35
53
|
alias :match :ss
|
36
54
|
|
55
|
+
##
|
56
|
+
# The match groups for the current scan.
|
57
|
+
|
37
58
|
def matches
|
38
59
|
m = (1..9).map { |i| ss[i] }
|
39
60
|
m.pop until m[-1] or m.empty?
|
40
61
|
m
|
41
62
|
end
|
42
63
|
|
64
|
+
##
|
65
|
+
# Yields on the current action.
|
66
|
+
|
43
67
|
def action
|
44
68
|
yield
|
45
69
|
end
|
46
70
|
|
71
|
+
|
72
|
+
##
|
73
|
+
# The current scanner class. Must be overridden in subclasses.
|
74
|
+
|
47
75
|
def scanner_class
|
48
76
|
StringScanner
|
49
77
|
end unless instance_methods(false).map(&:to_s).include?("scanner_class")
|
50
78
|
|
79
|
+
##
|
80
|
+
# Parse the given string.
|
81
|
+
|
51
82
|
def parse str
|
52
83
|
self.ss = scanner_class.new str
|
53
84
|
self.state ||= nil
|
@@ -55,6 +86,9 @@ class RubyLexer
|
|
55
86
|
do_parse
|
56
87
|
end
|
57
88
|
|
89
|
+
##
|
90
|
+
# Read in and parse the file at +path+.
|
91
|
+
|
58
92
|
def parse_file path
|
59
93
|
self.filename = path
|
60
94
|
open path do |f|
|
@@ -62,12 +96,18 @@ class RubyLexer
|
|
62
96
|
end
|
63
97
|
end
|
64
98
|
|
99
|
+
##
|
100
|
+
# The current location in the parse.
|
101
|
+
|
65
102
|
def location
|
66
103
|
[
|
67
104
|
(filename || "<input>"),
|
68
105
|
].compact.join(":")
|
69
106
|
end
|
70
107
|
|
108
|
+
##
|
109
|
+
# Lex the next token.
|
110
|
+
|
71
111
|
def next_token
|
72
112
|
return process_string if lex_strterm
|
73
113
|
self.cmd_state = self.command_start
|
@@ -90,24 +130,24 @@ class RubyLexer
|
|
90
130
|
process_brace_close text
|
91
131
|
when ss.match?(/\!/) then
|
92
132
|
case
|
93
|
-
when
|
94
|
-
action { result
|
133
|
+
when is_after_operator? && (ss.skip(/\!\@/)) then
|
134
|
+
action { result EXPR_ARG, :tUBANG, "!@" }
|
95
135
|
when text = ss.scan(/\![=~]?/) then
|
96
136
|
action { result :arg_state, TOKENS[text], text }
|
97
137
|
end # group /\!/
|
98
138
|
when ss.match?(/\./) then
|
99
139
|
case
|
100
140
|
when text = ss.scan(/\.\.\.?/) then
|
101
|
-
action { result
|
141
|
+
action { result EXPR_BEG, TOKENS[text], text }
|
102
142
|
when ss.skip(/\.\d/) then
|
103
143
|
action { rb_compile_error "no .<digit> floating literal anymore put 0 before dot" }
|
104
144
|
when ss.skip(/\./) then
|
105
|
-
action { self.lex_state =
|
145
|
+
action { self.lex_state = EXPR_BEG; result EXPR_DOT, :tDOT, "." }
|
106
146
|
end # group /\./
|
107
147
|
when text = ss.scan(/\(/) then
|
108
148
|
process_paren text
|
109
149
|
when text = ss.scan(/\,/) then
|
110
|
-
action { result
|
150
|
+
action { result EXPR_PAR, TOKENS[text], text }
|
111
151
|
when ss.match?(/=/) then
|
112
152
|
case
|
113
153
|
when text = ss.scan(/\=\=\=|\=\=|\=~|\=>|\=(?!begin\b)/) then
|
@@ -120,7 +160,7 @@ class RubyLexer
|
|
120
160
|
when ruby22_label? && (text = ss.scan(/\"#{SIMPLE_STRING}\":/o)) then
|
121
161
|
process_label text
|
122
162
|
when text = ss.scan(/\"(#{SIMPLE_STRING})\"/o) then
|
123
|
-
|
163
|
+
process_simple_string text
|
124
164
|
when text = ss.scan(/\"/) then
|
125
165
|
action { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
|
126
166
|
when text = ss.scan(/\@\@?\d/) then
|
@@ -141,7 +181,7 @@ class RubyLexer
|
|
141
181
|
process_colon1 text
|
142
182
|
end # group /:/
|
143
183
|
when ss.skip(/->/) then
|
144
|
-
action { result
|
184
|
+
action { result EXPR_ENDFN, :tLAMBDA, nil }
|
145
185
|
when text = ss.scan(/[+-]/) then
|
146
186
|
process_plus_minus text
|
147
187
|
when ss.match?(/[+\d]/) then
|
@@ -174,24 +214,24 @@ class RubyLexer
|
|
174
214
|
when ss.match?(/\|/) then
|
175
215
|
case
|
176
216
|
when ss.skip(/\|\|\=/) then
|
177
|
-
action { result
|
217
|
+
action { result EXPR_BEG, :tOP_ASGN, "||" }
|
178
218
|
when ss.skip(/\|\|/) then
|
179
|
-
action { result
|
219
|
+
action { result EXPR_BEG, :tOROP, "||" }
|
180
220
|
when ss.skip(/\|\=/) then
|
181
|
-
action { result
|
221
|
+
action { result EXPR_BEG, :tOP_ASGN, "|" }
|
182
222
|
when ss.skip(/\|/) then
|
183
|
-
action { result
|
223
|
+
action { state = is_after_operator? ? EXPR_ARG : EXPR_PAR; result state, :tPIPE, "|" }
|
184
224
|
end # group /\|/
|
185
225
|
when text = ss.scan(/\{/) then
|
186
226
|
process_brace_open text
|
187
227
|
when ss.match?(/\*/) then
|
188
228
|
case
|
189
229
|
when ss.skip(/\*\*=/) then
|
190
|
-
action { result
|
230
|
+
action { result EXPR_BEG, :tOP_ASGN, "**" }
|
191
231
|
when ss.skip(/\*\*/) then
|
192
232
|
action { result(:arg_state, space_vs_beginning(:tDSTAR, :tDSTAR, :tPOW), "**") }
|
193
233
|
when ss.skip(/\*\=/) then
|
194
|
-
action { result(
|
234
|
+
action { result(EXPR_BEG, :tOP_ASGN, "*") }
|
195
235
|
when ss.skip(/\*/) then
|
196
236
|
action { result(:arg_state, space_vs_beginning(:tSTAR, :tSTAR, :tSTAR2), "*") }
|
197
237
|
end # group /\*/
|
@@ -202,7 +242,7 @@ class RubyLexer
|
|
202
242
|
when ss.skip(/\<\=/) then
|
203
243
|
action { result :arg_state, :tLEQ, "<=" }
|
204
244
|
when ss.skip(/\<\<\=/) then
|
205
|
-
action { result
|
245
|
+
action { result EXPR_BEG, :tOP_ASGN, "<<" }
|
206
246
|
when text = ss.scan(/\<\</) then
|
207
247
|
process_lchevron text
|
208
248
|
when ss.skip(/\</) then
|
@@ -213,7 +253,7 @@ class RubyLexer
|
|
213
253
|
when ss.skip(/\>\=/) then
|
214
254
|
action { result :arg_state, :tGEQ, ">=" }
|
215
255
|
when ss.skip(/\>\>=/) then
|
216
|
-
action { result
|
256
|
+
action { result EXPR_BEG, :tOP_ASGN, ">>" }
|
217
257
|
when ss.skip(/\>\>/) then
|
218
258
|
action { result :arg_state, :tRSHFT, ">>" }
|
219
259
|
when ss.skip(/\>/) then
|
@@ -222,9 +262,9 @@ class RubyLexer
|
|
222
262
|
when ss.match?(/\`/) then
|
223
263
|
case
|
224
264
|
when expr_fname? && (ss.skip(/\`/)) then
|
225
|
-
action { result(
|
265
|
+
action { result(EXPR_END, :tBACK_REF2, "`") }
|
226
266
|
when expr_dot? && (ss.skip(/\`/)) then
|
227
|
-
action { result((cmd_state ?
|
267
|
+
action { result((cmd_state ? EXPR_CMDARG : EXPR_ARG), :tBACK_REF2, "`") }
|
228
268
|
when ss.skip(/\`/) then
|
229
269
|
action { string STR_XQUOTE, '`'; result(nil, :tXSTRING_BEG, "`") }
|
230
270
|
end # group /\`/
|
@@ -233,13 +273,13 @@ class RubyLexer
|
|
233
273
|
when ss.match?(/&/) then
|
234
274
|
case
|
235
275
|
when ss.skip(/\&\&\=/) then
|
236
|
-
action { result(
|
276
|
+
action { result(EXPR_BEG, :tOP_ASGN, "&&") }
|
237
277
|
when ss.skip(/\&\&/) then
|
238
|
-
action { result(
|
278
|
+
action { result(EXPR_BEG, :tANDOP, "&&") }
|
239
279
|
when ss.skip(/\&\=/) then
|
240
|
-
action { result(
|
280
|
+
action { result(EXPR_BEG, :tOP_ASGN, "&" ) }
|
241
281
|
when ss.skip(/\&\./) then
|
242
|
-
action { result(
|
282
|
+
action { result(EXPR_DOT, :tLONELY, "&.") }
|
243
283
|
when text = ss.scan(/\&/) then
|
244
284
|
process_amper text
|
245
285
|
end # group /&/
|
@@ -248,15 +288,15 @@ class RubyLexer
|
|
248
288
|
when ss.match?(/\^/) then
|
249
289
|
case
|
250
290
|
when ss.skip(/\^=/) then
|
251
|
-
action { result(
|
291
|
+
action { result(EXPR_BEG, :tOP_ASGN, "^") }
|
252
292
|
when ss.skip(/\^/) then
|
253
293
|
action { result(:arg_state, :tCARET, "^") }
|
254
294
|
end # group /\^/
|
255
295
|
when ss.skip(/\;/) then
|
256
|
-
action { self.command_start = true; result(
|
296
|
+
action { self.command_start = true; result(EXPR_BEG, :tSEMI, ";") }
|
257
297
|
when ss.match?(/~/) then
|
258
298
|
case
|
259
|
-
when
|
299
|
+
when is_after_operator? && (ss.skip(/\~@/)) then
|
260
300
|
action { result(:arg_state, :tTILDE, "~") }
|
261
301
|
when ss.skip(/\~/) then
|
262
302
|
action { result(:arg_state, :tTILDE, "~") }
|
@@ -288,14 +328,14 @@ class RubyLexer
|
|
288
328
|
process_nthref text
|
289
329
|
when text = ss.scan(/\$0/) then
|
290
330
|
process_gvar text
|
331
|
+
when text = ss.scan(/\$#{IDENT_CHAR}+/) then
|
332
|
+
process_gvar text
|
291
333
|
when text = ss.scan(/\$\W|\$\z/) then
|
292
334
|
process_gvar_oddity text
|
293
|
-
when text = ss.scan(/\$\w+/) then
|
294
|
-
process_gvar text
|
295
335
|
end # group /\$/
|
296
336
|
when text = ss.scan(/\_/) then
|
297
337
|
process_underscore text
|
298
|
-
when text = ss.scan(/#{
|
338
|
+
when text = ss.scan(/#{IDENT_CHAR}+/o) then
|
299
339
|
process_token text
|
300
340
|
when ss.skip(/\004|\032|\000|\Z/) then
|
301
341
|
action { [RubyLexer::EOF, RubyLexer::EOF] }
|
data/lib/ruby_parser.rb
CHANGED
@@ -9,28 +9,29 @@ class RubyParser
|
|
9
9
|
|
10
10
|
VERSIONS = []
|
11
11
|
|
12
|
-
|
13
|
-
include RubyParserStuff
|
12
|
+
attr_accessor :current
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
def self.for_current_ruby
|
15
|
+
name = "V#{RUBY_VERSION[/^\d+\.\d+/].delete "."}"
|
16
|
+
klass = if const_defined? name then
|
17
|
+
const_get name
|
18
|
+
else
|
19
|
+
latest = VERSIONS.first
|
20
|
+
warn "NOTE: RubyParser::#{name} undefined, using #{latest}."
|
21
|
+
latest
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
@version ||= Parser > self && self.name[/(?:V|Ruby)(\d+)/, 1].to_i
|
25
|
-
end
|
24
|
+
klass.new
|
26
25
|
end
|
27
26
|
|
28
|
-
|
27
|
+
def self.latest
|
28
|
+
VERSIONS.first.new
|
29
|
+
end
|
29
30
|
|
30
31
|
def process s, f = "(string)", t = 10
|
31
32
|
e = nil
|
32
33
|
VERSIONS.each do |klass|
|
33
|
-
parser = klass.new
|
34
|
+
self.current = parser = klass.new
|
34
35
|
begin
|
35
36
|
return parser.process s, f, t
|
36
37
|
rescue Racc::ParseError, RubyParser::SyntaxError => exc
|
@@ -46,22 +47,23 @@ class RubyParser
|
|
46
47
|
# do nothing
|
47
48
|
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
end
|
50
|
+
class Parser < Racc::Parser
|
51
|
+
include RubyParserStuff
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
const_get name
|
57
|
-
else
|
58
|
-
latest = VERSIONS.first
|
59
|
-
warn "NOTE: RubyParser::#{name} undefined, using #{latest}."
|
60
|
-
latest
|
61
|
-
end
|
53
|
+
def self.inherited x
|
54
|
+
RubyParser::VERSIONS << x
|
55
|
+
end
|
62
56
|
|
63
|
-
|
57
|
+
def self.version= v
|
58
|
+
@version = v
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.version
|
62
|
+
@version ||= Parser > self && self.name[/(?:V|Ruby)(\d+)/, 1].to_i
|
63
|
+
end
|
64
64
|
end
|
65
|
+
|
66
|
+
class SyntaxError < RuntimeError; end
|
65
67
|
end
|
66
68
|
|
67
69
|
##
|
@@ -76,10 +78,12 @@ require "ruby23_parser"
|
|
76
78
|
require "ruby24_parser"
|
77
79
|
require "ruby25_parser"
|
78
80
|
require "ruby26_parser"
|
81
|
+
require "ruby27_parser"
|
79
82
|
|
80
83
|
class RubyParser # HACK
|
81
84
|
VERSIONS.clear # also a HACK caused by racc namespace issues
|
82
85
|
|
86
|
+
class V27 < ::Ruby27Parser; end
|
83
87
|
class V26 < ::Ruby26Parser; end
|
84
88
|
class V25 < ::Ruby25Parser; end
|
85
89
|
class V24 < ::Ruby24Parser; end
|