1*16467b97STreehugger Robot /**
2*16467b97STreehugger Robot * Contains the default implementation of the common token used within
3*16467b97STreehugger Robot * java. Custom tokens should create this structure and then append to it using the
4*16467b97STreehugger Robot * custom pointer to install their own structure and API.
5*16467b97STreehugger Robot */
6*16467b97STreehugger Robot
7*16467b97STreehugger Robot // [The "BSD licence"]
8*16467b97STreehugger Robot // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
9*16467b97STreehugger Robot // http://www.temporal-wave.com
10*16467b97STreehugger Robot // http://www.linkedin.com/in/jimidle
11*16467b97STreehugger Robot //
12*16467b97STreehugger Robot // All rights reserved.
13*16467b97STreehugger Robot //
14*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
15*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
16*16467b97STreehugger Robot // are met:
17*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
18*16467b97STreehugger Robot // notice, this list of conditions and the following disclaimer.
19*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
20*16467b97STreehugger Robot // notice, this list of conditions and the following disclaimer in the
21*16467b97STreehugger Robot // documentation and/or other materials provided with the distribution.
22*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
23*16467b97STreehugger Robot // derived from this software without specific prior written permission.
24*16467b97STreehugger Robot //
25*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*16467b97STreehugger Robot
36*16467b97STreehugger Robot #include <antlr3.h>
37*16467b97STreehugger Robot
38*16467b97STreehugger Robot /* Token API
39*16467b97STreehugger Robot */
40*16467b97STreehugger Robot static pANTLR3_STRING getText (pANTLR3_COMMON_TOKEN token);
41*16467b97STreehugger Robot static void setText (pANTLR3_COMMON_TOKEN token, pANTLR3_STRING text);
42*16467b97STreehugger Robot static void setText8 (pANTLR3_COMMON_TOKEN token, pANTLR3_UINT8 text);
43*16467b97STreehugger Robot static ANTLR3_UINT32 getType (pANTLR3_COMMON_TOKEN token);
44*16467b97STreehugger Robot static void setType (pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 type);
45*16467b97STreehugger Robot static ANTLR3_UINT32 getLine (pANTLR3_COMMON_TOKEN token);
46*16467b97STreehugger Robot static void setLine (pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 line);
47*16467b97STreehugger Robot static ANTLR3_INT32 getCharPositionInLine (pANTLR3_COMMON_TOKEN token);
48*16467b97STreehugger Robot static void setCharPositionInLine (pANTLR3_COMMON_TOKEN token, ANTLR3_INT32 pos);
49*16467b97STreehugger Robot static ANTLR3_UINT32 getChannel (pANTLR3_COMMON_TOKEN token);
50*16467b97STreehugger Robot static void setChannel (pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 channel);
51*16467b97STreehugger Robot static ANTLR3_MARKER getTokenIndex (pANTLR3_COMMON_TOKEN token);
52*16467b97STreehugger Robot static void setTokenIndex (pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER);
53*16467b97STreehugger Robot static ANTLR3_MARKER getStartIndex (pANTLR3_COMMON_TOKEN token);
54*16467b97STreehugger Robot static void setStartIndex (pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER index);
55*16467b97STreehugger Robot static ANTLR3_MARKER getStopIndex (pANTLR3_COMMON_TOKEN token);
56*16467b97STreehugger Robot static void setStopIndex (pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER index);
57*16467b97STreehugger Robot static pANTLR3_STRING toString (pANTLR3_COMMON_TOKEN token);
58*16467b97STreehugger Robot
59*16467b97STreehugger Robot /* Factory API
60*16467b97STreehugger Robot */
61*16467b97STreehugger Robot static void factoryClose (pANTLR3_TOKEN_FACTORY factory);
62*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN newToken (void);
63*16467b97STreehugger Robot static void setInputStream (pANTLR3_TOKEN_FACTORY factory, pANTLR3_INPUT_STREAM input);
64*16467b97STreehugger Robot static void factoryReset (pANTLR3_TOKEN_FACTORY factory);
65*16467b97STreehugger Robot
66*16467b97STreehugger Robot /* Internal management functions
67*16467b97STreehugger Robot */
68*16467b97STreehugger Robot static ANTLR3_BOOLEAN newPool (pANTLR3_TOKEN_FACTORY factory);
69*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN newPoolToken (pANTLR3_TOKEN_FACTORY factory);
70*16467b97STreehugger Robot
71*16467b97STreehugger Robot
72*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TOKEN
antlr3CommonTokenNew(ANTLR3_UINT32 ttype)73*16467b97STreehugger Robot antlr3CommonTokenNew(ANTLR3_UINT32 ttype)
74*16467b97STreehugger Robot {
75*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN token;
76*16467b97STreehugger Robot
77*16467b97STreehugger Robot // Create a raw token with the interface installed
78*16467b97STreehugger Robot //
79*16467b97STreehugger Robot token = newToken();
80*16467b97STreehugger Robot
81*16467b97STreehugger Robot if (token != NULL)
82*16467b97STreehugger Robot {
83*16467b97STreehugger Robot token->setType(token, ttype);
84*16467b97STreehugger Robot }
85*16467b97STreehugger Robot
86*16467b97STreehugger Robot // All good
87*16467b97STreehugger Robot //
88*16467b97STreehugger Robot return token;
89*16467b97STreehugger Robot }
90*16467b97STreehugger Robot
91*16467b97STreehugger Robot ANTLR3_API pANTLR3_TOKEN_FACTORY
antlr3TokenFactoryNew(pANTLR3_INPUT_STREAM input)92*16467b97STreehugger Robot antlr3TokenFactoryNew(pANTLR3_INPUT_STREAM input)
93*16467b97STreehugger Robot {
94*16467b97STreehugger Robot pANTLR3_TOKEN_FACTORY factory;
95*16467b97STreehugger Robot
96*16467b97STreehugger Robot /* allocate memory
97*16467b97STreehugger Robot */
98*16467b97STreehugger Robot factory = (pANTLR3_TOKEN_FACTORY) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_TOKEN_FACTORY));
99*16467b97STreehugger Robot
100*16467b97STreehugger Robot if (factory == NULL)
101*16467b97STreehugger Robot {
102*16467b97STreehugger Robot return NULL;
103*16467b97STreehugger Robot }
104*16467b97STreehugger Robot
105*16467b97STreehugger Robot /* Install factory API
106*16467b97STreehugger Robot */
107*16467b97STreehugger Robot factory->newToken = newPoolToken;
108*16467b97STreehugger Robot factory->close = factoryClose;
109*16467b97STreehugger Robot factory->setInputStream = setInputStream;
110*16467b97STreehugger Robot factory->reset = factoryReset;
111*16467b97STreehugger Robot
112*16467b97STreehugger Robot /* Allocate the initial pool
113*16467b97STreehugger Robot */
114*16467b97STreehugger Robot factory->thisPool = -1;
115*16467b97STreehugger Robot factory->pools = NULL;
116*16467b97STreehugger Robot factory->maxPool = -1;
117*16467b97STreehugger Robot newPool(factory);
118*16467b97STreehugger Robot
119*16467b97STreehugger Robot /* Factory space is good, we now want to initialize our cheating token
120*16467b97STreehugger Robot * which one it is initialized is the model for all tokens we manufacture
121*16467b97STreehugger Robot */
122*16467b97STreehugger Robot antlr3SetTokenAPI(&factory->unTruc);
123*16467b97STreehugger Robot
124*16467b97STreehugger Robot /* Set some initial variables for future copying
125*16467b97STreehugger Robot */
126*16467b97STreehugger Robot factory->unTruc.factoryMade = ANTLR3_TRUE;
127*16467b97STreehugger Robot
128*16467b97STreehugger Robot // Input stream
129*16467b97STreehugger Robot //
130*16467b97STreehugger Robot setInputStream(factory, input);
131*16467b97STreehugger Robot
132*16467b97STreehugger Robot return factory;
133*16467b97STreehugger Robot
134*16467b97STreehugger Robot }
135*16467b97STreehugger Robot
136*16467b97STreehugger Robot static void
setInputStream(pANTLR3_TOKEN_FACTORY factory,pANTLR3_INPUT_STREAM input)137*16467b97STreehugger Robot setInputStream (pANTLR3_TOKEN_FACTORY factory, pANTLR3_INPUT_STREAM input)
138*16467b97STreehugger Robot {
139*16467b97STreehugger Robot factory->input = input;
140*16467b97STreehugger Robot factory->unTruc.input = input;
141*16467b97STreehugger Robot if (input != NULL)
142*16467b97STreehugger Robot {
143*16467b97STreehugger Robot factory->unTruc.strFactory = input->strFactory;
144*16467b97STreehugger Robot }
145*16467b97STreehugger Robot else
146*16467b97STreehugger Robot {
147*16467b97STreehugger Robot factory->unTruc.strFactory = NULL;
148*16467b97STreehugger Robot }
149*16467b97STreehugger Robot }
150*16467b97STreehugger Robot
151*16467b97STreehugger Robot static ANTLR3_BOOLEAN
newPool(pANTLR3_TOKEN_FACTORY factory)152*16467b97STreehugger Robot newPool(pANTLR3_TOKEN_FACTORY factory)
153*16467b97STreehugger Robot {
154*16467b97STreehugger Robot /* Increment factory count
155*16467b97STreehugger Robot */
156*16467b97STreehugger Robot ++(factory->thisPool);
157*16467b97STreehugger Robot
158*16467b97STreehugger Robot // If we were reusing this token factory then we may already have a pool
159*16467b97STreehugger Robot // allocated. If we exceeded the max available then we must allocate a new
160*16467b97STreehugger Robot // one.
161*16467b97STreehugger Robot if (factory->thisPool > factory->maxPool)
162*16467b97STreehugger Robot {
163*16467b97STreehugger Robot /* Ensure we have enough pointers allocated
164*16467b97STreehugger Robot */
165*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN *newPools = (pANTLR3_COMMON_TOKEN *)
166*16467b97STreehugger Robot ANTLR3_REALLOC((void *)factory->pools, /* Current pools pointer (starts at NULL) */
167*16467b97STreehugger Robot (ANTLR3_UINT32)((factory->thisPool + 1) * sizeof(pANTLR3_COMMON_TOKEN *)) /* Memory for new pool pointers */
168*16467b97STreehugger Robot );
169*16467b97STreehugger Robot if (newPools == NULL)
170*16467b97STreehugger Robot {
171*16467b97STreehugger Robot // We are out of memory, but the old allocation is still valid for now
172*16467b97STreehugger Robot --(factory->thisPool);
173*16467b97STreehugger Robot return ANTLR3_FALSE;
174*16467b97STreehugger Robot }
175*16467b97STreehugger Robot
176*16467b97STreehugger Robot factory->pools = newPools;
177*16467b97STreehugger Robot
178*16467b97STreehugger Robot /* Allocate a new pool for the factory
179*16467b97STreehugger Robot */
180*16467b97STreehugger Robot factory->pools[factory->thisPool] =
181*16467b97STreehugger Robot (pANTLR3_COMMON_TOKEN)
182*16467b97STreehugger Robot ANTLR3_CALLOC(1, (size_t)(sizeof(ANTLR3_COMMON_TOKEN) * ANTLR3_FACTORY_POOL_SIZE));
183*16467b97STreehugger Robot if (factory->pools[factory->thisPool] == NULL)
184*16467b97STreehugger Robot {
185*16467b97STreehugger Robot // Allocation failed
186*16467b97STreehugger Robot --(factory->thisPool);
187*16467b97STreehugger Robot return ANTLR3_FALSE;
188*16467b97STreehugger Robot }
189*16467b97STreehugger Robot
190*16467b97STreehugger Robot // We now have a new pool and can track it as the maximum we have created so far
191*16467b97STreehugger Robot //
192*16467b97STreehugger Robot factory->maxPool = factory->thisPool;
193*16467b97STreehugger Robot }
194*16467b97STreehugger Robot
195*16467b97STreehugger Robot /* Reset the counters
196*16467b97STreehugger Robot */
197*16467b97STreehugger Robot factory->nextToken = 0;
198*16467b97STreehugger Robot
199*16467b97STreehugger Robot /* Done
200*16467b97STreehugger Robot */
201*16467b97STreehugger Robot return ANTLR3_TRUE;
202*16467b97STreehugger Robot }
203*16467b97STreehugger Robot
204*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN
newPoolToken(pANTLR3_TOKEN_FACTORY factory)205*16467b97STreehugger Robot newPoolToken(pANTLR3_TOKEN_FACTORY factory)
206*16467b97STreehugger Robot {
207*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN token;
208*16467b97STreehugger Robot
209*16467b97STreehugger Robot if (factory == NULL) { return NULL; }
210*16467b97STreehugger Robot
211*16467b97STreehugger Robot /* See if we need a new token pool before allocating a new
212*16467b97STreehugger Robot * one
213*16467b97STreehugger Robot */
214*16467b97STreehugger Robot if (factory->nextToken >= ANTLR3_FACTORY_POOL_SIZE)
215*16467b97STreehugger Robot {
216*16467b97STreehugger Robot /* We ran out of tokens in the current pool, so we need a new pool
217*16467b97STreehugger Robot */
218*16467b97STreehugger Robot if (!newPool(factory))
219*16467b97STreehugger Robot {
220*16467b97STreehugger Robot return NULL;
221*16467b97STreehugger Robot }
222*16467b97STreehugger Robot }
223*16467b97STreehugger Robot
224*16467b97STreehugger Robot // make sure the factory is sane
225*16467b97STreehugger Robot if (factory->pools == NULL) { return NULL; }
226*16467b97STreehugger Robot if (factory->pools[factory->thisPool] == NULL) { return NULL; }
227*16467b97STreehugger Robot
228*16467b97STreehugger Robot /* Assuming everything went well (we are trying for performance here so doing minimal
229*16467b97STreehugger Robot * error checking. Then we can work out what the pointer is to the next token.
230*16467b97STreehugger Robot */
231*16467b97STreehugger Robot token = factory->pools[factory->thisPool] + factory->nextToken;
232*16467b97STreehugger Robot factory->nextToken++;
233*16467b97STreehugger Robot
234*16467b97STreehugger Robot /* We have our token pointer now, so we can initialize it to the predefined model.
235*16467b97STreehugger Robot * We only need do this though if the token is not already initialized, we just check
236*16467b97STreehugger Robot * an api function pointer for this as they are allocated via calloc.
237*16467b97STreehugger Robot */
238*16467b97STreehugger Robot if (token->setStartIndex == NULL)
239*16467b97STreehugger Robot {
240*16467b97STreehugger Robot antlr3SetTokenAPI(token);
241*16467b97STreehugger Robot
242*16467b97STreehugger Robot // It is factory made, and we need to copy the string factory pointer
243*16467b97STreehugger Robot //
244*16467b97STreehugger Robot token->factoryMade = ANTLR3_TRUE;
245*16467b97STreehugger Robot token->strFactory = factory->input == NULL ? NULL : factory->input->strFactory;
246*16467b97STreehugger Robot token->input = factory->input;
247*16467b97STreehugger Robot }
248*16467b97STreehugger Robot
249*16467b97STreehugger Robot /* And we are done
250*16467b97STreehugger Robot */
251*16467b97STreehugger Robot return token;
252*16467b97STreehugger Robot }
253*16467b97STreehugger Robot
254*16467b97STreehugger Robot static void
factoryReset(pANTLR3_TOKEN_FACTORY factory)255*16467b97STreehugger Robot factoryReset (pANTLR3_TOKEN_FACTORY factory)
256*16467b97STreehugger Robot {
257*16467b97STreehugger Robot // Just start again with pool #0 when we are
258*16467b97STreehugger Robot // called.
259*16467b97STreehugger Robot //
260*16467b97STreehugger Robot factory->thisPool = -1;
261*16467b97STreehugger Robot newPool(factory);
262*16467b97STreehugger Robot }
263*16467b97STreehugger Robot
264*16467b97STreehugger Robot static void
factoryClose(pANTLR3_TOKEN_FACTORY factory)265*16467b97STreehugger Robot factoryClose (pANTLR3_TOKEN_FACTORY factory)
266*16467b97STreehugger Robot {
267*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN pool;
268*16467b97STreehugger Robot ANTLR3_INT32 poolCount;
269*16467b97STreehugger Robot ANTLR3_UINT32 limit;
270*16467b97STreehugger Robot ANTLR3_UINT32 token;
271*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN check;
272*16467b97STreehugger Robot
273*16467b97STreehugger Robot /* We iterate the token pools one at a time
274*16467b97STreehugger Robot */
275*16467b97STreehugger Robot for (poolCount = 0; poolCount <= factory->thisPool; poolCount++)
276*16467b97STreehugger Robot {
277*16467b97STreehugger Robot /* Pointer to current pool
278*16467b97STreehugger Robot */
279*16467b97STreehugger Robot pool = factory->pools[poolCount];
280*16467b97STreehugger Robot
281*16467b97STreehugger Robot /* Work out how many tokens we need to check in this pool.
282*16467b97STreehugger Robot */
283*16467b97STreehugger Robot limit = (poolCount == factory->thisPool ? factory->nextToken : ANTLR3_FACTORY_POOL_SIZE);
284*16467b97STreehugger Robot
285*16467b97STreehugger Robot /* Marginal condition, we might be at the start of a brand new pool
286*16467b97STreehugger Robot * where the nextToken is 0 and nothing has been allocated.
287*16467b97STreehugger Robot */
288*16467b97STreehugger Robot if (limit > 0)
289*16467b97STreehugger Robot {
290*16467b97STreehugger Robot /* We have some tokens allocated from this pool
291*16467b97STreehugger Robot */
292*16467b97STreehugger Robot for (token = 0; token < limit; token++)
293*16467b97STreehugger Robot {
294*16467b97STreehugger Robot /* Next one in the chain
295*16467b97STreehugger Robot */
296*16467b97STreehugger Robot check = pool + token;
297*16467b97STreehugger Robot
298*16467b97STreehugger Robot /* If the programmer made this a custom token, then
299*16467b97STreehugger Robot * see if we need to call their free routine.
300*16467b97STreehugger Robot */
301*16467b97STreehugger Robot if (check->custom != NULL && check->freeCustom != NULL)
302*16467b97STreehugger Robot {
303*16467b97STreehugger Robot check->freeCustom(check->custom);
304*16467b97STreehugger Robot check->custom = NULL;
305*16467b97STreehugger Robot }
306*16467b97STreehugger Robot }
307*16467b97STreehugger Robot }
308*16467b97STreehugger Robot
309*16467b97STreehugger Robot /* We can now free this pool allocation
310*16467b97STreehugger Robot */
311*16467b97STreehugger Robot ANTLR3_FREE(factory->pools[poolCount]);
312*16467b97STreehugger Robot factory->pools[poolCount] = NULL;
313*16467b97STreehugger Robot }
314*16467b97STreehugger Robot
315*16467b97STreehugger Robot /* All the pools are deallocated we can free the pointers to the pools
316*16467b97STreehugger Robot * now.
317*16467b97STreehugger Robot */
318*16467b97STreehugger Robot ANTLR3_FREE(factory->pools);
319*16467b97STreehugger Robot
320*16467b97STreehugger Robot /* Finally, we can free the space for the factory itself
321*16467b97STreehugger Robot */
322*16467b97STreehugger Robot ANTLR3_FREE(factory);
323*16467b97STreehugger Robot }
324*16467b97STreehugger Robot
325*16467b97STreehugger Robot
326*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN
newToken(void)327*16467b97STreehugger Robot newToken(void)
328*16467b97STreehugger Robot {
329*16467b97STreehugger Robot pANTLR3_COMMON_TOKEN token;
330*16467b97STreehugger Robot
331*16467b97STreehugger Robot /* Allocate memory for this
332*16467b97STreehugger Robot */
333*16467b97STreehugger Robot token = (pANTLR3_COMMON_TOKEN) ANTLR3_CALLOC(1, (size_t)(sizeof(ANTLR3_COMMON_TOKEN)));
334*16467b97STreehugger Robot
335*16467b97STreehugger Robot if (token == NULL)
336*16467b97STreehugger Robot {
337*16467b97STreehugger Robot return NULL;
338*16467b97STreehugger Robot }
339*16467b97STreehugger Robot
340*16467b97STreehugger Robot // Install the API
341*16467b97STreehugger Robot //
342*16467b97STreehugger Robot antlr3SetTokenAPI(token);
343*16467b97STreehugger Robot token->factoryMade = ANTLR3_FALSE;
344*16467b97STreehugger Robot
345*16467b97STreehugger Robot return token;
346*16467b97STreehugger Robot }
347*16467b97STreehugger Robot
348*16467b97STreehugger Robot ANTLR3_API void
antlr3SetTokenAPI(pANTLR3_COMMON_TOKEN token)349*16467b97STreehugger Robot antlr3SetTokenAPI(pANTLR3_COMMON_TOKEN token)
350*16467b97STreehugger Robot {
351*16467b97STreehugger Robot token->getText = getText;
352*16467b97STreehugger Robot token->setText = setText;
353*16467b97STreehugger Robot token->setText8 = setText8;
354*16467b97STreehugger Robot token->getType = getType;
355*16467b97STreehugger Robot token->setType = setType;
356*16467b97STreehugger Robot token->getLine = getLine;
357*16467b97STreehugger Robot token->setLine = setLine;
358*16467b97STreehugger Robot token->setLine = setLine;
359*16467b97STreehugger Robot token->getCharPositionInLine = getCharPositionInLine;
360*16467b97STreehugger Robot token->setCharPositionInLine = setCharPositionInLine;
361*16467b97STreehugger Robot token->getChannel = getChannel;
362*16467b97STreehugger Robot token->setChannel = setChannel;
363*16467b97STreehugger Robot token->getTokenIndex = getTokenIndex;
364*16467b97STreehugger Robot token->setTokenIndex = setTokenIndex;
365*16467b97STreehugger Robot token->getStartIndex = getStartIndex;
366*16467b97STreehugger Robot token->setStartIndex = setStartIndex;
367*16467b97STreehugger Robot token->getStopIndex = getStopIndex;
368*16467b97STreehugger Robot token->setStopIndex = setStopIndex;
369*16467b97STreehugger Robot token->toString = toString;
370*16467b97STreehugger Robot
371*16467b97STreehugger Robot return;
372*16467b97STreehugger Robot }
373*16467b97STreehugger Robot
getText(pANTLR3_COMMON_TOKEN token)374*16467b97STreehugger Robot static pANTLR3_STRING getText (pANTLR3_COMMON_TOKEN token)
375*16467b97STreehugger Robot {
376*16467b97STreehugger Robot switch (token->textState)
377*16467b97STreehugger Robot {
378*16467b97STreehugger Robot case ANTLR3_TEXT_STRING:
379*16467b97STreehugger Robot
380*16467b97STreehugger Robot // Someone already created a string for this token, so we just
381*16467b97STreehugger Robot // use it.
382*16467b97STreehugger Robot //
383*16467b97STreehugger Robot return token->tokText.text;
384*16467b97STreehugger Robot break;
385*16467b97STreehugger Robot
386*16467b97STreehugger Robot case ANTLR3_TEXT_CHARP:
387*16467b97STreehugger Robot
388*16467b97STreehugger Robot // We had a straight text pointer installed, now we
389*16467b97STreehugger Robot // must convert it to a string. Note we have to do this here
390*16467b97STreehugger Robot // or otherwise setText8() will just install the same char*
391*16467b97STreehugger Robot //
392*16467b97STreehugger Robot if (token->strFactory != NULL)
393*16467b97STreehugger Robot {
394*16467b97STreehugger Robot token->tokText.text = token->strFactory->newStr8(token->strFactory, (pANTLR3_UINT8)token->tokText.chars);
395*16467b97STreehugger Robot token->textState = ANTLR3_TEXT_STRING;
396*16467b97STreehugger Robot return token->tokText.text;
397*16467b97STreehugger Robot }
398*16467b97STreehugger Robot else
399*16467b97STreehugger Robot {
400*16467b97STreehugger Robot // We cannot do anything here
401*16467b97STreehugger Robot //
402*16467b97STreehugger Robot return NULL;
403*16467b97STreehugger Robot }
404*16467b97STreehugger Robot break;
405*16467b97STreehugger Robot
406*16467b97STreehugger Robot default:
407*16467b97STreehugger Robot
408*16467b97STreehugger Robot // EOF is a special case
409*16467b97STreehugger Robot //
410*16467b97STreehugger Robot if (token->type == ANTLR3_TOKEN_EOF)
411*16467b97STreehugger Robot {
412*16467b97STreehugger Robot token->tokText.text = token->strFactory->newStr8(token->strFactory, (pANTLR3_UINT8)"<EOF>");
413*16467b97STreehugger Robot token->textState = ANTLR3_TEXT_STRING;
414*16467b97STreehugger Robot token->tokText.text->factory = token->strFactory;
415*16467b97STreehugger Robot return token->tokText.text;
416*16467b97STreehugger Robot }
417*16467b97STreehugger Robot
418*16467b97STreehugger Robot
419*16467b97STreehugger Robot // We had nothing installed in the token, create a new string
420*16467b97STreehugger Robot // from the input stream
421*16467b97STreehugger Robot //
422*16467b97STreehugger Robot
423*16467b97STreehugger Robot if (token->input != NULL)
424*16467b97STreehugger Robot {
425*16467b97STreehugger Robot
426*16467b97STreehugger Robot return token->input->substr( token->input,
427*16467b97STreehugger Robot token->getStartIndex(token),
428*16467b97STreehugger Robot token->getStopIndex(token)
429*16467b97STreehugger Robot );
430*16467b97STreehugger Robot }
431*16467b97STreehugger Robot
432*16467b97STreehugger Robot // Nothing to return, there is no input stream
433*16467b97STreehugger Robot //
434*16467b97STreehugger Robot return NULL;
435*16467b97STreehugger Robot break;
436*16467b97STreehugger Robot }
437*16467b97STreehugger Robot }
setText8(pANTLR3_COMMON_TOKEN token,pANTLR3_UINT8 text)438*16467b97STreehugger Robot static void setText8 (pANTLR3_COMMON_TOKEN token, pANTLR3_UINT8 text)
439*16467b97STreehugger Robot {
440*16467b97STreehugger Robot // No text to set, so ignore
441*16467b97STreehugger Robot //
442*16467b97STreehugger Robot if (text == NULL) return;
443*16467b97STreehugger Robot
444*16467b97STreehugger Robot switch (token->textState)
445*16467b97STreehugger Robot {
446*16467b97STreehugger Robot case ANTLR3_TEXT_NONE:
447*16467b97STreehugger Robot case ANTLR3_TEXT_CHARP: // Caller must free before setting again, if it needs to be freed
448*16467b97STreehugger Robot
449*16467b97STreehugger Robot // Nothing in there yet, or just a char *, so just set the
450*16467b97STreehugger Robot // text as a pointer
451*16467b97STreehugger Robot //
452*16467b97STreehugger Robot token->textState = ANTLR3_TEXT_CHARP;
453*16467b97STreehugger Robot token->tokText.chars = (pANTLR3_UCHAR)text;
454*16467b97STreehugger Robot break;
455*16467b97STreehugger Robot
456*16467b97STreehugger Robot default:
457*16467b97STreehugger Robot
458*16467b97STreehugger Robot // It was already a pANTLR3_STRING, so just override it
459*16467b97STreehugger Robot //
460*16467b97STreehugger Robot token->tokText.text->set8(token->tokText.text, (const char *)text);
461*16467b97STreehugger Robot break;
462*16467b97STreehugger Robot }
463*16467b97STreehugger Robot
464*16467b97STreehugger Robot // We are done
465*16467b97STreehugger Robot //
466*16467b97STreehugger Robot return;
467*16467b97STreehugger Robot }
468*16467b97STreehugger Robot
469*16467b97STreehugger Robot /** \brief Install the supplied text string as teh text for the token.
470*16467b97STreehugger Robot * The method assumes that the existing text (if any) was created by a factory
471*16467b97STreehugger Robot * and so does not attempt to release any memory it is using.Text not created
472*16467b97STreehugger Robot * by a string fctory (not advised) should be released prior to this call.
473*16467b97STreehugger Robot */
setText(pANTLR3_COMMON_TOKEN token,pANTLR3_STRING text)474*16467b97STreehugger Robot static void setText (pANTLR3_COMMON_TOKEN token, pANTLR3_STRING text)
475*16467b97STreehugger Robot {
476*16467b97STreehugger Robot // Merely replaces and existing pre-defined text with the supplied
477*16467b97STreehugger Robot // string
478*16467b97STreehugger Robot //
479*16467b97STreehugger Robot token->textState = ANTLR3_TEXT_STRING;
480*16467b97STreehugger Robot token->tokText.text = text;
481*16467b97STreehugger Robot
482*16467b97STreehugger Robot /* We are done
483*16467b97STreehugger Robot */
484*16467b97STreehugger Robot return;
485*16467b97STreehugger Robot }
486*16467b97STreehugger Robot
getType(pANTLR3_COMMON_TOKEN token)487*16467b97STreehugger Robot static ANTLR3_UINT32 getType (pANTLR3_COMMON_TOKEN token)
488*16467b97STreehugger Robot {
489*16467b97STreehugger Robot return token->type;
490*16467b97STreehugger Robot }
491*16467b97STreehugger Robot
setType(pANTLR3_COMMON_TOKEN token,ANTLR3_UINT32 type)492*16467b97STreehugger Robot static void setType (pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 type)
493*16467b97STreehugger Robot {
494*16467b97STreehugger Robot token->type = type;
495*16467b97STreehugger Robot }
496*16467b97STreehugger Robot
getLine(pANTLR3_COMMON_TOKEN token)497*16467b97STreehugger Robot static ANTLR3_UINT32 getLine (pANTLR3_COMMON_TOKEN token)
498*16467b97STreehugger Robot {
499*16467b97STreehugger Robot return token->line;
500*16467b97STreehugger Robot }
501*16467b97STreehugger Robot
setLine(pANTLR3_COMMON_TOKEN token,ANTLR3_UINT32 line)502*16467b97STreehugger Robot static void setLine (pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 line)
503*16467b97STreehugger Robot {
504*16467b97STreehugger Robot token->line = line;
505*16467b97STreehugger Robot }
506*16467b97STreehugger Robot
getCharPositionInLine(pANTLR3_COMMON_TOKEN token)507*16467b97STreehugger Robot static ANTLR3_INT32 getCharPositionInLine (pANTLR3_COMMON_TOKEN token)
508*16467b97STreehugger Robot {
509*16467b97STreehugger Robot return token->charPosition;
510*16467b97STreehugger Robot }
511*16467b97STreehugger Robot
setCharPositionInLine(pANTLR3_COMMON_TOKEN token,ANTLR3_INT32 pos)512*16467b97STreehugger Robot static void setCharPositionInLine (pANTLR3_COMMON_TOKEN token, ANTLR3_INT32 pos)
513*16467b97STreehugger Robot {
514*16467b97STreehugger Robot token->charPosition = pos;
515*16467b97STreehugger Robot }
516*16467b97STreehugger Robot
getChannel(pANTLR3_COMMON_TOKEN token)517*16467b97STreehugger Robot static ANTLR3_UINT32 getChannel (pANTLR3_COMMON_TOKEN token)
518*16467b97STreehugger Robot {
519*16467b97STreehugger Robot return token->channel;
520*16467b97STreehugger Robot }
521*16467b97STreehugger Robot
setChannel(pANTLR3_COMMON_TOKEN token,ANTLR3_UINT32 channel)522*16467b97STreehugger Robot static void setChannel (pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 channel)
523*16467b97STreehugger Robot {
524*16467b97STreehugger Robot token->channel = channel;
525*16467b97STreehugger Robot }
526*16467b97STreehugger Robot
getTokenIndex(pANTLR3_COMMON_TOKEN token)527*16467b97STreehugger Robot static ANTLR3_MARKER getTokenIndex (pANTLR3_COMMON_TOKEN token)
528*16467b97STreehugger Robot {
529*16467b97STreehugger Robot return token->index;
530*16467b97STreehugger Robot }
531*16467b97STreehugger Robot
setTokenIndex(pANTLR3_COMMON_TOKEN token,ANTLR3_MARKER index)532*16467b97STreehugger Robot static void setTokenIndex (pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER index)
533*16467b97STreehugger Robot {
534*16467b97STreehugger Robot token->index = index;
535*16467b97STreehugger Robot }
536*16467b97STreehugger Robot
getStartIndex(pANTLR3_COMMON_TOKEN token)537*16467b97STreehugger Robot static ANTLR3_MARKER getStartIndex (pANTLR3_COMMON_TOKEN token)
538*16467b97STreehugger Robot {
539*16467b97STreehugger Robot return token->start == -1 ? (ANTLR3_MARKER)(token->input->data) : token->start;
540*16467b97STreehugger Robot }
541*16467b97STreehugger Robot
setStartIndex(pANTLR3_COMMON_TOKEN token,ANTLR3_MARKER start)542*16467b97STreehugger Robot static void setStartIndex (pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER start)
543*16467b97STreehugger Robot {
544*16467b97STreehugger Robot token->start = start;
545*16467b97STreehugger Robot }
546*16467b97STreehugger Robot
getStopIndex(pANTLR3_COMMON_TOKEN token)547*16467b97STreehugger Robot static ANTLR3_MARKER getStopIndex (pANTLR3_COMMON_TOKEN token)
548*16467b97STreehugger Robot {
549*16467b97STreehugger Robot return token->stop;
550*16467b97STreehugger Robot }
551*16467b97STreehugger Robot
setStopIndex(pANTLR3_COMMON_TOKEN token,ANTLR3_MARKER stop)552*16467b97STreehugger Robot static void setStopIndex (pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER stop)
553*16467b97STreehugger Robot {
554*16467b97STreehugger Robot token->stop = stop;
555*16467b97STreehugger Robot }
556*16467b97STreehugger Robot
toString(pANTLR3_COMMON_TOKEN token)557*16467b97STreehugger Robot static pANTLR3_STRING toString (pANTLR3_COMMON_TOKEN token)
558*16467b97STreehugger Robot {
559*16467b97STreehugger Robot pANTLR3_STRING text;
560*16467b97STreehugger Robot pANTLR3_STRING outtext;
561*16467b97STreehugger Robot
562*16467b97STreehugger Robot text = token->getText(token);
563*16467b97STreehugger Robot
564*16467b97STreehugger Robot if (text == NULL)
565*16467b97STreehugger Robot {
566*16467b97STreehugger Robot return NULL;
567*16467b97STreehugger Robot }
568*16467b97STreehugger Robot
569*16467b97STreehugger Robot if (text->factory == NULL)
570*16467b97STreehugger Robot {
571*16467b97STreehugger Robot return text; // This usally means it is the EOF token
572*16467b97STreehugger Robot }
573*16467b97STreehugger Robot
574*16467b97STreehugger Robot /* A new empty string to assemble all the stuff in
575*16467b97STreehugger Robot */
576*16467b97STreehugger Robot outtext = text->factory->newRaw(text->factory);
577*16467b97STreehugger Robot
578*16467b97STreehugger Robot /* Now we use our handy dandy string utility to assemble the
579*16467b97STreehugger Robot * the reporting string
580*16467b97STreehugger Robot * return "[@"+getTokenIndex()+","+start+":"+stop+"='"+txt+"',<"+type+">"+channelStr+","+line+":"+getCharPositionInLine()+"]";
581*16467b97STreehugger Robot */
582*16467b97STreehugger Robot outtext->append8(outtext, "[Index: ");
583*16467b97STreehugger Robot outtext->addi (outtext, (ANTLR3_INT32)token->getTokenIndex(token));
584*16467b97STreehugger Robot outtext->append8(outtext, " (Start: ");
585*16467b97STreehugger Robot outtext->addi (outtext, (ANTLR3_INT32)token->getStartIndex(token));
586*16467b97STreehugger Robot outtext->append8(outtext, "-Stop: ");
587*16467b97STreehugger Robot outtext->addi (outtext, (ANTLR3_INT32)token->getStopIndex(token));
588*16467b97STreehugger Robot outtext->append8(outtext, ") ='");
589*16467b97STreehugger Robot outtext->appendS(outtext, text);
590*16467b97STreehugger Robot outtext->append8(outtext, "', type<");
591*16467b97STreehugger Robot outtext->addi (outtext, token->type);
592*16467b97STreehugger Robot outtext->append8(outtext, "> ");
593*16467b97STreehugger Robot
594*16467b97STreehugger Robot if (token->getChannel(token) > ANTLR3_TOKEN_DEFAULT_CHANNEL)
595*16467b97STreehugger Robot {
596*16467b97STreehugger Robot outtext->append8(outtext, "(channel = ");
597*16467b97STreehugger Robot outtext->addi (outtext, (ANTLR3_INT32)token->getChannel(token));
598*16467b97STreehugger Robot outtext->append8(outtext, ") ");
599*16467b97STreehugger Robot }
600*16467b97STreehugger Robot
601*16467b97STreehugger Robot outtext->append8(outtext, "Line: ");
602*16467b97STreehugger Robot outtext->addi (outtext, (ANTLR3_INT32)token->getLine(token));
603*16467b97STreehugger Robot outtext->append8(outtext, " LinePos:");
604*16467b97STreehugger Robot outtext->addi (outtext, token->getCharPositionInLine(token));
605*16467b97STreehugger Robot outtext->addc (outtext, ']');
606*16467b97STreehugger Robot
607*16467b97STreehugger Robot return outtext;
608*16467b97STreehugger Robot }
609*16467b97STreehugger Robot
610