pred.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 822 行 · 第 1/2 页
C
822 行
/*
* 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-2001
*/
#include <stdio.h>
#include "pcctscfg.h"
#include "set.h"
#include "syn.h"
#include "hash.h"
#include "generic.h"
#include "dlgdef.h"
#include <ctype.h>
#ifdef __USE_PROTOS
static void complete_context_sets(RuleRefNode *, Predicate *);
static void complete_context_trees(RuleRefNode *, Predicate *);
#else
static void complete_context_sets();
static void complete_context_trees();
#endif
char *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 __USE_PROTOS
predicateLookaheadDepth(ActionNode *a)
#else
predicateLookaheadDepth(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) {
max_k = 1; /* MR33 Badly designed if didn't set max_k when CLL_k = 1 */
if (CLL_k > 1) /* MR27 Don't warn if max(k,ck) == 1 */
{
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);
}
}
}
/* 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 __USE_PROTOS
find_in_aSubBlk( Junction *alt )
#else
find_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 __USE_PROTOS
find_in_aOptBlk( Junction *alt )
#else
find_in_aOptBlk( alt )
Junction *alt;
#endif
{
return find_in_aSubBlk( alt );
}
Predicate *
#ifdef __USE_PROTOS
find_in_aLoopBegin( Junction *alt )
#else
find_in_aLoopBegin( alt )
Junction *alt;
#endif
{
return find_in_aSubBlk( (Junction *) alt->p1 ); /* get preds in alts */
}
Predicate *
#ifdef __USE_PROTOS
find_in_aPlusBlk( Junction *alt )
#else
find_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 __USE_PROTOS
find_predicates( Node *alt )
#else
find_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 )
{
/* MR30 No need to use first_item_is_guess_block_extra
since we know this is an action, not a (...)* or
(...)+ block.
*/
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 + =
减小字号Ctrl + -
显示快捷键?