ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/lsys/ATokenBuffer.cpp
Revision: 1.1
Committed: Thu Nov 6 14:31:24 2008 UTC (15 years, 6 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /* ANTLRTokenBuffer.cpp
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-2000
28     */
29    
30     typedef int ANTLRTokenType; // fool AToken.h into compiling
31    
32     class ANTLRParser; /* MR1 */
33    
34     #define ANTLR_SUPPORT_CODE
35    
36     #include "pcctscfg.h"
37    
38     #include ATOKENBUFFER_H
39     #include APARSER_H // MR23
40    
41     typedef ANTLRAbstractToken *_ANTLRTokenPtr;
42    
43     #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
44     static unsigned char test[1000];
45     #endif
46    
47     #ifdef DBG_REFCOUNTTOKEN
48     int ANTLRRefCountToken::ctor = 0; /* MR23 */
49     int ANTLRRefCountToken::dtor = 0; /* MR23 */
50     #endif
51    
52     ANTLRTokenBuffer::
53     ANTLRTokenBuffer(ANTLRTokenStream *_input, int _k, int _chunk_size_formal) /* MR14 */
54     {
55     this->input = _input;
56     this->k = _k;
57     buffer_size = chunk_size = _chunk_size_formal;
58     buffer = (_ANTLRTokenPtr *)
59     calloc(chunk_size+1,sizeof(_ANTLRTokenPtr ));
60     if ( buffer == NULL ) {
61     panic("cannot alloc token buffer");
62     }
63     buffer++; // leave the first elem empty so tp-1 is valid ptr
64    
65     tp = &buffer[0];
66     last = tp-1;
67     next = &buffer[0];
68     num_markers = 0;
69     end_of_buffer = &buffer[buffer_size-1];
70     threshold = &buffer[(int)(buffer_size/2)]; // MR23 - Used to be 1.0/2.0 !
71     _deleteTokens = 1; // assume we delete tokens
72     parser=NULL; // MR5 - uninitialized reference
73     }
74    
75     static void f() {;}
76     ANTLRTokenBuffer::
77     ~ANTLRTokenBuffer()
78     {
79     f();
80     // Delete all remaining tokens (from 0..last inclusive)
81     if ( _deleteTokens )
82     {
83     _ANTLRTokenPtr *z;
84     for (z=buffer; z<=last; z++)
85     {
86     (*z)->deref();
87     // z->deref();
88     #ifdef DBG_REFCOUNTTOKEN
89     /* MR23 */ printMessage(stderr, "##########dtor: deleting token '%s' (ref %d)\n",
90     ((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
91     #endif
92     if ( (*z)->nref()==0 )
93     {
94     delete (*z);
95     }
96     }
97     }
98    
99     if ( buffer!=NULL ) free((char *)(buffer-1));
100     }
101    
102     #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
103     #include "pccts_stdio.h"
104     PCCTS_NAMESPACE_STD
105     #endif
106    
107     _ANTLRTokenPtr ANTLRTokenBuffer::
108     getToken()
109     {
110     if ( tp <= last ) // is there any buffered lookahead still to be read?
111     {
112     return *tp++; // read buffered lookahead
113     }
114     // out of buffered lookahead, get some more "real"
115     // input from getANTLRToken()
116     if ( num_markers==0 )
117     {
118     if( next > threshold )
119     {
120     #ifdef DBG_TBUF
121     /* MR23 */ printMessage(stderr,"getToken: next > threshold (high water is %d)\n", threshold-buffer);
122     #endif
123     makeRoom();
124     }
125     }
126     else {
127     if ( next > end_of_buffer )
128     {
129     #ifdef DBG_TBUF
130     /* MR23 */ printMessage(stderr,"getToken: next > end_of_buffer (size is %d)\n", buffer_size);
131     #endif
132     extendBuffer();
133     }
134     }
135     *next = getANTLRToken();
136     (*next)->ref(); // say we have a copy of this pointer in buffer
137     last = next;
138     next++;
139     tp = last;
140     return *tp++;
141     }
142    
143     void ANTLRTokenBuffer::
144     rewind(int pos)
145     {
146     #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
147     /* MR23 */ printMessage(stderr, "rewind(%d)[nm=%d,from=%d,%d.n=%d]\n", pos, num_markers, tp-buffer,pos,test[pos]);
148     test[pos]--;
149     #endif
150     tp = &buffer[pos];
151     num_markers--;
152     }
153    
154     /*
155     * This function is used to specify that the token pointers read
156     * by the ANTLRTokenBuffer should be buffered up (to be reused later).
157     */
158     int ANTLRTokenBuffer::
159     mark()
160     {
161     #if defined(DBG_TBUF)||defined(DBG_TBUF_MARK_REW)
162     test[tp-buffer]++;
163     /* MR23 */ printMessage(stderr,"mark(%d)[nm=%d,%d.n=%d]\n",tp-buffer,num_markers+1,tp-buffer,test[tp-buffer]);
164     #endif
165     num_markers++;
166     return tp - buffer;
167     }
168    
169     /*
170     * returns the token pointer n positions ahead.
171     * This implies that bufferedToken(1) gets the NEXT symbol of lookahead.
172     * This is used in conjunction with the ANTLRParser lookahead buffer.
173     *
174     * No markers are set or anything. A bunch of input is buffered--that's all.
175     * The tp pointer is left alone as the lookahead has not been advanced
176     * with getToken(). The next call to getToken() will find a token
177     * in the buffer and won't have to call getANTLRToken().
178     *
179     * If this is called before a consume() is done, how_many_more_i_need is
180     * set to 'n'.
181     */
182     _ANTLRTokenPtr ANTLRTokenBuffer::
183     bufferedToken(int n)
184     {
185     // int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1;
186     int how_many_more_i_need = (tp > last) ? n : n-(last-tp)-1;
187     // Make sure that at least n tokens are available in the buffer
188     #ifdef DBG_TBUF
189     /* MR23 */ printMessage(stderr, "bufferedToken(%d)\n", n);
190     #endif
191     for (int i=1; i<=how_many_more_i_need; i++)
192     {
193     if ( next > end_of_buffer ) // buffer overflow?
194     {
195     extendBuffer();
196     }
197     *next = getANTLRToken();
198     (*next)->ref(); // say we have a copy of this pointer in buffer
199     last = next;
200     next++;
201     }
202     return tp[n - 1];
203     }
204    
205     /* If no markers are set, the none of the input needs to be saved (except
206     * for the lookahead Token pointers). We save only k-1 token pointers as
207     * we are guaranteed to do a getANTLRToken() right after this because otherwise
208     * we wouldn't have needed to extend the buffer.
209     *
210     * If there are markers in the buffer, we need to save things and so
211     * extendBuffer() is called.
212     */
213     void ANTLRTokenBuffer::
214     makeRoom()
215     {
216     #ifdef DBG_TBUF
217     /* MR23 */ printMessage(stderr, "in makeRoom.................\n");
218     /* MR23 */ printMessage(stderr, "num_markers==%d\n", num_markers);
219     #endif
220     /*
221     if ( num_markers == 0 )
222     {
223     */
224     #ifdef DBG_TBUF
225     /* MR23 */ printMessage(stderr, "moving lookahead and resetting next\n");
226    
227     _ANTLRTokenPtr *r;
228     /* MR23 */ printMessage(stderr, "tbuf = [");
229     for (r=buffer; r<=last; r++)
230     {
231     if ( *r==NULL ) /* MR23 */ printMessage(stderr, " xxx");
232     else /* MR23 */ printMessage(stderr, " '%s'", ((ANTLRCommonToken *)*r)->getText());
233     }
234     /* MR23 */ printMessage(stderr, " ]\n");
235    
236     /* MR23 */ printMessage(stderr,
237     "before: tp=%d, last=%d, next=%d, threshold=%d\n",tp-buffer,last-buffer,next-buffer,threshold-buffer);
238     #endif
239    
240     // Delete all tokens from 0..last-(k-1) inclusive
241     if ( _deleteTokens )
242     {
243     _ANTLRTokenPtr *z;
244     for (z=buffer; z<=last-(k-1); z++)
245     {
246     (*z)->deref();
247     // z->deref();
248     #ifdef DBG_REFCOUNTTOKEN
249     /* MR23 */ printMessage(stderr, "##########makeRoom: deleting token '%s' (ref %d)\n",
250     ((ANTLRCommonToken *)*z)->getText(), (*z)->nref());
251     #endif
252     if ( (*z)->nref()==0 )
253     {
254     delete (*z);
255     }
256     }
257     }
258    
259     // reset the buffer to initial conditions, but move k-1 symbols
260     // to the beginning of buffer and put new input symbol at k
261     _ANTLRTokenPtr *p = buffer, *q = last-(k-1)+1;
262     // ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1)+1;
263     #ifdef DBG_TBUF
264     /* MR23 */ printMessage(stderr, "lookahead buffer = [");
265     #endif
266     for (int i=1; i<=(k-1); i++)
267     {
268     *p++ = *q++;
269     #ifdef DBG_TBUF
270     /* MR23 */ printMessage(stderr,
271     " '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());
272     #endif
273     }
274     #ifdef DBG_TBUF
275     /* MR23 */ printMessage(stderr, " ]\n");
276     #endif
277     next = &buffer[k-1];
278     tp = &buffer[k-1]; // tp points to what will be filled in next
279     last = tp-1;
280     #ifdef DBG_TBUF
281     /* MR23 */ printMessage(stderr,
282     "after: tp=%d, last=%d, next=%d\n",
283     tp-buffer, last-buffer, next-buffer);
284     #endif
285     /*
286     }
287     else {
288     extendBuffer();
289     }
290     */
291     }
292    
293     /* This function extends 'buffer' by chunk_size and returns with all
294     * pointers at the same relative positions in the buffer (the buffer base
295     * address could have changed in realloc()) except that 'next' comes
296     * back set to where the next token should be stored. All other pointers
297     * are untouched.
298     */
299     void
300     ANTLRTokenBuffer::
301     extendBuffer()
302     {
303     int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;
304     #ifdef DBG_TBUF
305     /* MR23 */ printMessage(stderr, "extending physical buffer\n");
306     #endif
307     buffer_size += chunk_size;
308     buffer = (_ANTLRTokenPtr *)
309     realloc((char *)(buffer-1),
310     (buffer_size+1)*sizeof(_ANTLRTokenPtr ));
311     if ( buffer == NULL ) {
312     panic("cannot alloc token buffer");
313     }
314     buffer++; // leave the first elem empty so tp-1 is valid ptr
315    
316     tp = buffer + save_tp; // put the pointers back to same relative position
317     last = buffer + save_last;
318     next = buffer + save_next;
319     end_of_buffer = &buffer[buffer_size-1];
320     threshold = &buffer[(int)(buffer_size*(1.0/2.0))];
321    
322     /*
323     // zero out new token ptrs so we'll know if something to delete in buffer
324     ANTLRAbstractToken **p = end_of_buffer-chunk_size+1;
325     for (; p<=end_of_buffer; p++) *p = NULL;
326     */
327     }
328    
329     ANTLRParser * ANTLRTokenBuffer:: // MR1
330     setParser(ANTLRParser *p) { // MR1
331     ANTLRParser *old=parser; // MR1
332     parser=p; // MR1
333     input->setParser(p); // MR1
334     return old; // MR1
335     } // MR1
336     // MR1
337     ANTLRParser * ANTLRTokenBuffer:: // MR1
338     getParser() { // MR1
339     return parser; // MR1
340     } // MR1
341    
342     void ANTLRTokenBuffer::panic(const char *msg) // MR23
343     {
344     if (parser) //MR23
345     parser->panic(msg); //MR23
346     else //MR23
347     exit(PCCTS_EXIT_FAILURE);
348     }
349    
350     //MR23
351     int ANTLRTokenBuffer::printMessage(FILE* pFile, const char* pFormat, ...)
352     {
353     va_list marker;
354     va_start( marker, pFormat );
355    
356     int iRet = 0;
357     if (parser)
358     parser->printMessageV(pFile, pFormat, marker);
359     else
360     iRet = vfprintf(pFile, pFormat, marker);
361    
362     va_end( marker );
363     return iRet;
364     }
365    
366     /* to avoid having to link in another file just for the smart token ptr
367     * stuff, we include it here. Ugh.
368     *
369     * MR23 This causes nothing but problems for IDEs.
370     * Change from .cpp to .h
371     *
372     */
373    
374     #include ATOKPTR_IMPL_H