fset.c

来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 1,556 行 · 第 1/4 页

C
1,556
字号
            alt2->altnum,
            alt2->line,
            "     are identical when compared without context and may have no\n",
            "     resolving power for some lookahead sequences.\n");
        };
        if (InfoP) {
          fprintf(output,"\n#if 0\n\n");
          fprintf(output,"The following predicates are identical when compared without\n");
          fprintf(output,"  lookahead context information.  For some ambiguous lookahead\n");
          fprintf(output,"  sequences they may not have any power to resolve the ambiguity.\n");
          fprintf(output,"\n");

          fprintf(output,"Choice 1: %s  alt %d  line %d  file %s\n\n",
                  MR_ruleNamePlusOffset( (Node *) alt1),
                  alt1->altnum,
                  alt1->line,
                  FileStr[alt1->file]);
          fprintf(output,"  The original predicate for choice 1 with available context information:\n\n");
          MR_dumpPred1(2,alt1->predicate,1);
          fprintf(output,"  The predicate for choice 1 after expansion (but without context information):\n\n");
          MR_dumpPred1(2,p1,0);
          if (p1 == NULL) {
            Predicate   *phelp;
            fprintf(output,"  The predicate for choice 1 after expansion (but before simplification)\n\n");
            phelp=predicate_dup_without_context(alt1->predicate);
            phelp=MR_unfold(phelp);
            MR_clearPredEntry(phelp);
            MR_simplifyInverted(phelp,0);
            phelp=MR_predSimplifyALLX(phelp,1);
            MR_dumpPred1(2,phelp,0);
            predicate_free(phelp);
          };
          fprintf(output,"\n");

          fprintf(output,"Choice 2: %s  alt %d  line %d  file %s\n\n",
                  MR_ruleNamePlusOffset( (Node *) alt2),
                  alt2->altnum,
                  alt2->line,
                  FileStr[alt2->file]);
          fprintf(output,"  The original predicate for choice 2 with available context information:\n\n");
          MR_dumpPred1(1,alt2->predicate,1);
          fprintf(output,"  The predicate for choice 2 after expansion (but without context information):\n\n");
          MR_dumpPred1(1,p2,0);
          if (p2 == NULL) {
            Predicate   *phelp;
            fprintf(output,"  The predicate for choice 2 after expansion (but before simplification)\n\n");
            phelp=predicate_dup_without_context(alt2->predicate);
            phelp=MR_unfold(phelp);
            MR_clearPredEntry(phelp);
            MR_simplifyInverted(phelp,0);
            phelp=MR_predSimplifyALLX(phelp,1);
            MR_dumpPred1(2,phelp,0);
            predicate_free(phelp);
          };
          fprintf(output,"\n#endif\n");
        };
      } else if (MR_secondPredicateUnreachable(p1,p2)) {
        if (jtype == aLoopBegin || jtype == aPlusBlk ) {
          fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);
          fprintf(stderr," warning: %s of %s in rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s%s",
            "the predicate used to disambiguate the first choice of the optional/exit paths of ",
            sub,
            CurRule,
            FileStr[alt1->file],
            alt1->altnum,
            alt1->line,
            alt2->altnum,
            alt2->line,
            "     appears to \"cover\" the second predicate when compared without context.\n",
            "     The second predicate may have no resolving power for some lookahead sequences.\n");
        } else {
          fprintf(stderr, ErrHdr, FileStr[parentRule->file], parentRule->line);
          fprintf(stderr," warning: %s rule %s\n     (file %s alt %d line %d and alt %d line %d)\n%s%s",
            "the predicate used to disambiguate the first choice of",
            CurRule,
            FileStr[alt1->file],
            alt1->altnum,
            alt1->line,
            alt2->altnum,
            alt2->line,
            "     appears to \"cover\" the second predicate when compared without context.\n",
            "     The second predicate may have no resolving power for some lookahead sequences.\n");
        };
        if (InfoP) {
          fprintf(output,"\n#if 0\n\n");
          fprintf(output,"The first predicate appears to \"cover\" the second predicate when they\n");
          fprintf(output,"  are compared without lookahead context information.  For some ambiguous\n");
          fprintf(output,"  lookahead sequences the second predicate may not have any power to\n");
          fprintf(output,"  resolve the ambiguity.\n");
          fprintf(output,"\n");
          fprintf(output,"Choice 1: %s  alt %d  line %d  file %s\n\n",
                  MR_ruleNamePlusOffset( (Node *) alt1),
                  alt1->altnum,
                  alt1->line,
                  FileStr[alt1->file]);
          fprintf(output,"  The original predicate for choice 1 with available context information:\n\n");
          MR_dumpPred1(2,alt1->predicate,1);
          fprintf(output,"  The predicate for choice 1 after expansion (but without context information):\n\n");
          MR_dumpPred1(2,p1,0);
          if (p1 == NULL) {
            Predicate   *phelp;
            fprintf(output,"  The predicate for choice 1 after expansion (but before simplification)\n\n");
            phelp=predicate_dup_without_context(alt1->predicate);
            phelp=MR_unfold(phelp);
            MR_clearPredEntry(phelp);
            MR_simplifyInverted(phelp,0);
            phelp=MR_predSimplifyALLX(phelp,1);
            MR_dumpPred1(2,phelp,0);
            predicate_free(phelp);
          };
          fprintf(output,"\n");

          fprintf(output,"Choice 2: %s  alt %d  line %d  file %s\n\n",
                  MR_ruleNamePlusOffset( (Node *) alt2),
                  alt2->altnum,
                  alt2->line,
                  FileStr[alt2->file]);
          fprintf(output,"  The original predicate for choice 2 with available context information:\n\n");
          MR_dumpPred1(1,alt2->predicate,1);
          fprintf(output,"  The predicate for choice 2 after expansion (but without context information):\n\n");
          MR_dumpPred1(1,p2,0);
          if (p2 == NULL) {
            Predicate   *phelp;
            fprintf(output,"  The predicate for choice 2 after expansion (but before simplification)\n\n");
            phelp=predicate_dup_without_context(alt2->predicate);
            phelp=MR_unfold(phelp);
            MR_clearPredEntry(phelp);
            MR_simplifyInverted(phelp,0);
            phelp=MR_predSimplifyALLX(phelp,1);
            MR_dumpPred1(2,phelp,0);
            predicate_free(phelp);
          };
          fprintf(output,"\n#endif\n");
        };
      };
      predicate_free(p1);
      predicate_free(p2);
    };
}

static  int     totalOverflow=0;                /* MR9 */

void
#ifdef __USE_PROTOS
HandleAmbiguity( Junction *block, Junction *alt1, Junction *alt2, int jtype )
#else
HandleAmbiguity( block, alt1, alt2, jtype )
Junction *block;
Junction *alt1;
Junction *alt2;
int jtype;
#endif
{
	unsigned **ftbl;
	set *fset, b;
	int i, numAmbig,n2;
	Tree *ambig=NULL, *t, *u;
	char *sub = "";
    long    n;
    int     thisOverflow=0;             /* MR9 */
    long    set_deg_value;              /* MR10 */
    long    threshhold;                 /* MR10 */

	require(block!=NULL, "NULL block");
	require(block->ntype==nJunction, "invalid block");

	/* These sets are used to constrain LL_k set, but are made CLL_k long anyway */
	fset = (set *) calloc(CLL_k+1, sizeof(set));
	require(fset!=NULL, "cannot allocate fset");
	ftbl = (unsigned **) calloc(CLL_k+1, sizeof(unsigned *));
	require(ftbl!=NULL, "cannot allocate ftbl");

	/* create constraint table and count number of possible ambiguities (use<=LL_k) */
	for (n=1,i=1; i<=CLL_k; i++)
	{
         		b = set_and(alt1->fset[i], alt2->fset[i]);
/* MR9 */       set_deg_value = set_deg(b);
/* MR10 */      if (n > 0) {
/* MR10 */        threshhold = LONG_MAX / n;
/* MR10 */        if (set_deg_value <= threshhold) {
/* MR10 */       	n *= set_deg_value;
/* MR10 */        } else {
/* MR10 */          n=LONG_MAX;
/* MR9 */           if (totalOverflow == 0) {
#if 0
                      /* MR10 comment this out because it just makes users worry */

/* MR9 */             warnNoFL("Overflow in computing number of possible ambiguities in HandleAmbiguity\n");
#endif
/* MR9 */           };
/* MR9 */           thisOverflow++;
/* MR9 */           totalOverflow++;
/* MR9 */         };
/* MR10 */      } else {
/* MR10 */        n *= set_deg_value;
/* MR9 */       };
		fset[i] = set_dup(b);
		ftbl[i] = set_pdq(b);
		set_free(b);
	}

	switch ( jtype )
	{
		case aSubBlk: sub = "of (..) "; break;
		case aOptBlk: sub = "of {..} "; break;
		case aLoopBegin: sub = "of (..)* "; break;
		case aLoopBlk: sub = "of (..)* "; break;
		case aPlusBlk: sub = "of (..)+ "; break;
		case RuleBlk: sub = "of the rule itself "; break;
		default : sub = ""; break;
	}

	/* If the block is marked as a compressed lookahead only block, then
	 * simply return; ambiguity warning is given only at warning level 2.
	 */
	if ( block->approx>0 )
	{
		if ( ParseWithPredicates )
		{
            if (alt1->predicate != NULL) predicate_free(alt1->predicate);  /* MR12 */
            if (alt2->predicate != NULL) predicate_free(alt2->predicate);  /* MR12 */

            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
          	alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);
            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
            require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");
            alt1->predicate=MR_predSimplifyALL(alt1->predicate);

            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
    		alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);
            require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
            require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");
            alt2->predicate=MR_predSimplifyALL(alt2->predicate);

            MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);

			if ( HoistPredicateContext
                    && (alt1->predicate!=NULL||alt2->predicate!=NULL) )
			{
				verify_context(alt1->predicate);
				verify_context(alt2->predicate);
			}

			if ( HoistPredicateContext
                     && (alt1->predicate!=NULL||alt2->predicate!=NULL)
                     && WarningLevel>1 )
			ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);
		}

		if ( WarningLevel>1 )
		{
			fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
			if ( jtype == aLoopBegin || jtype == aPlusBlk )
				fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
			else
				fprintf(stderr, " warning(approx): alts %d and %d %sambiguous upon",
						alt1->altnum, alt2->altnum, sub);
			dumpAmbigMsg(fset, stderr, 0);
            MR_traceAmbSource(fset,alt1,alt2);
		}
		for (i=1; i<=CLL_k; i++) set_free( fset[i] );
		free((char *)fset);
		for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
		free((char *)ftbl);
		return;
    }

	/* if all sets have degree 1 for k<LL_k, then must be ambig upon >=1 permutation;
	 * don't bother doing full LL(k) analysis.
	 * (This "if" block handles the LL(1) case)
	 */

	n2 = 0;
	for (i=1; i<LL_k; i++) n2 += set_deg(alt1->fset[i])+set_deg(alt2->fset[i]);

    /* here STARTS the special case in which the lookahead sets for alt1 and alt2
       all have degree 1 for k<LL_k (including LL_k=1)
    */

	if ( n2==2*(LL_k-1) )
	{

        /* TJP: added to fix the case where LL(1) and syntactic predicates didn't
         * work.  It now recognizes syntactic predicates, but does not like combo:
         * LL(1)/syn/sem predicates. (10/24/93)
         */

		if ( first_item_is_guess_block_extra((Junction *)alt1->p1)!=NULL )
		{
			if ( WarningLevel==1 )
			{
				for (i=1; i<=CLL_k; i++) set_free( fset[i] );
				free((char *)fset);
				for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
				free((char *)ftbl);
				return;
			}

			fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
			if ( jtype == aLoopBegin || jtype == aPlusBlk )
			   fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
			else
			   fprintf(stderr, " warning: alts %d and %d %sambiguous upon",
					   alt1->altnum, alt2->altnum, sub);
			dumpAmbigMsg(fset, stderr, 0);
            MR_traceAmbSource(fset,alt1,alt2);
		}

		ambig = NULL;
		if ( LL_k>1 ) ambig = make_tree_from_sets(alt1->fset, alt2->fset);
		if ( ParseWithPredicates )
		{
           if (alt1->predicate != NULL) predicate_free(alt1->predicate);  /* MR12 */
           if (alt2->predicate != NULL) predicate_free(alt2->predicate);  /* MR12 */

           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
           alt1->predicate = MR_find_predicates_and_supp((Node *)alt1->p1);
           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
           require (MR_predicate_context_completed(alt1->predicate),"predicate alt 1 not completed");
           alt1->predicate=MR_predSimplifyALL(alt1->predicate);

           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
    	   alt2->predicate = MR_find_predicates_and_supp((Node *)alt2->p1);
           require(MR_PredRuleRefStack.count == 0,"PredRuleRef stack not empty");
           require (MR_predicate_context_completed(alt2->predicate),"predicate alt 2 not completed");
           alt2->predicate=MR_predSimplifyALL(alt2->predicate);

           MR_doPredicatesHelp(0,alt1,alt2,jtype,sub);

		   if ( HoistPredicateContext && (alt1->predicate!=NULL||alt2->predicate!=NULL) )
		   {
				verify_context(alt1->predicate);
				verify_context(alt2->predicate);
		   }
		   if (HoistPredicateContext&&(alt1->predicate!=NULL||alt2->predicate!=NULL) && WarningLevel>1)
			  ensure_predicates_cover_ambiguous_lookahead_sequences(alt1, alt2, sub, ambig);
		   if ( WarningLevel == 1 &&
			   (alt1->predicate!=NULL||alt2->predicate!=NULL))
		   {
			  for (i=1; i<=CLL_k; i++) set_free( fset[i] );
			  free((char *)fset);
			  for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
			  free((char *)ftbl);
			  Tfree(ambig);
			  return;
		   }
		}
/* end TJP (10/24/93) */

		fprintf(stderr, ErrHdr, FileStr[alt1->file], alt1->line);
		if ( jtype == aLoopBegin || jtype == aPlusBlk )
			fprintf(stderr, " warning: optional/exit path and alt(s) %sambiguous upon", sub);
		else
		   fprintf(stderr, " warning: alts %d and %d %sambiguous upon",
				   alt1->altnum, alt2->altnum, sub);
		if ( elevel == 3 && LL_k>1 )
		{
		   preorder(ambig);
		   fprintf(stderr, "\n");
  	       for (i=1; i<=CLL_k; i++) set_free( fset[i] );
    	   free((char *)fset);
		   for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
		   free((char *)ftbl);
		   Tfree(ambig);
		   return;
        };

		Tfree(ambig);
		dumpAmbigMsg(fset, stderr, 0);

        /* because this is a special case in which both alt1 and alt2 have
           lookahead sets of degree 1 for k<LL_k (including k=1) the linear
           lookahead style search is adequate
        */

        MR_traceAmbSource(fset,alt1,alt2);

		for (i=1; i<=CLL_k; i++) set_free( fset[i] );
		free((char *)fset);
		for (i=1; i<=CLL_k; i++) free( (char *)ftbl[i] );
		free((char *)ftbl);
		return;
	}

    /* here ENDS the special case in which the lookahead sets for alt1 and alt2
       all have degree 1 for k<LL_k (including LL_k=1)
    */

	/* in case tree construction runs out of memory, set info to make good err msg */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?