summaryrefslogtreecommitdiff
path: root/BaseTools/Source/C/VfrCompile/Pccts/h/ATokenBuffer.cpp
blob: 9a2f2fc88b81265065dbbecd2303fa273ba2907b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/* ANTLRTokenBuffer.cpp
 *
 * SOFTWARE RIGHTS
 *
 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
 * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
 * company may do whatever they wish with source code distributed with
 * PCCTS or the code generated by PCCTS, including the incorporation of
 * PCCTS, or its output, into commerical software.
 *
 * We encourage users to develop software with PCCTS.  However, we do ask
 * that credit is given to us for developing PCCTS.  By "credit",
 * we mean that if you incorporate our source code into one of your
 * programs (commercial product, research project, or otherwise) that you
 * acknowledge this fact somewhere in the documentation, research report,
 * etc...  If you like PCCTS and have developed a nice tool with the
 * output, please mention that you developed it using PCCTS.  In
 * addition, we ask that this header remain intact in our source code.
 * As long as these guidelines are kept, we expect to continue enhancing
 * this system and expect to make other tools available as they are
 * completed.
 *
 * ANTLR 1.33
 * Terence Parr
 * Parr Research Corporation
 * with Purdue University and AHPCRC, University of Minnesota
 * 1989-2000
 */

typedef int ANTLRTokenType;	// fool AToken.h into compiling

class ANTLRParser;					/* MR1 */

#define ANTLR_SUPPORT_CODE

#include "pcctscfg.h"

#include ATOKENBUFFER_H
#include APARSER_H		// MR23

typedef ANTLRAbstractToken *_ANTLRTokenPtr;

#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
static unsigned char test[1000];
#endif

#ifdef DBG_REFCOUNTTOKEN
int ANTLRRefCountToken::ctor = 0; /* MR23 */
int ANTLRRefCountToken::dtor = 0; /* MR23 */
#endif

ANTLRTokenBuffer::
ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _chunk_size_formal) /* MR14 */
{
	this->input = _input;
	this->k = _k;
	buffer_size = chunk_size = _chunk_size_formal;
	buffer = (_ANTLRTokenPtr *)
			 calloc(chunk_size+1,sizeof(_ANTLRTokenPtr ));
	if ( buffer == NULL ) {
		panic("cannot alloc token buffer");
	}
	buffer++;				// leave the first elem empty so tp-1 is valid ptr

	tp = &buffer[0];
	last = tp-1;
	next = &buffer[0];
	num_markers = 0;
	end_of_buffer = &buffer[buffer_size-1];
	threshold = &buffer[(int)(buffer_size/2)];	// MR23 - Used to be 1.0/2.0 !
	_deleteTokens = 1; 	// assume we delete tokens
	parser=NULL;				// MR5 - uninitialized reference
}

static void f() {;}
ANTLRTokenBuffer::
~ANTLRTokenBuffer()
{
	f();
	// Delete all remaining tokens (from 0..last inclusive)
	if ( _deleteTokens )
	{
		_ANTLRTokenPtr *z;
		for (z=buffer; z<=last; z++)
		{
			(*z)->deref();
//			z->deref();
#ifdef DBG_REFCOUNTTOKEN
					/* MR23 */ printMessage(stderr, "##########dtor: deleting token '%s' (ref %d)\n",
							((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
#endif
			if ( (*z)->nref()==0 )
			{
				delete (*z);
			}
		}
	}

	if ( buffer!=NULL ) free((char *)(buffer-1));
}

#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
#include "pccts_stdio.h"
PCCTS_NAMESPACE_STD
#endif

_ANTLRTokenPtr ANTLRTokenBuffer::
getToken()
{
	if ( tp <= last )	// is there any buffered lookahead still to be read?
	{
		return *tp++;	// read buffered lookahead
	}
	// out of buffered lookahead, get some more "real"
	// input from getANTLRToken()
	if ( num_markers==0 )
	{
		if( next > threshold )
		{
#ifdef DBG_TBUF
/* MR23 */ printMessage(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer);
#endif
			makeRoom();
		}
	}
	else {
		if ( next > end_of_buffer )
		{
#ifdef DBG_TBUF
/* MR23 */ printMessage(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size);
#endif
			extendBuffer();
		}
	}
	*next = getANTLRToken();
	(*next)->ref();				// say we have a copy of this pointer in buffer
	last = next;
	next++;
	tp = last;
	return *tp++;
}

void ANTLRTokenBuffer::
rewind(int pos)
{
#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
	/* MR23 */ printMessage(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]);
	test[pos]--;
#endif
	tp = &buffer[pos];
	num_markers--;
}

/*
 * This function is used to specify that the token pointers read
 * by the ANTLRTokenBuffer should be buffered up (to be reused later).
 */
int ANTLRTokenBuffer::
mark()
{
#if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
	test[tp-buffer]++;
	/* MR23 */ printMessage(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]);
#endif
	num_markers++;
	return tp - buffer;
}

/*
 * returns the token pointer n positions ahead.
 * This implies that bufferedToken(1) gets the NEXT symbol of lookahead.
 * This is used in conjunction with the ANTLRParser lookahead buffer.
 *
 * No markers are set or anything.  A bunch of input is buffered--that's all.
 * The tp pointer is left alone as the lookahead has not been advanced
 * with getToken().  The next call to getToken() will find a token
 * in the buffer and won't have to call getANTLRToken().
 *
 * If this is called before a consume() is done, how_many_more_i_need is
 * set to 'n'.
 */
_ANTLRTokenPtr ANTLRTokenBuffer::
bufferedToken(int n)
{
//	int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1;
	int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1;
	// Make sure that at least n tokens are available in the buffer
#ifdef DBG_TBUF
	/* MR23 */ printMessage(stderr, "bufferedToken(%d)\n", n);
#endif
	for (int i=1; i<=how_many_more_i_need; i++)
	{
		if ( next > end_of_buffer )	// buffer overflow?
		{
			extendBuffer();
		}
		*next = getANTLRToken();
		(*next)->ref();		// say we have a copy of this pointer in buffer
		last = next;
		next++;
	}
	return tp[n - 1];
}

/* If no markers are set, the none of the input needs to be saved (except
 * for the lookahead Token pointers).  We save only k-1 token pointers as
 * we are guaranteed to do a getANTLRToken() right after this because otherwise
 * we wouldn't have needed to extend the buffer.
 *
 * If there are markers in the buffer, we need to save things and so
 * extendBuffer() is called.
 */
void ANTLRTokenBuffer::
makeRoom()
{
#ifdef DBG_TBUF
	/* MR23 */ printMessage(stderr, "in makeRoom.................\n");
	/* MR23 */ printMessage(stderr, "num_markers==%d\n", num_markers);
#endif
/*
	if ( num_markers == 0 )
	{
*/
#ifdef DBG_TBUF
		/* MR23 */ printMessage(stderr, "moving lookahead and resetting next\n");

		_ANTLRTokenPtr *r;
		/* MR23 */ printMessage(stderr, "tbuf = [");
		for (r=buffer; r<=last; r++)
		{
			if ( *r==NULL ) /* MR23 */ printMessage(stderr, " xxx");
			else /* MR23 */ printMessage(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText());
		}
		/* MR23 */ printMessage(stderr, " ]\n");

		/* MR23 */ printMessage(stderr,
		"before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer);
#endif

		// Delete all tokens from 0..last-(k-1) inclusive
		if ( _deleteTokens )
		{
			_ANTLRTokenPtr *z;
			for (z=buffer; z<=last-(k-1); z++)
			{
				(*z)->deref();
//				z->deref();
#ifdef DBG_REFCOUNTTOKEN
					/* MR23 */ printMessage(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n",
							((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
#endif
				if ( (*z)->nref()==0 )
				{
					delete (*z);
				}
			}
		}

		// reset the buffer to initial conditions, but move k-1 symbols
		// to the beginning of buffer and put new input symbol at k
		_ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1;
//		ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1;
#ifdef DBG_TBUF
		/* MR23 */ printMessage(stderr, "lookahead buffer = [");
#endif
		for (int i=1; i<=(k-1); i++)
		{
			*p++ = *q++;
#ifdef DBG_TBUF
			/* MR23 */ printMessage(stderr,
			" '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());
#endif
		}
#ifdef DBG_TBUF
		/* MR23 */ printMessage(stderr, " ]\n");
#endif
		next = &buffer[k-1];
		tp = &buffer[k-1];	// tp points to what will be filled in next
		last = tp-1;
#ifdef DBG_TBUF
		/* MR23 */ printMessage(stderr,
		"after: tp=%d, last=%d, next=%d\n",
		tp-buffer, last-buffer, next-buffer);
#endif
/*
	}
	else {
		extendBuffer();
	}
*/
}

/* This function extends 'buffer' by chunk_size and returns with all
 * pointers at the same relative positions in the buffer (the buffer base
 * address could have changed in realloc()) except that 'next' comes
 * back set to where the next token should be stored.  All other pointers
 * are untouched.
 */
void
ANTLRTokenBuffer::
extendBuffer()
{
	int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;
#ifdef DBG_TBUF
	/* MR23 */ printMessage(stderr, "extending physical buffer\n");
#endif
	buffer_size += chunk_size;
	buffer = (_ANTLRTokenPtr *)
		realloc((char *)(buffer-1),
				(buffer_size+1)*sizeof(_ANTLRTokenPtr ));
	if ( buffer == NULL ) {
		panic("cannot alloc token buffer");
	}
	buffer++;				// leave the first elem empty so tp-1 is valid ptr

	tp = buffer + save_tp;	// put the pointers back to same relative position
	last = buffer + save_last;
	next = buffer + save_next;
	end_of_buffer = &buffer[buffer_size-1];
	threshold = &buffer[(int)(buffer_size*(1.0/2.0))];

/*
	// zero out new token ptrs so we'll know if something to delete in buffer
	ANTLRAbstractToken **p = end_of_buffer-chunk_size+1;
	for (; p<=end_of_buffer; p++) *p = NULL;
*/
}

ANTLRParser * ANTLRTokenBuffer::				// MR1
setParser(ANTLRParser *p) {					// MR1
  ANTLRParser	*old=parser;					// MR1
  parser=p;							// MR1
  input->setParser(p);						// MR1
  return old;							// MR1
}								// MR1
								// MR1
ANTLRParser * ANTLRTokenBuffer::				// MR1
getParser() {							// MR1
  return parser;						// MR1
}								// MR1

void ANTLRTokenBuffer::panic(const char *msg) // MR23
{ 
	if (parser)				//MR23
		parser->panic(msg);	//MR23
	else					//MR23
		exit(PCCTS_EXIT_FAILURE); 
} 

//MR23
int ANTLRTokenBuffer::printMessage(FILE* pFile, const char* pFormat, ...)
{
	va_list marker;
	va_start( marker, pFormat );

	int iRet = 0;
	if (parser)
		parser->printMessageV(pFile, pFormat, marker);
	else
  		iRet = vfprintf(pFile, pFormat, marker);

	va_end( marker );
	return iRet;
}

/* to avoid having to link in another file just for the smart token ptr
 * stuff, we include it here.  Ugh.
 *
 * MR23 This causes nothing but problems for IDEs.
 *      Change from .cpp to .h
 *
 */

#include ATOKPTR_IMPL_H