ParseTree 1.3.2 → 1.3.3
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.
- data/History.txt +10 -0
- data/Makefile +1 -3
- data/bin/parse_tree_abc +11 -5
- data/lib/parse_tree.rb +35 -19
- data/lib/sexp_processor.rb +11 -4
- data/test/something.rb +15 -0
- data/test/test_parse_tree.rb +16 -0
- data/test/test_sexp_processor.rb +1 -1
- metadata +5 -4
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
*** 1.3.3 / 2005-02-01
|
2
|
+
|
3
|
+
+ 3 minor enhancement
|
4
|
+
+ Cleaned up parse_tree_abc output
|
5
|
+
+ Patched up null class names (delegate classes are weird!)
|
6
|
+
+ Added UnknownNodeError and switched SyntaxError over to it.
|
7
|
+
+ 2 bug fixes
|
8
|
+
+ Fixed BEGIN node handling to recurse instead of going flat.
|
9
|
+
+ FINALLY fixed the weird compiler errors seen on some versions of gcc 3.4.x related to type punned pointers.
|
10
|
+
|
1
11
|
*** 1.3.2 / 2005-01-04
|
2
12
|
|
3
13
|
+ 1 minor enhancement
|
data/Makefile
CHANGED
data/bin/parse_tree_abc
CHANGED
@@ -6,6 +6,8 @@
|
|
6
6
|
#
|
7
7
|
# A simple way to measure the complexity of a function or method.
|
8
8
|
|
9
|
+
PARSE_TREE_ABC=true
|
10
|
+
|
9
11
|
begin
|
10
12
|
require 'rubygems'
|
11
13
|
require_gem 'ParseTree'
|
@@ -21,7 +23,11 @@ ObjectSpace.each_object(Module) do |klass|
|
|
21
23
|
end
|
22
24
|
|
23
25
|
ARGV.each do |name|
|
24
|
-
|
26
|
+
begin
|
27
|
+
require name
|
28
|
+
rescue NameError => err
|
29
|
+
$stderr.puts "ERROR requiring #{name}. Perhaps you need to add some -I's?\n\n#{err}"
|
30
|
+
end
|
25
31
|
end
|
26
32
|
|
27
33
|
new_classes = []
|
@@ -60,12 +66,12 @@ klasses.each do |klass|
|
|
60
66
|
end
|
61
67
|
end
|
62
68
|
key = ["#{klassname}.#{methodname}", a, b, c]
|
63
|
-
val = a+b+c
|
69
|
+
val = Math.sqrt(a*a+b*b+c*c)
|
64
70
|
score[key] = val
|
65
71
|
end
|
66
72
|
end
|
67
73
|
|
68
|
-
puts "
|
74
|
+
puts "|ABC| = Math.sqrt(assignments^2 + branches^2 + calls^2)"
|
69
75
|
puts
|
70
76
|
count = 1
|
71
77
|
ta = tb = tc = tval = 0
|
@@ -75,7 +81,7 @@ score.sort_by { |k,v| v }.reverse.each do |key,val|
|
|
75
81
|
tb += b
|
76
82
|
tc += c
|
77
83
|
tval += val
|
78
|
-
printf "%3d) %-50s = %2d + %2d + %2d = %
|
84
|
+
printf "%3d) %-50s = %2d + %2d + %2d = %6.2f\n", count, name, a, b, c, val
|
79
85
|
count += 1
|
80
86
|
end
|
81
|
-
printf "%3d) %-50s = %2d + %2d + %2d = %
|
87
|
+
printf "%3d) %-50s = %2d + %2d + %2d = %6.2f\n", count, "Total", ta, tb, tc, tval
|
data/lib/parse_tree.rb
CHANGED
@@ -18,16 +18,17 @@ end
|
|
18
18
|
# end
|
19
19
|
#
|
20
20
|
# ParseTree.new.parse_tree(Example)
|
21
|
-
# =>
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
21
|
+
# => [[:class, :Example, :Object,
|
22
|
+
# [:defn,
|
23
|
+
# "blah",
|
24
|
+
# [:scope,
|
25
|
+
# [:block,
|
26
|
+
# [:args],
|
27
|
+
# [:return, [:call, [:lit, 1], "+", [:array, [:lit, 1]]]]]]]]]
|
27
28
|
|
28
29
|
class ParseTree
|
29
30
|
|
30
|
-
VERSION = '1.3.
|
31
|
+
VERSION = '1.3.3'
|
31
32
|
|
32
33
|
##
|
33
34
|
# Initializes a ParseTree instance. Includes newline nodes if
|
@@ -53,8 +54,11 @@ class ParseTree
|
|
53
54
|
def parse_tree(*klasses)
|
54
55
|
result = []
|
55
56
|
klasses.each do |klass|
|
57
|
+
# TODO: remove this on v 1.1
|
56
58
|
raise "You should call parse_tree_for_method(#{klasses.first}, #{klass}) instead of parse_tree" if Symbol === klass or String === klass
|
57
|
-
klassname = klass.name
|
59
|
+
klassname = klass.name || '' # HACK klass.name should never be nil
|
60
|
+
# Tempfile's DelegateClass(File) seems to
|
61
|
+
# cause this
|
58
62
|
klassname = "UnnamedClass_#{klass.object_id}" if klassname.empty?
|
59
63
|
klassname = klassname.to_sym
|
60
64
|
|
@@ -87,6 +91,10 @@ class ParseTree
|
|
87
91
|
parse_tree_for_meth(klass, method.to_sym, @include_newlines)
|
88
92
|
end
|
89
93
|
|
94
|
+
############################################################
|
95
|
+
# END of rdoc methods
|
96
|
+
############################################################
|
97
|
+
|
90
98
|
inline do |builder|
|
91
99
|
builder.add_type_converter("VALUE", '', '')
|
92
100
|
builder.add_type_converter("ID *", '', '')
|
@@ -102,6 +110,12 @@ class ParseTree
|
|
102
110
|
builder.add_compile_flags "-Wcast-align"
|
103
111
|
builder.add_compile_flags "-Wwrite-strings"
|
104
112
|
builder.add_compile_flags "-Wmissing-noreturn"
|
113
|
+
# NOTE: If you get weird compiler errors like:
|
114
|
+
# dereferencing type-punned pointer will break strict-aliasing rules
|
115
|
+
# PLEASE do one of the following:
|
116
|
+
# 1) Get me a login on your box so I can repro this and get it fixed.
|
117
|
+
# 2) Fix it and send me the patch
|
118
|
+
# 3) (quick, but dirty and bad), comment out the following line:
|
105
119
|
builder.add_compile_flags "-Werror"
|
106
120
|
# NOTE: this flag doesn't work w/ gcc 2.95.x - the FreeBSD default
|
107
121
|
# builder.add_compile_flags "-Wno-strict-aliasing"
|
@@ -110,7 +124,7 @@ class ParseTree
|
|
110
124
|
# builder.add_compile_flags "-Wconversion"
|
111
125
|
# builder.add_compile_flags "-Wstrict-prototypes"
|
112
126
|
# builder.add_compile_flags "-Wmissing-prototypes"
|
113
|
-
# builder.add_compile_flags "-Wsign-compare"
|
127
|
+
# builder.add_compile_flags "-Wsign-compare"
|
114
128
|
|
115
129
|
builder.prefix %q{
|
116
130
|
#define nd_3rd u3.node
|
@@ -246,17 +260,15 @@ again_no_block:
|
|
246
260
|
rb_ary_push(current, ID2SYM(node->nd_mid));
|
247
261
|
break;
|
248
262
|
|
249
|
-
case NODE_BEGIN:
|
250
|
-
node = node->nd_body;
|
251
|
-
goto again;
|
252
|
-
|
253
263
|
case NODE_MATCH2:
|
254
264
|
case NODE_MATCH3:
|
255
265
|
add_to_parse_tree(current, node->nd_recv, newlines, locals);
|
256
266
|
add_to_parse_tree(current, node->nd_value, newlines, locals);
|
257
267
|
break;
|
258
268
|
|
269
|
+
case NODE_BEGIN:
|
259
270
|
case NODE_OPT_N:
|
271
|
+
case NODE_NOT:
|
260
272
|
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
261
273
|
break;
|
262
274
|
|
@@ -333,9 +345,15 @@ again_no_block:
|
|
333
345
|
case NODE_RESCUE:
|
334
346
|
add_to_parse_tree(current, node->nd_1st, newlines, locals);
|
335
347
|
add_to_parse_tree(current, node->nd_2nd, newlines, locals);
|
348
|
+
add_to_parse_tree(current, node->nd_3rd, newlines, locals);
|
336
349
|
break;
|
337
350
|
|
338
|
-
|
351
|
+
// rescue body:
|
352
|
+
// begin stmt rescue exception => var; stmt; [rescue e2 => v2; s2;]* end
|
353
|
+
// stmt rescue stmt
|
354
|
+
// a = b rescue c
|
355
|
+
|
356
|
+
case NODE_RESBODY:
|
339
357
|
add_to_parse_tree(current, node->nd_3rd, newlines, locals);
|
340
358
|
add_to_parse_tree(current, node->nd_2nd, newlines, locals);
|
341
359
|
add_to_parse_tree(current, node->nd_1st, newlines, locals);
|
@@ -354,10 +372,6 @@ again_no_block:
|
|
354
372
|
add_to_parse_tree(current, node->nd_2nd, newlines, locals);
|
355
373
|
break;
|
356
374
|
|
357
|
-
case NODE_NOT:
|
358
|
-
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
359
|
-
break;
|
360
|
-
|
361
375
|
case NODE_DOT2:
|
362
376
|
case NODE_DOT3:
|
363
377
|
case NODE_FLIP2:
|
@@ -706,6 +720,7 @@ again_no_block:
|
|
706
720
|
|
707
721
|
builder.c %q{
|
708
722
|
static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE newlines) {
|
723
|
+
VALUE n;
|
709
724
|
NODE *node = NULL;
|
710
725
|
ID id;
|
711
726
|
VALUE result = rb_ary_new();
|
@@ -714,7 +729,8 @@ static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE newlines) {
|
|
714
729
|
(void) argc; // quell warnings
|
715
730
|
|
716
731
|
id = rb_to_id(method);
|
717
|
-
if (st_lookup(RCLASS(klass)->m_tbl, id,
|
732
|
+
if (st_lookup(RCLASS(klass)->m_tbl, id, &n)) {
|
733
|
+
node = (NODE*)n;
|
718
734
|
rb_ary_push(result, ID2SYM(rb_intern("defn")));
|
719
735
|
rb_ary_push(result, ID2SYM(id));
|
720
736
|
add_to_parse_tree(result, node->nd_body, newlines, NULL);
|
data/lib/sexp_processor.rb
CHANGED
@@ -198,6 +198,12 @@ end
|
|
198
198
|
|
199
199
|
class UnsupportedNodeError < SyntaxError; end
|
200
200
|
|
201
|
+
##
|
202
|
+
# Raised by SexpProcessor if it is in strict mode and sees a node for
|
203
|
+
# which there is no processor available.
|
204
|
+
|
205
|
+
class UnknownNodeError < SyntaxError; end
|
206
|
+
|
201
207
|
##
|
202
208
|
# Raised by SexpProcessor if a processor did not process every node in
|
203
209
|
# a sexp and @require_empty is true.
|
@@ -346,7 +352,7 @@ class SexpProcessor
|
|
346
352
|
end
|
347
353
|
end
|
348
354
|
|
349
|
-
raise UnsupportedNodeError, "'#{type}' is not a supported node type
|
355
|
+
raise UnsupportedNodeError, "'#{type}' is not a supported node type" if @unsupported.include? type
|
350
356
|
|
351
357
|
# do a pass through the rewriter first, if any, reassign back to exp
|
352
358
|
meth = @rewriters[type]
|
@@ -407,7 +413,7 @@ class SexpProcessor
|
|
407
413
|
# nothing to do, on purpose
|
408
414
|
end
|
409
415
|
else
|
410
|
-
raise
|
416
|
+
raise UnknownNodeError, "Bug! Unknown type #{type.inspect} to #{self.class}"
|
411
417
|
end
|
412
418
|
end
|
413
419
|
result
|
@@ -432,8 +438,9 @@ class SexpProcessor
|
|
432
438
|
#
|
433
439
|
# Bogus Example:
|
434
440
|
#
|
435
|
-
#
|
436
|
-
#
|
441
|
+
# def process_something(exp)
|
442
|
+
# return s(:dummy, process(exp), s(:extra, 42))
|
443
|
+
# end
|
437
444
|
|
438
445
|
def process_dummy(exp)
|
439
446
|
result = @expected.new(:dummy)
|
data/test/something.rb
CHANGED
@@ -164,6 +164,21 @@ class Something
|
|
164
164
|
self.type = other.type
|
165
165
|
end
|
166
166
|
|
167
|
+
# TODO: sort list
|
168
|
+
def bbegin
|
169
|
+
begin
|
170
|
+
1
|
171
|
+
rescue SyntaxError => e1
|
172
|
+
2
|
173
|
+
rescue Exception => e2
|
174
|
+
3
|
175
|
+
else
|
176
|
+
4
|
177
|
+
ensure
|
178
|
+
5
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
167
182
|
def self.bmethod_maker
|
168
183
|
define_method(:bmethod_added) do |x|
|
169
184
|
x + 1
|
data/test/test_parse_tree.rb
CHANGED
@@ -234,6 +234,22 @@ class TestParseTree < Test::Unit::TestCase
|
|
234
234
|
[:block,
|
235
235
|
[:args, :arg1, :arg2],
|
236
236
|
[:return, [:lvar, :arg1]]]]]
|
237
|
+
@@bbegin = [:defn, :bbegin,
|
238
|
+
[:scope,
|
239
|
+
[:block,
|
240
|
+
[:args],
|
241
|
+
[:begin,
|
242
|
+
[:ensure,
|
243
|
+
[:rescue,
|
244
|
+
[:lit, 1],
|
245
|
+
[:resbody,
|
246
|
+
[:array, [:const, :SyntaxError]],
|
247
|
+
[:block, [:lasgn, :e1, [:gvar, :$!]], [:lit, 2]],
|
248
|
+
[:resbody,
|
249
|
+
[:array, [:const, :Exception]],
|
250
|
+
[:block, [:lasgn, :e2, [:gvar, :$!]], [:lit, 3]]]],
|
251
|
+
[:lit, 4]],
|
252
|
+
[:lit, 5]]]]]]
|
237
253
|
@@determine_args = [:defn, :determine_args,
|
238
254
|
[:scope,
|
239
255
|
[:block,
|
data/test/test_sexp_processor.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.4
|
3
3
|
specification_version: 1
|
4
4
|
name: ParseTree
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.3.
|
7
|
-
date: 2005-01
|
6
|
+
version: 1.3.3
|
7
|
+
date: 2005-02-01
|
8
8
|
summary: Extract and enumerate ruby parse trees.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
- test
|
12
|
-
author: Ryan Davis
|
13
12
|
email: ryand-ruby@zenspider.com
|
14
13
|
homepage: http://www.zenspider.com/ZSS/Products/ParseTree/
|
15
14
|
rubyforge_project: parsetree
|
@@ -28,6 +27,8 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
28
27
|
version: 0.0.0
|
29
28
|
version:
|
30
29
|
platform: ruby
|
30
|
+
authors:
|
31
|
+
- Ryan Davis
|
31
32
|
files:
|
32
33
|
- History.txt
|
33
34
|
- Makefile
|