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