ParseTree 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|