Home | History | Annotate | Download | only in antlr
      1 /*
      2  * pred.c -- source for predicate detection, manipulation
      3  *
      4  * SOFTWARE RIGHTS
      5  *
      6  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
      7  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
      8  * company may do whatever they wish with source code distributed with
      9  * PCCTS or the code generated by PCCTS, including the incorporation of
     10  * PCCTS, or its output, into commerical software.
     11  *
     12  * We encourage users to develop software with PCCTS.  However, we do ask
     13  * that credit is given to us for developing PCCTS.  By "credit",
     14  * we mean that if you incorporate our source code into one of your
     15  * programs (commercial product, research project, or otherwise) that you
     16  * acknowledge this fact somewhere in the documentation, research report,
     17  * etc...  If you like PCCTS and have developed a nice tool with the
     18  * output, please mention that you developed it using PCCTS.  In
     19  * addition, we ask that this header remain intact in our source code.
     20  * As long as these guidelines are kept, we expect to continue enhancing
     21  * this system and expect to make other tools available as they are
     22  * completed.
     23  *
     24  * ANTLR 1.33
     25  * Terence Parr
     26  * Parr Research Corporation
     27  * with Purdue University and AHPCRC, University of Minnesota
     28  * 1989-2001
     29  */
     30 
     31 #include <stdio.h>
     32 #include "pcctscfg.h"
     33 #include "set.h"
     34 #include "syn.h"
     35 #include "hash.h"
     36 #include "generic.h"
     37 #include "dlgdef.h"
     38 #include <ctype.h>
     39 
     40 #ifdef __USE_PROTOS
     41 static void complete_context_sets(RuleRefNode *, Predicate *);
     42 static void complete_context_trees(RuleRefNode *, Predicate *);
     43 #else
     44 static void complete_context_sets();
     45 static void complete_context_trees();
     46 #endif
     47 
     48 char *PRED_AND_LIST = "AND";
     49 char *PRED_OR_LIST = "OR";
     50 
     51 /*
     52  * In C mode, return the largest constant integer found as the
     53  * sole argument to LATEXT(i).
     54  *
     55  * In C++ mode, return the largest constant integer found as the
     56  * sole argument to LT(i) given that the char before is nonalpha.
     57  */
     58 
     59 int
     60 #ifdef __USE_PROTOS
     61 predicateLookaheadDepth(ActionNode *a)
     62 #else
     63 predicateLookaheadDepth(a)
     64 ActionNode *a;
     65 #endif
     66 {
     67 	int     max_k=0;
     68 
     69     if (a->predEntry != NULL) {
     70        MR_pred_depth(a->predEntry->pred,&max_k);
     71        goto PREDENTRY_EXIT;
     72     }
     73 
     74 	if ( GenCC )
     75 	{
     76 		/* scan for LT(i) */
     77 		int k = 0;
     78 		char *p = a->action;
     79 		while ( p!=NULL )
     80 		{
     81 			p = strstr(p, "LT(");
     82 			if ( p!=NULL )
     83 			{
     84 				if ( p>=a->action && !isalpha(*(p-1)) )
     85 				{
     86 					k = atoi(p+strlen("LT("));
     87 					if ( k>max_k ) max_k=k;
     88 				}
     89 				p += strlen("LT(");
     90 			}
     91 		}
     92 	}
     93 	else {
     94 		/* scan for LATEXT(i) */
     95 		int k = 0;
     96 		char *p = a->action;
     97 		while ( p!=NULL )
     98 		{
     99 			p = strstr(p, "LATEXT(");
    100 			if ( p!=NULL )
    101 			{
    102 				p += strlen("LATEXT(");
    103 				k = atoi(p);
    104 				if ( k>max_k ) max_k=k;
    105 			}
    106 		}
    107 	}
    108 
    109 	if (max_k==0) {
    110 		max_k = 1;	   /* MR33 Badly designed if didn't set max_k when CLL_k = 1 */
    111 		if (CLL_k > 1) /* MR27 Don't warn if max(k,ck) == 1 */
    112 		{
    113 			if ( !a->frmwarned )
    114 			{
    115 				a->frmwarned = 1;
    116 				warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1",
    117 							 GenCC?"LT(i)":"LATEXT(i)"),
    118 					   FileStr[a->file], a->line);
    119 			}
    120 		}
    121 	}
    122 
    123 /* MR10 */    if ( max_k > CLL_k) {
    124 /* MR10 */		if ( !a->frmwarned )
    125 /* MR10 */        {
    126 /* MR10 */			a->frmwarned = 1;
    127 /* MR11 */ errFL(eMsgd2("predicate refers to lookahead token %d. Semantic lookahead is limited to max(k,ck)==%d",
    128 /* MR10 */                        max_k,CLL_k),
    129 /* MR10 */                        FileStr[a->file],a->line);
    130 /* MR10 */          if (max_k >= OutputLL_k) {
    131 /* MR10 */            if (!GenCC) {
    132 /* MR10 */              errFL(eMsgd("    the lookahead buffer size in C mode is %d token(s) (including the one just recognized)",
    133 /* MR10 */                        OutputLL_k),
    134 /* MR10 */                        FileStr[a->file],a->line);
    135 /* MR10 */            };
    136 /* MR10 */          };
    137 /* MR10 */        };
    138 /* MR10 */        max_k= CLL_k;
    139 /* MR10 */    };
    140 
    141 PREDENTRY_EXIT:
    142 	return max_k;
    143 }
    144 
    145 /* Find all predicates in a block of alternatives.  DO NOT find predicates
    146  * behind the block because that predicate could depend on things set in
    147  * one of the nonoptional blocks
    148  */
    149 
    150 Predicate *
    151 #ifdef __USE_PROTOS
    152 find_in_aSubBlk( Junction *alt )
    153 #else
    154 find_in_aSubBlk( alt )
    155 Junction *alt;
    156 #endif
    157 {
    158 	Predicate *a, *head=NULL, *tail=NULL, *root=NULL;
    159 	Junction *p = alt;
    160 
    161     if (MRhoisting) {
    162       return MR_find_in_aSubBlk(alt);
    163     };
    164 	for (; p!=NULL; p=(Junction *)p->p2)
    165 	{
    166 		/* ignore empty alts */
    167 		if ( p->p1->ntype != nJunction ||
    168 			 ((Junction *)p->p1)->jtype != EndBlk )
    169 		{
    170 			a = find_predicates(p->p1);	/* get preds for this alt */
    171 			if ( a==NULL ) continue;
    172 
    173 			/* make an OR list of predicates */
    174 			if ( head==NULL )
    175 			{
    176 				root = new_pred();
    177 				root->expr = PRED_OR_LIST;
    178 				head = tail = a;
    179 				root->down = head;
    180 			}
    181 			else {
    182 				tail->right = a;
    183 				a->left = tail;
    184 				a->up = tail->up;
    185 				tail = a;
    186 			}
    187 		}
    188 	}
    189 
    190 	/* if just one pred, remove OR root */
    191 	if ( root!=NULL && root->down->right == NULL )
    192 	{
    193 		Predicate *d = root->down;
    194 		free( (char *) root);
    195 		return d;
    196 	}
    197 
    198 	return root;
    199 }
    200 
    201 Predicate *
    202 #ifdef __USE_PROTOS
    203 find_in_aOptBlk( Junction *alt )
    204 #else
    205 find_in_aOptBlk( alt )
    206 Junction *alt;
    207 #endif
    208 {
    209 	return find_in_aSubBlk( alt );
    210 }
    211 
    212 Predicate *
    213 #ifdef __USE_PROTOS
    214 find_in_aLoopBegin( Junction *alt )
    215 #else
    216 find_in_aLoopBegin( alt )
    217 Junction *alt;
    218 #endif
    219 {
    220 	return find_in_aSubBlk( (Junction *) alt->p1 );	/* get preds in alts */
    221 }
    222 
    223 Predicate *
    224 #ifdef __USE_PROTOS
    225 find_in_aPlusBlk( Junction *alt )
    226 #else
    227 find_in_aPlusBlk( alt )
    228 Junction *alt;
    229 #endif
    230 {
    231 	require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk");
    232 	return find_in_aSubBlk( alt );
    233 }
    234 
    235 /* Look for a predicate;
    236  *
    237  * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs.
    238  * This means that a "hoisting distance" of zero is the only distance
    239  * allowable.  Init actions are ignored.
    240  *
    241  * WARNING:
    242  *		Assumes no (..)? block after predicate for the moment.
    243  *		Does not check to see if pred is in production that can generate
    244  *			a sequence contained in the set of ambiguous tuples.
    245  *
    246  * Return the predicate found if any.
    247  */
    248 
    249 
    250 Predicate *
    251 #ifdef __USE_PROTOS
    252 find_predicates( Node *alt )
    253 #else
    254 find_predicates( alt )
    255 Node *alt;
    256 #endif
    257 {
    258 #ifdef DBG_PRED
    259 	Junction *j;
    260 	RuleRefNode *r;
    261 	TokNode *t;
    262 #endif
    263 	Predicate *pred;
    264 
    265 	if ( alt==NULL ) return NULL;
    266 
    267 #ifdef DBG_PRED
    268 	switch ( alt->ntype )
    269 	{
    270 		case nJunction :
    271 			j = (Junction *) alt;
    272 			fprintf(stderr, "Junction(in %s)", j->rname);
    273 			switch ( j->jtype )
    274 			{
    275 				case aSubBlk :
    276 					fprintf(stderr,"aSubBlk\n");
    277 					break;
    278 				case aOptBlk :
    279 					fprintf(stderr,"aOptBlk\n");
    280 					break;
    281 				case aLoopBegin :
    282 					fprintf(stderr,"aLoopBeginBlk\n");
    283 					break;
    284 				case aLoopBlk :
    285 					fprintf(stderr,"aLoopBlk\n");
    286 					break;
    287 				case aPlusBlk :
    288 					fprintf(stderr,"aPlusBlk\n");
    289 					break;
    290 				case EndBlk :
    291 					fprintf(stderr,"EndBlk\n");
    292 					break;
    293 				case RuleBlk :
    294 					fprintf(stderr,"RuleBlk\n");
    295 					break;
    296 				case Generic :
    297 					fprintf(stderr,"Generic\n");
    298 					break;
    299 				case EndRule :
    300 					fprintf(stderr,"EndRule\n");
    301 					break;
    302 			}
    303 			break;
    304 		case nRuleRef :
    305 			r = (RuleRefNode *) alt;
    306 			fprintf(stderr, "RuleRef(in %s)\n", r->rname);
    307 			break;
    308 		case nToken :
    309 			t = (TokNode *) alt;
    310 			fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token));
    311 			break;
    312 		case nAction :
    313 			fprintf(stderr, "Action\n");
    314 			break;
    315 	}
    316 #endif
    317 
    318 	switch ( alt->ntype )
    319 	{
    320 		case nJunction :
    321 		{
    322 			Predicate *a, *b;
    323 			Junction *p = (Junction *) alt;
    324 
    325 			/* lock nodes */
    326 			if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
    327 				 p->jtype==aPlusBlk || p->jtype==EndRule )
    328 			{
    329 				require(p->pred_lock!=NULL, "rJunc: lock array is NULL");
    330 				if ( p->pred_lock[1] )
    331 				{
    332 					return NULL;
    333 				}
    334 				p->pred_lock[1] = TRUE;
    335 			}
    336 
    337 			switch ( p->jtype )
    338 			{
    339 				case aSubBlk :
    340 					a = find_in_aSubBlk(p);
    341 					return a;	/* nothing is visible past this guy */
    342 				case aOptBlk :
    343 					a = find_in_aOptBlk(p);
    344 					return a;
    345 				case aLoopBegin :
    346 					a = find_in_aLoopBegin(p);
    347 					return a;
    348 				case aLoopBlk :
    349 					a = find_in_aSubBlk(p);
    350 					p->pred_lock[1] = FALSE;
    351 					return a;
    352 				case aPlusBlk :
    353 					a = find_in_aPlusBlk(p);
    354 					p->pred_lock[1] = FALSE;
    355 					return a;	/* nothing is visible past this guy */
    356 				case RuleBlk :
    357 					a = find_predicates(p->p1);
    358 					p->pred_lock[1] = FALSE;
    359 					return a;
    360 				case Generic :
    361 					a = find_predicates(p->p1);
    362 					b = find_predicates(p->p2);
    363 					if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE;
    364 					if ( a==NULL ) return b;
    365 					if ( b==NULL ) return a;
    366 					/* otherwise OR the two preds together */
    367 					{
    368 					fatal_internal("hit unknown situation during predicate hoisting");
    369 					}
    370 				case EndBlk :
    371 				case EndRule :	/* Find no predicates after a rule ref */
    372 					return NULL;
    373 				default:
    374 					fatal_internal("this cannot be printed\n");
    375 					break;
    376 			}
    377 		}
    378 		case nAction :
    379 		{
    380 			ActionNode *p = (ActionNode *) alt;
    381             if ( p->noHoist) return NULL;                           /* MR12c */
    382 			if ( p->init_action ) return find_predicates(p->next);
    383 			if ( p->is_predicate )
    384 			{
    385 				Tree *t=NULL;
    386 #ifdef DBG_PRED
    387 				fprintf(stderr, "predicate: <<%s>>?\n", p->action);
    388 #endif
    389 				if ( p->guardpred!=NULL )
    390 				{
    391 					pred = predicate_dup(p->guardpred);
    392                     MR_guardPred_plainSet(p,pred);                  /* MR12c */
    393 				}
    394 				else
    395 				{
    396 					pred = new_pred();
    397 					pred->k = predicateLookaheadDepth(p);
    398 					pred->source = p;
    399 					pred->expr = p->action;
    400 					if ( HoistPredicateContext && pred->k > 1 )
    401 					{
    402 						/* MR30 No need to use first_item_is_guess_block_extra
    403 						   since we know this is an action, not a (...)* or
    404 						   (...)+ block.
    405 						*/
    406 
    407 						if ( first_item_is_guess_block((Junction *)p->next) )
    408 						{
    409                             warnFL("cannot compute context of predicate in front of (..)? block",
    410                             FileStr[p->file], p->line);
    411 						}
    412 						else
    413 						{
    414 							ConstrainSearch = 0;
    415 /* MR11 */                  if (p->ampersandPred != NULL) {
    416 /* MR11 */  					TRAV(p,
    417 /* MR11 */							 pred->k,
    418 /* MR11 */  						 &(pred->completionTree), t);
    419 /* MR11 */                  } else {
    420     							TRAV(p->next,
    421     								 pred->k,
    422     								 &(pred->completionTree), t);
    423                             };
    424 							pred->tcontext = t;
    425                             MR_check_pred_too_long(pred,pred->completionTree);
    426 #ifdef DBG_PRED
    427 							fprintf(stderr, "LL(%d) context:", pred->k);
    428 							preorder(t);
    429 							fprintf(stderr, "\n");
    430 #endif
    431 						}
    432 					}
    433 					else if ( HoistPredicateContext && pred->k == 1 )
    434 					{
    435 						pred->scontext[1] = empty;
    436 						/* MR30 No need to use first_item_is_guess_block_extra
    437 						   since we know this is an action.
    438 						*/
    439 						if ( first_item_is_guess_block((Junction *)p->next) )
    440 						{
    441                         warnFL("cannot compute context of predicate in front of (..)? block",
    442                                              FileStr[p->file], p->line);
    443 						}
    444 						else
    445 						{
    446 							REACH((Junction *)p->next,
    447 								  1,
    448 								  &(pred->completionSet),
    449 								  pred->scontext[1]);
    450                             MR_check_pred_too_long(pred,pred->completionSet);
    451 #ifdef DBG_PRED
    452 							fprintf(stderr, "LL(1) context:");
    453 							s_fprT(stderr, pred->scontext[1]);
    454 							fprintf(stderr, "\n");
    455 #endif
    456 						}
    457 					}
    458 				}
    459 				{
    460 					Predicate  *d = find_predicates(p->next);
    461                     Predicate  *root;
    462 
    463 /* Warning: Doesn't seem like the up pointers will all be set correctly;
    464  * TJP: that's ok, we're not using them now.
    465  */
    466 					if ( d!=NULL )
    467 					{
    468 						root = new_pred();
    469 						root->expr = PRED_AND_LIST;
    470 						root->down = pred;
    471 						pred->right = d;
    472 						pred->up = root;
    473 						d->left = pred;
    474 						d->up = pred->up;
    475 						return root;
    476 					}
    477 				}
    478 				return pred;
    479 			}
    480 			return NULL;
    481 		}
    482 		case nRuleRef :
    483 		{
    484 			Predicate   *a;
    485 			RuleRefNode *p = (RuleRefNode *) alt;
    486 			Junction    *r;
    487             Junction    *save_MR_RuleBlkWithHalt;
    488 
    489 			RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
    490 			if ( q == NULL )
    491 			{
    492 				warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );
    493 				return NULL;
    494 			}
    495 			r = RulePtr[q->rulenum];
    496 			if ( r->pred_lock[1] )
    497 			{
    498 				/* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis
    499 				 * must have seen it earlier.
    500 				 */
    501 				return NULL;
    502 			}
    503 
    504             /* MR10 There should only be one halt set at a time.        */
    505             /* MR10 Life would have been easier with a global variable  */
    506             /* MR10    (at least for this particular need)              */
    507             /* MR10 Unset the old one and set the new one, later undo.  */
    508 
    509             require(r->end->halt == FALSE,"should only have one halt at a time");
    510 
    511 /* MR10 */  require(MR_RuleBlkWithHalt == NULL ||
    512 /* MR10 */          (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == TRUE),
    513 /* MR10 */             "RuleBlkWithHalt->end not RuleBlk or does not have halt set");
    514 /* MR10 */  if (MR_RuleBlkWithHalt != NULL) {
    515 /* MR10 */    MR_RuleBlkWithHalt->end->halt=FALSE;
    516 /* MR10 */  };
    517 
    518 /***        fprintf(stderr,"\nSetting halt on junction #%d\n",r->end->seq);     ***/
    519 
    520             require(r->end->halt == FALSE,"rule->end->halt already set");
    521 
    522             save_MR_RuleBlkWithHalt=MR_RuleBlkWithHalt;
    523 
    524 /* MR10 */  MR_pointerStackPush(&MR_RuleBlkWithHaltStack,MR_RuleBlkWithHalt);
    525 /* MR10 */  MR_pointerStackPush(&MR_PredRuleRefStack,p);
    526 
    527 			r->end->halt = TRUE;
    528 /* MR10 */  MR_RuleBlkWithHalt=r;
    529 
    530 			a = find_predicates((Node *)r);
    531 
    532             require(r->end->halt == TRUE,"rule->end->halt not set");
    533             r->end->halt = FALSE;
    534 
    535 /* MR10 */  MR_pointerStackPop(&MR_PredRuleRefStack);
    536 /* MR10 */  MR_RuleBlkWithHalt=(Junction *) MR_pointerStackPop(&MR_RuleBlkWithHaltStack);
    537 
    538             require (MR_RuleBlkWithHalt==save_MR_RuleBlkWithHalt,
    539                     "RuleBlkWithHaltStack not consistent");
    540 
    541 /* MR10 */  require(MR_RuleBlkWithHalt == NULL ||
    542 /* MR10 */          (MR_RuleBlkWithHalt->jtype == RuleBlk && MR_RuleBlkWithHalt->end->halt == FALSE),
    543 /* MR10 */             "RuleBlkWithHalt->end not RuleBlk or has no halt set");
    544 /* MR10 */  if (MR_RuleBlkWithHalt != NULL) {
    545 /* MR10 */    MR_RuleBlkWithHalt->end->halt=TRUE;
    546 /* MR10 */  };
    547 
    548 /***        fprintf(stderr,"\nRestoring halt on junction #%d\n",r->end->seq);   ***/
    549 
    550 			if ( a==NULL ) return NULL;
    551 
    552 			/* attempt to compute the "local" FOLLOW just like in normal lookahead
    553 			 * computation if needed
    554 			 */
    555 
    556 			complete_context_sets(p,a);
    557 			complete_context_trees(p,a);
    558 
    559 /* MR10 */  MR_cleanup_pred_trees(a);
    560 
    561 			return a;
    562 		}
    563 		case nToken :
    564 			break;
    565 	}
    566 
    567 	return NULL;
    568 }
    569 
    570 #ifdef __USE_PROTOS
    571 Predicate *MR_find_predicates_and_supp(Node *alt)
    572 #else
    573 Predicate *MR_find_predicates_and_supp(alt)
    574   Node      *alt;
    575 #endif
    576 {
    577     Predicate   *p;
    578 
    579     p=find_predicates(alt);
    580     p=MR_suppressK(alt,p);
    581     return p;
    582 }
    583 
    584 Predicate *
    585 #ifdef __USE_PROTOS
    586 new_pred( void )
    587 #else
    588 new_pred( )
    589 #endif
    590 {
    591 	Predicate *p = (Predicate *) calloc(1,sizeof(Predicate)); /* MR10 */
    592 	require(p!=NULL, "new_pred: cannot alloc predicate");
    593     p->scontext[0]=empty;
    594     p->scontext[1]=empty;
    595     p->completionTree=empty;
    596     p->completionSet=empty;
    597     p->plainSet=empty;
    598 	return p;
    599 }
    600 
    601 static void
    602 #ifdef __USE_PROTOS
    603 complete_context_sets( RuleRefNode *p, Predicate *a )
    604 #else
    605 complete_context_sets( p, a )
    606 RuleRefNode *p;
    607 Predicate *a;
    608 #endif
    609 {
    610 	set rk2, b;
    611 	int k2;
    612 
    613 #ifdef DBG_PRED
    614 	fprintf(stderr, "enter complete_context_sets\n");
    615 #endif
    616 	for (; a!=NULL; a=a->right)
    617 	{
    618 		if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
    619 		{
    620 			complete_context_sets(p,a->down);
    621 			continue;
    622 		}
    623 		rk2 = b = empty;
    624 		while ( !set_nil(a->completionSet) )
    625 		{
    626 			k2 = set_int(a->completionSet);
    627 			set_rm(k2, a->completionSet);
    628 
    629             REACH(p->next, k2, &rk2, b);
    630 			set_orin(&(a->scontext[1]), b);
    631 			set_free(b);
    632 		}
    633 
    634 		set_orin(&(a->completionSet), rk2);/* remember what we couldn't do */
    635 		set_free(rk2);
    636 #ifdef DBG_PRED
    637 		fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a);
    638 		s_fprT(stderr, a->scontext[1]);
    639 		fprintf(stderr, "\n");
    640 #endif
    641 /*		complete_context_sets(p, a->down);*/
    642 	}
    643 #ifdef DBG_PRED
    644 	fprintf(stderr, "exit complete_context_sets\n");
    645 #endif
    646 }
    647 
    648 static void
    649 #ifdef __USE_PROTOS
    650 complete_context_trees( RuleRefNode *p, Predicate *a )
    651 #else
    652 complete_context_trees( p, a )
    653 RuleRefNode *p;
    654 Predicate *a;
    655 #endif
    656 {
    657 	set rk2;
    658 	int k2;
    659 	Tree *u;
    660 
    661 #ifdef DBG_PRED
    662 	fprintf(stderr, "enter complete_context_trees\n");
    663 #endif
    664 	for (; a!=NULL; a=a->right)
    665 	{
    666 		if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
    667 		{
    668 			complete_context_trees(p, a->down);
    669 			continue;
    670 		}
    671 		rk2 = empty;
    672 
    673 		/* any k left to do? if so, link onto tree */
    674 		while ( !set_nil(a->completionTree) )
    675 		{
    676 			k2 = set_int(a->completionTree);
    677 			set_rm(k2, a->completionTree);
    678 			u = NULL;
    679 
    680             TRAV(p->next, k2, &rk2, u);
    681 
    682 			/* any subtrees missing k2 tokens, add u onto end */
    683 			a->tcontext = tlink(a->tcontext, u, k2);
    684             Tfree(u);   /* MR10 */
    685 		}
    686 		set_orin(&(a->completionTree), rk2);/* remember what we couldn't do */
    687 		set_free(rk2);
    688 #ifdef DBG_PRED
    689 		fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k);
    690 		preorder(a->tcontext);
    691 		fprintf(stderr, "\n");
    692 #endif
    693 /*		complete_context_trees(p, a->down);*/
    694 	}
    695 #ifdef DBG_PRED
    696 	fprintf(stderr, "exit complete_context_trees\n");
    697 #endif
    698 }
    699 
    700 /* Walk a list of predicates and return the set of all tokens in scontext[1]'s */
    701 set
    702 #ifdef __USE_PROTOS
    703 covered_set( Predicate *p )
    704 #else
    705 covered_set( p )
    706 Predicate *p;
    707 #endif
    708 {
    709 	set a;
    710 
    711 	a = empty;
    712 	for (; p!=NULL; p=p->right)
    713 	{
    714 		if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST )
    715 		{
    716 			set_orin(&a, covered_set(p->down));
    717 			continue;
    718 		}
    719 		set_orin(&a, p->scontext[1]);
    720 		set_orin(&a, covered_set(p->down));
    721 	}
    722 	return a;
    723 }
    724 
    725 /* MR10 predicate_free()
    726    MR10 Don't free the leaf nodes since they are part of the action node
    727 */
    728 
    729 #ifdef __USE_PROTOS
    730 void predicate_free(Predicate *p)
    731 #else
    732 void predicate_free(p)
    733   Predicate     *p;
    734 #endif
    735 {
    736   if (p == NULL) return;
    737   predicate_free(p->right);
    738   predicate_free(p->down);
    739   if (p->cloned ||
    740       p->source == NULL ||
    741       p->source->guardpred == NULL ||
    742       p->expr == PRED_AND_LIST ||
    743       p->expr == PRED_OR_LIST) {
    744     set_free(p->scontext[1]);
    745     set_free(p->completionSet);
    746     set_free(p->completionTree);
    747     set_free(p->plainSet);
    748     Tfree(p->tcontext);
    749     free( (char *) p);
    750   } else {
    751     p->right=NULL;
    752     p->down=NULL;  /* MR13 *** debug */
    753   };
    754 }
    755 
    756 /* MR10 predicate_dup() */
    757 
    758 #ifdef __USE_PROTOS
    759 Predicate * predicate_dup_xxx(Predicate *p,int contextToo)
    760 #else
    761 Predicate * predicate_dup_xxx(p,contextToo)
    762   Predicate     *p;
    763   int           contextToo;
    764 #endif
    765 {
    766   Predicate     *q;
    767 
    768   if (p == NULL) return NULL;
    769   q=new_pred();
    770   q->down=predicate_dup(p->down);
    771   q->right=predicate_dup(p->right);
    772 
    773   /*
    774      don't replicate expr - it is read-only
    775      and address comparison is used to look
    776      for identical predicates.
    777   */
    778 
    779   q->expr=p->expr;
    780   q->k=p->k;
    781   q->source=p->source;
    782   q->cloned=1;
    783   q->ampersandStyle=p->ampersandStyle;
    784   q->inverted=p->inverted;
    785   q->predEntry=p->predEntry;
    786   q->plainSet=set_dup(p->plainSet);
    787 
    788   if (contextToo) {
    789     q->tcontext=tdup(p->tcontext);
    790     q->scontext[0]=set_dup(p->scontext[0]);
    791     q->scontext[1]=set_dup(p->scontext[1]);
    792     q->completionTree=set_dup(p->completionTree);
    793     q->completionSet=set_dup(p->completionSet);
    794   };
    795 
    796   /* don't need to dup "redundant" */
    797 
    798   return q;
    799 
    800 }
    801 
    802 #ifdef __USE_PROTOS
    803 Predicate * predicate_dup_without_context(Predicate *p)
    804 #else
    805 Predicate * predicate_dup_without_context(p)
    806   Predicate     *p;
    807 #endif
    808 {
    809   return predicate_dup_xxx(p,0);
    810 }
    811 
    812 #ifdef __USE_PROTOS
    813 Predicate * predicate_dup(Predicate *p)
    814 #else
    815 Predicate * predicate_dup(p)
    816   Predicate     *p;
    817 #endif
    818 {
    819   return predicate_dup_xxx(p,1);
    820 }
    821 
    822