aniero-tire_swing 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/lib/tire_swing.rb +5 -2
- data/lib/tire_swing/error.rb +1 -1
- data/lib/tire_swing/node.rb +30 -21
- data/lib/tire_swing/parser_extension.rb +7 -1
- data/spec/error_spec.rb +8 -0
- data/spec/node_spec.rb +22 -10
- data/spec/parser_extension_spec.rb +1 -1
- data/tire_swing.gemspec +2 -2
- metadata +2 -2
data/History.txt
CHANGED
data/lib/tire_swing.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module TireSwing
|
2
2
|
|
3
3
|
# :stopdoc:
|
4
|
-
VERSION = "0.0.
|
4
|
+
VERSION = "0.0.6"
|
5
5
|
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
6
6
|
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
7
7
|
# :startdoc:
|
@@ -47,6 +47,9 @@ require "rubygems"
|
|
47
47
|
gem "extlib"
|
48
48
|
gem "attributes"
|
49
49
|
|
50
|
-
|
50
|
+
require "extlib/string"
|
51
|
+
require "extlib/inflection" unless "".respond_to?(:pluralize) # activesupport compatibility mode to prevent interference
|
52
|
+
|
53
|
+
%w(attributes treetop).each { |lib| require lib }
|
51
54
|
|
52
55
|
TireSwing.require_all_libs_relative_to __FILE__
|
data/lib/tire_swing/error.rb
CHANGED
data/lib/tire_swing/node.rb
CHANGED
@@ -15,12 +15,9 @@ module TireSwing
|
|
15
15
|
attribs.each do |attrib|
|
16
16
|
case attrib
|
17
17
|
when Symbol, String
|
18
|
-
|
18
|
+
add_mapping(attrib, attrib)
|
19
19
|
when Hash
|
20
|
-
attrib.each
|
21
|
-
attribute(name.to_s) { raise "no value given for #{name}" }
|
22
|
-
attribute_mapping[name.to_s] = symbol
|
23
|
-
end
|
20
|
+
attrib.each { |name, symbol| add_mapping(name, symbol) }
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
@@ -31,6 +28,12 @@ module TireSwing
|
|
31
28
|
@attribute_mapping ||= {}
|
32
29
|
end
|
33
30
|
|
31
|
+
def self.add_mapping(name, value)
|
32
|
+
attribute(name.to_s) { raise "no value given for #{name}" }
|
33
|
+
attribute_mapping[name.to_s] = value
|
34
|
+
end
|
35
|
+
|
36
|
+
# keep track of where this node lives in the tree
|
34
37
|
attr_accessor :parent
|
35
38
|
|
36
39
|
# Instantiate a node.
|
@@ -56,13 +59,9 @@ module TireSwing
|
|
56
59
|
protected
|
57
60
|
|
58
61
|
# Auto-builds this node using the provided parsed node and the defined attributes and mapped attributes.
|
59
|
-
def build_from_parsed_node(
|
62
|
+
def build_from_parsed_node(node)
|
60
63
|
attributes.each do |attrib|
|
61
|
-
|
62
|
-
value = apply_mapping(handler, parsed_node)
|
63
|
-
else
|
64
|
-
value = parsed_node.send(attrib)
|
65
|
-
end
|
64
|
+
value = apply_mapping(attrib, node)
|
66
65
|
|
67
66
|
value = if value.kind_of?(Array)
|
68
67
|
value.map { |val| extract_value(val) }
|
@@ -74,18 +73,28 @@ module TireSwing
|
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
77
|
-
def apply_mapping(
|
78
|
-
|
76
|
+
def apply_mapping(attrib, node)
|
77
|
+
handler = mapping_for(attrib)
|
78
|
+
|
79
79
|
if handler.kind_of?(Proc)
|
80
|
-
value = handler.call(
|
80
|
+
value = handler.call(node)
|
81
81
|
else
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
send_handler_method handler, node
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def send_handler_method(handler, node)
|
88
|
+
if node.respond_to?(handler)
|
89
|
+
value = node.send(handler)
|
90
|
+
else
|
91
|
+
value = node.text_value.send(handler)
|
88
92
|
end
|
93
|
+
rescue NoMethodError
|
94
|
+
context = node.text_value.split("\n")
|
95
|
+
context = context.size > 1 ? context.first + "..." : context
|
96
|
+
raise ParseError,
|
97
|
+
%Q{expected node containing "#{context}" or its text value to respond to #{handler.inspect}}
|
89
98
|
end
|
90
99
|
|
91
100
|
def extract_value(value)
|
@@ -104,7 +113,7 @@ module TireSwing
|
|
104
113
|
self.class.attributes
|
105
114
|
end
|
106
115
|
|
107
|
-
def
|
116
|
+
def mapping_for(name)
|
108
117
|
self.class.attribute_mapping[name]
|
109
118
|
end
|
110
119
|
|
@@ -29,7 +29,13 @@ module TireSwing
|
|
29
29
|
#
|
30
30
|
# You can specify an alternate module which contains the AST if desired.
|
31
31
|
def self.parses_grammar(grammar, ast=nil)
|
32
|
-
|
32
|
+
# use either extlib or activesupport, if that's loaded instead
|
33
|
+
parser = grammar.to_s + "Parser"
|
34
|
+
parser = if defined?(Extlib::Inflection)
|
35
|
+
Extlib::Inflection.constantize
|
36
|
+
else
|
37
|
+
parser.constantize
|
38
|
+
end
|
33
39
|
ast ||= grammar
|
34
40
|
parser.module_eval do
|
35
41
|
extend ParserExtension
|
data/spec/error_spec.rb
CHANGED
@@ -6,6 +6,14 @@ describe TireSwing::ParseError do
|
|
6
6
|
it "takes a message and a parser instance" do
|
7
7
|
TireSwing::ParseError.new("message", "parser").should be_an_instance_of(TireSwing::ParseError)
|
8
8
|
end
|
9
|
+
|
10
|
+
it "does not require a parser instance" do
|
11
|
+
TireSwing::ParseError.new("message").message.should == "message"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "is a subclass of StandardError" do
|
16
|
+
TireSwing::ParseError.new("message", "parser").should be_a_kind_of(StandardError)
|
9
17
|
end
|
10
18
|
|
11
19
|
it "has a message" do
|
data/spec/node_spec.rb
CHANGED
@@ -48,11 +48,6 @@ describe TireSwing::Node do
|
|
48
48
|
n = @node.new
|
49
49
|
lambda { n.lhs }.should raise_error(RuntimeError, "no value given for lhs")
|
50
50
|
end
|
51
|
-
|
52
|
-
it "returns a class with an attribute mapping" do
|
53
|
-
@node.attribute_mapping.should == {"lhs" => :left_value, "rhs" => :right_value}
|
54
|
-
end
|
55
|
-
|
56
51
|
end
|
57
52
|
|
58
53
|
describe "with a mix of named attributes and hash attributes" do
|
@@ -63,11 +58,6 @@ describe TireSwing::Node do
|
|
63
58
|
it "creates a class with attributes matching the named attributes and hash keys" do
|
64
59
|
@node.attributes.should == %w(one two three)
|
65
60
|
end
|
66
|
-
|
67
|
-
it "updates the attribute mapping" do
|
68
|
-
@node.attribute_mapping.should == {"three" => :value}
|
69
|
-
end
|
70
|
-
|
71
61
|
end
|
72
62
|
|
73
63
|
end
|
@@ -153,6 +143,28 @@ describe TireSwing::Node do
|
|
153
143
|
end
|
154
144
|
end
|
155
145
|
|
146
|
+
describe "for a node lacking the required named attribute" do
|
147
|
+
it "raises a parse exception including the text value of the node" do
|
148
|
+
node = TireSwing::Node.create :foo
|
149
|
+
@top.should_receive(:foo).and_raise(NoMethodError.new("undefined method `foo'..."))
|
150
|
+
@top.stub!(:text_value).and_return("value")
|
151
|
+
lambda do
|
152
|
+
node.new(@top)
|
153
|
+
end.should raise_error(TireSwing::ParseError, /expected.*"value".*foo/)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "for a node lacking the defined method for a name/method mapping" do
|
158
|
+
it "raises an exception including the text value of the node" do
|
159
|
+
node = TireSwing::Node.create :foo => :bar
|
160
|
+
@top.should_receive(:bar).and_raise(NoMethodError.new("undefined method `bar'..."))
|
161
|
+
@top.stub!(:text_value).and_return("value")
|
162
|
+
lambda do
|
163
|
+
node.new(@top)
|
164
|
+
end.should raise_error(TireSwing::ParseError, /expected.*"value".*bar/)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
156
168
|
end
|
157
169
|
end
|
158
170
|
|
data/tire_swing.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{tire_swing}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.6"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Nathan Witmer"]
|
9
|
-
s.date = %q{2008-
|
9
|
+
s.date = %q{2008-12-05}
|
10
10
|
s.description = %q{Simple node and visitor definitions for Treetop grammars.}
|
11
11
|
s.email = %q{nwitmer at gmail dot com}
|
12
12
|
s.extra_rdoc_files = ["History.txt", "README.txt", "spec/fixtures/assignments.txt"]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aniero-tire_swing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Witmer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-12-05 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|