2 /// Provides the debugging functions invoked by a recognizer
\r
3 /// built using the debug generator mode of the antlr tool.
\r
4 /// See antlr3debugeventlistener.h for documentation.
\r
7 // [The "BSD licence"]
\r
8 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
\r
9 // http://www.temporal-wave.com
\r
10 // http://www.linkedin.com/in/jimidle
\r
12 // All rights reserved.
\r
14 // Redistribution and use in source and binary forms, with or without
\r
15 // modification, are permitted provided that the following conditions
\r
17 // 1. Redistributions of source code must retain the above copyright
\r
18 // notice, this list of conditions and the following disclaimer.
\r
19 // 2. Redistributions in binary form must reproduce the above copyright
\r
20 // notice, this list of conditions and the following disclaimer in the
\r
21 // documentation and/or other materials provided with the distribution.
\r
22 // 3. The name of the author may not be used to endorse or promote products
\r
23 // derived from this software without specific prior written permission.
\r
25 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
26 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
27 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
28 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
30 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
34 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
38 // Not everyone wishes to include the debugger stuff in their final deployment because
\r
39 // it will then rely on being linked with the socket libraries. Hence if the programmer turns
\r
40 // off the debugging, we do some dummy stuff that satifies compilers etc but means there is
\r
41 // no debugger and no reliance on the socket librarires. If you set this flag, then using the -debug
\r
42 // option to generate your code will produce code that just crashes, but then I presme you are smart
\r
43 // enough to realize that building the libraries without debugger support means you can't call the
\r
46 #ifdef ANTLR3_NODEBUGGER
\r
47 ANTLR3_API pANTLR3_DEBUG_EVENT_LISTENER
\r
48 antlr3DebugListenerNew()
\r
50 ANTLR3_PRINTF("C runtime was compiled without debugger support. This program will crash!!");
\r
55 static ANTLR3_BOOLEAN handshake (pANTLR3_DEBUG_EVENT_LISTENER delboy);
\r
56 static void enterRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName);
\r
57 static void enterAlt (pANTLR3_DEBUG_EVENT_LISTENER delboy, int alt);
\r
58 static void exitRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName);
\r
59 static void enterSubRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
\r
60 static void exitSubRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
\r
61 static void enterDecision (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
\r
62 static void exitDecision (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber);
\r
63 static void consumeToken (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t);
\r
64 static void consumeHiddenToken (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t);
\r
65 static void LT (pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_COMMON_TOKEN t);
\r
66 static void mark (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker);
\r
67 static void rewindMark (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker);
\r
68 static void rewindLast (pANTLR3_DEBUG_EVENT_LISTENER delboy);
\r
69 static void beginBacktrack (pANTLR3_DEBUG_EVENT_LISTENER delboy, int level);
\r
70 static void endBacktrack (pANTLR3_DEBUG_EVENT_LISTENER delboy, int level, ANTLR3_BOOLEAN successful);
\r
71 static void location (pANTLR3_DEBUG_EVENT_LISTENER delboy, int line, int pos);
\r
72 static void recognitionException (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_EXCEPTION e);
\r
73 static void beginResync (pANTLR3_DEBUG_EVENT_LISTENER delboy);
\r
74 static void endResync (pANTLR3_DEBUG_EVENT_LISTENER delboy);
\r
75 static void semanticPredicate (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_BOOLEAN result, const char * predicate);
\r
76 static void commence (pANTLR3_DEBUG_EVENT_LISTENER delboy);
\r
77 static void terminate (pANTLR3_DEBUG_EVENT_LISTENER delboy);
\r
78 static void consumeNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
\r
79 static void LTT (pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_BASE_TREE t);
\r
80 static void nilNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
\r
81 static void errorNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
\r
82 static void createNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t);
\r
83 static void createNodeTok (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE node, pANTLR3_COMMON_TOKEN token);
\r
84 static void becomeRoot (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot);
\r
85 static void addChild (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE root, pANTLR3_BASE_TREE child);
\r
86 static void setTokenBoundaries (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t, ANTLR3_MARKER tokenStartIndex, ANTLR3_MARKER tokenStopIndex);
\r
87 static void ack (pANTLR3_DEBUG_EVENT_LISTENER delboy);
\r
89 /// Create and initialize a new debug event listener that can be connected to
\r
90 /// by ANTLRWorks and any other debugger via a socket.
\r
92 ANTLR3_API pANTLR3_DEBUG_EVENT_LISTENER
\r
93 antlr3DebugListenerNew()
\r
95 pANTLR3_DEBUG_EVENT_LISTENER delboy;
\r
97 delboy = ANTLR3_CALLOC(1, sizeof(ANTLR3_DEBUG_EVENT_LISTENER));
\r
104 // Initialize the API
\r
106 delboy->addChild = addChild;
\r
107 delboy->becomeRoot = becomeRoot;
\r
108 delboy->beginBacktrack = beginBacktrack;
\r
109 delboy->beginResync = beginResync;
\r
110 delboy->commence = commence;
\r
111 delboy->consumeHiddenToken = consumeHiddenToken;
\r
112 delboy->consumeNode = consumeNode;
\r
113 delboy->consumeToken = consumeToken;
\r
114 delboy->createNode = createNode;
\r
115 delboy->createNodeTok = createNodeTok;
\r
116 delboy->endBacktrack = endBacktrack;
\r
117 delboy->endResync = endResync;
\r
118 delboy->enterAlt = enterAlt;
\r
119 delboy->enterDecision = enterDecision;
\r
120 delboy->enterRule = enterRule;
\r
121 delboy->enterSubRule = enterSubRule;
\r
122 delboy->exitDecision = exitDecision;
\r
123 delboy->exitRule = exitRule;
\r
124 delboy->exitSubRule = exitSubRule;
\r
125 delboy->handshake = handshake;
\r
126 delboy->location = location;
\r
129 delboy->mark = mark;
\r
130 delboy->nilNode = nilNode;
\r
131 delboy->recognitionException = recognitionException;
\r
132 delboy->rewind = rewindMark;
\r
133 delboy->rewindLast = rewindLast;
\r
134 delboy->semanticPredicate = semanticPredicate;
\r
135 delboy->setTokenBoundaries = setTokenBoundaries;
\r
136 delboy->terminate = terminate;
\r
137 delboy->errorNode = errorNode;
\r
139 delboy->PROTOCOL_VERSION = 2; // ANTLR 3.1 is at protocol version 2
\r
141 delboy->port = DEFAULT_DEBUGGER_PORT;
\r
146 pANTLR3_DEBUG_EVENT_LISTENER
\r
147 antlr3DebugListenerNewPort(ANTLR3_UINT32 port)
\r
149 pANTLR3_DEBUG_EVENT_LISTENER delboy;
\r
151 delboy = antlr3DebugListenerNew();
\r
153 if (delboy != NULL)
\r
155 delboy->port = port;
\r
161 //--------------------------------------------------------------------------------
\r
162 // Support functions for sending stuff over the socket interface
\r
165 sockSend(SOCKET sock, const char * ptr, int len)
\r
174 // Send as many bytes as we can
\r
176 thisSend = send(sock, ptr, len - sent, 0);
\r
178 // Check for errors and tell the user if we got one
\r
180 if (thisSend == -1)
\r
182 return ANTLR3_FALSE;
\r
185 // Increment our offset by how many we were able to send
\r
190 return ANTLR3_TRUE;
\r
193 static ANTLR3_BOOLEAN
\r
194 handshake (pANTLR3_DEBUG_EVENT_LISTENER delboy)
\r
196 /// Connection structure with which to wait and accept a connection from
\r
199 SOCKET serverSocket;
\r
201 // Connection structures to deal with the client after we accept the connection
\r
202 // and the server while we accept a connection.
\r
204 ANTLR3_SOCKADDRT client;
\r
205 ANTLR3_SOCKADDRT server;
\r
207 // Buffer to construct our message in
\r
211 // Specifies the length of the connection structure to accept()
\r
212 // Windows use int, everyone else uses size_t
\r
214 ANTLR3_SALENT sockaddr_len;
\r
216 // Option holder for setsockopt()
\r
220 if (delboy->initialized == ANTLR3_FALSE)
\r
222 // Windows requires us to initialize WinSock.
\r
224 #ifdef ANTLR3_WINDOWS
\r
226 WORD wVersionRequested;
\r
228 int err; // Return code from WSAStartup
\r
230 // We must initialise the Windows socket system when the DLL is loaded.
\r
231 // We are asking for Winsock 1.1 or better as we don't need anything
\r
232 // too complicated for this.
\r
234 wVersionRequested = MAKEWORD( 1, 1);
\r
236 err = WSAStartup( wVersionRequested, &wsaData );
\r
240 // Tell the user that we could not find a usable
\r
248 // Create the server socket, we are the server because we just wait until
\r
249 // a debugger connects to the port we are listening on.
\r
251 serverSocket = socket(AF_INET, SOCK_STREAM, 0);
\r
253 if (serverSocket == INVALID_SOCKET)
\r
255 return ANTLR3_FALSE;
\r
258 // Set the listening port
\r
260 server.sin_port = htons((unsigned short)delboy->port);
\r
261 server.sin_family = AF_INET;
\r
262 server.sin_addr.s_addr = htonl (INADDR_ANY);
\r
264 // We could allow a rebind on the same addr/port pair I suppose, but
\r
265 // I imagine that most people will just want to start debugging one parser at once.
\r
266 // Maybe change this at some point, but rejecting the bind at this point will ensure
\r
267 // that people realize they have left something running in the background.
\r
269 if (bind(serverSocket, (pANTLR3_SOCKADDRC)&server, sizeof(server)) == -1)
\r
271 return ANTLR3_FALSE;
\r
274 // We have bound the socket to the port and address so we now ask the TCP subsystem
\r
275 // to start listening on that address/port
\r
277 if (listen(serverSocket, 1) == -1)
\r
279 // Some error, just fail
\r
281 return ANTLR3_FALSE;
\r
284 // Now we can try to accept a connection on the port
\r
286 sockaddr_len = sizeof(client);
\r
287 delboy->socket = accept(serverSocket, (pANTLR3_SOCKADDRC)&client, &sockaddr_len);
\r
289 // Having accepted a connection, we can stop listening and close down the socket
\r
291 shutdown (serverSocket, 0x02);
\r
292 ANTLR3_CLOSESOCKET (serverSocket);
\r
294 if (delboy->socket == -1)
\r
296 return ANTLR3_FALSE;
\r
299 // Disable Nagle as this is essentially a chat exchange
\r
302 setsockopt(delboy->socket, SOL_SOCKET, TCP_NODELAY, (const void *)&optVal, sizeof(optVal));
\r
306 // We now have a good socket connection with the debugging client, so we
\r
307 // send it the protocol version we are using and what the name of the grammar
\r
308 // is that we represent.
\r
310 sprintf (message, "ANTLR %d\n", delboy->PROTOCOL_VERSION);
\r
311 sockSend (delboy->socket, message, (int)strlen(message));
\r
312 sprintf (message, "grammar \"%s\n", delboy->grammarFileName->chars);
\r
313 sockSend (delboy->socket, message, (int)strlen(message));
\r
316 delboy->initialized = ANTLR3_TRUE;
\r
318 return ANTLR3_TRUE;
\r
321 // Send the supplied text and wait for an ack from the client
\r
323 transmit(pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * ptr)
\r
325 sockSend(delboy->socket, ptr, (int)strlen(ptr));
\r
330 ack (pANTLR3_DEBUG_EVENT_LISTENER delboy)
\r
332 // Local buffer to read the next character in to
\r
337 // Ack terminates in a line feed, so we just wait for
\r
338 // one of those. Speed is not of the essence so we don't need
\r
339 // to buffer the input or anything.
\r
343 rCount = recv(delboy->socket, &buffer, 1, 0);
\r
345 while (rCount == 1 && buffer != '\n');
\r
347 // If the socket ws closed on us, then we will get an error or
\r
348 // (with a graceful close), 0. We can assume the the debugger stopped for some reason
\r
349 // (such as Java crashing again). Therefore we just exit the program
\r
350 // completely if we don't get the terminating '\n' for the ack.
\r
354 ANTLR3_PRINTF("Exiting debugger as remote client closed the socket\n");
\r
355 ANTLR3_PRINTF("Received char count was %d, and last char received was %02X\n", rCount, buffer);
\r
360 // Given a buffer string and a source string, serialize the
\r
361 // text, escaping any newlines and linefeeds. We have no need
\r
362 // for speed here, this is the debugger.
\r
365 serializeText(pANTLR3_STRING buffer, pANTLR3_STRING text)
\r
368 ANTLR3_UCHAR character;
\r
370 // strings lead in with a "
\r
372 buffer->append(buffer, " \"");
\r
379 // Now we replace linefeeds, newlines and the escape
\r
380 // leadin character '%' with their hex equivalents
\r
383 for (c = 0; c < text->len; c++)
\r
385 switch (character = text->charAt(text, c))
\r
389 buffer->append(buffer, "%0A");
\r
394 buffer->append(buffer, "%0D");
\r
399 buffer->append(buffer, "%25");
\r
402 // Other characters: The Song Remains the Same.
\r
406 buffer->addc(buffer, character);
\r
412 // Given a token, create a stringified version of it, in the supplied
\r
413 // buffer. We create a string for this in the debug 'object', if there
\r
414 // is not one there already, and then reuse it here if asked to do this
\r
418 serializeToken(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t)
\r
420 // Do we already have a serialization buffer?
\r
422 if (delboy->tokenString == NULL)
\r
424 // No, so create one, using the string factory that
\r
425 // the grammar name used, which is guaranteed to exist.
\r
426 // 64 bytes will do us here for starters.
\r
428 delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
\r
433 delboy->tokenString->set(delboy->tokenString, (const char *)"");
\r
435 // Now we serialize the elements of the token.Note that the debugger only
\r
438 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getTokenIndex(t)));
\r
439 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
440 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getType(t)));
\r
441 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
442 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getChannel(t)));
\r
443 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
444 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getLine(t)));
\r
445 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
446 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(t->getCharPositionInLine(t)));
\r
448 // Now send the text that the token represents.
\r
450 serializeText(delboy->tokenString, t->getText(t));
\r
452 // Finally, as the debugger is a Java program it will expect to get UTF-8
\r
453 // encoded strings. We don't use UTF-8 internally to the C runtime, so we
\r
454 // must force encode it. We have a method to do this in the string class, but
\r
455 // it returns malloc space that we must free afterwards.
\r
457 return delboy->tokenString->toUTF8(delboy->tokenString);
\r
460 // Given a tree node, create a stringified version of it in the supplied
\r
464 serializeNode(pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE node)
\r
466 pANTLR3_COMMON_TOKEN token;
\r
469 // Do we already have a serialization buffer?
\r
471 if (delboy->tokenString == NULL)
\r
473 // No, so create one, using the string factory that
\r
474 // the grammar name used, which is guaranteed to exist.
\r
475 // 64 bytes will do us here for starters.
\r
477 delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
\r
482 delboy->tokenString->set(delboy->tokenString, (const char *)"");
\r
484 // Protect against bugs/errors etc
\r
488 return delboy->tokenString;
\r
491 // Now we serialize the elements of the node.Note that the debugger only
\r
494 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
498 delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getUniqueID(delboy->adaptor, node));
\r
499 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
501 // Type of the current token (which may be imaginary)
\r
503 delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getType(delboy->adaptor, node));
\r
505 // See if we have an actual token or just an imaginary
\r
507 token = delboy->adaptor->getToken(delboy->adaptor, node);
\r
509 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
514 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(token->getLine(token)));
\r
515 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
516 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_INT32)(token->getCharPositionInLine(token)));
\r
520 // Imaginary tokens have no location
\r
522 delboy->tokenString->addi(delboy->tokenString, -1);
\r
523 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
524 delboy->tokenString->addi(delboy->tokenString, -1);
\r
527 // Start Index of the node
\r
529 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
530 delboy->tokenString->addi(delboy->tokenString, (ANTLR3_UINT32)(delboy->adaptor->getTokenStartIndex(delboy->adaptor, node)));
\r
532 // Now send the text that the node represents.
\r
534 serializeText(delboy->tokenString, delboy->adaptor->getText(delboy->adaptor, node));
\r
536 // Finally, as the debugger is a Java program it will expect to get UTF-8
\r
537 // encoded strings. We don't use UTF-8 internally to the C runtime, so we
\r
538 // must force encode it. We have a method to do this in the string class, but
\r
539 // there is no utf8 string implementation as of yet
\r
541 return delboy->tokenString->toUTF8(delboy->tokenString);
\r
544 //------------------------------------------------------------------------------------------------------------------
\r
548 enterRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName)
\r
552 // Create the message (speed is not of the essence)
\r
554 sprintf(buffer, "enterRule %s %s\n", grammarFileName, ruleName);
\r
555 transmit(delboy, buffer);
\r
559 enterAlt (pANTLR3_DEBUG_EVENT_LISTENER delboy, int alt)
\r
563 // Create the message (speed is not of the essence)
\r
565 sprintf(buffer, "enterAlt %d\n", alt);
\r
566 transmit(delboy, buffer);
\r
570 exitRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName)
\r
574 // Create the message (speed is not of the essence)
\r
576 sprintf(buffer, "enterRule %s %s\n", grammarFileName, ruleName);
\r
577 transmit(delboy, buffer);
\r
581 enterSubRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
\r
585 // Create the message (speed is not of the essence)
\r
587 sprintf(buffer, "enterSubRule %d\n", decisionNumber);
\r
588 transmit(delboy, buffer);
\r
592 exitSubRule (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
\r
596 // Create the message (speed is not of the essence)
\r
598 sprintf(buffer, "exitSubRule %d\n", decisionNumber);
\r
599 transmit(delboy, buffer);
\r
603 enterDecision (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
\r
607 // Create the message (speed is not of the essence)
\r
609 sprintf(buffer, "enterDecision %d\n", decisionNumber);
\r
610 transmit(delboy, buffer);
\r
615 exitDecision (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber)
\r
619 // Create the message (speed is not of the essence)
\r
621 sprintf(buffer, "exitDecision %d\n", decisionNumber);
\r
622 transmit(delboy, buffer);
\r
626 consumeToken (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t)
\r
628 pANTLR3_STRING msg;
\r
630 // Create the serialized token
\r
632 msg = serializeToken(delboy, t);
\r
634 // Insert the debug event indicator
\r
636 msg->insert8(msg, 0, "consumeToken ");
\r
638 msg->addc(msg, '\n');
\r
640 // Transmit the message and wait for ack
\r
642 transmit(delboy, (const char *)(msg->chars));
\r
646 consumeHiddenToken (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t)
\r
648 pANTLR3_STRING msg;
\r
650 // Create the serialized token
\r
652 msg = serializeToken(delboy, t);
\r
654 // Insert the debug event indicator
\r
656 msg->insert8(msg, 0, "consumeHiddenToken ");
\r
658 msg->addc(msg, '\n');
\r
660 // Transmit the message and wait for ack
\r
662 transmit(delboy, (const char *)(msg->chars));
\r
665 // Looking at the next token event.
\r
668 LT (pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_COMMON_TOKEN t)
\r
670 pANTLR3_STRING msg;
\r
674 // Create the serialized token
\r
676 msg = serializeToken(delboy, t);
\r
678 // Insert the index parameter
\r
680 msg->insert8(msg, 0, " ");
\r
681 msg->inserti(msg, 0, i);
\r
683 // Insert the debug event indicator
\r
685 msg->insert8(msg, 0, "LT ");
\r
687 msg->addc(msg, '\n');
\r
689 // Transmit the message and wait for ack
\r
691 transmit(delboy, (const char *)(msg->chars));
\r
696 mark (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker)
\r
700 sprintf(buffer, "mark %d\n", (ANTLR3_UINT32)(marker & 0xFFFFFFFF));
\r
702 // Transmit the message and wait for ack
\r
704 transmit(delboy, buffer);
\r
708 rewindMark (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker)
\r
712 sprintf(buffer, "rewind %d\n", (ANTLR3_UINT32)(marker & 0xFFFFFFFF));
\r
714 // Transmit the message and wait for ack
\r
716 transmit(delboy, buffer);
\r
721 rewindLast (pANTLR3_DEBUG_EVENT_LISTENER delboy)
\r
723 transmit(delboy, (const char *)"rewind\n");
\r
727 beginBacktrack (pANTLR3_DEBUG_EVENT_LISTENER delboy, int level)
\r
731 sprintf(buffer, "beginBacktrack %d\n", (ANTLR3_UINT32)(level & 0xFFFFFFFF));
\r
733 // Transmit the message and wait for ack
\r
735 transmit(delboy, buffer);
\r
739 endBacktrack (pANTLR3_DEBUG_EVENT_LISTENER delboy, int level, ANTLR3_BOOLEAN successful)
\r
743 sprintf(buffer, "endBacktrack %d %d\n", level, successful);
\r
745 // Transmit the message and wait for ack
\r
747 transmit(delboy, buffer);
\r
751 location (pANTLR3_DEBUG_EVENT_LISTENER delboy, int line, int pos)
\r
755 sprintf(buffer, "location %d %d\n", line, pos);
\r
757 // Transmit the message and wait for ack
\r
759 transmit(delboy, buffer);
\r
763 recognitionException (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_EXCEPTION e)
\r
767 sprintf(buffer, "exception %s %d %d %d\n", (char *)(e->name), (ANTLR3_INT32)(e->index), e->line, e->charPositionInLine);
\r
769 // Transmit the message and wait for ack
\r
771 transmit(delboy, buffer);
\r
775 beginResync (pANTLR3_DEBUG_EVENT_LISTENER delboy)
\r
777 transmit(delboy, (const char *)"beginResync\n");
\r
781 endResync (pANTLR3_DEBUG_EVENT_LISTENER delboy)
\r
783 transmit(delboy, (const char *)"endResync\n");
\r
787 semanticPredicate (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_BOOLEAN result, const char * predicate)
\r
789 unsigned char * buffer;
\r
790 unsigned char * out;
\r
792 if (predicate != NULL)
\r
794 buffer = (unsigned char *)ANTLR3_MALLOC(64 + 2*strlen(predicate));
\r
796 if (buffer != NULL)
\r
798 out = buffer + sprintf((char *)buffer, "semanticPredicate %s ", result == ANTLR3_TRUE ? "true" : "false");
\r
800 while (*predicate != '\0')
\r
828 *out++ = *predicate;
\r
838 // Send it and wait for the ack
\r
840 transmit(delboy, (const char *)buffer);
\r
844 #ifdef ANTLR3_WINDOWS
\r
845 #pragma warning (push)
\r
846 #pragma warning (disable : 4100)
\r
850 commence (pANTLR3_DEBUG_EVENT_LISTENER delboy)
\r
852 // Nothing to see here
\r
856 #ifdef ANTLR3_WINDOWS
\r
857 #pragma warning (pop)
\r
861 terminate (pANTLR3_DEBUG_EVENT_LISTENER delboy)
\r
863 // Terminate sequence
\r
865 sockSend(delboy->socket, "terminate\n", 10); // Send out the command
\r
868 //----------------------------------------------------------------
\r
869 // Tree parsing events
\r
872 consumeNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
\r
874 pANTLR3_STRING buffer;
\r
876 buffer = serializeNode (delboy, t);
\r
878 // Now prepend the command
\r
880 buffer->insert8 (buffer, 0, "consumeNode ");
\r
881 buffer->addc (buffer, '\n');
\r
883 // Send to the debugger and wait for the ack
\r
885 transmit (delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
\r
889 LTT (pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_BASE_TREE t)
\r
891 pANTLR3_STRING buffer;
\r
893 buffer = serializeNode (delboy, t);
\r
895 // Now prepend the command
\r
897 buffer->insert8 (buffer, 0, " ");
\r
898 buffer->inserti (buffer, 0, i);
\r
899 buffer->insert8 (buffer, 0, "LN ");
\r
900 buffer->addc (buffer, '\n');
\r
902 // Send to the debugger and wait for the ack
\r
904 transmit (delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
\r
908 nilNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
\r
911 sprintf(buffer, "nilNode %d\n", delboy->adaptor->getUniqueID(delboy->adaptor, t));
\r
912 transmit(delboy, buffer);
\r
916 createNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
\r
918 // Do we already have a serialization buffer?
\r
920 if (delboy->tokenString == NULL)
\r
922 // No, so create one, using the string factory that
\r
923 // the grammar name used, which is guaranteed to exist.
\r
924 // 64 bytes will do us here for starters.
\r
926 delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
\r
931 delboy->tokenString->set8(delboy->tokenString, (const char *)"createNodeFromTokenElements ");
\r
933 // Now we serialize the elements of the node.Note that the debugger only
\r
938 delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getUniqueID(delboy->adaptor, t));
\r
939 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
941 // Type of the current token (which may be imaginary)
\r
943 delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getType(delboy->adaptor, t));
\r
945 // The text that this node represents
\r
947 serializeText(delboy->tokenString, delboy->adaptor->getText(delboy->adaptor, t));
\r
948 delboy->tokenString->addc(delboy->tokenString, '\n');
\r
950 // Finally, as the debugger is a Java program it will expect to get UTF-8
\r
951 // encoded strings. We don't use UTF-8 internally to the C runtime, so we
\r
952 // must force encode it. We have a method to do this in the string class, but
\r
953 // there is no utf8 string implementation as of yet
\r
955 transmit(delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
\r
959 errorNode (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t)
\r
961 // Do we already have a serialization buffer?
\r
963 if (delboy->tokenString == NULL)
\r
965 // No, so create one, using the string factory that
\r
966 // the grammar name used, which is guaranteed to exist.
\r
967 // 64 bytes will do us here for starters.
\r
969 delboy->tokenString = delboy->grammarFileName->factory->newSize(delboy->grammarFileName->factory, 64);
\r
974 delboy->tokenString->set8(delboy->tokenString, (const char *)"errorNode ");
\r
976 // Now we serialize the elements of the node.Note that the debugger only
\r
981 delboy->tokenString->addi(delboy->tokenString, delboy->adaptor->getUniqueID(delboy->adaptor, t));
\r
982 delboy->tokenString->addc(delboy->tokenString, ' ');
\r
984 // Type of the current token (which is an error)
\r
986 delboy->tokenString->addi(delboy->tokenString, ANTLR3_TOKEN_INVALID);
\r
988 // The text that this node represents
\r
990 serializeText(delboy->tokenString, delboy->adaptor->getText(delboy->adaptor, t));
\r
991 delboy->tokenString->addc(delboy->tokenString, '\n');
\r
993 // Finally, as the debugger is a Java program it will expect to get UTF-8
\r
994 // encoded strings. We don't use UTF-8 internally to the C runtime, so we
\r
995 // must force encode it. We have a method to do this in the string class, but
\r
996 // there is no utf8 string implementation as of yet
\r
998 transmit(delboy, (const char *)(delboy->tokenString->toUTF8(delboy->tokenString)->chars));
\r
1003 createNodeTok (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE node, pANTLR3_COMMON_TOKEN token)
\r
1007 sprintf(buffer, "createNode %d %d\n", delboy->adaptor->getUniqueID(delboy->adaptor, node), (ANTLR3_UINT32)token->getTokenIndex(token));
\r
1009 transmit(delboy, buffer);
\r
1013 becomeRoot (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot)
\r
1017 sprintf(buffer, "becomeRoot %d %d\n", delboy->adaptor->getUniqueID(delboy->adaptor, newRoot),
\r
1018 delboy->adaptor->getUniqueID(delboy->adaptor, oldRoot)
\r
1020 transmit(delboy, buffer);
\r
1025 addChild (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE root, pANTLR3_BASE_TREE child)
\r
1029 sprintf(buffer, "addChild %d %d\n", delboy->adaptor->getUniqueID(delboy->adaptor, root),
\r
1030 delboy->adaptor->getUniqueID(delboy->adaptor, child)
\r
1032 transmit(delboy, buffer);
\r
1036 setTokenBoundaries (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t, ANTLR3_MARKER tokenStartIndex, ANTLR3_MARKER tokenStopIndex)
\r
1040 sprintf(buffer, "becomeRoot %d %d %d\n", delboy->adaptor->getUniqueID(delboy->adaptor, t),
\r
1041 (ANTLR3_UINT32)tokenStartIndex,
\r
1042 (ANTLR3_UINT32)tokenStopIndex
\r
1044 transmit(delboy, buffer);
\r