]> pd.if.org Git - pccts/blob - h/ATokenBuffer.cpp
auto commit for import
[pccts] / h / ATokenBuffer.cpp
1 /* ANTLRTokenBuffer.C
2  *
3  * SOFTWARE RIGHTS
4  *
5  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
6  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
7  * company may do whatever they wish with source code distributed with
8  * PCCTS or the code generated by PCCTS, including the incorporation of
9  * PCCTS, or its output, into commerical software.
10  * 
11  * We encourage users to develop software with PCCTS.  However, we do ask
12  * that credit is given to us for developing PCCTS.  By "credit",
13  * we mean that if you incorporate our source code into one of your
14  * programs (commercial product, research project, or otherwise) that you
15  * acknowledge this fact somewhere in the documentation, research report,
16  * etc...  If you like PCCTS and have developed a nice tool with the
17  * output, please mention that you developed it using PCCTS.  In
18  * addition, we ask that this header remain intact in our source code.
19  * As long as these guidelines are kept, we expect to continue enhancing
20  * this system and expect to make other tools available as they are
21  * completed.
22  *
23  * ANTLR 1.33
24  * Terence Parr
25  * Parr Research Corporation
26  * with Purdue University and AHPCRC, University of Minnesota
27  * 1989-1995
28  */
29
30 typedef int ANTLRTokenType;     // fool AToken.h into compiling
31
32 #define ANTLR_SUPPORT_CODE
33
34 #include "config.h"
35 #include ATOKENBUFFER_H
36 typedef ANTLRAbstractToken *_ANTLRTokenPtr;
37
38 #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
39 static unsigned char test[1000];
40 #endif
41
42 #ifdef DBG_REFCOUNTTOKEN
43 int ANTLRCommonToken::ctor = 0;
44 int ANTLRCommonToken::dtor = 0;
45 #endif
46
47 ANTLRTokenBuffer::
48 ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _cs)
49 {
50         this->input = _input;
51         this->k = _k;
52         buffer_size = chunk_size = _cs;
53         buffer = (_ANTLRTokenPtr *)
54                          calloc(chunk_size+1,sizeof(_ANTLRTokenPtr ));
55         if ( buffer == NULL ) {
56                 panic("cannot alloc token buffer");
57         }
58         buffer++;                               // leave the first elem empty so tp-1 is valid ptr
59
60         tp = &buffer[0];
61         last = tp-1;
62         next = &buffer[0];
63         num_markers = 0;
64         end_of_buffer = &buffer[buffer_size-1];
65         threshold = &buffer[(int)(buffer_size*(1.0/2.0))];
66         _deleteTokens = 1;      // assume we delete tokens
67 }
68
69 static void f() {;}
70 ANTLRTokenBuffer::
71 ~ANTLRTokenBuffer()
72 {
73         f();
74         // Delete all remaining tokens (from 0..last inclusive)
75         if ( _deleteTokens )
76         {
77                 _ANTLRTokenPtr *z;
78                 for (z=buffer; z<=last; z++)
79                 {
80                         (*z)->deref();
81 //                      z->deref();
82 #ifdef DBG_REFCOUNTTOKEN
83                                         fprintf(stderr, "##########dtor: deleting token '%s' (ref %d)\n",
84                                                         ((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
85 #endif
86                         if ( (*z)->nref()==0 )
87                         {
88                                 delete (*z);
89                         }
90                 }
91         }
92
93         if ( buffer!=NULL ) free((char *)(buffer-1));
94 }
95
96 #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
97 #include <stdio.h>
98 #endif
99
100 _ANTLRTokenPtr ANTLRTokenBuffer::
101 getToken()
102 {
103         if ( tp <= last )       // is there any buffered lookahead still to be read?
104         {
105                 return *tp++;   // read buffered lookahead
106         }
107         // out of buffered lookahead, get some more "real"
108         // input from getANTLRToken()
109         if ( num_markers==0 )
110         {
111                 if( next > threshold )
112                 {
113 #ifdef DBG_TBUF
114 fprintf(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer);
115 #endif
116                         makeRoom();
117                 }
118         }
119         else {
120                 if ( next > end_of_buffer )
121                 {
122 #ifdef DBG_TBUF
123 fprintf(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size);
124 #endif
125                         extendBuffer();
126                 }
127         }
128         *next = getANTLRToken();
129         (*next)->ref();                         // say we have a copy of this pointer in buffer
130         last = next;
131         next++;
132         tp = last;
133         return *tp++;
134 }
135
136 void ANTLRTokenBuffer::
137 rewind(int pos)
138 {
139 #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
140         fprintf(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]);
141         test[pos]--;
142 #endif
143         tp = &buffer[pos];
144         num_markers--;
145 }
146
147 /*
148  * This function is used to specify that the token pointers read
149  * by the ANTLRTokenBuffer should be buffered up (to be reused later).
150  */
151 int ANTLRTokenBuffer::
152 mark()
153 {
154 #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
155         test[tp-buffer]++;
156         fprintf(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]);
157 #endif
158         num_markers++;
159         return tp - buffer;
160 }
161
162 /*
163  * returns the token pointer n positions ahead.
164  * This implies that bufferedToken(1) gets the NEXT symbol of lookahead.
165  * This is used in conjunction with the ANTLRParser lookahead buffer.
166  *
167  * No markers are set or anything.  A bunch of input is buffered--that's all.
168  * The tp pointer is left alone as the lookahead has not been advanced
169  * with getToken().  The next call to getToken() will find a token
170  * in the buffer and won't have to call getANTLRToken().
171  *
172  * If this is called before a consume() is done, how_many_more_i_need is
173  * set to 'n'.
174  */
175 _ANTLRTokenPtr ANTLRTokenBuffer::
176 bufferedToken(int n)
177 {
178 //      int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1;
179         int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1;
180         // Make sure that at least n tokens are available in the buffer
181 #ifdef DBG_TBUF
182         fprintf(stderr, "bufferedToken(%d)\n", n);
183 #endif
184         for (int i=1; i<=how_many_more_i_need; i++)
185         {
186                 if ( next > end_of_buffer )     // buffer overflow?
187                 {
188                         extendBuffer();
189                 }
190                 *next = getANTLRToken();
191                 (*next)->ref();         // say we have a copy of this pointer in buffer
192                 last = next;
193                 next++;
194         }
195         return tp[n - 1];
196 }
197
198 /* If no markers are set, the none of the input needs to be saved (except
199  * for the lookahead Token pointers).  We save only k-1 token pointers as
200  * we are guaranteed to do a getANTLRToken() right after this because otherwise
201  * we wouldn't have needed to extend the buffer.
202  *
203  * If there are markers in the buffer, we need to save things and so
204  * extendBuffer() is called.
205  */
206 void ANTLRTokenBuffer::
207 makeRoom()
208 {
209 #ifdef DBG_TBUF
210         fprintf(stderr, "in makeRoom.................\n");
211         fprintf(stderr, "num_markers==%d\n", num_markers);
212 #endif
213 /*
214         if ( num_markers == 0 )
215         {
216 */
217 #ifdef DBG_TBUF
218                 fprintf(stderr, "moving lookahead and resetting next\n");
219
220                 _ANTLRTokenPtr *r;
221                 fprintf(stderr, "tbuf = [");
222                 for (r=buffer; r<=last; r++)
223                 {
224                         if ( *r==NULL ) fprintf(stderr, " xxx");
225                         else fprintf(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText());
226                 }
227                 fprintf(stderr, " ]\n");
228
229                 fprintf(stderr,
230                 "before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer);
231 #endif
232
233                 // Delete all tokens from 0..last-(k-1) inclusive
234                 if ( _deleteTokens )
235                 {
236                         _ANTLRTokenPtr *z;
237                         for (z=buffer; z<=last-(k-1); z++)
238                         {
239                                 (*z)->deref();
240 //                              z->deref();
241 #ifdef DBG_REFCOUNTTOKEN
242                                         fprintf(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n",
243                                                         ((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
244 #endif
245                                 if ( (*z)->nref()==0 )
246                                 {
247                                         delete (*z);
248                                 }
249                         }
250                 }
251
252                 // reset the buffer to initial conditions, but move k-1 symbols
253                 // to the beginning of buffer and put new input symbol at k
254                 _ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1;
255 //              ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1;
256 #ifdef DBG_TBUF
257                 fprintf(stderr, "lookahead buffer = [");
258 #endif
259                 for (int i=1; i<=(k-1); i++)
260                 {
261                         *p++ = *q++;
262 #ifdef DBG_TBUF
263                         fprintf(stderr,
264                         " '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());
265 #endif
266                 }
267 #ifdef DBG_TBUF
268                 fprintf(stderr, " ]\n");
269 #endif
270                 next = &buffer[k-1];
271                 tp = &buffer[k-1];      // tp points to what will be filled in next
272                 last = tp-1;
273 #ifdef DBG_TBUF
274                 fprintf(stderr,
275                 "after: tp=%d, last=%d, next=%d\n",
276                 tp-buffer, last-buffer, next-buffer);
277 #endif
278 /*
279         }
280         else {
281                 extendBuffer();
282         }
283 */
284 }
285
286 /* This function extends 'buffer' by chunk_size and returns with all
287  * pointers at the same relative positions in the buffer (the buffer base
288  * address could have changed in realloc()) except that 'next' comes
289  * back set to where the next token should be stored.  All other pointers
290  * are untouched.
291  */
292 void
293 ANTLRTokenBuffer::
294 extendBuffer()
295 {
296         int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;
297 #ifdef DBG_TBUF
298         fprintf(stderr, "extending physical buffer\n");
299 #endif
300         buffer_size += chunk_size;
301         buffer = (_ANTLRTokenPtr *)
302                 realloc((char *)(buffer-1),
303                                 (buffer_size+1)*sizeof(_ANTLRTokenPtr ));
304         if ( buffer == NULL ) {
305                 panic("cannot alloc token buffer");
306         }
307         buffer++;                               // leave the first elem empty so tp-1 is valid ptr
308
309         tp = buffer + save_tp;  // put the pointers back to same relative position
310         last = buffer + save_last;
311         next = buffer + save_next;
312         end_of_buffer = &buffer[buffer_size-1];
313         threshold = &buffer[(int)(buffer_size*(1.0/2.0))];
314
315 /*
316         // zero out new token ptrs so we'll know if something to delete in buffer
317         ANTLRAbstractToken **p = end_of_buffer-chunk_size+1;
318         for (; p<=end_of_buffer; p++) *p = NULL;
319 */
320 }
321
322 /* to avoid having to link in another file just for the smart token ptr
323  * stuff, we include it here.  Ugh.
324  */
325 #include ATOKPTR_C