Home | History | Annotate | Download | only in src
      1 /// \file
      2 /// Provides the debugging functions invoked by a recognizer
      3 /// built using the debug generator mode of the antlr tool.
      4 /// See antlr3debugeventlistener.h for documentation.
      5 ///
      6 
      7 // [The "BSD licence"]
      8 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
      9 // http://www.temporal-wave.com
     10 // http://www.linkedin.com/in/jimidle
     11 //
     12 // All rights reserved.
     13 //
     14 // Redistribution and use in source and binary forms, with or without
     15 // modification, are permitted provided that the following conditions
     16 // are met:
     17 // 1. Redistributions of source code must retain the above copyright
     18 //    notice, this list of conditions and the following disclaimer.
     19 // 2. Redistributions in binary form must reproduce the above copyright
     20 //    notice, this list of conditions and the following disclaimer in the
     21 //    documentation and/or other materials provided with the distribution.
     22 // 3. The name of the author may not be used to endorse or promote products
     23 //    derived from this software without specific prior written permission.
     24 //
     25 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     26 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     27 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     28 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     30 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     34 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     35 
     36 #include    <antlr3.h>
     37 
     38 // Not everyone wishes to include the debugger stuff in their final deployment because
     39 // it will then rely on being linked with the socket libraries. Hence if the programmer turns
     40 // off the debugging, we do some dummy stuff that satifies compilers etc but means there is
     41 // no debugger and no reliance on the socket librarires. If you set this flag, then using the -debug
     42 // option to generate your code will produce code that just crashes, but then I presme you are smart
     43 // enough to realize that building the libraries without debugger support means you can't call the
     44 // debugger ;-)
     45 //
     46 #ifdef ANTLR3_NODEBUGGER
     47 ANTLR3_API pANTLR3_DEBUG_EVENT_LISTENER
     48 antlr3DebugListenerNew()
     49 {
     50 		ANTLR3_PRINTF("C runtime was compiled without debugger support. This program will crash!!");
     51 		return NULL;
     52 }
     53 #else
     54 
     55 static	ANTLR3_BOOLEAN	handshake		(pANTLR3_DEBUG_EVENT_LISTENER delboy);
     56 static	void	enterRule				(pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName);
     57 static	void	enterAlt				(pANTLR3_DEBUG_EVENT_LISTENER delboy, int alt);
     58 static	void	exitRule				(pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName);
     59 static	void	enterSubRule			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
     60 static	void	exitSubRule				(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
     61 static	void	enterDecision			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
     62 static	void	exitDecision			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
     63 static	void	consumeToken			(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t);
     64 static	void	consumeHiddenToken		(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t);
     65 static	void	LT						(pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_COMMON_TOKEN t);
     66 static	void	mark					(pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker);
     67 static	void	rewindMark				(pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker);
     68 static	void	rewindLast				(pANTLR3_DEBUG_EVENT_LISTENER delboy);
     69 static	void	beginBacktrack			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int level);
     70 static	void	endBacktrack			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int level, ANTLR3_BOOLEAN successful);
     71 static	void	location				(pANTLR3_DEBUG_EVENT_LISTENER delboy, int line, int pos);
     72 static	void	recognitionException	(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_EXCEPTION e);
     73 static	void	beginResync				(pANTLR3_DEBUG_EVENT_LISTENER delboy);
     74 static	void	endResync				(pANTLR3_DEBUG_EVENT_LISTENER delboy);
     75 static	void	semanticPredicate		(pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_BOOLEAN result, const char * predicate);
     76 static	void	commence				(pANTLR3_DEBUG_EVENT_LISTENER delboy);
     77 static	void	terminate				(pANTLR3_DEBUG_EVENT_LISTENER delboy);
     78 static	void	consumeNode				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
     79 static	void	LTT						(pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_BASE_TREE t);
     80 static	void	nilNode					(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
     81 static	void	errorNode				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
     82 static	void	createNode				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
     83 static	void	createNodeTok			(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE node, pANTLR3_COMMON_TOKEN token);
     84 static	void	becomeRoot				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot);
     85 static	void	addChild				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE root, pANTLR3_BASE_TREE child);
     86 static	void	setTokenBoundaries		(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t, ANTLR3_MARKER tokenStartIndex, ANTLR3_MARKER tokenStopIndex);
     87 static	void	ack						(pANTLR3_DEBUG_EVENT_LISTENER delboy);
     88 
     89 /// Create and initialize a new debug event listener that can be connected to
     90 /// by ANTLRWorks and any other debugger via a socket.
     91 ///
     92 ANTLR3_API pANTLR3_DEBUG_EVENT_LISTENER
     93 antlr3DebugListenerNew()
     94 {
     95 	pANTLR3_DEBUG_EVENT_LISTENER	delboy;
     96 
     97 	delboy = ANTLR3_CALLOC(1, sizeof(ANTLR3_DEBUG_EVENT_LISTENER));
     98 
     99 	if	(delboy == NULL)
    100 	{
    101 		return NULL;
    102 	}
    103 
    104 	// Initialize the API
    105 	//
    106 	delboy->addChild				= addChild;
    107 	delboy->becomeRoot				= becomeRoot;
    108 	delboy->beginBacktrack			= beginBacktrack;
    109 	delboy->beginResync				= beginResync;
    110 	delboy->commence				= commence;
    111 	delboy->consumeHiddenToken		= consumeHiddenToken;
    112 	delboy->consumeNode				= consumeNode;
    113 	delboy->consumeToken			= consumeToken;
    114 	delboy->createNode				= createNode;
    115 	delboy->createNodeTok			= createNodeTok;
    116 	delboy->endBacktrack			= endBacktrack;
    117 	delboy->endResync				= endResync;
    118 	delboy->enterAlt				= enterAlt;
    119 	delboy->enterDecision			= enterDecision;
    120 	delboy->enterRule				= enterRule;
    121 	delboy->enterSubRule			= enterSubRule;
    122 	delboy->exitDecision			= exitDecision;
    123 	delboy->exitRule				= exitRule;
    124 	delboy->exitSubRule				= exitSubRule;
    125 	delboy->handshake				= handshake;
    126 	delboy->location				= location;
    127 	delboy->LT						= LT;
    128 	delboy->LTT						= LTT;
    129 	delboy->mark					= mark;
    130 	delboy->nilNode					= nilNode;
    131 	delboy->recognitionException	= recognitionException;
    132 	delboy->rewind					= rewindMark;
    133 	delboy->rewindLast				= rewindLast;
    134 	delboy->semanticPredicate		= semanticPredicate;
    135 	delboy->setTokenBoundaries		= setTokenBoundaries;
    136 	delboy->terminate				= terminate;
    137 	delboy->errorNode				= errorNode;
    138 
    139 	delboy->PROTOCOL_VERSION		= 2;	// ANTLR 3.1 is at protocol version 2
    140 
    141 	delboy->port					= DEFAULT_DEBUGGER_PORT;
    142 
    143 	return delboy;
    144 }
    145 
    146 pANTLR3_DEBUG_EVENT_LISTENER
    147 antlr3DebugListenerNewPort(ANTLR3_UINT32 port)
    148 {
    149 	pANTLR3_DEBUG_EVENT_LISTENER	delboy;
    150 
    151 	delboy		 = antlr3DebugListenerNew();
    152 
    153 	if	(delboy != NULL)
    154 	{
    155 		delboy->port = port;
    156 	}
    157 
    158 	return delboy;
    159 }
    160 
    161 //--------------------------------------------------------------------------------
    162 // Support functions for sending stuff over the socket interface
    163 //
    164 static int
    165 sockSend(SOCKET sock, const char * ptr, int len)
    166 {
    167 	int		sent;
    168 	int		thisSend;
    169 
    170 	sent	= 0;
    171 
    172 	while	(sent < len)
    173 	{
    174 		// Send as many bytes as we can
    175 		//
    176 		thisSend =	send(sock, ptr, len - sent, 0);
    177 
    178 		// Check for errors and tell the user if we got one
    179 		//
    180 		if	(thisSend	== -1)
    181 		{
    182 			return	ANTLR3_FALSE;
    183 		}
    184 
    185 		// Increment our offset by how many we were able to send
    186 		//
    187 		ptr			+= thisSend;
    188 		sent		+= thisSend;
    189 	}
    190 	return	ANTLR3_TRUE;
    191 }
    192 
    193 static	ANTLR3_BOOLEAN
    194 handshake				(pANTLR3_DEBUG_EVENT_LISTENER delboy)
    195 {
    196 	/// Connection structure with which to wait and accept a connection from
    197 	/// a debugger.
    198 	///
    199 	SOCKET				serverSocket;
    200 
    201 	// Connection structures to deal with the client after we accept the connection
    202 	// and the server while we accept a connection.
    203 	//
    204 	ANTLR3_SOCKADDRT	client;
    205 	ANTLR3_SOCKADDRT	server;
    206 
    207 	// Buffer to construct our message in
    208 	//
    209 	char	message[256];
    210 
    211 	// Specifies the length of the connection structure to accept()
    212 	// Windows use int, everyone else uses size_t
    213 	//
    214 	ANTLR3_SALENT				sockaddr_len;
    215 
    216 	// Option holder for setsockopt()
    217 	//
    218 	int		optVal;
    219 
    220 	if	(delboy->initialized == ANTLR3_FALSE)
    221 	{
    222 		// Windows requires us to initialize WinSock.
    223 		//
    224 #ifdef ANTLR3_WINDOWS
    225 		{
    226 			WORD		wVersionRequested;
    227 			WSADATA		wsaData;
    228 			int			err;			// Return code from WSAStartup
    229 
    230 			// We must initialise the Windows socket system when the DLL is loaded.
    231 			// We are asking for Winsock 1.1 or better as we don't need anything
    232 			// too complicated for this.
    233 			//
    234 			wVersionRequested = MAKEWORD( 1, 1);
    235 
    236 			err = WSAStartup( wVersionRequested, &wsaData );
    237 
    238 			if ( err != 0 )
    239 			{
    240 				// Tell the user that we could not find a usable
    241 				// WinSock DLL
    242 				//
    243 				return FALSE;
    244 			}
    245 		}
    246 #endif
    247 
    248 		// Create the server socket, we are the server because we just wait until
    249 		// a debugger connects to the port we are listening on.
    250 		//
    251 		serverSocket	= socket(AF_INET, SOCK_STREAM, 0);
    252 
    253 		if	(serverSocket == INVALID_SOCKET)
    254 		{
    255 			return ANTLR3_FALSE;
    256 		}
    257 
    258 		// Set the listening port
    259 		//
    260 		server.sin_port			= htons((unsigned short)delboy->port);
    261 		server.sin_family		= AF_INET;
    262 		server.sin_addr.s_addr	= htonl (INADDR_ANY);
    263 
    264 		// We could allow a rebind on the same addr/port pair I suppose, but
    265 		// I imagine that most people will just want to start debugging one parser at once.
    266 		// Maybe change this at some point, but rejecting the bind at this point will ensure
    267 		// that people realize they have left something running in the background.
    268 		//
    269 		if	(bind(serverSocket, (pANTLR3_SOCKADDRC)&server, sizeof(server)) == -1)
    270 		{
    271 			return ANTLR3_FALSE;
    272 		}
    273 
    274 		// We have bound the socket to the port and address so we now ask the TCP subsystem
    275 		// to start listening on that address/port
    276 		//
    277 		if	(listen(serverSocket, 1) == -1)
    278 		{
    279 			// Some error, just fail
    280 			//
    281 			return	ANTLR3_FALSE;
    282 		}
    283 
    284 		// Now we can try to accept a connection on the port
    285 		//
    286 		sockaddr_len	= sizeof(client);
    287 		delboy->socket	= accept(serverSocket, (pANTLR3_SOCKADDRC)&client, &sockaddr_len);
    288 
    289 		// Having accepted a connection, we can stop listening and close down the socket
    290 		//
    291 		shutdown		(serverSocket, 0x02);
    292 		ANTLR3_CLOSESOCKET		(serverSocket);
    293 
    294 		if	(delboy->socket == -1)
    295 		{
    296 			return ANTLR3_FALSE;
    297 		}
    298 
    299 		// Disable Nagle as this is essentially a chat exchange
    300 		//
    301 		optVal	= 1;
    302 		setsockopt(delboy->socket, SOL_SOCKET, TCP_NODELAY, (const void *)&optVal, sizeof(optVal));
    303 
    304 	}
    305 
    306 	// We now have a good socket connection with the debugging client, so we
    307 	// send it the protocol version we are using and what the name of the grammar
    308 	// is that we represent.
    309 	//
    310 	sprintf		(message, "ANTLR %d\n", delboy->PROTOCOL_VERSION);
    311 	sockSend	(delboy->socket, message, (int)strlen(message));
    312 	sprintf		(message, "grammar \"%s\n", delboy->grammarFileName->chars);
    313 	sockSend	(delboy->socket, message, (int)strlen(message));
    314 	ack			(delboy);
    315 
    316 	delboy->initialized = ANTLR3_TRUE;
    317 
    318 	return	ANTLR3_TRUE;
    319 }
    320 
    321 // Send the supplied text and wait for an ack from the client
    322 static void
    323 transmit(pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * ptr)
    324 {
    325 	sockSend(delboy->socket, ptr, (int)strlen(ptr));
    326 	ack(delboy);
    327 }
    328 
    329 static	void
    330 ack						(pANTLR3_DEBUG_EVENT_LISTENER delboy)
    331 {
    332 	// Local buffer to read the next character in to
    333 	//
    334 	char	buffer;
    335 	int		rCount;
    336 
    337 	// Ack terminates in a line feed, so we just wait for
    338 	// one of those. Speed is not of the essence so we don't need
    339 	// to buffer the input or anything.
    340 	//
    341 	do
    342 	{
    343 		rCount = recv(delboy->socket, &buffer, 1, 0);
    344 	}
    345 	while	(rCount == 1 && buffer != '\n');
    346 
    347 	// If the socket ws closed on us, then we will get an error or
    348 	// (with a graceful close), 0. We can assume the the debugger stopped for some reason
    349 	// (such as Java crashing again). Therefore we just exit the program
    350 	// completely if we don't get the terminating '\n' for the ack.
    351 	//
    352 	if	(rCount != 1)
    353 	{
    354 		ANTLR3_PRINTF("Exiting debugger as remote client closed the socket\n");
    355 		ANTLR3_PRINTF("Received char count was %d, and last char received was %02X\n", rCount, buffer);
    356 		exit(0);
    357 	}
    358 }
    359 
    360 // Given a buffer string and a source string, serialize the
    361 // text, escaping any newlines and linefeeds. We have no need
    362 // for speed here, this is the debugger.
    363 //
    364 void
    365 serializeText(pANTLR3_STRING buffer, pANTLR3_STRING text)
    366 {
    367 	ANTLR3_UINT32	c;
    368 	ANTLR3_UCHAR	character;
    369 
    370 	// strings lead in with a "
    371 	//
    372 	buffer->append(buffer, "\t\"");
    373 
    374 	if	(text == NULL)
    375 	{
    376 		return;
    377 	}
    378 
    379 	// Now we replace linefeeds, newlines and the escape
    380 	// leadin character '%' with their hex equivalents
    381 	// prefixed by '%'
    382 	//
    383 	for	(c = 0; c < text->len; c++)
    384 	{
    385 		switch	(character = text->charAt(text, c))
    386 		{
    387 			case	'\n':
    388 
    389 				buffer->append(buffer, "%0A");
    390 				break;
    391 
    392 			case	'\r':
    393 
    394 				buffer->append(buffer, "%0D");
    395 				break;
    396 
    397 			case	'\\':
    398 
    399 				buffer->append(buffer, "%25");
    400 				break;
    401 
    402 				// Other characters: The Song Remains the Same.
    403 				//
    404 			default:
    405 
    406 				buffer->addc(buffer, character);
    407 				break;
    408 		}
    409 	}
    410 }
    411 
    412 // Given a token, create a stringified version of it, in the supplied
    413 // buffer. We create a string for this in the debug 'object', if there
    414 // is not one there already, and then reuse it here if asked to do this
    415 // again.
    416 //
    417 pANTLR3_STRING
    418 serializeToken(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t)
    419 {
    420 	// Do we already have a serialization buffer?
    421 	//
    422 	if	(delboy->tokenString == NULL)
    423 	{
    424 		// No, so create one, using the string factory that
    425 		// the grammar name used, which is guaranteed to exist.
    426 		// 64 bytes will do us here for starters.
    427 		//
    428 		delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
    429 	}
    430 
    431 	// Empty string
    432 	//
    433 	delboy->tokenString->set(delboy->tokenString, (const char *)"");
    434 
    435 	// Now we serialize the elements of the token.Note that the debugger only
    436 	// uses 32 bits.
    437 	//
    438 	delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getTokenIndex(t)));
    439 	delboy->tokenString->addc(delboy->tokenString, '\t');
    440 	delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getType(t)));
    441 	delboy->tokenString->addc(delboy->tokenString, '\t');
    442 	delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getChannel(t)));
    443 	delboy->tokenString->addc(delboy->tokenString, '\t');
    444 	delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getLine(t)));
    445 	delboy->tokenString->addc(delboy->tokenString, '\t');
    446 	delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getCharPositionInLine(t)));
    447 
    448 	// Now send the text that the token represents.
    449 	//
    450 	serializeText(delboy->tokenString, t->getText(t));
    451 
    452 	// Finally, as the debugger is a Java program it will expect to get UTF-8
    453 	// encoded strings. We don't use UTF-8 internally to the C runtime, so we
    454 	// must force encode it. We have a method to do this in the string class, but
    455 	// it returns malloc space that we must free afterwards.
    456 	//
    457 	return delboy->tokenString->toUTF8(delboy->tokenString);
    458 }
    459 
    460 // Given a tree node, create a stringified version of it in the supplied
    461 // buffer.
    462 //
    463 pANTLR3_STRING
    464 serializeNode(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE node)
    465 {
    466 	pANTLR3_COMMON_TOKEN	token;
    467 
    468 
    469 	// Do we already have a serialization buffer?
    470 	//
    471 	if	(delboy->tokenString == NULL)
    472 	{
    473 		// No, so create one, using the string factory that
    474 		// the grammar name used, which is guaranteed to exist.
    475 		// 64 bytes will do us here for starters.
    476 		//
    477 		delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
    478 	}
    479 
    480 	// Empty string
    481 	//
    482 	delboy->tokenString->set(delboy->tokenString, (const char *)"");
    483 
    484 	// Protect against bugs/errors etc
    485 	//
    486 	if	(node == NULL)
    487 	{
    488 		return delboy->tokenString;
    489 	}
    490 
    491 	// Now we serialize the elements of the node.Note that the debugger only
    492 	// uses 32 bits.
    493 	//
    494 	delboy->tokenString->addc(delboy->tokenString, '\t');
    495 
    496 	// Adaptor ID
    497 	//
    498 	delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getUniqueID(delboy->adaptor, node));
    499 	delboy->tokenString->addc(delboy->tokenString, '\t');
    500 
    501 	// Type of the current token (which may be imaginary)
    502 	//
    503 	delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getType(delboy->adaptor, node));
    504 
    505 	// See if we have an actual token or just an imaginary
    506 	//
    507 	token	= delboy->adaptor->getToken(delboy->adaptor, node);
    508 
    509 	delboy->tokenString->addc(delboy->tokenString, '\t');
    510 	if	(token != NULL)
    511 	{
    512 		// Real token
    513 		//
    514 		delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(token->getLine(token)));
    515 		delboy->tokenString->addc(delboy->tokenString, ' ');
    516 		delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(token->getCharPositionInLine(token)));
    517 	}
    518 	else
    519 	{
    520 		// Imaginary tokens have no location
    521 		//
    522 		delboy->tokenString->addi(delboy->tokenString, -1);
    523 		delboy->tokenString->addc(delboy->tokenString, '\t');
    524 		delboy->tokenString->addi(delboy->tokenString, -1);
    525 	}
    526 
    527 	// Start Index of the node
    528 	//
    529 	delboy->tokenString->addc(delboy->tokenString, '\t');
    530 	delboy->tokenString->addi(delboy->tokenString, (ANTLR3_UINT32)(delboy->adaptor->getTokenStartIndex(delboy->adaptor, node)));
    531 
    532 	// Now send the text that the node represents.
    533 	//
    534 	serializeText(delboy->tokenString, delboy->adaptor->getText(delboy->adaptor, node));
    535 
    536 	// Finally, as the debugger is a Java program it will expect to get UTF-8
    537 	// encoded strings. We don't use UTF-8 internally to the C runtime, so we
    538 	// must force encode it. We have a method to do this in the string class, but
    539 	// there is no utf8 string implementation as of yet
    540 	//
    541 	return delboy->tokenString->toUTF8(delboy->tokenString);
    542 }
    543 
    544 //------------------------------------------------------------------------------------------------------------------
    545 // EVENTS
    546 //
    547 static	void
    548 enterRule				(pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName)
    549 {
    550 	char	buffer[512];
    551 
    552 	// Create the message (speed is not of the essence)
    553 	//
    554 	sprintf(buffer, "enterRule\t%s\t%s\n", grammarFileName, ruleName);
    555 	transmit(delboy, buffer);
    556 }
    557 
    558 static	void
    559 enterAlt				(pANTLR3_DEBUG_EVENT_LISTENER delboy, int alt)
    560 {
    561 	char	buffer[512];
    562 
    563 	// Create the message (speed is not of the essence)
    564 	//
    565 	sprintf(buffer, "enterAlt\t%d\n", alt);
    566 	transmit(delboy, buffer);
    567 }
    568 
    569 static	void
    570 exitRule				(pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName)
    571 {
    572 	char	buffer[512];
    573 
    574 	// Create the message (speed is not of the essence)
    575 	//
    576 	sprintf(buffer, "exitRule\t%s\t%s\n", grammarFileName, ruleName);
    577 	transmit(delboy, buffer);
    578 }
    579 
    580 static	void
    581 enterSubRule			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
    582 {
    583 	char	buffer[512];
    584 
    585 	// Create the message (speed is not of the essence)
    586 	//
    587 	sprintf(buffer, "enterSubRule\t%d\n", decisionNumber);
    588 	transmit(delboy, buffer);
    589 }
    590 
    591 static	void
    592 exitSubRule				(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
    593 {
    594 	char	buffer[512];
    595 
    596 	// Create the message (speed is not of the essence)
    597 	//
    598 	sprintf(buffer, "exitSubRule\t%d\n", decisionNumber);
    599 	transmit(delboy, buffer);
    600 }
    601 
    602 static	void
    603 enterDecision			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
    604 {
    605 	char	buffer[512];
    606 
    607 	// Create the message (speed is not of the essence)
    608 	//
    609 	sprintf(buffer, "enterDecision\t%d\n", decisionNumber);
    610 	transmit(delboy, buffer);
    611 
    612 }
    613 
    614 static	void
    615 exitDecision			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
    616 {
    617 	char	buffer[512];
    618 
    619 	// Create the message (speed is not of the essence)
    620 	//
    621 	sprintf(buffer, "exitDecision\t%d\n", decisionNumber);
    622 	transmit(delboy, buffer);
    623 }
    624 
    625 static	void
    626 consumeToken			(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t)
    627 {
    628 	pANTLR3_STRING msg;
    629 
    630 	// Create the serialized token
    631 	//
    632 	msg = serializeToken(delboy, t);
    633 
    634 	// Insert the debug event indicator
    635 	//
    636 	msg->insert8(msg, 0, "consumeToken\t");
    637 
    638 	msg->addc(msg, '\n');
    639 
    640 	// Transmit the message and wait for ack
    641 	//
    642 	transmit(delboy, (const char *)(msg->chars));
    643 }
    644 
    645 static	void
    646 consumeHiddenToken		(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t)
    647 {
    648 	pANTLR3_STRING msg;
    649 
    650 	// Create the serialized token
    651 	//
    652 	msg = serializeToken(delboy, t);
    653 
    654 	// Insert the debug event indicator
    655 	//
    656 	msg->insert8(msg, 0, "consumeHiddenToken\t");
    657 
    658 	msg->addc(msg, '\n');
    659 
    660 	// Transmit the message and wait for ack
    661 	//
    662 	transmit(delboy, (const char *)(msg->chars));
    663 }
    664 
    665 // Looking at the next token event.
    666 //
    667 static	void
    668 LT						(pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_COMMON_TOKEN t)
    669 {
    670 	pANTLR3_STRING msg;
    671 
    672 	if	(t != NULL)
    673 	{
    674 		// Create the serialized token
    675 		//
    676 		msg = serializeToken(delboy, t);
    677 
    678 		// Insert the index parameter
    679 		//
    680 		msg->insert8(msg, 0, "\t");
    681 		msg->inserti(msg, 0, i);
    682 
    683 		// Insert the debug event indicator
    684 		//
    685 		msg->insert8(msg, 0, "LT\t");
    686 
    687 		msg->addc(msg, '\n');
    688 
    689 		// Transmit the message and wait for ack
    690 		//
    691 		transmit(delboy, (const char *)(msg->chars));
    692 	}
    693 }
    694 
    695 static	void
    696 mark					(pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker)
    697 {
    698 	char buffer[128];
    699 
    700 	sprintf(buffer, "mark\t%d\n", (ANTLR3_UINT32)(marker & 0xFFFFFFFF));
    701 
    702 	// Transmit the message and wait for ack
    703 	//
    704 	transmit(delboy, buffer);
    705 }
    706 
    707 static	void
    708 rewindMark					(pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker)
    709 {
    710 	char buffer[128];
    711 
    712 	sprintf(buffer, "rewind\t%d\n", (ANTLR3_UINT32)(marker & 0xFFFFFFFF));
    713 
    714 	// Transmit the message and wait for ack
    715 	//
    716 	transmit(delboy, buffer);
    717 
    718 }
    719 
    720 static	void
    721 rewindLast				(pANTLR3_DEBUG_EVENT_LISTENER delboy)
    722 {
    723 	transmit(delboy, (const char *)"rewind\n");
    724 }
    725 
    726 static	void
    727 beginBacktrack			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int level)
    728 {
    729 	char buffer[128];
    730 
    731 	sprintf(buffer, "beginBacktrack\t%d\n", (ANTLR3_UINT32)(level & 0xFFFFFFFF));
    732 
    733 	// Transmit the message and wait for ack
    734 	//
    735 	transmit(delboy, buffer);
    736 }
    737 
    738 static	void
    739 endBacktrack			(pANTLR3_DEBUG_EVENT_LISTENER delboy, int level, ANTLR3_BOOLEAN successful)
    740 {
    741 	char buffer[128];
    742 
    743 	sprintf(buffer, "endBacktrack\t%d\t%d\n", level, successful);
    744 
    745 	// Transmit the message and wait for ack
    746 	//
    747 	transmit(delboy, buffer);
    748 }
    749 
    750 static	void
    751 location				(pANTLR3_DEBUG_EVENT_LISTENER delboy, int line, int pos)
    752 {
    753 	char buffer[128];
    754 
    755 	sprintf(buffer, "location\t%d\t%d\n", line, pos);
    756 
    757 	// Transmit the message and wait for ack
    758 	//
    759 	transmit(delboy, buffer);
    760 }
    761 
    762 static	void
    763 recognitionException	(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_EXCEPTION e)
    764 {
    765 	char	buffer[256];
    766 
    767 	sprintf(buffer, "exception\t%s\t%d\t%d\t%d\n", (char *)(e->name), (ANTLR3_INT32)(e->index), e->line, e->charPositionInLine);
    768 
    769 	// Transmit the message and wait for ack
    770 	//
    771 	transmit(delboy, buffer);
    772 }
    773 
    774 static	void
    775 beginResync				(pANTLR3_DEBUG_EVENT_LISTENER delboy)
    776 {
    777 	transmit(delboy, (const char *)"beginResync\n");
    778 }
    779 
    780 static	void
    781 endResync				(pANTLR3_DEBUG_EVENT_LISTENER delboy)
    782 {
    783 	transmit(delboy, (const char *)"endResync\n");
    784 }
    785 
    786 static	void
    787 semanticPredicate		(pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_BOOLEAN result, const char * predicate)
    788 {
    789 	unsigned char * buffer;
    790 	unsigned char * out;
    791 
    792 	if	(predicate != NULL)
    793 	{
    794 		buffer	= (unsigned char *)ANTLR3_MALLOC(64 + 2*strlen(predicate));
    795 
    796 		if	(buffer != NULL)
    797 		{
    798 			out = buffer + sprintf((char *)buffer, "semanticPredicate\t%s\t", result == ANTLR3_TRUE ? "true" : "false");
    799 
    800 			while (*predicate != '\0')
    801 			{
    802 				switch(*predicate)
    803 				{
    804 					case	'\n':
    805 
    806 						*out++	= '%';
    807 						*out++	= '0';
    808 						*out++	= 'A';
    809 						break;
    810 
    811 					case	'\r':
    812 
    813 						*out++	= '%';
    814 						*out++	= '0';
    815 						*out++	= 'D';
    816 						break;
    817 
    818 					case	'%':
    819 
    820 						*out++	= '%';
    821 						*out++	= '0';
    822 						*out++	= 'D';
    823 						break;
    824 
    825 
    826 					default:
    827 
    828 						*out++	= *predicate;
    829 						break;
    830 				}
    831 
    832 				predicate++;
    833 			}
    834 			*out++	= '\n';
    835 			*out++	= '\0';
    836 		}
    837 
    838 		// Send it and wait for the ack
    839 		//
    840 		transmit(delboy, (const char *)buffer);
    841 	}
    842 }
    843 
    844 #ifdef ANTLR3_WINDOWS
    845 #pragma warning	(push)
    846 #pragma warning (disable : 4100)
    847 #endif
    848 
    849 static	void
    850 commence				(pANTLR3_DEBUG_EVENT_LISTENER delboy)
    851 {
    852 	// Nothing to see here
    853 	//
    854 }
    855 
    856 #ifdef ANTLR3_WINDOWS
    857 #pragma warning	(pop)
    858 #endif
    859 
    860 static	void
    861 terminate				(pANTLR3_DEBUG_EVENT_LISTENER delboy)
    862 {
    863 	// Terminate sequence
    864 	//
    865 	sockSend(delboy->socket, "terminate\n", 10);		// Send out the command
    866 }
    867 
    868 //----------------------------------------------------------------
    869 // Tree parsing events
    870 //
    871 static	void
    872 consumeNode				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
    873 {
    874 	pANTLR3_STRING	buffer;
    875 
    876 	buffer = serializeNode	(delboy, t);
    877 
    878 	// Now prepend the command
    879 	//
    880 	buffer->insert8	(buffer, 0, "consumeNode\t");
    881 	buffer->addc	(buffer, '\n');
    882 
    883 	// Send to the debugger and wait for the ack
    884 	//
    885 	transmit		(delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
    886 }
    887 
    888 static	void
    889 LTT						(pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_BASE_TREE t)
    890 {
    891 	pANTLR3_STRING	buffer;
    892 
    893 	buffer = serializeNode	(delboy, t);
    894 
    895 	// Now prepend the command
    896 	//
    897 	buffer->insert8	(buffer, 0, "\t");
    898 	buffer->inserti	(buffer, 0, i);
    899 	buffer->insert8	(buffer, 0, "LN\t");
    900 	buffer->addc	(buffer, '\n');
    901 
    902 	// Send to the debugger and wait for the ack
    903 	//
    904 	transmit		(delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
    905 }
    906 
    907 static	void
    908 nilNode					(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
    909 {
    910 	char	buffer[128];
    911 	sprintf(buffer, "nilNode\t%d\n", delboy->adaptor->getUniqueID(delboy->adaptor, t));
    912 	transmit(delboy, buffer);
    913 }
    914 
    915 static	void
    916 createNode				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
    917 {
    918 	// Do we already have a serialization buffer?
    919 	//
    920 	if	(delboy->tokenString == NULL)
    921 	{
    922 		// No, so create one, using the string factory that
    923 		// the grammar name used, which is guaranteed to exist.
    924 		// 64 bytes will do us here for starters.
    925 		//
    926 		delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
    927 	}
    928 
    929 	// Empty string
    930 	//
    931 	delboy->tokenString->set8(delboy->tokenString, (const char *)"createNodeFromTokenElements ");
    932 
    933 	// Now we serialize the elements of the node.Note that the debugger only
    934 	// uses 32 bits.
    935 	//
    936 	// Adaptor ID
    937 	//
    938 	delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getUniqueID(delboy->adaptor, t));
    939 	delboy->tokenString->addc(delboy->tokenString, '\t');
    940 
    941 	// Type of the current token (which may be imaginary)
    942 	//
    943 	delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getType(delboy->adaptor, t));
    944 
    945 	// The text that this node represents
    946 	//
    947 	serializeText(delboy->tokenString, delboy->adaptor->getText(delboy->adaptor, t));
    948 	delboy->tokenString->addc(delboy->tokenString, '\n');
    949 
    950 	// Finally, as the debugger is a Java program it will expect to get UTF-8
    951 	// encoded strings. We don't use UTF-8 internally to the C runtime, so we
    952 	// must force encode it. We have a method to do this in the string class, but
    953 	// there is no utf8 string implementation as of yet
    954 	//
    955 	transmit(delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
    956 
    957 }
    958 static void
    959 errorNode				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
    960 {
    961 	// Do we already have a serialization buffer?
    962 	//
    963 	if	(delboy->tokenString == NULL)
    964 	{
    965 		// No, so create one, using the string factory that
    966 		// the grammar name used, which is guaranteed to exist.
    967 		// 64 bytes will do us here for starters.
    968 		//
    969 		delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
    970 	}
    971 
    972 	// Empty string
    973 	//
    974 	delboy->tokenString->set8(delboy->tokenString, (const char *)"errorNode\t");
    975 
    976 	// Now we serialize the elements of the node.Note that the debugger only
    977 	// uses 32 bits.
    978 	//
    979 	// Adaptor ID
    980 	//
    981 	delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getUniqueID(delboy->adaptor, t));
    982 	delboy->tokenString->addc(delboy->tokenString, '\t');
    983 
    984 	// Type of the current token (which is an error)
    985 	//
    986 	delboy->tokenString->addi(delboy->tokenString, ANTLR3_TOKEN_INVALID);
    987 
    988 	// The text that this node represents
    989 	//
    990 	serializeText(delboy->tokenString, delboy->adaptor->getText(delboy->adaptor, t));
    991 	delboy->tokenString->addc(delboy->tokenString, '\n');
    992 
    993 	// Finally, as the debugger is a Java program it will expect to get UTF-8
    994 	// encoded strings. We don't use UTF-8 internally to the C runtime, so we
    995 	// must force encode it. We have a method to do this in the string class, but
    996 	// there is no utf8 string implementation as of yet
    997 	//
    998 	transmit(delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
    999 
   1000 }
   1001 
   1002 static	void
   1003 createNodeTok			(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE node, pANTLR3_COMMON_TOKEN token)
   1004 {
   1005 	char	buffer[128];
   1006 
   1007 	sprintf(buffer, "createNode\t%d\t%d\n",	delboy->adaptor->getUniqueID(delboy->adaptor, node), (ANTLR3_UINT32)token->getTokenIndex(token));
   1008 
   1009 	transmit(delboy, buffer);
   1010 }
   1011 
   1012 static	void
   1013 becomeRoot				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot)
   1014 {
   1015 	char	buffer[128];
   1016 
   1017 	sprintf(buffer, "becomeRoot\t%d\t%d\n",	delboy->adaptor->getUniqueID(delboy->adaptor, newRoot),
   1018 											delboy->adaptor->getUniqueID(delboy->adaptor, oldRoot)
   1019 											);
   1020 	transmit(delboy, buffer);
   1021 }
   1022 
   1023 
   1024 static	void
   1025 addChild				(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE root, pANTLR3_BASE_TREE child)
   1026 {
   1027 	char	buffer[128];
   1028 
   1029 	sprintf(buffer, "addChild\t%d\t%d\n",	delboy->adaptor->getUniqueID(delboy->adaptor, root),
   1030 											delboy->adaptor->getUniqueID(delboy->adaptor, child)
   1031 											);
   1032 	transmit(delboy, buffer);
   1033 }
   1034 
   1035 static	void
   1036 setTokenBoundaries		(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t, ANTLR3_MARKER tokenStartIndex, ANTLR3_MARKER tokenStopIndex)
   1037 {
   1038 	char	buffer[128];
   1039 
   1040 	sprintf(buffer, "becomeRoot\t%d\t%d\t%d\n",	delboy->adaptor->getUniqueID(delboy->adaptor, t),
   1041 												(ANTLR3_UINT32)tokenStartIndex,
   1042 												(ANTLR3_UINT32)tokenStopIndex
   1043 											);
   1044 	transmit(delboy, buffer);
   1045 }
   1046 #endif
   1047 
   1048