ruby_parser 3.8.4 → 3.9.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 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