antlr3 1.2.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.
Files changed (85) hide show
  1. data/ANTLR-LICENSE.txt +26 -0
  2. data/History.txt +66 -0
  3. data/README.txt +139 -0
  4. data/bin/antlr4ruby +33 -0
  5. data/java/RubyTarget.java +524 -0
  6. data/java/antlr-full-3.2.1.jar +0 -0
  7. data/lib/antlr3.rb +176 -0
  8. data/lib/antlr3/constants.rb +88 -0
  9. data/lib/antlr3/debug.rb +701 -0
  10. data/lib/antlr3/debug/event-hub.rb +210 -0
  11. data/lib/antlr3/debug/record-event-listener.rb +25 -0
  12. data/lib/antlr3/debug/rule-tracer.rb +55 -0
  13. data/lib/antlr3/debug/socket.rb +360 -0
  14. data/lib/antlr3/debug/trace-event-listener.rb +92 -0
  15. data/lib/antlr3/dfa.rb +247 -0
  16. data/lib/antlr3/dot.rb +174 -0
  17. data/lib/antlr3/error.rb +657 -0
  18. data/lib/antlr3/main.rb +561 -0
  19. data/lib/antlr3/modes/ast-builder.rb +41 -0
  20. data/lib/antlr3/modes/filter.rb +56 -0
  21. data/lib/antlr3/profile.rb +322 -0
  22. data/lib/antlr3/recognizers.rb +1280 -0
  23. data/lib/antlr3/streams.rb +985 -0
  24. data/lib/antlr3/streams/interactive.rb +91 -0
  25. data/lib/antlr3/streams/rewrite.rb +412 -0
  26. data/lib/antlr3/test/call-stack.rb +57 -0
  27. data/lib/antlr3/test/config.rb +23 -0
  28. data/lib/antlr3/test/core-extensions.rb +269 -0
  29. data/lib/antlr3/test/diff.rb +165 -0
  30. data/lib/antlr3/test/functional.rb +207 -0
  31. data/lib/antlr3/test/grammar.rb +371 -0
  32. data/lib/antlr3/token.rb +592 -0
  33. data/lib/antlr3/tree.rb +1415 -0
  34. data/lib/antlr3/tree/debug.rb +163 -0
  35. data/lib/antlr3/tree/visitor.rb +84 -0
  36. data/lib/antlr3/tree/wizard.rb +481 -0
  37. data/lib/antlr3/util.rb +149 -0
  38. data/lib/antlr3/version.rb +27 -0
  39. data/samples/ANTLRv3Grammar.g +621 -0
  40. data/samples/Cpp.g +749 -0
  41. data/templates/AST.stg +335 -0
  42. data/templates/ASTDbg.stg +40 -0
  43. data/templates/ASTParser.stg +153 -0
  44. data/templates/ASTTreeParser.stg +272 -0
  45. data/templates/Dbg.stg +192 -0
  46. data/templates/Ruby.stg +1514 -0
  47. data/test/functional/ast-output/auto-ast.rb +797 -0
  48. data/test/functional/ast-output/construction.rb +555 -0
  49. data/test/functional/ast-output/hetero-nodes.rb +753 -0
  50. data/test/functional/ast-output/rewrites.rb +1327 -0
  51. data/test/functional/ast-output/tree-rewrite.rb +1662 -0
  52. data/test/functional/debugging/debug-mode.rb +689 -0
  53. data/test/functional/debugging/profile-mode.rb +165 -0
  54. data/test/functional/debugging/rule-tracing.rb +74 -0
  55. data/test/functional/delegation/import.rb +379 -0
  56. data/test/functional/lexer/basic.rb +559 -0
  57. data/test/functional/lexer/filter-mode.rb +245 -0
  58. data/test/functional/lexer/nuances.rb +47 -0
  59. data/test/functional/lexer/properties.rb +104 -0
  60. data/test/functional/lexer/syn-pred.rb +32 -0
  61. data/test/functional/lexer/xml.rb +206 -0
  62. data/test/functional/main/main-scripts.rb +245 -0
  63. data/test/functional/parser/actions.rb +224 -0
  64. data/test/functional/parser/backtracking.rb +244 -0
  65. data/test/functional/parser/basic.rb +282 -0
  66. data/test/functional/parser/calc.rb +98 -0
  67. data/test/functional/parser/ll-star.rb +143 -0
  68. data/test/functional/parser/nuances.rb +165 -0
  69. data/test/functional/parser/predicates.rb +103 -0
  70. data/test/functional/parser/properties.rb +242 -0
  71. data/test/functional/parser/rule-methods.rb +132 -0
  72. data/test/functional/parser/scopes.rb +274 -0
  73. data/test/functional/token-rewrite/basic.rb +318 -0
  74. data/test/functional/token-rewrite/via-parser.rb +100 -0
  75. data/test/functional/tree-parser/basic.rb +750 -0
  76. data/test/unit/sample-input/file-stream-1 +2 -0
  77. data/test/unit/sample-input/teststreams.input2 +2 -0
  78. data/test/unit/test-dfa.rb +52 -0
  79. data/test/unit/test-exceptions.rb +44 -0
  80. data/test/unit/test-recognizers.rb +55 -0
  81. data/test/unit/test-scheme.rb +62 -0
  82. data/test/unit/test-streams.rb +459 -0
  83. data/test/unit/test-tree-wizard.rb +535 -0
  84. data/test/unit/test-trees.rb +854 -0
  85. metadata +205 -0
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module ANTLR3
5
+ module Debug
6
+ =begin rdoc ANTLR3::Debug::EventHub
7
+
8
+ A special event listener that intercepts debug events and forwards them to other
9
+ debug event listners. As debug-mode recognizers are able to send event
10
+ information to only one listener, EventHubs provide a simple solution in
11
+ situations where multiple event listners are desired.
12
+
13
+ =end
14
+ class EventHub
15
+ include ANTLR3::Debug::EventListener
16
+ attr_reader :listeners
17
+
18
+ def initialize(*listeners)
19
+ @listeners = [listeners].flatten!
20
+ @listeners.compact!
21
+ end
22
+
23
+ def add(*listeners)
24
+ @listeners.push(*listeners)
25
+ end
26
+
27
+ def add_child(root, child)
28
+ for listener in @listeners
29
+ listener.add_child(root, child)
30
+ end
31
+ end
32
+
33
+ def backtrack(level)
34
+ for listener in @listeners
35
+ listener.backtrack(level)
36
+ end
37
+ end
38
+
39
+ def become_root(new_root, old_root)
40
+ for listener in @listeners
41
+ listener.become_root(new_root, old_root)
42
+ end
43
+ end
44
+
45
+ def begin_backtrack(level)
46
+ for listener in @listeners
47
+ listener.begin_backtrack(level)
48
+ end
49
+ end
50
+
51
+ def begin_resync()
52
+ for listener in @listeners
53
+ listener.begin_resync()
54
+ end
55
+ end
56
+
57
+ def commence()
58
+ for listener in @listeners
59
+ listener.commence()
60
+ end
61
+ end
62
+
63
+ def consume_hidden_token(tree)
64
+ for listener in @listeners
65
+ listener.consume_hidden_token(tree)
66
+ end
67
+ end
68
+
69
+ def consume_node(tree)
70
+ for listener in @listeners
71
+ listener.consume_node(tree)
72
+ end
73
+ end
74
+
75
+ def consume_token(tree)
76
+ for listener in @listeners
77
+ listener.consume_token(tree)
78
+ end
79
+ end
80
+
81
+ def create_node(node, token)
82
+ for listener in @listeners
83
+ listener.create_node(node, token)
84
+ end
85
+ end
86
+
87
+ def end_backtrack(level, successful)
88
+ for listener in @listeners
89
+ listener.end_backtrack(level, successful)
90
+ end
91
+ end
92
+
93
+ def end_resync()
94
+ for listener in @listeners
95
+ listener.end_resync()
96
+ end
97
+ end
98
+
99
+ def enter_alternative(alt)
100
+ for listener in @listeners
101
+ listener.enter_alternative(alt)
102
+ end
103
+ end
104
+
105
+ def enter_decision(decision_number)
106
+ for listener in @listeners
107
+ listener.enter_decision(decision_number)
108
+ end
109
+ end
110
+
111
+ def enter_rule(grammar_file_name, rule_name)
112
+ for listener in @listeners
113
+ listener.enter_rule(grammar_file_name, rule_name)
114
+ end
115
+ end
116
+
117
+ def enter_sub_rule(decision_number)
118
+ for listener in @listeners
119
+ listener.enter_sub_rule(decision_number)
120
+ end
121
+ end
122
+
123
+ def error_node(tree)
124
+ for listener in @listeners
125
+ listener.error_node(tree)
126
+ end
127
+ end
128
+
129
+ def exit_decision(decision_number)
130
+ for listener in @listeners
131
+ listener.exit_decision(decision_number)
132
+ end
133
+ end
134
+
135
+ def exit_rule(grammar_file_name, rule_name)
136
+ for listener in @listeners
137
+ listener.exit_rule(grammar_file_name, rule_name)
138
+ end
139
+ end
140
+
141
+ def exit_sub_rule(decision_number)
142
+ for listener in @listeners
143
+ listener.exit_sub_rule(decision_number)
144
+ end
145
+ end
146
+
147
+ def flat_node(tree)
148
+ for listener in @listeners
149
+ listener.flat_node(tree)
150
+ end
151
+ end
152
+
153
+ def location(line, position)
154
+ for listener in @listeners
155
+ listener.location(line, position)
156
+ end
157
+ end
158
+
159
+ def look(i, tree)
160
+ for listener in @listeners
161
+ listener.look(i, tree)
162
+ end
163
+ end
164
+
165
+ def mark(marker)
166
+ for listener in @listeners
167
+ listener.mark(marker)
168
+ end
169
+ end
170
+
171
+ def recognition_exception(exception)
172
+ for listener in @listeners
173
+ listener.recognition_exception(exception)
174
+ end
175
+ end
176
+
177
+ def resync()
178
+ for listener in @listeners
179
+ listener.resync()
180
+ end
181
+ end
182
+
183
+ def rewind(marker)
184
+ for listener in @listeners
185
+ listener.rewind(marker)
186
+ end
187
+ end
188
+
189
+ def semantic_predicate(result, predicate)
190
+ for listener in @listeners
191
+ listener.semantic_predicate(result, predicate)
192
+ end
193
+ end
194
+
195
+ def set_token_boundaries(tree, token_start_index, token_stop_index)
196
+ for listener in @listeners
197
+ listener.set_token_boundaries(tree, token_start_index, token_stop_index)
198
+ end
199
+ end
200
+
201
+ def terminate()
202
+ for listener in @listeners
203
+ listener.terminate()
204
+ end
205
+ end
206
+
207
+ end
208
+
209
+ end
210
+ end
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module ANTLR3
5
+ module Debug
6
+
7
+ =begin rdoc ANTLR3::Debug::RecordEventListener
8
+
9
+ A debug listener that records intercepted events as strings in an array.
10
+
11
+ =end
12
+ class RecordEventListener < TraceEventListener
13
+ attr_reader :events
14
+ def initialize( adaptor = nil )
15
+ super
16
+ @events = []
17
+ end
18
+
19
+ def record(event_message, *interpolation_arguments)
20
+ event_message = event_message.to_s
21
+ @events << event_message % interpolation_arguments
22
+ end
23
+ end
24
+ end # module Debug
25
+ end # module ANTLR3
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ module ANTLR3
5
+ module Debug
6
+ =begin rdoc ANTLR3::Debug::RuleTracer
7
+
8
+ RuleTracer is simple debug event listener that writes the names of rule methods
9
+ as they are entered and exitted to an output stream.
10
+
11
+ =end
12
+ class RuleTracer
13
+ include EventListener
14
+
15
+ ARROW_IN = '--> '.freeze
16
+ ARROW_OUT = '<-- '.freeze
17
+
18
+ attr_reader :level
19
+ attr_accessor :spaces_per_indent, :device
20
+
21
+ def initialize(options = {})
22
+ @input = options[:input]
23
+ @level = 0
24
+ @spaces_per_indent = options[:spaces_per_indent] || 2
25
+ @device = options[:device] || options[:output] || $stderr
26
+ end
27
+
28
+ def enter_rule(grammar_file, name)
29
+ indent = @level * @spaces_per_indent
30
+
31
+ @device.print(' ' * indent, ARROW_IN, name)
32
+ if @input
33
+ input_symbol = @input.look || :EOF
34
+ @device.puts(" look = %p" % input_symbol)
35
+ else @device.print("\n")
36
+ end
37
+
38
+ @level += 1
39
+ end
40
+
41
+ def exit_rule(grammar_file, name)
42
+ @level -= 1
43
+
44
+ indent = @level * @spaces_per_indent
45
+
46
+ @device.print(' ' * indent, ARROW_OUT, name)
47
+ if @input
48
+ input_symbol = (@input.look || :EOF)
49
+ @device.puts(" look = %p" % input_symbol)
50
+ else @device.print("\n")
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,360 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ require 'socket'
5
+
6
+ module ANTLR3
7
+ module Debug
8
+
9
+
10
+ =begin rdoc ANTLR3::Debug::EventSocketProxy
11
+
12
+ A proxy debug event listener that forwards events over a socket to
13
+ a debugger (or any other listener) using a simple text-based protocol;
14
+ one event per line. ANTLRWorks listens on server socket with a
15
+ RemoteDebugEventSocketListener instance. These two objects must therefore
16
+ be kept in sync. New events must be handled on both sides of socket.
17
+
18
+ =end
19
+ class EventSocketProxy
20
+ include EventListener
21
+
22
+ SOCKET_ADDR_PACK = 'snCCCCa8'.freeze
23
+
24
+ def initialize(recognizer, options = {})
25
+ super()
26
+ @grammar_file_name = recognizer.grammar_file_name
27
+ @adaptor = options[:adaptor]
28
+ @port = options[:port] || DEFAULT_PORT
29
+ @log = options[:log]
30
+ @socket = nil
31
+ @connection = nil
32
+ end
33
+
34
+ def log!(message, *interpolation_arguments)
35
+ @log and @log.printf(message, *interpolation_arguments)
36
+ end
37
+
38
+ def handshake
39
+ unless @socket
40
+ begin
41
+ @socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
42
+ @socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
43
+ @socket.bind(Socket.pack_sockaddr_in( @port, '' ))
44
+ @socket.listen(1)
45
+ log!("waiting for incoming connection on port %i\n", @port)
46
+
47
+ @connection, addr = @socket.accept
48
+ port, host = Socket.unpack_sockaddr_in(addr)
49
+ log!("Accepted connection from %s:%s\n", host, port)
50
+
51
+ @connection.setsockopt(Socket::SOL_TCP, Socket::TCP_NODELAY, 1)
52
+
53
+ write('ANTLR %s', PROTOCOL_VERSION)
54
+ write('grammar %p', @grammar_file_name)
55
+ ack
56
+ rescue IOError => error
57
+ log!("handshake failed due to an IOError:\n")
58
+ log!(" %s: %s", error.class, error.message)
59
+ log!(" Backtrace: ")
60
+ log!(" - %s", error.backtrace.join("\n - "))
61
+ @connection and @connection.close
62
+ @socket and @socket.close
63
+ @socket = nil
64
+ raise
65
+ end
66
+ end
67
+ return self
68
+ end
69
+
70
+ def write(message, *interpolation_arguments)
71
+ message << ?\n
72
+ log!("---> #{message}", *interpolation_arguments)
73
+ @connection.printf(message, *interpolation_arguments)
74
+ @connection.flush
75
+ end
76
+
77
+ def ack
78
+ line = @connection.readline
79
+ log!("<--- %s", line)
80
+ line
81
+ end
82
+
83
+ def transmit(event, *interpolation_arguments)
84
+ write(event, *interpolation_arguments)
85
+ ack()
86
+ rescue IOError
87
+ @connection.close
88
+ raise
89
+ end
90
+
91
+ def commence
92
+ # don't bother sending event; listener will trigger upon connection
93
+ end
94
+
95
+ def terminate
96
+ transmit 'terminate'
97
+ @connection.close
98
+ @socket.close
99
+ end
100
+
101
+ def enter_rule( grammar_file_name, rule_name )
102
+ transmit "%s\t%s\t%s", __method__, grammar_file_name, rule_name
103
+ end
104
+
105
+ def enter_alternative( alt )
106
+ transmit "%s\t%s", __method__, alt
107
+ end
108
+
109
+ def exit_rule( grammar_file_name, rule_name )
110
+ transmit "%s\t%s\t%s", __method__, grammar_file_name, rule_name
111
+ end
112
+
113
+ def enter_subrule( decision_number )
114
+ transmit "%s\t%i", __method__, decision_number
115
+ end
116
+
117
+ def exit_subrule( decision_number )
118
+ transmit "%s\t%i", __method__, decision_number
119
+ end
120
+
121
+ def enter_decision( decision_number )
122
+ transmit "%s\t%i", __method__, decision_number
123
+ end
124
+
125
+ def exit_decision( decision_number )
126
+ transmit "%s\t%i", __method__, decision_number
127
+ end
128
+
129
+ def consume_token( token )
130
+ transmit "%s\t%s", __method__, serialize_token( token )
131
+ end
132
+
133
+ def consume_hidden_token( token )
134
+ transmit "%s\t%s", __method__, serialize_token( token )
135
+ end
136
+
137
+ def look(i, item)
138
+ case item
139
+ when AST::Tree
140
+ look_tree( i, item )
141
+ when nil
142
+ else
143
+ transmit "%s\t%i\t%s", __method__, i, serialize_token(item)
144
+ end
145
+ end
146
+
147
+ def mark(i)
148
+ transmit "%s\t%i", __method__, i
149
+ end
150
+
151
+ def rewind(i = nil)
152
+ i ? transmit( "%s\t%i", __method__, i ) : transmit( '%s', __method__ )
153
+ end
154
+
155
+ def begin_backtrack( level )
156
+ transmit "%s\t%i", __method__, level
157
+ end
158
+ def end_backtrack( level, successful )
159
+ transmit "%s\t%i\t%p", __method__, level, (successful ? true : false)
160
+ end
161
+
162
+ def location( line, position )
163
+ transmit "%s\t%i\t%i", __method__, line, position
164
+ end
165
+
166
+ def recognition_exception( exception )
167
+ transmit "%s\t%p\t%i\t%i\t%i", __method__, exception.class,
168
+ exception.index, exception.line, exception.column
169
+ end
170
+
171
+ def begin_resync
172
+ transmit '%s', __method__
173
+ end
174
+
175
+ def end_resync
176
+ transmit '%s', __method__
177
+ end
178
+
179
+ def semantic_predicate( result, predicate )
180
+ pure_boolean = !(!result)
181
+ transmit "%s\t%s\t%s", __method__, pure_boolean, escape_newlines( predicate )
182
+ end
183
+
184
+ def consume_node( tree )
185
+ transmit "%s\t%s", __method__, serialize_node( tree )
186
+ end
187
+
188
+ def adaptor
189
+ @adaptor ||= ANTLR3::CommonTreeAdaptor.new
190
+ end
191
+
192
+ def look_tree( i, tree )
193
+ transmit "%s\t%s\t%s", __method__, i, serialize_node( tree )
194
+ end
195
+
196
+ def flat_node( tree )
197
+ transmit "%s\t%i", __method__, adaptor.unique_id( tree )
198
+ end
199
+
200
+ def error_node( tree )
201
+ transmit "%s\t%i\t%i\t%p", __method__, adaptor.unique_id( tree ),
202
+ Token::INVALID_TOKEN_TYPE, escape_newlines( tree.to_s )
203
+ end
204
+
205
+ def create_node( node, token = nil )
206
+ if token
207
+ transmit "%s\t%i\t%i", __method__, adaptor.unique_id( node ),
208
+ token.token_index
209
+ else
210
+ transmit "%s\t%i\t%i\t%p", __method__, adaptor.unique_id( node ),
211
+ adaptor.type_of( node ), adaptor.text_of( node )
212
+ end
213
+ end
214
+
215
+ def become_root( new_root, old_root )
216
+ transmit "%s\t%i\t%i", __method__, adaptor.unique_id( new_root ),
217
+ adaptor.unique_id( old_root )
218
+ end
219
+
220
+ def add_child( root, child )
221
+ transmit "%s\t%i\t%i", __method__, adaptor.unique_id( root ),
222
+ adaptor.unique_id( child )
223
+ end
224
+
225
+ def set_token_boundaries( t, token_start_index, token_stop_index )
226
+ transmit "%s\t%i\t%i\t%i", __method__, adaptor.unique_id( t ),
227
+ token_start_index, token_stop_index
228
+ end
229
+
230
+ attr_accessor :adaptor
231
+
232
+ def serialize_token( token )
233
+ [token.token_index, token.type, token.channel,
234
+ token.line, token.column,
235
+ escape_newlines( token.text )].join( "\t" )
236
+ end
237
+
238
+ def serialize_node( node )
239
+ adaptor ||= ANTLR3::AST::CommonTreeAdaptor.new
240
+ id = adaptor.unique_id( node )
241
+ type = adaptor.type_of( node )
242
+ token = adaptor.token( node )
243
+ line = token.line rescue -1
244
+ col = token.column rescue -1
245
+ index = adaptor.token_start_index( node )
246
+ [ id, type, line, col, index ].join( "\t" )
247
+ end
248
+
249
+
250
+ def escape_newlines( text )
251
+ text.inspect.tap do |t|
252
+ t.gsub!(/%/, '%%')
253
+ end
254
+ end
255
+ end
256
+
257
+ =begin rdoc ANTLR3::Debug::RemoteEventSocketListener
258
+
259
+ A debugging event listener which intercepts debug event messages sent by a EventSocketProxy
260
+ over an IP socket.
261
+
262
+ =end
263
+ class RemoteEventSocketListener < ::Thread
264
+ autoload :StringIO, 'stringio'
265
+ ESCAPE_MAP = Hash.new { |h, k| k }
266
+ ESCAPE_MAP.update(
267
+ ?n => ?\n, ?t => ?\t, ?a => ?\a, ?b => ?\b, ?e => ?\e,
268
+ ?f => ?\f, ?r => ?\r, ?v => ?\v
269
+ )
270
+
271
+ attr_reader :host, :port
272
+
273
+ def initialize( options = {} )
274
+ @listener = listener
275
+ @host = options.fetch( :host, 'localhost' )
276
+ @port = options.fetch( :port, DEFAULT_PORT )
277
+ @buffer = StringIO.new
278
+ super do
279
+ connect do
280
+ handshake
281
+ loop do
282
+ yield( read_event )
283
+ end
284
+ end
285
+ end
286
+ end
287
+
288
+ private
289
+
290
+ def handshake
291
+ @version = @socket.readline.split("\t")[-1]
292
+ @grammar_file = @socket.readline.split("\t")[-1]
293
+ ack
294
+ end
295
+
296
+ def ack
297
+ @socket.puts("ack")
298
+ @socket.flush
299
+ end
300
+
301
+ def unpack_event(event)
302
+ event.nil? and raise( StopIteration )
303
+ event.chomp!
304
+ name, *elements = event.split("\t",-1)
305
+ name = name.to_sym
306
+ name == :terminate and raise StopIteration
307
+ elements.map! do |elem|
308
+ elem.empty? and next(nil)
309
+ case elem
310
+ when /^\d+$/ then Integer(elem)
311
+ when /^\d+\.\d+$/ then Float(elem)
312
+ when /^true$/ then true
313
+ when /^false$/ then false
314
+ when /^"(.*)"$/ then parse_string($1)
315
+ end
316
+ end
317
+ elements.unshift(name)
318
+ return( elements )
319
+ end
320
+
321
+ def read_event
322
+ event = @socket.readline or raise( StopIteration )
323
+ ack
324
+ return unpack_event( event )
325
+ end
326
+
327
+ def connect
328
+ TCPSocket.open(@host, @port) do |socket|
329
+ @socket = socket
330
+ yield
331
+ end
332
+ end
333
+
334
+ def parse_string( string )
335
+ @buffer.string = string
336
+ @buffer.rewind
337
+ out = ''
338
+ until @buffer.eof?
339
+ case c = @buffer.getc
340
+ when ?\\ # escape
341
+ nc = @buffer.getc
342
+ out <<
343
+ if nc.between?( ?0, ?9 ) # octal integer
344
+ @buffer.ungetc( nc )
345
+ @buffer.read( 3 ).to_i( 8 ).chr
346
+ elsif nc == ?x
347
+ @buffer.read( 2 ).to_i( 16 ).chr
348
+ else
349
+ ESCAPE_MAP[ nc ]
350
+ end
351
+ else
352
+ out << c
353
+ end
354
+ end
355
+ return out
356
+ end
357
+
358
+ end # class RemoteEventSocketListener
359
+ end # module Debug
360
+ end # module ANTLR3