📄 pred.c
字号:
/* * pred.c -- source for predicate detection, manipulation * * SOFTWARE RIGHTS * * We reserve no LEGAL rights to the Purdue Compiler Construction Tool * Set (PCCTS) -- PCCTS is in the public domain. An individual or * company may do whatever they wish with source code distributed with * PCCTS or the code generated by PCCTS, including the incorporation of * PCCTS, or its output, into commerical software. * * We encourage users to develop software with PCCTS. However, we do ask * that credit is given to us for developing PCCTS. By "credit", * we mean that if you incorporate our source code into one of your * programs (commercial product, research project, or otherwise) that you * acknowledge this fact somewhere in the documentation, research report, * etc... If you like PCCTS and have developed a nice tool with the * output, please mention that you developed it using PCCTS. In * addition, we ask that this header remain intact in our source code. * As long as these guidelines are kept, we expect to continue enhancing * this system and expect to make other tools available as they are * completed. * * ANTLR 1.33 * Terence Parr * Parr Research Corporation * with Purdue University and AHPCRC, University of Minnesota * 1989-1998 */#include <stdio.h>#ifdef __cplusplus#ifndef __STDC__#define __STDC__#endif#endif#include "set.h"#include "syn.h"#include "hash.h"#include "generic.h"#include "dlgdef.h"#include <ctype.h>#ifdef __STDC__static void complete_context_sets(RuleRefNode *, Predicate *);static void complete_context_trees(RuleRefNode *, Predicate *);#elsestatic void complete_context_sets();static void complete_context_trees();#endifchar *PRED_AND_LIST = "AND";char *PRED_OR_LIST = "OR";/* * In C mode, return the largest constant integer found as the * sole argument to LATEXT(i). * * In C++ mode, return the largest constant integer found as the * sole argument to LT(i) given that the char before is nonalpha. */int#ifdef __STDC__predicateLookaheadDepth(ActionNode *a)#elsepredicateLookaheadDepth(a)ActionNode *a;#endif{ int max_k=0; if (a->predEntry != NULL) { MR_pred_depth(a->predEntry->pred,&max_k); goto PREDENTRY_EXIT; } if ( GenCC ) { /* scan for LT(i) */ int k = 0; char *p = a->action; while ( p!=NULL ) { p = strstr(p, "LT("); if ( p!=NULL ) { if ( p>=a->action && !isalpha(*(p-1)) ) { k = atoi(p+strlen("LT(")); if ( k>max_k ) max_k=k; } p += strlen("LT("); } } } else { /* scan for LATEXT(i) */ int k = 0; char *p = a->action; while ( p!=NULL ) { p = strstr(p, "LATEXT("); if ( p!=NULL ) { p += strlen("LATEXT("); k = atoi(p); if ( k>max_k ) max_k=k; } } } if ( max_k==0 ) { if ( !a->frmwarned ) { a->frmwarned = 1; warnFL(eMsg1("predicate: %s missing, bad, or with i=0; assuming i=1", GenCC?"LT(i)":"LATEXT(i)"), FileStr[a->file], a->line); } max_k = 1; }/* MR10 */ if ( max_k > CLL_k) {/* MR10 */ if ( !a->frmwarned )/* MR10 */ {/* MR10 */ a->frmwarned = 1;/* MR11 */ errFL(eMsgd2("predicate refers to lookahead token %d. Semantic lookahead is limited to max(k,ck)==%d",/* MR10 */ max_k,CLL_k),/* MR10 */ FileStr[a->file],a->line);/* MR10 */ if (max_k >= OutputLL_k) {/* MR10 */ if (!GenCC) {/* MR10 */ errFL(eMsgd(" the lookahead buffer size in C mode is %d token(s) (including the one just recognized)",/* MR10 */ OutputLL_k),/* MR10 */ FileStr[a->file],a->line);/* MR10 */ };/* MR10 */ };/* MR10 */ };/* MR10 */ max_k= CLL_k;/* MR10 */ };PREDENTRY_EXIT: return max_k;}/* Find all predicates in a block of alternatives. DO NOT find predicates * behind the block because that predicate could depend on things set in * one of the nonoptional blocks */Predicate *#ifdef __STDC__find_in_aSubBlk( Junction *alt )#elsefind_in_aSubBlk( alt )Junction *alt;#endif{ Predicate *a, *head=NULL, *tail=NULL, *root=NULL; Junction *p = alt; if (MRhoisting) { return MR_find_in_aSubBlk(alt); }; for (; p!=NULL; p=(Junction *)p->p2) { /* ignore empty alts */ if ( p->p1->ntype != nJunction || ((Junction *)p->p1)->jtype != EndBlk ) { a = find_predicates(p->p1); /* get preds for this alt */ if ( a==NULL ) continue; /* make an OR list of predicates */ if ( head==NULL ) { root = new_pred(); root->expr = PRED_OR_LIST; head = tail = a; root->down = head; } else { tail->right = a; a->left = tail; a->up = tail->up; tail = a; } } } /* if just one pred, remove OR root */ if ( root!=NULL && root->down->right == NULL ) { Predicate *d = root->down; free( (char *) root); return d; } return root;}Predicate *#ifdef __STDC__find_in_aOptBlk( Junction *alt )#elsefind_in_aOptBlk( alt )Junction *alt;#endif{ return find_in_aSubBlk( alt );}Predicate *#ifdef __STDC__find_in_aLoopBegin( Junction *alt )#elsefind_in_aLoopBegin( alt )Junction *alt;#endif{ return find_in_aSubBlk( (Junction *) alt->p1 ); /* get preds in alts */}Predicate *#ifdef __STDC__find_in_aPlusBlk( Junction *alt )#elsefind_in_aPlusBlk( alt )Junction *alt;#endif{ require(alt!=NULL&&alt->p2!=NULL, "invalid aPlusBlk"); return find_in_aSubBlk( alt );}/* Look for a predicate; * * Do not pass anything but Junction nodes; no Actions, Tokens, RuleRefs. * This means that a "hoisting distance" of zero is the only distance * allowable. Init actions are ignored. * * WARNING: * Assumes no (..)? block after predicate for the moment. * Does not check to see if pred is in production that can generate * a sequence contained in the set of ambiguous tuples. * * Return the predicate found if any. */Predicate *#ifdef __STDC__find_predicates( Node *alt )#elsefind_predicates( alt )Node *alt;#endif{#ifdef DBG_PRED Junction *j; RuleRefNode *r; TokNode *t;#endif Predicate *pred; if ( alt==NULL ) return NULL;#ifdef DBG_PRED switch ( alt->ntype ) { case nJunction : j = (Junction *) alt; fprintf(stderr, "Junction(in %s)", j->rname); switch ( j->jtype ) { case aSubBlk : fprintf(stderr,"aSubBlk\n"); break; case aOptBlk : fprintf(stderr,"aOptBlk\n"); break; case aLoopBegin : fprintf(stderr,"aLoopBeginBlk\n"); break; case aLoopBlk : fprintf(stderr,"aLoopBlk\n"); break; case aPlusBlk : fprintf(stderr,"aPlusBlk\n"); break; case EndBlk : fprintf(stderr,"EndBlk\n"); break; case RuleBlk : fprintf(stderr,"RuleBlk\n"); break; case Generic : fprintf(stderr,"Generic\n"); break; case EndRule : fprintf(stderr,"EndRule\n"); break; } break; case nRuleRef : r = (RuleRefNode *) alt; fprintf(stderr, "RuleRef(in %s)\n", r->rname); break; case nToken : t = (TokNode *) alt; fprintf(stderr, "TokenNode(in %s)%s\n", t->rname, TokenString(t->token)); break; case nAction : fprintf(stderr, "Action\n"); break; }#endif switch ( alt->ntype ) { case nJunction : { Predicate *a, *b; Junction *p = (Junction *) alt; /* lock nodes */ if ( p->jtype==aLoopBlk || p->jtype==RuleBlk || p->jtype==aPlusBlk || p->jtype==EndRule ) { require(p->pred_lock!=NULL, "rJunc: lock array is NULL"); if ( p->pred_lock[1] ) { return NULL; } p->pred_lock[1] = TRUE; } switch ( p->jtype ) { case aSubBlk : a = find_in_aSubBlk(p); return a; /* nothing is visible past this guy */ case aOptBlk : a = find_in_aOptBlk(p); return a; case aLoopBegin : a = find_in_aLoopBegin(p); return a; case aLoopBlk : a = find_in_aSubBlk(p); p->pred_lock[1] = FALSE; return a; case aPlusBlk : a = find_in_aPlusBlk(p); p->pred_lock[1] = FALSE; return a; /* nothing is visible past this guy */ case RuleBlk : a = find_predicates(p->p1); p->pred_lock[1] = FALSE; return a; case Generic : a = find_predicates(p->p1); b = find_predicates(p->p2); if ( p->pred_lock!=NULL ) p->pred_lock[1] = FALSE; if ( a==NULL ) return b; if ( b==NULL ) return a; /* otherwise OR the two preds together */ { fatal_internal("hit unknown situation during predicate hoisting"); } case EndBlk : case EndRule : /* Find no predicates after a rule ref */ return NULL; default: fatal_internal("this cannot be printed\n"); break; } } case nAction : { ActionNode *p = (ActionNode *) alt; if ( p->noHoist) return NULL; /* MR12c */ if ( p->init_action ) return find_predicates(p->next); if ( p->is_predicate ) { Tree *t=NULL;#ifdef DBG_PRED fprintf(stderr, "predicate: <<%s>>?\n", p->action);#endif if ( p->guardpred!=NULL ) { pred = predicate_dup(p->guardpred); MR_guardPred_plainSet(p,pred); /* MR12c */ } else { pred = new_pred(); pred->k = predicateLookaheadDepth(p); pred->source = p; pred->expr = p->action; if ( HoistPredicateContext && pred->k > 1 ) { if ( first_item_is_guess_block((Junction *)p->next) ) { warnFL("cannot compute context of predicate in front of (..)? block", FileStr[p->file], p->line); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -