ATokenBuffer.cpp
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:9k
源码类别:

编译器/解释器

开发平台:

Others

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