onion 0.1.1 → 0.1.2
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/{README.rdoc → License.txt} +2 -19
- data/README.txt +34 -0
- data/lib/onion.rb +2 -2
- data/lib/onion/control_client.rb +87 -0
- data/lib/onion/elements.rb +4 -0
- data/lib/onion/elements/circuit.rb +11 -0
- data/lib/onion/elements/circuit_list.rb +18 -0
- data/lib/onion/elements/router.rb +3 -3
- data/lib/onion/elements/router_list.rb +4 -6
- data/lib/onion/elements/stream.rb +12 -0
- data/lib/onion/elements/stream_list.rb +20 -0
- data/lib/onion/parsers/circuit_lists.rb +491 -0
- data/lib/onion/parsers/circuit_lists.treetop +53 -0
- data/lib/onion/parsers/common.rb +1692 -0
- data/lib/onion/parsers/common.treetop +127 -0
- data/lib/onion/parsers/router_statuses.rb +1035 -0
- data/lib/onion/parsers/router_statuses.treetop +111 -0
- data/lib/onion/parsers/stream_lists.rb +356 -0
- data/lib/onion/parsers/stream_lists.treetop +32 -0
- data/lib/tasks/treetop.rake +1 -1
- metadata +18 -5
- data/lib/onion/parsers/router_lists.treetop +0 -133
data/{README.rdoc → License.txt}
RENAMED
@@ -1,22 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
== Introduction
|
4
|
-
|
5
|
-
Onion is a library for interacting with Tor. Onion is in an alpha state and is
|
6
|
-
made availible for early adopters and contributors only.
|
7
|
-
|
8
|
-
== Functionality
|
9
|
-
|
10
|
-
* Parse router status entries per the directory protocol version 2.0.
|
11
|
-
|
12
|
-
== Authors
|
13
|
-
|
14
|
-
Onion was written by Tim Sally <poet@stack.io>. Please send bug reports and
|
15
|
-
suggestions to the author.
|
16
|
-
|
17
|
-
== License
|
18
|
-
|
19
|
-
(The MIT License)
|
1
|
+
LICENSE.txt
|
2
|
+
===========
|
20
3
|
|
21
4
|
Copyright (c) 2010 Tim Sally
|
22
5
|
|
data/README.txt
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
README.txt
|
2
|
+
==========
|
3
|
+
|
4
|
+
Introduction
|
5
|
+
------------
|
6
|
+
|
7
|
+
Onion is a library for interacting with Tor. Onion is in an alpha state and is
|
8
|
+
made available for early adopters and contributors only.
|
9
|
+
|
10
|
+
Basic Concepts
|
11
|
+
--------------
|
12
|
+
|
13
|
+
Elements are pieces of the Tor network. Routers, circuits, and streams are
|
14
|
+
examples of elements. You don't care about how the library gets these, you
|
15
|
+
just want to be able to interact with them. Methods in the Control Client
|
16
|
+
return elements.
|
17
|
+
|
18
|
+
Parsers take information received from Tor and turn the information into
|
19
|
+
elements. Parsers are used internally by the Control Client to create elements
|
20
|
+
to return to the user.
|
21
|
+
|
22
|
+
The Control Client is what you can use in scripts to interact with Tor.
|
23
|
+
|
24
|
+
Authors
|
25
|
+
-------
|
26
|
+
|
27
|
+
Onion was written by Tim Sally <poet@stack.io>. Please send bug reports and
|
28
|
+
suggestions to the author.
|
29
|
+
|
30
|
+
License
|
31
|
+
-------
|
32
|
+
|
33
|
+
Copyright (c) 2010 Tim Sally and provided under the MIT License. Please see
|
34
|
+
LICENSE.txt for details.
|
data/lib/onion.rb
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
module Onion
|
5
|
+
# Onion::ControlClient is a client to the Tor Control Protocol.
|
6
|
+
class ControlClient
|
7
|
+
attr_reader :host, :port
|
8
|
+
|
9
|
+
def initialize(host="127.0.0.1", port=9051, log_level=Logger::ERROR)
|
10
|
+
@log = Logger.new(STDOUT)
|
11
|
+
@log.level = log_level
|
12
|
+
|
13
|
+
@host = host # Host of the Tor process.
|
14
|
+
@port = port # Port accepting the Tor Control Protocol.
|
15
|
+
@sock = TCPSocket.new(host, port)
|
16
|
+
|
17
|
+
@log.info("[TOR CONTROL CLIENT ] Connected to #{host}:#{port}.")
|
18
|
+
end
|
19
|
+
|
20
|
+
def send(text)
|
21
|
+
@sock << "#{text}\r\n"
|
22
|
+
@log.debug("[TOR CONTROL CLIENT] #{text}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def authenticate(pass="\"\"")
|
26
|
+
send("authenticate #{pass}")
|
27
|
+
@log.debug("[TOR CONTROL CLIENT] #{@sock.gets}")
|
28
|
+
end
|
29
|
+
|
30
|
+
def extend_circuit(specs, id=0)
|
31
|
+
send("extendcircuit #{id} #{specs.join(",")}")
|
32
|
+
response = @sock.gets
|
33
|
+
if response.split[1] == "EXTENDED"
|
34
|
+
@log.debug("[TOR CONTROL CLIENT] #{response}")
|
35
|
+
return response.split[2]
|
36
|
+
else
|
37
|
+
@log.warn("[TOR CONTROL CLIENT] Circuit (#{specs.join(",")}) was not extended.")
|
38
|
+
@log.warn("[TOR CONTROL CLIENT] #{response}.")
|
39
|
+
|
40
|
+
return -1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def attach_stream(stream_id, circuit_id)
|
45
|
+
send("attachstream #{stream_id} #{circuit_id}")
|
46
|
+
response = @sock.gets
|
47
|
+
if response.split[1] == "OK"
|
48
|
+
@log.info("[TOR CONTROL CLIENT] #{response}")
|
49
|
+
else
|
50
|
+
@log.warn("[TOR CONTROL CLIENT] Stream #{stream_id} was not attached to circuit #{circuit_id}.")
|
51
|
+
@log.warn("[TOR CONTROL CLIENT] #{response}.")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def router_status_info(nicknames=nil,fingerprints=nil)
|
56
|
+
statuses = ""
|
57
|
+
|
58
|
+
p "start!"
|
59
|
+
|
60
|
+
if nicknames
|
61
|
+
nicknames.each do |name|
|
62
|
+
send("getinfo ns/name/#{name}")
|
63
|
+
statuses << @sock.gets
|
64
|
+
end
|
65
|
+
while not @sock.eof?
|
66
|
+
statuses << @sock.gets
|
67
|
+
end
|
68
|
+
end
|
69
|
+
p "done!"
|
70
|
+
Onion::RouterList.new(statuses)
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_stream_status
|
74
|
+
send("getinfo stream-status")
|
75
|
+
result = []
|
76
|
+
line = @sock.gets
|
77
|
+
while line != "250 OK\r\n"
|
78
|
+
unless line == "250+stream-status=\r\n" or line == ".\r\n"
|
79
|
+
line = line.gsub("250-stream-status=", "")
|
80
|
+
result << line
|
81
|
+
end
|
82
|
+
line = @sock.gets
|
83
|
+
end
|
84
|
+
return result
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/onion/elements.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
module Onion
|
2
|
+
autoload :Circuit, 'onion/elements/circuit'
|
3
|
+
autoload :CircuitList, 'onion/elements/circuit_list'
|
2
4
|
autoload :Router, 'onion/elements/router'
|
3
5
|
autoload :RouterList, 'onion/elements/router_list'
|
6
|
+
autoload :Stream, 'onion/elements/stream'
|
7
|
+
autoload :StreamList, 'onion/elements/stream_list'
|
4
8
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Onion
|
2
|
+
# Onion::CircuitList is a list of Onion::Circuit objects.
|
3
|
+
class CircuitList
|
4
|
+
attr_reader :circuits
|
5
|
+
def initialize(text)
|
6
|
+
if text.blank?
|
7
|
+
@circuits = []
|
8
|
+
return self
|
9
|
+
end
|
10
|
+
parser = Onion::CircuitListsParser.new
|
11
|
+
if nodes = parser.parse(text)
|
12
|
+
@circuits = nodes.circuits
|
13
|
+
else
|
14
|
+
raise Exception, "Couldn't parse #{text} b/c #{parser.failure_reason}."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Onion
|
2
2
|
# Onion::Router is a Ruby object representing a Tor router.
|
3
3
|
class Router
|
4
|
-
attr_reader :nick, :
|
5
|
-
def initialize(nick,
|
4
|
+
attr_reader :nick, :fingerprint, :status_flags
|
5
|
+
def initialize(nick, fingerprint, status_flags)
|
6
6
|
@nick = nick # Nickname of the router.
|
7
|
-
@
|
7
|
+
@fingerprint = fingerprint # Fingerprint of the router.
|
8
8
|
@status_flags = status_flags # Array of strings with status flags.
|
9
9
|
end
|
10
10
|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module Onion
|
2
|
-
# Onion::RouterList is a list of Onion::Router objects.
|
3
|
-
# the text given is parsed with Onion::RouterListParser. The text should be
|
4
|
-
# in the router status format specified by the directory protocol 2.0 spec.
|
2
|
+
# Onion::RouterList is a list of Onion::Router objects.
|
5
3
|
class RouterList
|
6
4
|
attr_reader :routers
|
7
5
|
def initialize(text)
|
@@ -9,11 +7,11 @@ module Onion
|
|
9
7
|
@routers = []
|
10
8
|
return self
|
11
9
|
end
|
12
|
-
parser = Onion::
|
10
|
+
parser = Onion::RouterStatusesParser.new
|
13
11
|
if nodes = parser.parse(text)
|
14
12
|
@routers = nodes.routers
|
15
13
|
else
|
16
|
-
raise Exception "Couldn't parse #{text} b/c #{parser.failure_reason}."
|
14
|
+
raise Exception, "Couldn't parse #{text} b/c #{parser.failure_reason}."
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
@@ -29,7 +27,7 @@ module Onion
|
|
29
27
|
|
30
28
|
# Returns the routers that are neither guard or exit routers.
|
31
29
|
def middlemen
|
32
|
-
@routers.
|
30
|
+
@routers.reject { |r| r.guard? or r.exit? }
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Onion
|
2
|
+
# Onion::StreamList is a list of Onion::Stream objects.
|
3
|
+
class StreamList
|
4
|
+
attr_reader :streams
|
5
|
+
def initialize(text)
|
6
|
+
if text.blank?
|
7
|
+
@streams = []
|
8
|
+
return self
|
9
|
+
end
|
10
|
+
|
11
|
+
parser = Onion::StreamListsParser.new
|
12
|
+
if nodes = parser.parse(text)
|
13
|
+
@streams = nodes.streams
|
14
|
+
else
|
15
|
+
raise Exception, "Couldn't parse #{text} b/c #{parser.failure_reason}."
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,491 @@
|
|
1
|
+
# Autogenerated from a Treetop grammar. Edits may be lost.
|
2
|
+
|
3
|
+
|
4
|
+
module Onion
|
5
|
+
module CircuitLists
|
6
|
+
include Treetop::Runtime
|
7
|
+
|
8
|
+
def root
|
9
|
+
@root ||= :circuit_list
|
10
|
+
end
|
11
|
+
|
12
|
+
include Common
|
13
|
+
|
14
|
+
module CircuitList0
|
15
|
+
def circuits
|
16
|
+
circuits = []
|
17
|
+
self.elements.each do |circuit|
|
18
|
+
if circuit.respond_to? :p
|
19
|
+
to_process = [circuit.p.first]
|
20
|
+
counter = 1
|
21
|
+
circuit.p.rest.elements.each do |e|
|
22
|
+
to_process << e.LongName
|
23
|
+
end
|
24
|
+
routers = []
|
25
|
+
to_process.each do |router|
|
26
|
+
if router.respond_to? :n
|
27
|
+
routers << Router.new(router.n.text_value.strip, router.f.text_value.strip, nil)
|
28
|
+
else
|
29
|
+
routers << Router.new(nil, nil, nil)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
circuits << Circuit.new(circuit.id.text_value.strip, routers)
|
33
|
+
else
|
34
|
+
circuits << Circuit.new(circuit.id.text_value.strip, [])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return circuits
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def _nt_circuit_list
|
42
|
+
start_index = index
|
43
|
+
if node_cache[:circuit_list].has_key?(index)
|
44
|
+
cached = node_cache[:circuit_list][index]
|
45
|
+
if cached
|
46
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
47
|
+
@index = cached.interval.end
|
48
|
+
end
|
49
|
+
return cached
|
50
|
+
end
|
51
|
+
|
52
|
+
s0, i0 = [], index
|
53
|
+
loop do
|
54
|
+
r1 = _nt_circuit_list_entry
|
55
|
+
if r1
|
56
|
+
s0 << r1
|
57
|
+
else
|
58
|
+
break
|
59
|
+
end
|
60
|
+
end
|
61
|
+
if s0.empty?
|
62
|
+
@index = i0
|
63
|
+
r0 = nil
|
64
|
+
else
|
65
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
66
|
+
r0.extend(CircuitList0)
|
67
|
+
end
|
68
|
+
|
69
|
+
node_cache[:circuit_list][start_index] = r0
|
70
|
+
|
71
|
+
r0
|
72
|
+
end
|
73
|
+
|
74
|
+
module CircuitListEntry0
|
75
|
+
def id
|
76
|
+
elements[0]
|
77
|
+
end
|
78
|
+
|
79
|
+
def SP1
|
80
|
+
elements[1]
|
81
|
+
end
|
82
|
+
|
83
|
+
def s
|
84
|
+
elements[2]
|
85
|
+
end
|
86
|
+
|
87
|
+
def SP2
|
88
|
+
elements[3]
|
89
|
+
end
|
90
|
+
|
91
|
+
def p
|
92
|
+
elements[4]
|
93
|
+
end
|
94
|
+
|
95
|
+
def SP3
|
96
|
+
elements[5]
|
97
|
+
end
|
98
|
+
|
99
|
+
def purp
|
100
|
+
elements[7]
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
module CircuitListEntry1
|
106
|
+
def id
|
107
|
+
elements[0]
|
108
|
+
end
|
109
|
+
|
110
|
+
def SP1
|
111
|
+
elements[1]
|
112
|
+
end
|
113
|
+
|
114
|
+
def s
|
115
|
+
elements[2]
|
116
|
+
end
|
117
|
+
|
118
|
+
def SP2
|
119
|
+
elements[3]
|
120
|
+
end
|
121
|
+
|
122
|
+
def p
|
123
|
+
elements[4]
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
module CircuitListEntry2
|
129
|
+
def id
|
130
|
+
elements[0]
|
131
|
+
end
|
132
|
+
|
133
|
+
def SP
|
134
|
+
elements[1]
|
135
|
+
end
|
136
|
+
|
137
|
+
def s
|
138
|
+
elements[2]
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
def _nt_circuit_list_entry
|
144
|
+
start_index = index
|
145
|
+
if node_cache[:circuit_list_entry].has_key?(index)
|
146
|
+
cached = node_cache[:circuit_list_entry][index]
|
147
|
+
if cached
|
148
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
149
|
+
@index = cached.interval.end
|
150
|
+
end
|
151
|
+
return cached
|
152
|
+
end
|
153
|
+
|
154
|
+
i0 = index
|
155
|
+
i1, s1 = index, []
|
156
|
+
r2 = _nt_CircuitID
|
157
|
+
s1 << r2
|
158
|
+
if r2
|
159
|
+
r3 = _nt_SP
|
160
|
+
s1 << r3
|
161
|
+
if r3
|
162
|
+
r4 = _nt_CircStatus
|
163
|
+
s1 << r4
|
164
|
+
if r4
|
165
|
+
r5 = _nt_SP
|
166
|
+
s1 << r5
|
167
|
+
if r5
|
168
|
+
r6 = _nt_Path
|
169
|
+
s1 << r6
|
170
|
+
if r6
|
171
|
+
r7 = _nt_SP
|
172
|
+
s1 << r7
|
173
|
+
if r7
|
174
|
+
if has_terminal?("PURPOSE=", false, index)
|
175
|
+
r8 = instantiate_node(SyntaxNode,input, index...(index + 8))
|
176
|
+
@index += 8
|
177
|
+
else
|
178
|
+
terminal_parse_failure("PURPOSE=")
|
179
|
+
r8 = nil
|
180
|
+
end
|
181
|
+
s1 << r8
|
182
|
+
if r8
|
183
|
+
r9 = _nt_Purpose
|
184
|
+
s1 << r9
|
185
|
+
if r9
|
186
|
+
if has_terminal?("\n", false, index)
|
187
|
+
r10 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
188
|
+
@index += 1
|
189
|
+
else
|
190
|
+
terminal_parse_failure("\n")
|
191
|
+
r10 = nil
|
192
|
+
end
|
193
|
+
s1 << r10
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
if s1.last
|
203
|
+
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
|
204
|
+
r1.extend(CircuitListEntry0)
|
205
|
+
else
|
206
|
+
@index = i1
|
207
|
+
r1 = nil
|
208
|
+
end
|
209
|
+
if r1
|
210
|
+
r0 = r1
|
211
|
+
else
|
212
|
+
i11, s11 = index, []
|
213
|
+
r12 = _nt_CircuitID
|
214
|
+
s11 << r12
|
215
|
+
if r12
|
216
|
+
r13 = _nt_SP
|
217
|
+
s11 << r13
|
218
|
+
if r13
|
219
|
+
r14 = _nt_CircStatus
|
220
|
+
s11 << r14
|
221
|
+
if r14
|
222
|
+
r15 = _nt_SP
|
223
|
+
s11 << r15
|
224
|
+
if r15
|
225
|
+
r16 = _nt_Path
|
226
|
+
s11 << r16
|
227
|
+
if r16
|
228
|
+
if has_terminal?("\n", false, index)
|
229
|
+
r17 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
230
|
+
@index += 1
|
231
|
+
else
|
232
|
+
terminal_parse_failure("\n")
|
233
|
+
r17 = nil
|
234
|
+
end
|
235
|
+
s11 << r17
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
if s11.last
|
242
|
+
r11 = instantiate_node(SyntaxNode,input, i11...index, s11)
|
243
|
+
r11.extend(CircuitListEntry1)
|
244
|
+
else
|
245
|
+
@index = i11
|
246
|
+
r11 = nil
|
247
|
+
end
|
248
|
+
if r11
|
249
|
+
r0 = r11
|
250
|
+
else
|
251
|
+
i18, s18 = index, []
|
252
|
+
r19 = _nt_CircuitID
|
253
|
+
s18 << r19
|
254
|
+
if r19
|
255
|
+
r20 = _nt_SP
|
256
|
+
s18 << r20
|
257
|
+
if r20
|
258
|
+
r21 = _nt_CircStatus
|
259
|
+
s18 << r21
|
260
|
+
if r21
|
261
|
+
if has_terminal?("\n", false, index)
|
262
|
+
r22 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
263
|
+
@index += 1
|
264
|
+
else
|
265
|
+
terminal_parse_failure("\n")
|
266
|
+
r22 = nil
|
267
|
+
end
|
268
|
+
s18 << r22
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
if s18.last
|
273
|
+
r18 = instantiate_node(SyntaxNode,input, i18...index, s18)
|
274
|
+
r18.extend(CircuitListEntry2)
|
275
|
+
else
|
276
|
+
@index = i18
|
277
|
+
r18 = nil
|
278
|
+
end
|
279
|
+
if r18
|
280
|
+
r0 = r18
|
281
|
+
else
|
282
|
+
@index = i0
|
283
|
+
r0 = nil
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
node_cache[:circuit_list_entry][start_index] = r0
|
289
|
+
|
290
|
+
r0
|
291
|
+
end
|
292
|
+
|
293
|
+
module Path0
|
294
|
+
def LongName
|
295
|
+
elements[1]
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
module Path1
|
300
|
+
def first
|
301
|
+
elements[0]
|
302
|
+
end
|
303
|
+
|
304
|
+
def rest
|
305
|
+
elements[1]
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def _nt_Path
|
310
|
+
start_index = index
|
311
|
+
if node_cache[:Path].has_key?(index)
|
312
|
+
cached = node_cache[:Path][index]
|
313
|
+
if cached
|
314
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
315
|
+
@index = cached.interval.end
|
316
|
+
end
|
317
|
+
return cached
|
318
|
+
end
|
319
|
+
|
320
|
+
i0, s0 = index, []
|
321
|
+
r1 = _nt_LongName
|
322
|
+
s0 << r1
|
323
|
+
if r1
|
324
|
+
s2, i2 = [], index
|
325
|
+
loop do
|
326
|
+
i3, s3 = index, []
|
327
|
+
if has_terminal?(",", false, index)
|
328
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
329
|
+
@index += 1
|
330
|
+
else
|
331
|
+
terminal_parse_failure(",")
|
332
|
+
r4 = nil
|
333
|
+
end
|
334
|
+
s3 << r4
|
335
|
+
if r4
|
336
|
+
r5 = _nt_LongName
|
337
|
+
s3 << r5
|
338
|
+
end
|
339
|
+
if s3.last
|
340
|
+
r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
|
341
|
+
r3.extend(Path0)
|
342
|
+
else
|
343
|
+
@index = i3
|
344
|
+
r3 = nil
|
345
|
+
end
|
346
|
+
if r3
|
347
|
+
s2 << r3
|
348
|
+
else
|
349
|
+
break
|
350
|
+
end
|
351
|
+
end
|
352
|
+
r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
|
353
|
+
s0 << r2
|
354
|
+
end
|
355
|
+
if s0.last
|
356
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
357
|
+
r0.extend(Path1)
|
358
|
+
else
|
359
|
+
@index = i0
|
360
|
+
r0 = nil
|
361
|
+
end
|
362
|
+
|
363
|
+
node_cache[:Path][start_index] = r0
|
364
|
+
|
365
|
+
r0
|
366
|
+
end
|
367
|
+
|
368
|
+
def _nt_CircStatus
|
369
|
+
start_index = index
|
370
|
+
if node_cache[:CircStatus].has_key?(index)
|
371
|
+
cached = node_cache[:CircStatus][index]
|
372
|
+
if cached
|
373
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
374
|
+
@index = cached.interval.end
|
375
|
+
end
|
376
|
+
return cached
|
377
|
+
end
|
378
|
+
|
379
|
+
i0 = index
|
380
|
+
if has_terminal?("LAUNCHED", false, index)
|
381
|
+
r1 = instantiate_node(SyntaxNode,input, index...(index + 8))
|
382
|
+
@index += 8
|
383
|
+
else
|
384
|
+
terminal_parse_failure("LAUNCHED")
|
385
|
+
r1 = nil
|
386
|
+
end
|
387
|
+
if r1
|
388
|
+
r0 = r1
|
389
|
+
else
|
390
|
+
if has_terminal?("BUILT", false, index)
|
391
|
+
r2 = instantiate_node(SyntaxNode,input, index...(index + 5))
|
392
|
+
@index += 5
|
393
|
+
else
|
394
|
+
terminal_parse_failure("BUILT")
|
395
|
+
r2 = nil
|
396
|
+
end
|
397
|
+
if r2
|
398
|
+
r0 = r2
|
399
|
+
else
|
400
|
+
if has_terminal?("EXTENDED", false, index)
|
401
|
+
r3 = instantiate_node(SyntaxNode,input, index...(index + 8))
|
402
|
+
@index += 8
|
403
|
+
else
|
404
|
+
terminal_parse_failure("EXTENDED")
|
405
|
+
r3 = nil
|
406
|
+
end
|
407
|
+
if r3
|
408
|
+
r0 = r3
|
409
|
+
else
|
410
|
+
if has_terminal?("FAILED", false, index)
|
411
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
412
|
+
@index += 6
|
413
|
+
else
|
414
|
+
terminal_parse_failure("FAILED")
|
415
|
+
r4 = nil
|
416
|
+
end
|
417
|
+
if r4
|
418
|
+
r0 = r4
|
419
|
+
else
|
420
|
+
if has_terminal?("CLOSED", false, index)
|
421
|
+
r5 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
422
|
+
@index += 6
|
423
|
+
else
|
424
|
+
terminal_parse_failure("CLOSED")
|
425
|
+
r5 = nil
|
426
|
+
end
|
427
|
+
if r5
|
428
|
+
r0 = r5
|
429
|
+
else
|
430
|
+
@index = i0
|
431
|
+
r0 = nil
|
432
|
+
end
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
node_cache[:CircStatus][start_index] = r0
|
439
|
+
|
440
|
+
r0
|
441
|
+
end
|
442
|
+
|
443
|
+
def _nt_Purpose
|
444
|
+
start_index = index
|
445
|
+
if node_cache[:Purpose].has_key?(index)
|
446
|
+
cached = node_cache[:Purpose][index]
|
447
|
+
if cached
|
448
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
449
|
+
@index = cached.interval.end
|
450
|
+
end
|
451
|
+
return cached
|
452
|
+
end
|
453
|
+
|
454
|
+
i0 = index
|
455
|
+
if has_terminal?("GENERAL", false, index)
|
456
|
+
r1 = instantiate_node(SyntaxNode,input, index...(index + 7))
|
457
|
+
@index += 7
|
458
|
+
else
|
459
|
+
terminal_parse_failure("GENERAL")
|
460
|
+
r1 = nil
|
461
|
+
end
|
462
|
+
if r1
|
463
|
+
r0 = r1
|
464
|
+
else
|
465
|
+
if has_terminal?("CONTROLER", false, index)
|
466
|
+
r2 = instantiate_node(SyntaxNode,input, index...(index + 9))
|
467
|
+
@index += 9
|
468
|
+
else
|
469
|
+
terminal_parse_failure("CONTROLER")
|
470
|
+
r2 = nil
|
471
|
+
end
|
472
|
+
if r2
|
473
|
+
r0 = r2
|
474
|
+
else
|
475
|
+
@index = i0
|
476
|
+
r0 = nil
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
node_cache[:Purpose][start_index] = r0
|
481
|
+
|
482
|
+
r0
|
483
|
+
end
|
484
|
+
|
485
|
+
end
|
486
|
+
|
487
|
+
class CircuitListsParser < Treetop::Runtime::CompiledParser
|
488
|
+
include CircuitLists
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|