]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/CodeTools/TianoTools/Pccts/antlr/pred.c
2 * pred.c -- source for predicate detection, manipulation
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.
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
26 * Parr Research Corporation
27 * with Purdue University and AHPCRC, University of Minnesota
41 static void complete_context_sets(RuleRefNode
*, Predicate
*);
42 static void complete_context_trees(RuleRefNode
*, Predicate
*);
44 static void complete_context_sets();
45 static void complete_context_trees();
48 char *PRED_AND_LIST
= "AND";
49 char *PRED_OR_LIST
= "OR";
52 * In C mode, return the largest constant integer found as the
53 * sole argument to LATEXT(i).
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.
61 predicateLookaheadDepth(ActionNode
*a
)
63 predicateLookaheadDepth(a
)
69 if (a
->predEntry
!= NULL
) {
70 MR_pred_depth(a
->predEntry
->pred
,&max_k
);
84 if ( p
>=a
->action
&& !isalpha(*(p
-1)) )
86 k
= atoi(p
+strlen("LT("));
87 if ( k
>max_k
) max_k
=k
;
94 /* scan for LATEXT(i) */
99 p
= strstr(p
, "LATEXT(");
102 p
+= strlen("LATEXT(");
104 if ( k
>max_k
) max_k
=k
;
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 */
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
);
123 /* MR10 */ if ( max_k
> CLL_k
) {
124 /* MR10 */ if ( !a
->frmwarned
)
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
);
138 /* MR10 */ max_k
= CLL_k
;
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
152 find_in_aSubBlk( Junction
*alt
)
154 find_in_aSubBlk( alt
)
158 Predicate
*a
, *head
=NULL
, *tail
=NULL
, *root
=NULL
;
162 return MR_find_in_aSubBlk(alt
);
164 for (; p
!=NULL
; p
=(Junction
*)p
->p2
)
166 /* ignore empty alts */
167 if ( p
->p1
->ntype
!= nJunction
||
168 ((Junction
*)p
->p1
)->jtype
!= EndBlk
)
170 a
= find_predicates(p
->p1
); /* get preds for this alt */
171 if ( a
==NULL
) continue;
173 /* make an OR list of predicates */
177 root
->expr
= PRED_OR_LIST
;
190 /* if just one pred, remove OR root */
191 if ( root
!=NULL
&& root
->down
->right
== NULL
)
193 Predicate
*d
= root
->down
;
194 free( (char *) root
);
203 find_in_aOptBlk( Junction
*alt
)
205 find_in_aOptBlk( alt
)
209 return find_in_aSubBlk( alt
);
214 find_in_aLoopBegin( Junction
*alt
)
216 find_in_aLoopBegin( alt
)
220 return find_in_aSubBlk( (Junction
*) alt
->p1
); /* get preds in alts */
225 find_in_aPlusBlk( Junction
*alt
)
227 find_in_aPlusBlk( alt
)
231 require(alt
!=NULL
&&alt
->p2
!=NULL
, "invalid aPlusBlk");
232 return find_in_aSubBlk( alt
);
235 /* Look for a predicate;
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.
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.
246 * Return the predicate found if any.
252 find_predicates( Node
*alt
)
254 find_predicates( alt
)
265 if ( alt
==NULL
) return NULL
;
268 switch ( alt
->ntype
)
271 j
= (Junction
*) alt
;
272 fprintf(stderr
, "Junction(in %s)", j
->rname
);
276 fprintf(stderr
,"aSubBlk\n");
279 fprintf(stderr
,"aOptBlk\n");
282 fprintf(stderr
,"aLoopBeginBlk\n");
285 fprintf(stderr
,"aLoopBlk\n");
288 fprintf(stderr
,"aPlusBlk\n");
291 fprintf(stderr
,"EndBlk\n");
294 fprintf(stderr
,"RuleBlk\n");
297 fprintf(stderr
,"Generic\n");
300 fprintf(stderr
,"EndRule\n");
305 r
= (RuleRefNode
*) alt
;
306 fprintf(stderr
, "RuleRef(in %s)\n", r
->rname
);
310 fprintf(stderr
, "TokenNode(in %s)%s\n", t
->rname
, TokenString(t
->token
));
313 fprintf(stderr
, "Action\n");
318 switch ( alt
->ntype
)
323 Junction
*p
= (Junction
*) alt
;
326 if ( p
->jtype
==aLoopBlk
|| p
->jtype
==RuleBlk
||
327 p
->jtype
==aPlusBlk
|| p
->jtype
==EndRule
)
329 require(p
->pred_lock
!=NULL
, "rJunc: lock array is NULL");
330 if ( p
->pred_lock
[1] )
334 p
->pred_lock
[1] = TRUE
;
340 a
= find_in_aSubBlk(p
);
341 return a
; /* nothing is visible past this guy */
343 a
= find_in_aOptBlk(p
);
346 a
= find_in_aLoopBegin(p
);
349 a
= find_in_aSubBlk(p
);
350 p
->pred_lock
[1] = FALSE
;
353 a
= find_in_aPlusBlk(p
);
354 p
->pred_lock
[1] = FALSE
;
355 return a
; /* nothing is visible past this guy */
357 a
= find_predicates(p
->p1
);
358 p
->pred_lock
[1] = FALSE
;
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 */
368 fatal_internal("hit unknown situation during predicate hoisting");
371 case EndRule
: /* Find no predicates after a rule ref */
374 fatal_internal("this cannot be printed\n");
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
)
387 fprintf(stderr
, "predicate: <<%s>>?\n", p
->action
);
389 if ( p
->guardpred
!=NULL
)
391 pred
= predicate_dup(p
->guardpred
);
392 MR_guardPred_plainSet(p
,pred
); /* MR12c */
397 pred
->k
= predicateLookaheadDepth(p
);
399 pred
->expr
= p
->action
;
400 if ( HoistPredicateContext
&& pred
->k
> 1 )
402 /* MR30 No need to use first_item_is_guess_block_extra
403 since we know this is an action, not a (...)* or
407 if ( first_item_is_guess_block((Junction
*)p
->next
) )
409 warnFL("cannot compute context of predicate in front of (..)? block",
410 FileStr
[p
->file
], p
->line
);
415 /* MR11 */ if (p
->ampersandPred
!= NULL
) {
418 /* MR11 */ &(pred
->completionTree
), t
);
422 &(pred
->completionTree
), t
);
425 MR_check_pred_too_long(pred
,pred
->completionTree
);
427 fprintf(stderr
, "LL(%d) context:", pred
->k
);
429 fprintf(stderr
, "\n");
433 else if ( HoistPredicateContext
&& pred
->k
== 1 )
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.
439 if ( first_item_is_guess_block((Junction
*)p
->next
) )
441 warnFL("cannot compute context of predicate in front of (..)? block",
442 FileStr
[p
->file
], p
->line
);
446 REACH((Junction
*)p
->next
,
448 &(pred
->completionSet
),
450 MR_check_pred_too_long(pred
,pred
->completionSet
);
452 fprintf(stderr
, "LL(1) context:");
453 s_fprT(stderr
, pred
->scontext
[1]);
454 fprintf(stderr
, "\n");
460 Predicate
*d
= find_predicates(p
->next
);
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.
469 root
->expr
= PRED_AND_LIST
;
485 RuleRefNode
*p
= (RuleRefNode
*) alt
;
487 Junction
*save_MR_RuleBlkWithHalt
;
489 RuleEntry
*q
= (RuleEntry
*) hash_get(Rname
, p
->text
);
492 warnFL( eMsg1("rule %s not defined",p
->text
), FileStr
[p
->file
], p
->line
);
495 r
= RulePtr
[q
->rulenum
];
496 if ( r
->pred_lock
[1] )
498 /* infinite left-recursion; ignore 'cause LL sup 1 (k) analysis
499 * must have seen it earlier.
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. */
509 require(r
->end
->halt
== FALSE
,"should only have one halt at a time");
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
;
518 /*** fprintf(stderr,"\nSetting halt on junction #%d\n",r->end->seq); ***/
520 require(r
->end
->halt
== FALSE
,"rule->end->halt already set");
522 save_MR_RuleBlkWithHalt
=MR_RuleBlkWithHalt
;
524 /* MR10 */ MR_pointerStackPush(&MR_RuleBlkWithHaltStack
,MR_RuleBlkWithHalt
);
525 /* MR10 */ MR_pointerStackPush(&MR_PredRuleRefStack
,p
);
528 /* MR10 */ MR_RuleBlkWithHalt
=r
;
530 a
= find_predicates((Node
*)r
);
532 require(r
->end
->halt
== TRUE
,"rule->end->halt not set");
533 r
->end
->halt
= FALSE
;
535 /* MR10 */ MR_pointerStackPop(&MR_PredRuleRefStack
);
536 /* MR10 */ MR_RuleBlkWithHalt
=(Junction
*) MR_pointerStackPop(&MR_RuleBlkWithHaltStack
);
538 require (MR_RuleBlkWithHalt
==save_MR_RuleBlkWithHalt
,
539 "RuleBlkWithHaltStack not consistent");
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
;
548 /*** fprintf(stderr,"\nRestoring halt on junction #%d\n",r->end->seq); ***/
550 if ( a
==NULL
) return NULL
;
552 /* attempt to compute the "local" FOLLOW just like in normal lookahead
553 * computation if needed
556 complete_context_sets(p
,a
);
557 complete_context_trees(p
,a
);
559 /* MR10 */ MR_cleanup_pred_trees(a
);
571 Predicate
*MR_find_predicates_and_supp(Node
*alt
)
573 Predicate
*MR_find_predicates_and_supp(alt
)
579 p
=find_predicates(alt
);
580 p
=MR_suppressK(alt
,p
);
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
;
603 complete_context_sets( RuleRefNode
*p
, Predicate
*a
)
605 complete_context_sets( p
, a
)
614 fprintf(stderr
, "enter complete_context_sets\n");
616 for (; a
!=NULL
; a
=a
->right
)
618 if ( a
->expr
== PRED_AND_LIST
|| a
->expr
== PRED_OR_LIST
)
620 complete_context_sets(p
,a
->down
);
624 while ( !set_nil(a
->completionSet
) )
626 k2
= set_int(a
->completionSet
);
627 set_rm(k2
, a
->completionSet
);
629 REACH(p
->next
, k2
, &rk2
, b
);
630 set_orin(&(a
->scontext
[1]), b
);
634 set_orin(&(a
->completionSet
), rk2
);/* remember what we couldn't do */
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");
641 /* complete_context_sets(p, a->down);*/
644 fprintf(stderr
, "exit complete_context_sets\n");
650 complete_context_trees( RuleRefNode
*p
, Predicate
*a
)
652 complete_context_trees( p
, a
)
662 fprintf(stderr
, "enter complete_context_trees\n");
664 for (; a
!=NULL
; a
=a
->right
)
666 if ( a
->expr
== PRED_AND_LIST
|| a
->expr
== PRED_OR_LIST
)
668 complete_context_trees(p
, a
->down
);
673 /* any k left to do? if so, link onto tree */
674 while ( !set_nil(a
->completionTree
) )
676 k2
= set_int(a
->completionTree
);
677 set_rm(k2
, a
->completionTree
);
680 TRAV(p
->next
, k2
, &rk2
, u
);
682 /* any subtrees missing k2 tokens, add u onto end */
683 a
->tcontext
= tlink(a
->tcontext
, u
, k2
);
686 set_orin(&(a
->completionTree
), rk2
);/* remember what we couldn't do */
689 fprintf(stderr
, "LL(i<%d) context after ruleref:", LL_k
);
690 preorder(a
->tcontext
);
691 fprintf(stderr
, "\n");
693 /* complete_context_trees(p, a->down);*/
696 fprintf(stderr
, "exit complete_context_trees\n");
700 /* Walk a list of predicates and return the set of all tokens in scontext[1]'s */
703 covered_set( Predicate
*p
)
712 for (; p
!=NULL
; p
=p
->right
)
714 if ( p
->expr
== PRED_AND_LIST
|| p
->expr
== PRED_OR_LIST
)
716 set_orin(&a
, covered_set(p
->down
));
719 set_orin(&a
, p
->scontext
[1]);
720 set_orin(&a
, covered_set(p
->down
));
725 /* MR10 predicate_free()
726 MR10 Don't free the leaf nodes since they are part of the action node
730 void predicate_free(Predicate
*p
)
732 void predicate_free(p
)
736 if (p
== NULL
) return;
737 predicate_free(p
->right
);
738 predicate_free(p
->down
);
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
);
752 p
->down
=NULL
; /* MR13 *** debug */
756 /* MR10 predicate_dup() */
759 Predicate
* predicate_dup_xxx(Predicate
*p
,int contextToo
)
761 Predicate
* predicate_dup_xxx(p
,contextToo
)
768 if (p
== NULL
) return NULL
;
770 q
->down
=predicate_dup(p
->down
);
771 q
->right
=predicate_dup(p
->right
);
774 don't replicate expr - it is read-only
775 and address comparison is used to look
776 for identical predicates.
783 q
->ampersandStyle
=p
->ampersandStyle
;
784 q
->inverted
=p
->inverted
;
785 q
->predEntry
=p
->predEntry
;
786 q
->plainSet
=set_dup(p
->plainSet
);
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
);
796 /* don't need to dup "redundant" */
803 Predicate
* predicate_dup_without_context(Predicate
*p
)
805 Predicate
* predicate_dup_without_context(p
)
809 return predicate_dup_xxx(p
,0);
813 Predicate
* predicate_dup(Predicate
*p
)
815 Predicate
* predicate_dup(p
)
819 return predicate_dup_xxx(p
,1);