ruby_parser 3.8.4 → 3.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0abf3a43140d5d77875d4ae77c8657ff6e011b9
4
- data.tar.gz: f7634c27ce13a769c186cda5763d9597d68f1202
3
+ metadata.gz: db3aec0f342263aec6c4bc598f2af937d889219b
4
+ data.tar.gz: 0a7300cfcb5109443168aa3432eefb0b103a07a1
5
5
  SHA512:
6
- metadata.gz: 4dca307209ff4d2d19ce5aeebe96a4368abb74acd38837988b4950c21eedc7a0bf48cfdf3155547b585050e97e1a2ab84baee6abf12b54247084e74ae3d40d7b
7
- data.tar.gz: 3ce888e70acce944e24c30883600314d34cc95ff32a6df6ce7ae32c8aa01d7dfea9e93e42c27c3e9954dc6288248f82b8c5fe2f978e0adaf955df3042299668a
6
+ metadata.gz: c26c726384052dc9ea43d9cb29f982ed03768458c1ff0e64a515026c721be346f009ead616d18c499d449fbf9a6c23234a4c637afb14cf28fb74035a33a743db
7
+ data.tar.gz: 4f3d570afe84856c5275be5a9eaf9277168a89db5bd3dea605cc86cf8c38492d9ee0b5ec2d32c3413124c068ff57e24a5241d8474463e15018376328fff024ec
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/History.rdoc CHANGED
@@ -1,3 +1,32 @@
1
+ === 3.9.0 / 2017-04-13
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Added tentative ruby 2.4 support. Probably missing things.
6
+
7
+ * 13 minor enhancements:
8
+
9
+ * Added RubyParser.latest.
10
+ * Added RubyParser::Parser.version to make version range comparisons easier
11
+ * Changed superclasses of all parsers to RubyParser::Parser
12
+ * Cleaned up a lot of the version specific code to be more generic/flexible.
13
+ * Documented how to add new versions in README.
14
+ * Moved RubyParser from ruby_parser_extras.rb into ruby_parser.rb to fix bootstrap issues.
15
+ * Renamed RubyParserStuff#get_match_node to new_match. Aliased and deprecated.
16
+ * Renamed RubyParserStuff#logop to logical_op. Aliased and deprecated.
17
+ * Renamed RubyParserStuff#node_assign to new_assign. Aliased and deprecated.
18
+ * Renamed all parsers to RubyParser::V##.
19
+ * Revamped grammar preprocessing to make adding new versions easier.
20
+ * RubyParser.for_current_ruby falls back to latest if current not available.
21
+ * Subclasses of RubyParser::Parser register themselves into RubyParser::VERSIONS.
22
+
23
+ * 4 bug fixes:
24
+
25
+ * Fixed `&.` after newline. (presidentbeef)
26
+ * Fixed bug setting line number for hash literals to line of opening brace.
27
+ * Fixed grammar preprocessing bug.
28
+ * Properly handle kDO with no-parens stabby lambda. (presidentbeef)
29
+
1
30
  === 3.8.4 / 2017-01-13
2
31
 
3
32
  * 3 bug fixes:
data/Manifest.txt CHANGED
@@ -5,7 +5,10 @@ README.rdoc
5
5
  Rakefile
6
6
  bin/ruby_parse
7
7
  bin/ruby_parse_extract_error
8
+ compare/normalize.rb
8
9
  lib/.document
10
+ lib/rp_extensions.rb
11
+ lib/rp_stringscanner.rb
9
12
  lib/ruby18_parser.rb
10
13
  lib/ruby18_parser.y
11
14
  lib/ruby19_parser.rb
@@ -18,6 +21,8 @@ lib/ruby22_parser.rb
18
21
  lib/ruby22_parser.y
19
22
  lib/ruby23_parser.rb
20
23
  lib/ruby23_parser.y
24
+ lib/ruby24_parser.rb
25
+ lib/ruby24_parser.y
21
26
  lib/ruby_lexer.rb
22
27
  lib/ruby_lexer.rex
23
28
  lib/ruby_lexer.rex.rb
data/README.rdoc CHANGED
@@ -57,6 +57,18 @@ You can also use Ruby19Parser, Ruby18Parser, or RubyParser.for_current_ruby:
57
57
  RubyParser.for_current_ruby.parse "1+1"
58
58
  # => s(:call, s(:lit, 1), :+, s(:lit, 1))
59
59
 
60
+ == DEVELOPER NOTES:
61
+
62
+ To add a new version:
63
+
64
+ * New parser should be generated from lib/ruby_parser.yy.
65
+ * Extend lib/ruby_parser.yy with new class name.
66
+ * Add new version number to Rakefile for rule creation.
67
+ * Require generated parser in lib/ruby_parser.rb.
68
+ * Add empty TestRubyParserShared##Plus module and TestRubyParserV## to test/test_ruby_parser.rb.
69
+ * Extend Manifest.txt with generated file names.
70
+ * Extend sexp_processor's pt_testcase.rb to match version
71
+
60
72
  == REQUIREMENTS:
61
73
 
62
74
  * ruby. woot.
data/Rakefile CHANGED
@@ -14,6 +14,10 @@ Hoe.add_include_dirs "../../sexp_processor/dev/lib"
14
14
  Hoe.add_include_dirs "../../minitest/dev/lib"
15
15
  Hoe.add_include_dirs "../../oedipus_lex/dev/lib"
16
16
 
17
+ V1 = %w[18 19]
18
+ V2 = %w[20 21 22 23 24]
19
+ V1_2 = V1 + V2
20
+
17
21
  Hoe.spec "ruby_parser" do
18
22
  developer "Ryan Davis", "ryand-ruby@zenspider.com"
19
23
 
@@ -24,45 +28,35 @@ Hoe.spec "ruby_parser" do
24
28
  dependency "oedipus_lex", "~> 2.1", :developer
25
29
 
26
30
  if plugin? :perforce then # generated files
27
- self.perforce_ignore << "lib/ruby18_parser.rb"
28
- self.perforce_ignore << "lib/ruby19_parser.rb"
29
- self.perforce_ignore << "lib/ruby20_parser.rb"
30
- self.perforce_ignore << "lib/ruby20_parser.y"
31
- self.perforce_ignore << "lib/ruby21_parser.rb"
32
- self.perforce_ignore << "lib/ruby21_parser.y"
33
- self.perforce_ignore << "lib/ruby22_parser.rb"
34
- self.perforce_ignore << "lib/ruby22_parser.y"
35
- self.perforce_ignore << "lib/ruby23_parser.rb"
36
- self.perforce_ignore << "lib/ruby23_parser.y"
37
- self.perforce_ignore << "lib/ruby_lexer.rex.rb"
38
- end
31
+ V1_2.each do |n|
32
+ self.perforce_ignore << "lib/ruby#{n}_parser.rb"
33
+ end
39
34
 
40
- self.racc_flags << " -t" if plugin?(:racc) && ENV["DEBUG"]
41
- end
35
+ V2.each do |n|
36
+ self.perforce_ignore << "lib/ruby#{n}_parser.y"
37
+ end
42
38
 
43
- file "lib/ruby20_parser.y" => "lib/ruby_parser.yy" do |t|
44
- sh "unifdef -tk -DRUBY20 -URUBY21 -URUBY22 -URUBY23 -UDEAD #{t.source} > #{t.name} || true"
45
- end
39
+ self.perforce_ignore << "lib/ruby_lexer.rex.rb"
40
+ end
46
41
 
47
- file "lib/ruby21_parser.y" => "lib/ruby_parser.yy" do |t|
48
- sh "unifdef -tk -URUBY20 -DRUBY21 -URUBY22 -URUBY23 -UDEAD #{t.source} > #{t.name} || true"
42
+ if plugin?(:racc)
43
+ self.racc_flags << " -t" if ENV["DEBUG"]
44
+ self.racc_flags << " --superclass RubyParser::Parser"
45
+ # self.racc_flags << " --runtime ruby_parser" # TODO: broken in racc
46
+ end
49
47
  end
50
48
 
51
- file "lib/ruby22_parser.y" => "lib/ruby_parser.yy" do |t|
52
- sh "unifdef -tk -URUBY20 -URUBY21 -DRUBY22 -URUBY23 -UDEAD #{t.source} > #{t.name} || true"
49
+ V2.each do |n|
50
+ file "lib/ruby#{n}_parser.y" => "lib/ruby_parser.yy" do |t|
51
+ cmd = 'unifdef -tk -DV=%s -UDEAD %s > %s || true' % [n, t.source, t.name]
52
+ sh cmd
53
+ end
53
54
  end
54
55
 
55
- file "lib/ruby23_parser.y" => "lib/ruby_parser.yy" do |t|
56
- sh "unifdef -tk -URUBY20 -URUBY21 -URUBY22 -DRUBY23 -UDEAD #{t.source} > #{t.name} || true"
56
+ V1_2.each do |n|
57
+ file "lib/ruby#{n}_parser.rb" => "lib/ruby#{n}_parser.y"
57
58
  end
58
59
 
59
-
60
- file "lib/ruby18_parser.rb" => "lib/ruby18_parser.y"
61
- file "lib/ruby19_parser.rb" => "lib/ruby19_parser.y"
62
- file "lib/ruby20_parser.rb" => "lib/ruby20_parser.y"
63
- file "lib/ruby21_parser.rb" => "lib/ruby21_parser.y"
64
- file "lib/ruby22_parser.rb" => "lib/ruby22_parser.y"
65
- file "lib/ruby23_parser.rb" => "lib/ruby23_parser.y"
66
60
  file "lib/ruby_lexer.rex.rb" => "lib/ruby_lexer.rex"
67
61
 
68
62
  task :clean do
@@ -94,32 +88,110 @@ end
94
88
 
95
89
  task :isolate => :phony
96
90
 
97
- # to create parseXX.output:
98
- #
99
- # 1) check out the XX version of ruby
100
- # 2) Edit uncommon.mk, find the ".y.c" rule and remove the RM lines
101
- # 3) run `rm -f parse.c; make parse.c`
102
- # 4) run `bison -r all parse.tmp.y`
103
- # 5) mv parse.tmp.output parseXX.output
104
-
105
- # possibly new instructions:
106
- #
107
- # 1) check out the XX version of ruby
108
- # 2) YFLAGS="-r all" make parse.c
109
- # 3) mv y.output parseXX.output
110
-
111
- %w[18 19 20 21 22 23].each do |v|
112
- task "compare#{v}" do
113
- sh "./yack.rb lib/ruby#{v}_parser.output > racc#{v}.txt"
114
- sh "./yack.rb parse#{v}.output > yacc#{v}.txt"
115
- sh "diff -du racc#{v}.txt yacc#{v}.txt || true"
116
- puts
117
- sh "diff -du racc#{v}.txt yacc#{v}.txt | wc -l"
91
+ def in_compare
92
+ Dir.chdir "compare" do
93
+ yield
94
+ end
95
+ end
96
+
97
+ def dl v
98
+ dir = v[/^\d+\.\d+/]
99
+ url = "https://cache.ruby-lang.org/pub/ruby/#{dir}/ruby-#{v}.tar.bz2"
100
+ path = File.basename url
101
+ unless File.exist? path then
102
+ system "curl -O #{url}"
103
+ end
104
+ end
105
+
106
+ def ruby_parse version
107
+ v = version[/^\d+\.\d+/].delete "."
108
+ rp_txt = "rp#{v}.txt"
109
+ mri_txt = "mri#{v}.txt"
110
+ parse_y = "parse#{v}.y"
111
+ tarball = "ruby-#{version}.tar.bz2"
112
+ ruby_dir = "ruby-#{version}"
113
+ diff = "diff#{v}.diff"
114
+ rp_out = "lib/ruby#{v}_parser.output"
115
+
116
+ c_diff = "compare/#{diff}"
117
+ c_rp_txt = "compare/#{rp_txt}"
118
+ c_mri_txt = "compare/#{mri_txt}"
119
+ c_parse_y = "compare/#{parse_y}"
120
+ c_tarball = "compare/#{tarball}"
121
+
122
+ file tarball do
123
+ in_compare do
124
+ dl version
125
+ end
126
+ end
127
+
128
+ file c_parse_y => c_tarball do
129
+ in_compare do
130
+ system "tar yxf #{tarball} #{ruby_dir}/{id.h,parse.y,tool/{id2token.rb,vpath.rb}}"
131
+ Dir.chdir ruby_dir do
132
+ if File.exist? "tool/id2token.rb" then
133
+ sh "ruby tool/id2token.rb --path-separator=.:./ id.h parse.y > ../#{parse_y}"
134
+ else
135
+ cp "parse.y", "../#{parse_y}"
136
+ end
137
+ end
138
+ sh "rm -rf #{ruby_dir}"
139
+ end
140
+ end
141
+
142
+ file c_mri_txt => c_parse_y do
143
+ in_compare do
144
+ sh "bison -r all #{parse_y}"
145
+ sh "./normalize.rb parse#{v}.output > #{mri_txt}"
146
+ rm ["parse#{v}.output", "parse#{v}.tab.c"]
147
+ end
148
+ end
149
+
150
+ file rp_out => :parser
151
+
152
+ file c_rp_txt => rp_out do
153
+ in_compare do
154
+ sh "./normalize.rb ../#{rp_out} > #{rp_txt}"
155
+ end
156
+ end
157
+
158
+ compare = "compare#{v}"
159
+
160
+ desc "Compare all grammars to MRI"
161
+ task :compare => compare
162
+
163
+ task c_diff => [c_mri_txt, c_rp_txt] do
164
+ in_compare do
165
+ system "diff -du #{mri_txt} #{rp_txt} > #{diff}"
166
+ end
167
+ end
168
+
169
+ desc "Compare #{v} grammar to MRI #{version}"
170
+ task compare => c_diff do
171
+ in_compare do
172
+ system "wc -l #{diff}"
173
+ end
174
+ end
175
+
176
+ task :clean do
177
+ rm_f Dir[c_parse_y, c_mri_txt, c_rp_txt]
178
+ end
179
+
180
+ task :realclean do
181
+ rm_f Dir[tarball]
118
182
  end
119
183
  end
120
184
 
185
+ ruby_parse "1.8.7-p374"
186
+ ruby_parse "1.9.3-p551"
187
+ ruby_parse "2.0.0-p648"
188
+ ruby_parse "2.1.9"
189
+ ruby_parse "2.2.6"
190
+ ruby_parse "2.3.3"
191
+ # TODO ruby_parse "2.4.0"
192
+
121
193
  task :debug => :isolate do
122
- ENV["V"] ||= "23"
194
+ ENV["V"] ||= V1_2.last
123
195
  Rake.application[:parser].invoke # this way we can have DEBUG set
124
196
  Rake.application[:lexer].invoke # this way we can have DEBUG set
125
197
 
@@ -127,22 +199,9 @@ task :debug => :isolate do
127
199
  require "ruby_parser"
128
200
  require "pp"
129
201
 
130
- parser = case ENV["V"]
131
- when "18" then
132
- Ruby18Parser.new
133
- when "19" then
134
- Ruby19Parser.new
135
- when "20" then
136
- Ruby20Parser.new
137
- when "21" then
138
- Ruby21Parser.new
139
- when "22" then
140
- Ruby22Parser.new
141
- when "23" then
142
- Ruby23Parser.new
143
- else
144
- raise "Unsupported version #{ENV["V"]}"
145
- end
202
+ klass = Object.const_get("Ruby#{ENV["V"]}Parser") rescue nil
203
+ raise "Unsupported version #{ENV["V"]}" unless klass
204
+ parser = klass.new
146
205
 
147
206
  time = (ENV["RP_TIMEOUT"] || 10).to_i
148
207
 
@@ -173,7 +232,7 @@ task :debug_ruby do
173
232
  end
174
233
 
175
234
  task :extract => :isolate do
176
- ENV["V"] ||= "19"
235
+ ENV["V"] ||= V1_2.last
177
236
  Rake.application[:parser].invoke # this way we can have DEBUG set
178
237
 
179
238
  file = ENV["F"] || ENV["FILE"]
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+ good = false
4
+
5
+ rules = Hash.new { |h,k| h[k] = [] }
6
+ rule = nil
7
+ order = []
8
+
9
+ def munge s
10
+ renames = [
11
+ "'='", "tEQL",
12
+ "'!'", "tBANG",
13
+ "'%'", "tPERCENT",
14
+ "'&'", "tAMPER2",
15
+ "'('", "tLPAREN2",
16
+ "')'", "tRPAREN",
17
+ "'*'", "tSTAR2",
18
+ "'+'", "tPLUS",
19
+ "','", "tCOMMA",
20
+ "'-'", "tMINUS",
21
+ "'.'", "tDOT",
22
+ "'/'", "tDIVIDE",
23
+ "';'", "tSEMI",
24
+ "':'", "tCOLON",
25
+ "'<'", "tLT",
26
+ "'>'", "tGT",
27
+ "'?'", "tEH",
28
+ "'['", "tLBRACK",
29
+ "'\\n'", "tNL",
30
+ "']'", "tRBRACK",
31
+ "'^'", "tCARET",
32
+ "'`'", "tBACK_REF2",
33
+ "'{'", "tLCURLY",
34
+ "'|'", "tPIPE",
35
+ "'}'", "tRCURLY",
36
+ "'~'", "tTILDE",
37
+ '"["', "tLBRACK",
38
+
39
+ # 2.0 changes?
40
+ '"<=>"', "tCMP",
41
+ '"=="', "tEQ",
42
+ '"==="', "tEQQ",
43
+ '"!~"', "tNMATCH",
44
+ '"=~"', "tMATCH",
45
+ '">="', "tGEQ",
46
+ '"<="', "tLEQ",
47
+ '"!="', "tNEQ",
48
+ '"<<"', "tLSHFT",
49
+ '">>"', "tRSHFT",
50
+ '"*"', "tSTAR",
51
+
52
+ '".."', "tDOT2",
53
+
54
+ '"&"', "tAMPER",
55
+ '"&&"', "tANDOP",
56
+ '"||"', "tOROP",
57
+
58
+ '"..."', "tDOT3",
59
+ '"**"', "tPOW",
60
+ '"unary+"', "tUPLUS",
61
+ '"unary-"', "tUMINUS",
62
+ '"[]"', "tAREF",
63
+ '"[]="', "tASET",
64
+ '"::"', "tCOLON2",
65
+ '"{ arg"', "tLBRACE_ARG",
66
+ '"( arg"', "tLPAREN_ARG",
67
+ '"("', "tLPAREN",
68
+ 'rparen', "tRPAREN",
69
+ '"{"', "tLBRACE",
70
+ '"=>"', "tASSOC",
71
+ '"->"', "tLAMBDA",
72
+ '":: at EXPR_BEG"', "tCOLON3",
73
+ '"**arg"', "tDSTAR",
74
+ '","', "tCOMMA",
75
+
76
+ # other
77
+
78
+ 'tLBRACK2', "tLBRACK", # HACK
79
+
80
+ "' '", "tSPACE", # needs to be later to avoid bad hits
81
+
82
+ "/* empty */", "none",
83
+ /^\s*$/, "none",
84
+ "keyword_BEGIN", "klBEGIN",
85
+ "keyword_END", "klEND",
86
+ /keyword_(\w+)/, proc { "k#{$1.upcase}" },
87
+ /\bk_([a-z_]+)/, proc { "k#{$1.upcase}" },
88
+ /modifier_(\w+)/, proc { "k#{$1.upcase}_MOD" },
89
+ "kVARIABLE", "keyword_variable", # ugh
90
+
91
+ /@(\d+)\s+/, "",
92
+ ]
93
+
94
+ renames.each_slice(2) do |(a, b)|
95
+ if Proc === b then
96
+ s.gsub!(a, &b)
97
+ else
98
+ s.gsub!(a, b)
99
+ end
100
+ end
101
+
102
+ s.strip
103
+ end
104
+
105
+ ARGF.each_line do |line|
106
+ next unless good or line =~ /^-* ?Grammar|\$accept : /
107
+
108
+ case line.strip
109
+ when /^$/ then
110
+ when /^(\d+) (\$?\w+): (.*)/ then # yacc
111
+ rule = $2
112
+ order << rule unless rules.has_key? rule
113
+ rules[rule] << munge($3)
114
+ when /^(\d+) \s+\| (.*)/ then # yacc
115
+ rules[rule] << munge($2)
116
+ when /^(\d+) (@\d+): (.*)/ then # yacc
117
+ rule = $2
118
+ order << rule unless rules.has_key? rule
119
+ rules[rule] << munge($3)
120
+ when /^rule (\d+) (@?\w+):(.*)/ then # racc
121
+ rule = $2
122
+ order << rule unless rules.has_key? rule
123
+ rules[rule] << munge($3)
124
+ when /\$accept/ then # byacc?
125
+ good = true
126
+ when /Grammar/ then # both
127
+ good = true
128
+ when /^-+ Symbols/ then # racc
129
+ break
130
+ when /^Terminals/ then # yacc
131
+ break
132
+ when /^\cL/ then # byacc
133
+ break
134
+ else
135
+ warn "unparsed: #{$.}: #{line.chomp}"
136
+ end
137
+ end
138
+
139
+ require 'yaml'
140
+
141
+ order.each do |k|
142
+ next if k =~ /@/
143
+ puts
144
+ puts "#{k}:"
145
+ puts rules[k].map { |r| " #{r}" }.join "\n"
146
+ end