pred.c
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:19k
源码类别:

编译器/解释器

开发平台:

Others

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