2 * pred.c -- source for predicate detection, manipulation
4 * $Id: pred.c,v 1.6 95/09/26 12:58:44 parrt Exp $
9 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
10 * Set (PCCTS) -- PCCTS is in the public domain. An individual or
11 * company may do whatever they wish with source code distributed with
12 * PCCTS or the code generated by PCCTS, including the incorporation of
13 * PCCTS, or its output, into commerical software.
15 * We encourage users to develop software with PCCTS. However, we do ask
16 * that credit is given to us for developing PCCTS. By "credit",
17 * we mean that if you incorporate our source code into one of your
18 * programs (commercial product, research project, or otherwise) that you
19 * acknowledge this fact somewhere in the documentation, research report,
20 * etc... If you like PCCTS and have developed a nice tool with the
21 * output, please mention that you developed it using PCCTS. In
22 * addition, we ask that this header remain intact in our source code.
23 * As long as these guidelines are kept, we expect to continue enhancing
24 * this system and expect to make other tools available as they are
29 * Parr Research Corporation
30 * with Purdue University and AHPCRC, University of Minnesota
47 static void complete_context_sets(RuleRefNode *, Predicate *);
48 static void complete_context_trees(RuleRefNode *, Predicate *);
50 static void complete_context_sets();
51 static void complete_context_trees();
54 static Predicate pred_empty = {
55 NULL,NULL,NULL,NULL,NULL,NULL,0,
56 {set_init,set_init},set_init
59 char *PRED_AND_LIST = "AND";
60 char *PRED_OR_LIST = "OR";
63 * In C mode, return the largest constant integer found as the
64 * sole argument to LATEXT(i).
66 * In C++ mode, return the largest constant integer found as the
67 * sole argument to LT(i) given that the char before is nonalpha.
71 predicateLookaheadDepth(ActionNode *a)
73 predicateLookaheadDepth(a)
89 if ( p>=a->action && !isalpha(*(p-1)) )
91 k = atoi(p+strlen("LT("));
92 if ( k>max_k ) max_k=k;
99 /* scan for LATEXT(i) */
104 p = strstr(p, "LATEXT(");
107 p += strlen("LATEXT(");
109 if ( k>max_k ) max_k=k;
119 warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1",
120 GenCC?"LT(i)":"LATEXT(i)"),
121 FileStr[a->file], a->line);
129 /* Find all predicates in a block of alternatives. DO NOT find predicates
130 * behind the block because that predicate could depend on things set in
131 * one of the nonoptional blocks
135 find_in_aSubBlk( Junction *alt )
137 find_in_aSubBlk( alt )
141 Predicate *a, *head=NULL, *tail, *root=NULL;
144 for (; p!=NULL; p=(Junction *)p->p2)
146 /* ignore empty alts */
147 if ( p->p1->ntype != nJunction ||
148 ((Junction *)p->p1)->jtype != EndBlk )
150 a = find_predicates(p->p1); /* get preds for this alt */
151 if ( a==NULL ) continue;
153 /* make an OR list of predicates */
157 root->expr = PRED_OR_LIST;
170 /* if just one pred, remove OR root */
171 if ( root!=NULL && root->down->right == NULL )
173 Predicate *d = root->down;
183 find_in_aOptBlk( Junction *alt )
185 find_in_aOptBlk( alt )
189 return find_in_aSubBlk( alt );
194 find_in_aLoopBegin( Junction *alt )
196 find_in_aLoopBegin( alt )
200 return find_in_aSubBlk( (Junction *) alt->p1 ); /* get preds in alts */
205 find_in_aPlusBlk( Junction *alt )
207 find_in_aPlusBlk( alt )
211 require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk");
212 return find_in_aSubBlk( alt );
215 /* Look for a predicate;
217 * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs.
218 * This means that a "hoisting distance" of zero is the only distance
219 * allowable. Init actions are ignored.
222 * Assumes no (..)? block after predicate for the moment.
223 * Does not check to see if pred is in production that can generate
224 * a sequence contained in the set of ambiguous tuples.
226 * Return the predicate found if any.
230 find_predicates( Node *alt )
232 find_predicates( alt )
243 if ( alt==NULL ) return NULL;
246 switch ( alt->ntype )
249 j = (Junction *) alt;
250 fprintf(stderr, "Junction(in %s)", j->rname);
254 fprintf(stderr,"aSubBlk\n");
257 fprintf(stderr,"aOptBlk\n");
260 fprintf(stderr,"aLoopBeginBlk\n");
263 fprintf(stderr,"aLoopBlk\n");
266 fprintf(stderr,"aPlusBlk\n");
269 fprintf(stderr,"EndBlk\n");
272 fprintf(stderr,"RuleBlk\n");
275 fprintf(stderr,"Generic\n");
278 fprintf(stderr,"EndRule\n");
283 r = (RuleRefNode *) alt;
284 fprintf(stderr, "RuleRef(in %s)\n", r->rname);
288 fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token));
291 fprintf(stderr, "Action\n");
296 switch ( alt->ntype )
301 Junction *p = (Junction *) alt;
304 if ( p->jtype==aLoopBlk || p->jtype==RuleBlk ||
305 p->jtype==aPlusBlk || p->jtype==EndRule )
307 require(p->pred_lock!=NULL, "rJunc: lock array is NULL");
308 if ( p->pred_lock[1] )
312 p->pred_lock[1] = TRUE;
318 a = find_in_aSubBlk(p);
319 return a; /* nothing is visible past this guy */
321 a = find_in_aOptBlk(p);
324 a = find_in_aLoopBegin(p);
327 a = find_in_aSubBlk(p);
328 p->pred_lock[1] = FALSE;
331 a = find_in_aPlusBlk(p);
332 p->pred_lock[1] = FALSE;
333 return a; /* nothing is visible past this guy */
335 a = find_predicates(p->p1);
336 p->pred_lock[1] = FALSE;
339 a = find_predicates(p->p1);
340 b = find_predicates(p->p2);
341 if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE;
342 if ( a==NULL ) return b;
343 if ( b==NULL ) return a;
344 /* otherwise OR the two preds together */
346 fatal_internal("hit unknown situation during predicate hoisting");
349 case EndRule : /* Find no predicates after a rule ref */
352 fatal_internal("this cannot be printed\n");
358 ActionNode *p = (ActionNode *) alt;
359 if ( p->init_action ) return find_predicates(p->next);
360 if ( p->is_predicate )
364 fprintf(stderr, "predicate: <<%s>>?\n", p->action);
366 if ( p->guardpred!=NULL )
373 pred->k = predicateLookaheadDepth(p);
375 pred->expr = p->action;
376 if ( HoistPredicateContext && pred->k > 1 )
378 if ( first_item_is_guess_block((Junction *)p->next) )
380 warnFL("cannot compute context of predicate in front of (..)? block", FileStr[p->file], p->line);
387 &(pred->completion), t);
390 fprintf(stderr, "LL(%d) context:", pred->k);
392 fprintf(stderr, "\n");
396 else if ( HoistPredicateContext && pred->k == 1 )
398 pred->scontext[1] = empty;
399 if ( first_item_is_guess_block((Junction *)p->next) )
401 warnFL("cannot compute context of predicate in front of (..)? block", FileStr[p->file], p->line);
405 REACH((Junction *)p->next,
410 fprintf(stderr, "LL(1) context:");
411 s_fprT(stderr, pred->scontext[1]);
412 fprintf(stderr, "\n");
418 Predicate *d = find_predicates(p->next), *root;
419 /* Warning: Doesn't seem like the up pointers will all be set correctly;
420 * TJP: that's ok, we're not using them now.
425 root->expr = PRED_AND_LIST;
441 RuleRefNode *p = (RuleRefNode *) alt;
444 RuleEntry *q = (RuleEntry *) hash_get(Rname, p->text);
447 warnFL( eMsg1("rule %s not defined",p->text), FileStr[p->file], p->line );
450 r = RulePtr[q->rulenum];
451 if ( r->pred_lock[1] )
453 /* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis
454 * must have seen it earlier.
458 save_halt = r->end->halt;
460 /* a = find_predicates((Node *)r->p1);*/
461 a = find_predicates((Node *)r);
462 r->end->halt = save_halt;
463 if ( a==NULL ) return NULL;
464 /* attempt to compute the "local" FOLLOW just like in normal lookahead
465 * computation if needed
467 complete_context_sets(p,a);
468 complete_context_trees(p,a);
485 Predicate *p = (Predicate *) malloc(sizeof(Predicate));
486 require(p!=NULL, "new_pred: cannot alloc predicate");
493 complete_context_sets( RuleRefNode *p, Predicate *a )
495 complete_context_sets( p, a )
504 fprintf(stderr, "enter complete_context_sets\n");
506 for (; a!=NULL; a=a->right)
508 if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
510 complete_context_sets(p, a->down);
514 while ( !set_nil(a->completion) )
516 k2 = set_int(a->completion);
517 set_rm(k2, a->completion);
518 REACH(p->next, k2, &rk2, b);
519 set_orin(&(a->scontext[1]), b);
522 set_orin(&(a->completion), rk2);/* remember what we couldn't do */
525 fprintf(stderr, "LL(1) context for %s(addr 0x%x) after ruleref:", a->expr, a);
526 s_fprT(stderr, a->scontext[1]);
527 fprintf(stderr, "\n");
529 /* complete_context_sets(p, a->down);*/
532 fprintf(stderr, "exit complete_context_sets\n");
538 complete_context_trees( RuleRefNode *p, Predicate *a )
540 complete_context_trees( p, a )
550 fprintf(stderr, "enter complete_context_trees\n");
552 for (; a!=NULL; a=a->right)
554 if ( a->expr == PRED_AND_LIST || a->expr == PRED_OR_LIST )
556 complete_context_trees(p, a->down);
560 /* any k left to do? if so, link onto tree */
561 while ( !set_nil(a->completion) )
563 k2 = set_int(a->completion);
564 set_rm(k2, a->completion);
566 TRAV(p->next, k2, &rk2, u);
567 /* any subtrees missing k2 tokens, add u onto end */
568 a->tcontext = tlink(a->tcontext, u, k2);
570 set_orin(&(a->completion), rk2);/* remember what we couldn't do */
573 fprintf(stderr, "LL(i<%d) context after ruleref:", LL_k);
574 preorder(a->tcontext);
575 fprintf(stderr, "\n");
577 /* complete_context_trees(p, a->down);*/
580 fprintf(stderr, "exit complete_context_trees\n");
584 /* Walk a list of predicates and return the set of all tokens in scontext[1]'s */
587 covered_set( Predicate *p )
596 for (; p!=NULL; p=p->right)
598 if ( p->expr == PRED_AND_LIST || p->expr == PRED_OR_LIST )
600 set_orin(&a, covered_set(p->down));
603 set_orin(&a, p->scontext[1]);
604 set_orin(&a, covered_set(p->down));