1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'socket'
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Debug
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Debug::EventSocketProxy
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
12324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA proxy debug event listener that forwards events over a socket to
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvera debugger (or any other listener) using a simple text-based protocol;
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverone event per line.  ANTLRWorks listens on server socket with a
15324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRemoteDebugEventSocketListener instance.  These two objects must therefore
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverbe kept in sync.  New events must be handled on both sides of socket.
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass EventSocketProxy
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  include EventListener
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  SOCKET_ADDR_PACK = 'snCCCCa8'.freeze
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( recognizer, options = {} )
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super()
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @grammar_file_name = recognizer.grammar_file_name
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor = options[ :adaptor ]
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @port = options[ :port ] || DEFAULT_PORT
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @log = options[ :log ]
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @socket = nil
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @connection = nil
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def log!( message, *interpolation_arguments )
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @log and @log.printf( message, *interpolation_arguments )
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def handshake
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    unless @socket
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      begin
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @socket = Socket.new( Socket::AF_INET, Socket::SOCK_STREAM, 0 )
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @socket.bind( Socket.pack_sockaddr_in( @port, '' ) )
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @socket.listen( 1 )
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log!( "waiting for incoming connection on port %i\n", @port )
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @connection, addr = @socket.accept
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        port, host = Socket.unpack_sockaddr_in( addr )
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log!( "Accepted connection from %s:%s\n", host, port )
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @connection.setsockopt( Socket::SOL_TCP, Socket::TCP_NODELAY, 1 )
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        write( 'ANTLR %s', PROTOCOL_VERSION )
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        write( 'grammar %p', @grammar_file_name )
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ack
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      rescue IOError => error
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log!( "handshake failed due to an IOError:\n" )
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log!( "  %s: %s", error.class, error.message )
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log!( "  Backtrace: " )
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log!( "  - %s", error.backtrace.join( "\n  - " ) )
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @connection and @connection.close
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @socket and @socket.close
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        @socket = nil
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return self
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def write( message, *interpolation_arguments )
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    message << ?\n
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    log!( "---> #{ message }", *interpolation_arguments )
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @connection.printf( message, *interpolation_arguments )
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @connection.flush
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def ack
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    line = @connection.readline
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    log!( "<--- %s", line )
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    line
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def transmit( event, *interpolation_arguments )
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    write( event, *interpolation_arguments )
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ack()
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  rescue IOError
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @connection.close
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    raise
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def commence
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # don't bother sending event; listener will trigger upon connection
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def terminate
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit 'terminate'
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @connection.close
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @socket.close
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_rule( grammar_file_name, rule_name )
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s\t%s", :enter_rule, grammar_file_name, rule_name
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_alternative( alt )
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s", :enter_alternative, alt
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def exit_rule( grammar_file_name, rule_name )
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s\t%s", :exit_rule, grammar_file_name, rule_name
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_subrule( decision_number )
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i", :enter_subrule, decision_number
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def exit_subrule( decision_number )
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i", :exit_subrule, decision_number
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def enter_decision( decision_number )
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i", :enter_decision, decision_number
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def exit_decision( decision_number )
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i", :exit_decision, decision_number
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume_token( token )
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s", :consume_token, serialize_token( token )
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume_hidden_token( token )
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s", :consume_hidden_token, serialize_token( token )
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def look( i, item )
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    case item
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when AST::Tree
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      look_tree( i, item )
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when nil
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      transmit "%s\t%i\t%s", :look, i, serialize_token( item )
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def mark( i )
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i", :mark, i
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def rewind( i = nil )
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    i ? transmit( "%s\t%i", :rewind, i ) : transmit( '%s', :rewind )
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def begin_backtrack( level )
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i", :begin_backtrack, level
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def end_backtrack( level, successful )
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i\t%p", :end_backtrack, level, ( successful ? true : false )
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def location( line, position )
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i\t%i", :location, line, position
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def recognition_exception( exception )
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%p\t%i\t%i\t%i", :recognition_exception, exception.class,
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      exception.index, exception.line, exception.column
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def begin_resync
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit '%s', :begin_resync
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def end_resync
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit '%s', :end_resync
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def semantic_predicate( result, predicate )
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pure_boolean = !( !result )
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s\t%s", :semantic_predicate, pure_boolean, escape_newlines( predicate )
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def consume_node( tree )
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s", :consume_node, serialize_node( tree )
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def adaptor
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @adaptor ||= ANTLR3::CommonTreeAdaptor.new
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def look_tree( i, tree )
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%s\t%s", :look_tree, i, serialize_node( tree )
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def flat_node( tree )
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i", :flat_node, adaptor.unique_id( tree )
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def error_node( tree )
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i\t%i\t%p", :error_node, adaptor.unique_id( tree ),
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Token::INVALID_TOKEN_TYPE, escape_newlines( tree.to_s )
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def create_node( node, token = nil )
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if token
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      transmit "%s\t%i\t%i", :create_node, adaptor.unique_id( node ),
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              token.token_index
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    else
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      transmit "%s\t%i\t%i\t%p", :create_node, adaptor.unique_id( node ),
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          adaptor.type_of( node ), adaptor.text_of( node )
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def become_root( new_root, old_root )
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i\t%i", :become_root, adaptor.unique_id( new_root ),
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              adaptor.unique_id( old_root )
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def add_child( root, child )
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i\t%i", :add_child, adaptor.unique_id( root ),
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             adaptor.unique_id( child )
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def set_token_boundaries( t, token_start_index, token_stop_index )
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    transmit "%s\t%i\t%i\t%i", :set_token_boundaries, adaptor.unique_id( t ),
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                               token_start_index, token_stop_index
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_accessor :adaptor
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def serialize_token( token )
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    [ token.token_index, token.type, token.channel,
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     token.line, token.column,
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     escape_newlines( token.text ) ].join( "\t" )
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def serialize_node( node )
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    adaptor ||= ANTLR3::AST::CommonTreeAdaptor.new
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    id = adaptor.unique_id( node )
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    type = adaptor.type_of( node )
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    token = adaptor.token( node )
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    line = token.line rescue -1
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    col  = token.column rescue -1
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    index = adaptor.token_start_index( node )
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    [ id, type, line, col, index ].join( "\t" )
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def escape_newlines( text )
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    text.inspect.tap do |t|
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      t.gsub!( /%/, '%%' )
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Debug::RemoteEventSocketListener
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
259324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA debugging event listener which intercepts debug event messages sent by a EventSocketProxy
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverover an IP socket.
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RemoteEventSocketListener < ::Thread
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  autoload :StringIO, 'stringio'
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ESCAPE_MAP = Hash.new { |h, k| k }
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  ESCAPE_MAP.update( 
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ?n => ?\n, ?t => ?\t, ?a => ?\a, ?b => ?\b, ?e => ?\e,
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ?f => ?\f, ?r => ?\r, ?v => ?\v
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  )
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  attr_reader :host, :port
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def initialize( options = {} )
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @listener = listener
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @host = options.fetch( :host, 'localhost' )
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @port = options.fetch( :port, DEFAULT_PORT )
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @buffer = StringIO.new
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    super do
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      connect do
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        handshake
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        loop do
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          yield( read_event )
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        end
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def handshake
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @version = @socket.readline.split( "\t" )[ -1 ]
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @grammar_file = @socket.readline.split( "\t" )[ -1 ]
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ack
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def ack
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @socket.puts( "ack" )
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @socket.flush
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def unpack_event( event )
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    event.nil? and raise( StopIteration )
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    event.chomp!
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    name, *elements = event.split( "\t",-1 )
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    name = name.to_sym
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    name == :terminate and raise StopIteration
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    elements.map! do |elem|
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      elem.empty? and next( nil )
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      case elem
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when /^\d+$/ then Integer( elem )
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when /^\d+\.\d+$/ then Float( elem )
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when /^true$/ then true
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when /^false$/ then false
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when /^"(.*)"$/ then parse_string( $1 )
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    elements.unshift( name )
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return( elements )
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def read_event
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    event = @socket.readline or raise( StopIteration )
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ack
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return unpack_event( event )
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def connect
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    TCPSocket.open( @host, @port ) do |socket|
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @socket = socket
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      yield
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  def parse_string( string )
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @buffer.string = string
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @buffer.rewind
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    out = ''
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    until @buffer.eof?
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      case c = @buffer.getc
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      when ?\\                    # escape
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        nc = @buffer.getc
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        out << 
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          if nc.between?( ?0, ?9 )  # octal integer
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            @buffer.ungetc( nc )
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            @buffer.read( 3 ).to_i( 8 ).chr
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          elsif nc == ?x
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            @buffer.read( 2 ).to_i( 16 ).chr
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          else
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ESCAPE_MAP[ nc ]
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          end
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      else
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        out << c
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      end
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    end
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return out
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # class RemoteEventSocketListener
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # module Debug
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # module ANTLR3
361