]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/CodeTools/TianoTools/Pccts/h/PCCTSAST.cpp
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / CodeTools / TianoTools / Pccts / h / PCCTSAST.cpp
CommitLineData
878ddf1f 1/*\r
2 * PCCTSAST.C\r
3 *\r
4 * SOFTWARE RIGHTS\r
5 *\r
6 * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public\r
7 * domain. An individual or company may do whatever they wish with\r
8 * source code distributed with SORCERER or the code generated by\r
9 * SORCERER, including the incorporation of SORCERER, or its output, into\r
10 * commerical software.\r
11 *\r
12 * We encourage users to develop software with SORCERER. However, we do\r
13 * ask that credit is given to us for developing SORCERER. By "credit",\r
14 * we mean that if you incorporate our source code into one of your\r
15 * programs (commercial product, research project, or otherwise) that you\r
16 * acknowledge this fact somewhere in the documentation, research report,\r
17 * etc... If you like SORCERER and have developed a nice tool with the\r
18 * output, please mention that you developed it using SORCERER. In\r
19 * addition, we ask that this header remain intact in our source code.\r
20 * As long as these guidelines are kept, we expect to continue enhancing\r
21 * this system and expect to make other tools available as they are\r
22 * completed.\r
23 *\r
24 * SORCERER 1.00B14 and ANTLR 1.33\r
25 * Terence Parr\r
26 * Parr Research Corporation\r
27 * AHPCRC, University of Minnesota\r
28 * 1992-2000\r
29 */\r
30\r
31#define ANTLR_SUPPORT_CODE\r
32\r
33#include "pcctscfg.h"\r
34\r
35#include "PCCTSAST.h"\r
36#include "pccts_stdarg.h"\r
37\r
38PCCTS_NAMESPACE_STD\r
39\r
40#include <ctype.h>\r
41\r
42//#include "SList.h"\r
43\r
44 /* String Scanning/Parsing Stuff */\r
45\r
46const char *PCCTS_AST::scan_token_tbl[] = { /* MR20 const */\r
47 "invalid", /* 0 */\r
48 "LPAREN", /* 1 */\r
49 "RPAREN", /* 2 */\r
50 "PERCENT", /* 3 */\r
51 "INT", /* 4 */\r
52 "COLON", /* 5 */\r
53 "POUND", /* 6 */\r
54 "PERIOD", /* 7 */\r
55};\r
56\r
57void PCCTS_AST::\r
58addChild(PCCTS_AST *t)\r
59{\r
60 if ( t==NULL ) return;\r
61 PCCTS_AST *s = down();\r
62 if ( s!=NULL )\r
63 {\r
64 while ( s->right()!=NULL ) s = s->right();\r
65 s->setRight(t);\r
66 }\r
67 else\r
68 this->setDown(t);\r
69}\r
70\r
71void PCCTS_AST::\r
72lisp(FILE *f)\r
73{\r
74 if ( down() != NULL ) /* MR23 */ printMessage(f," (");\r
75 lisp_action(f);\r
76 if ( down()!=NULL ) down()->lisp(f);\r
77 if ( down() != NULL ) /* MR23 */ printMessage(f," )");\r
78 if ( right()!=NULL ) right()->lisp(f);\r
79}\r
80\r
81/* build a tree (root child1 child2 ... NULL)\r
82 * If root is NULL, simply make the children siblings and return ptr\r
83 * to 1st sibling (child1). If root is not single node, return NULL.\r
84 *\r
85 * Siblings that are actually sibling lists themselves are handled\r
86 * correctly. For example #( NULL, #( NULL, A, B, C), D) results\r
87 * in the tree ( NULL A B C D ).\r
88 *\r
89 * Requires at least two parameters with the last one being NULL. If\r
90 * both are NULL, return NULL.\r
91 *\r
92 * The down() and right() down/right pointers are used to make the tree.\r
93 */\r
94PCCTS_AST *PCCTS_AST::\r
95make(PCCTS_AST *rt, ...)\r
96{\r
97 va_list ap;\r
98 register PCCTS_AST *child, *sibling=NULL, *tail=NULL /*MR23*/, *w;\r
99 PCCTS_AST *root;\r
100\r
101 va_start(ap, rt);\r
102 root = rt;\r
103\r
104 if ( root != NULL )\r
105 if ( root->down() != NULL ) return NULL;\r
106 child = va_arg(ap, PCCTS_AST *);\r
107 while ( child != NULL )\r
108 {\r
109 /* find end of child */\r
110 for (w=child; w->right()!=NULL; w=w->right()) {;}\r
111 if ( sibling == NULL ) {sibling = child; tail = w;}\r
112 else {tail->setRight(child); tail = w;}\r
113 child = va_arg(ap, PCCTS_AST *);\r
114 }\r
115 if ( root==NULL ) root = sibling;\r
116 else root->setDown(sibling);\r
117 va_end(ap);\r
118 return root;\r
119}\r
120\r
121/* The following push and pop routines are only used by ast_find_all() */\r
122\r
123void PCCTS_AST::\r
124_push(PCCTS_AST **st, int *sp, PCCTS_AST *e)\r
125{\r
126 (*sp)--;\r
127 require((*sp)>=0, "stack overflow");\r
128 st[(*sp)] = e;\r
129}\r
130\r
131PCCTS_AST *PCCTS_AST::\r
132_pop(PCCTS_AST **st, int *sp)\r
133{\r
134 PCCTS_AST *e = st[*sp];\r
135 (*sp)++;\r
136 require((*sp)<=MaxTreeStackDepth, "stack underflow");\r
137 return e;\r
138}\r
139\r
140/* Find all occurrences of u in t.\r
141 * 'cursor' must be initialized to 't'. It eventually\r
142 * returns NULL when no more occurrences of 'u' are found.\r
143 */\r
144PCCTS_AST *PCCTS_AST::\r
145ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor)\r
146{\r
147 PCCTS_AST *sib;\r
148 /*** static ***/ PCCTS_AST *template_stack[MaxTreeStackDepth]; /* MR23 Remove "static" */\r
149 /*** static ***/ int tsp = MaxTreeStackDepth; /* MR23 Remove "static" */\r
150\r
151////static int nesting = 0; /* MR23 Not referenced */\r
152\r
153 if ( *cursor == NULL ) return NULL;\r
154 if ( *cursor!=this ) sib = *cursor;\r
155 else {\r
156 /* else, first time--start at top of template 't' */\r
157 tsp = MaxTreeStackDepth;\r
158 sib = this;\r
159 /* bottom of stack is always a NULL--"cookie" indicates "done" */\r
160 _push(template_stack, &tsp, NULL);\r
161 }\r
162\r
163keep_looking:\r
164 if ( sib==NULL ) /* hit end of sibling list */\r
165 {\r
166 sib = _pop(template_stack, &tsp);\r
167 if ( sib == NULL ) { *cursor = NULL; return NULL; }\r
168 }\r
169\r
170 if ( sib->type() != u->type() )\r
171 {\r
172 /* look for another match */\r
173 if ( sib->down()!=NULL )\r
174 {\r
175 if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());\r
176 sib=sib->down();\r
177 goto keep_looking;\r
178 }\r
179 /* nothing below to try, try next sibling */\r
180 sib=sib->right();\r
181 goto keep_looking;\r
182 }\r
183\r
184 /* found a matching root node, try to match what's below */\r
185 if ( match_partial(sib, u) )\r
186 {\r
187 /* record sibling cursor so we can pick up next from there */\r
188 if ( sib->down()!=NULL )\r
189 {\r
190 if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());\r
191 *cursor = sib->down();\r
192 }\r
193 else if ( sib->right()!=NULL ) *cursor = sib->right();\r
194 else *cursor = _pop(template_stack, &tsp);\r
195 return sib;\r
196 }\r
197\r
198 /* no match, keep searching */\r
199 if ( sib->down()!=NULL )\r
200 {\r
201 if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());\r
202 sib=sib->down();\r
203 }\r
204 else sib = sib->right(); /* else, try to right if zip below */\r
205 goto keep_looking;\r
206}\r
207\r
208/* are two trees exactly alike? */\r
209int PCCTS_AST::\r
210match(PCCTS_AST *u)\r
211{\r
212 PCCTS_AST *t = this;\r
213 PCCTS_AST *sib;\r
214\r
215 if ( u==NULL ) return 0;\r
216\r
217 for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())\r
218 {\r
219 if ( sib->type() != u->type() ) return 0;\r
220 if ( sib->down()!=NULL )\r
221 if ( !sib->down()->match(u->down()) ) return 0;\r
222 }\r
223 return 1;\r
224}\r
225\r
226/* Is 'u' a subtree of 't' beginning at the root? */\r
227int PCCTS_AST::\r
228match_partial(PCCTS_AST *t, PCCTS_AST *u)\r
229{\r
230 PCCTS_AST *sib;\r
231\r
232 if ( u==NULL ) return 1;\r
233 if ( t==NULL ) return 0; /* MR23 removed unreachable code */\r
234\r
235 for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())\r
236 {\r
237 if ( sib->type() != u->type() ) return 0;\r
238 if ( sib->down()!=NULL )\r
239 if ( !match_partial(sib->down(), u->down()) ) return 0;\r
240 }\r
241 return 1;\r
242}\r
243\r
244#ifdef _MSC_VER // MR23\r
245//Turn off "unreachable code" warning\r
246#pragma warning(disable : 4702)\r
247#endif\r
248/* Walk the template tree 't' (matching against 'this'), filling in the\r
249 * 'labels' array, and setting 'n' according to how many labels were matched.\r
250 */\r
251int PCCTS_AST::\r
252scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n)\r
253{\r
254 ScanAST *sib;\r
255 PCCTS_AST *u = this;\r
256\r
257 if ( u==NULL ) return 0;\r
258\r
259 for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())\r
260 {\r
261 /* make sure tokens match; token of '0' means wildcard match */\r
262 if ( sib->type() != u->type() && sib->type()!=0 ) return 0;\r
263 /* we have a matched token here; set label pointers if exists */\r
264 if ( sib->label_num>0 )\r
265 {\r
266 require(labels!=NULL, "label found in template, but no array of labels");\r
267 (*n)++;\r
268 *(labels[sib->label_num-1]) = u;\r
269 }\r
270 /* match what's below if something there and current node is not wildcard */\r
271 if ( sib->down()!=NULL && sib->type()!=0 )\r
272 {\r
273 if ( sib->down()==NULL ) \r
274 {\r
275 if ( u->down()!=NULL ) \r
276 return 0; \r
277 else \r
278 return 1;\r
279 }\r
280 if ( !u->down()->scanmatch(sib->down(), labels, n) ) return 0;\r
281 }\r
282 }\r
283 return 1;\r
284}\r
285#ifdef _MSC_VER // MR23\r
286#pragma warning(default : 4702)\r
287#endif\r
288\r
289void PCCTS_AST::\r
290insert_after(PCCTS_AST *b)\r
291{\r
292 PCCTS_AST *end;\r
293 if ( b==NULL ) return;\r
294 /* find end of b's child list */\r
295 for (end=b; end->right()!=NULL; end=end->right()) {;}\r
296 end->setRight(this->right());\r
297 this->setRight(b);\r
298}\r
299\r
300void PCCTS_AST::\r
301append(PCCTS_AST *b)\r
302{\r
303 PCCTS_AST *end;\r
304 require(b!=NULL, "append: NULL input tree");\r
305 /* find end of child list */\r
306 for (end=this; end->right()!=NULL; end=end->right()) {;}\r
307 end->setRight(b);\r
308}\r
309\r
310PCCTS_AST *PCCTS_AST::\r
311tail()\r
312{\r
313 PCCTS_AST *end;\r
314 /* find end of child list */\r
315 for (end=this; end->right()!=NULL; end=end->right()) {;}\r
316 return end;\r
317}\r
318\r
319PCCTS_AST *PCCTS_AST::\r
320bottom()\r
321{\r
322 PCCTS_AST *end;\r
323 /* find end of child list */\r
324 for (end=this; end->down()!=NULL; end=end->down()) {;}\r
325 return end;\r
326}\r
327\r
328PCCTS_AST *PCCTS_AST::\r
329cut_between(PCCTS_AST *a, PCCTS_AST *b)\r
330{\r
331 PCCTS_AST *end, *ret;\r
332 if (a==NULL||b==NULL) return NULL;\r
333 /* find node pointing to b */\r
334 for (end=a; end->right()!=NULL&&end->right()!=b; end=end->right())\r
335 {;}\r
336 if (end->right()==NULL) return NULL; //ast_cut_between: a,b not connected\r
337 end->setRight(NULL); /* don't want it point to 'b' anymore */\r
338 ret = a->right();\r
339 a->setRight(b);\r
340 return ret;\r
341}\r
342\r
343#ifdef NOT_YET\r
344SList *PCCTS_AST::\r
345to_slist()\r
346{\r
347 SList *list = new SList;\r
348 PCCTS_AST *p;\r
349\r
350 for (p=this; p!=NULL; p=p->right())\r
351 {\r
352 list->add(p);\r
353 }\r
354 return list;\r
355}\r
356#endif\r
357\r
358void PCCTS_AST::\r
359tfree()\r
360{\r
361 PCCTS_AST *t = this;\r
362 if ( t->down()!=NULL ) t->down()->tfree();\r
363 if ( t->right()!=NULL ) t->right()->tfree();\r
364 delete t;\r
365}\r
366\r
367int PCCTS_AST::\r
368nsiblings()\r
369{\r
370 PCCTS_AST *t = this;\r
371 int n=0;\r
372\r
373 while ( t!=NULL )\r
374 {\r
375 n++;\r
376 t = t->right();\r
377 }\r
378 return n;\r
379}\r
380\r
381PCCTS_AST *PCCTS_AST::\r
382sibling_index(int i)\r
383{\r
384 PCCTS_AST *t = this;\r
385 int j=1;\r
386 require(i>0, "sibling_index: i<=0");\r
387\r
388 while ( t!=NULL )\r
389 {\r
390 if ( j==i ) return t;\r
391 j++;\r
392 t = t->right();\r
393 }\r
394 return NULL;\r
395}\r
396\r
397/* Assume this is a root node of a tree--\r
398 * duplicate that node and what's below; ignore siblings of root node.\r
399 */\r
400\r
401// MR9 23-Sep-97 RJV\r
402// MR9\r
403// MR9 RJV: Original version only duplicated the node and down elements.\r
404// MR9 Made copies of the pointers to sibling.\r
405// MR9 Changed call "down()->deepCopy()" to "down()->deepCopyBushy()"\r
406// MR9\r
407\r
408PCCTS_AST *PCCTS_AST::\r
409deepCopy()\r
410{\r
411 PCCTS_AST *u = this->shallowCopy();\r
412 if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());\r
413 u->setRight(NULL);\r
414 return u;\r
415}\r
416\r
417/* Copy all nodes including siblings of root. */\r
418PCCTS_AST *PCCTS_AST::\r
419deepCopyBushy()\r
420{\r
421 PCCTS_AST *u = this->shallowCopy();\r
422 /* copy the rest of the tree */\r
423 if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());\r
424 if ( right()!=NULL ) u->setRight(right()->deepCopyBushy());\r
425 return u;\r
426}\r
427\r
428void PCCTS_AST::\r
429scanast_free(ScanAST *t)\r
430{\r
431 if ( t == NULL ) return;\r
432 scanast_free( t->down() );\r
433 scanast_free( t->right() );\r
434 free( (char *) t ); // MR1\r
435}\r
436\r
437/*\r
438 * scan\r
439 *\r
440 * This function is like scanf(): it attempts to match a template\r
441 * against an input tree. A variable number of tree pointers\r
442 * may be set according to the '%i' labels in the template string.\r
443 * For example:\r
444 *\r
445 * t->ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )",\r
446 * &w, &x, &y, &z);\r
447 *\r
448 * Naturally, you'd want this converted from\r
449 *\r
450 * t->ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )",\r
451 * &w, &x, &y, &z);\r
452 *\r
453 * by SORCERER.\r
454 *\r
455 * This function call must be done withing a SORCERER file because SORCERER\r
456 * must convert the token references to the associated token number.\r
457 *\r
458 * This functions parses the template and creates trees which are then\r
459 * matched against the input tree. The labels are set as they are\r
460 * encountered; hence, partial matches may leave some pointers set\r
461 * and some NULL. This routines initializes all argument pointers to NULL\r
462 * at the beginning.\r
463 *\r
464 * This function returns the number of labels matched.\r
465 */\r
466int PCCTS_AST::\r
467ast_scan(char *templ, ...)\r
468{\r
469 va_list ap;\r
470 ScanAST *tmpl;\r
471 int n, i, found=0;\r
472 PCCTS_AST ***label_ptrs=NULL;\r
473\r
474 va_start(ap, templ);\r
475\r
476 /* make a ScanAST tree out of the template */\r
477 tmpl = stringparser_parse_scanast(templ, &n);\r
478\r
479 /* make an array out of the labels */\r
480 if ( n>0 )\r
481 {\r
482 label_ptrs = (PCCTS_AST ***) calloc(n, sizeof(PCCTS_AST **));\r
483 require(label_ptrs!=NULL, "scan: out of memory");\r
484 for (i=1; i<=n; i++)\r
485 {\r
486 label_ptrs[i-1] = va_arg(ap, PCCTS_AST **);\r
487 *(label_ptrs[i-1]) = NULL;\r
488 }\r
489 }\r
490\r
491 /* match the input tree against the template */\r
492 scanmatch(tmpl, label_ptrs, &found);\r
493\r
494 scanast_free(tmpl);\r
495 free( (char *) label_ptrs); // MR1\r
496\r
497 return found;\r
498}\r
499\r
500ScanAST *PCCTS_AST::\r
501new_scanast(int tok)\r
502{\r
503 ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST));\r
504//\r
505// 7-Apr-97 133MR1\r
506//\r
507 if ( p == NULL )\r
508 panic("out of memory\n"); // MR23\r
509 p->_token = tok;\r
510 return p;\r
511}\r
512\r
513ScanAST *PCCTS_AST::\r
514stringparser_parse_scanast(char *templ, int *num_labels)\r
515{\r
516 StringLexer lex;\r
517 StringParser parser;\r
518 ScanAST *t;\r
519\r
520 stringlexer_init(&lex, templ);\r
521 stringparser_init(&parser, &lex);\r
522 t = stringparser_parse_tree(&parser);\r
523 *num_labels = parser.num_labels;\r
524 return t;\r
525}\r
526\r
527void PCCTS_AST::\r
528stringparser_match(StringParser *parser, int token)\r
529{\r
530 if ( parser->token != token ) panic("bad tree in scan()");\r
531}\r
532\r
533/*\r
534 * Match a tree of the form:\r
535 * (root child1 child2 ... childn)\r
536 * or,\r
537 * node\r
538 *\r
539 * where the elements are integers or labeled integers.\r
540 */\r
541ScanAST *PCCTS_AST::\r
542stringparser_parse_tree(StringParser *parser)\r
543{\r
544 ScanAST *t=NULL, *root, *child, *last=NULL /*MR23*/;\r
545\r
546 if ( parser->token != __POUND )\r
547 {\r
548 return stringparser_parse_element(parser);\r
549 }\r
550 stringparser_match(parser,__POUND);\r
551 parser->token = stringscan_gettok(parser->lexer);\r
552 stringparser_match(parser,__LPAREN);\r
553 parser->token = stringscan_gettok(parser->lexer);\r
554 root = stringparser_parse_element(parser);\r
555 while ( parser->token != __RPAREN )\r
556 {\r
557 child = stringparser_parse_element(parser);\r
558 if ( t==NULL ) { t = child; last = t; }\r
559 else { last->_right = child; last = child; }\r
560 }\r
561 stringparser_match(parser,__RPAREN);\r
562 parser->token = stringscan_gettok(parser->lexer);\r
563 root->_down = t;\r
564 return root;\r
565}\r
566\r
567ScanAST *PCCTS_AST::\r
568stringparser_parse_element(StringParser *parser)\r
569{\r
570 char ebuf[100];\r
571 int label = 0;\r
572\r
573 if ( parser->token == __POUND )\r
574 {\r
575 return stringparser_parse_tree(parser);\r
576 }\r
577 if ( parser->token == __PERCENT )\r
578 {\r
579 parser->token = stringscan_gettok(parser->lexer);\r
580 stringparser_match(parser,__INT);\r
581 label = atoi(parser->lexer->text);\r
582 parser->num_labels++;\r
583 if ( label==0 ) panic("%%0 is an invalid label");\r
584 parser->token = stringscan_gettok(parser->lexer);\r
585 stringparser_match(parser,__COLON);\r
586 parser->token = stringscan_gettok(parser->lexer);\r
587 /* can label tokens and wildcards */\r
588 if ( parser->token != __INT && parser->token != __PERIOD )\r
589 panic("can only label tokens");\r
590 }\r
591 if ( parser->token == __INT )\r
592 {\r
593 ScanAST *p = new_scanast(atoi(parser->lexer->text));\r
594 parser->token = stringscan_gettok(parser->lexer);\r
595 p->label_num = label;\r
596 return p;\r
597 }\r
598 if ( parser->token == __PERIOD )\r
599 {\r
600 ScanAST *p = new_scanast(0); /* token of 0 is wildcard */\r
601 parser->token = stringscan_gettok(parser->lexer);\r
602 p->label_num = label;\r
603 return p;\r
604 }\r
605 sprintf(ebuf, "mismatch token in scan(): %s", scan_token_str(parser->token));\r
606 panic(ebuf);\r
607 return NULL;\r
608}\r
609\r
610void PCCTS_AST::\r
611stringparser_init(StringParser *parser, StringLexer *input)\r
612{\r
613 parser->lexer = input;\r
614 parser->token = stringscan_gettok(parser->lexer);\r
615 parser->num_labels = 0;\r
616}\r
617\r
618void PCCTS_AST::\r
619stringlexer_init(StringLexer *scanner, char *input)\r
620{\r
621 scanner->text[0]='\0';\r
622 scanner->input = input;\r
623 scanner->p = input;\r
624 stringscan_advance(scanner);\r
625}\r
626\r
627void PCCTS_AST::\r
628stringscan_advance(StringLexer *scanner)\r
629{\r
630 if ( *(scanner->p) == '\0' ) scanner->c = __StringScanEOF;\r
631 scanner->c = *(scanner->p)++;\r
632}\r
633\r
634int PCCTS_AST::\r
635stringscan_gettok(StringLexer *scanner)\r
636{\r
637 char *index = &scanner->text[0];\r
638 char ebuf[100]; /* MR23 Remove static */\r
639\r
640 while ( isspace(scanner->c) ) { stringscan_advance(scanner); }\r
641 if ( isdigit(scanner->c) )\r
642 {\r
643 int tok = __INT;\r
644 while ( isdigit(scanner->c) ) {\r
645 *index++ = (char) /* static_cast<char> */ (scanner->c); // MR23\r
646 stringscan_advance(scanner);\r
647 }\r
648 *index = '\0';\r
649 return tok;\r
650 }\r
651 switch ( scanner->c )\r
652 {\r
653 case '#' : stringscan_advance(scanner); return __POUND;\r
654 case '(' : stringscan_advance(scanner); return __LPAREN;\r
655 case ')' : stringscan_advance(scanner); return __RPAREN;\r
656 case '%' : stringscan_advance(scanner); return __PERCENT;\r
657 case ':' : stringscan_advance(scanner); return __COLON;\r
658 case '.' : stringscan_advance(scanner); return __PERIOD;\r
659 case '\0' : return __StringScanEOF;\r
660 case __StringScanEOF : return __StringScanEOF;\r
661 default :\r
662 sprintf(ebuf, "invalid char in scan: '%c'", scanner->c);\r
663 panic(ebuf);\r
664 }\r
665 return __StringScanEOF; // never reached\r
666}\r
667\r
668const char *PCCTS_AST:: /* MR20 const */\r
669scan_token_str(int t)\r
670{\r
671 if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t];\r
672 else if ( t==__StringScanEOF ) return "<end-of-string>";\r
673 else return "<invalid-token>";\r
674}\r
675\r
676//MR23\r
677int PCCTS_AST::printMessage(FILE* pFile, const char* pFormat, ...)\r
678{\r
679 va_list marker;\r
680 va_start( marker, pFormat );\r
681 int iRet = vfprintf(pFile, pFormat, marker);\r
682 va_end( marker );\r
683 return iRet;\r
684}\r