build.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 814 行 · 第 1/2 页
C
814 行
/*
* build.c -- functions associated with building syntax diagrams.
*
* 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 <stdlib.h>
#include <ctype.h>
#include "pcctscfg.h"
#include "set.h"
#include "syn.h"
#include "hash.h"
#include "generic.h"
#include "dlgdef.h"
#define SetBlk(g, t, approx, first_set_symbol) { \
((Junction *)g.left)->jtype = t; \
((Junction *)g.left)->approx = approx; \
((Junction *)g.left)->pFirstSetSymbol = first_set_symbol; \
((Junction *)g.left)->end = (Junction *) g.right; \
((Junction *)g.right)->jtype = EndBlk;}
/* Add the parameter string 'parm' to the parms field of a block-type junction
* g.left points to the sentinel node on a block. i.e. g.left->p1 points to
* the actual junction with its jtype == some block-type.
*/
void
#ifdef __USE_PROTOS
addParm( Node *p, char *parm )
#else
addParm( p, parm )
Node *p;
char *parm;
#endif
{
char *q = (char *) malloc( strlen(parm) + 1 );
require(p!=NULL, "addParm: NULL object\n");
require(q!=NULL, "addParm: unable to alloc parameter\n");
strcpy(q, parm);
if ( p->ntype == nRuleRef )
{
((RuleRefNode *)p)->parms = q;
}
else if ( p->ntype == nJunction )
{
((Junction *)p)->parm = q; /* only one parameter allowed on subrules */
}
else fatal_internal("addParm: invalid node for adding parm");
}
/*
* Build an action node for the syntax diagram
*
* buildAction(ACTION) ::= --o-->ACTION-->o--
*
* Where o is a junction node.
*/
Graph
#ifdef __USE_PROTOS
buildAction( char *action, int file, int line, int is_predicate )
#else
buildAction( action, file, line, is_predicate )
char *action;
int file;
int line;
int is_predicate;
#endif
{
Junction *j1, *j2;
Graph g;
ActionNode *a;
require(action!=NULL, "buildAction: invalid action");
j1 = newJunction();
j2 = newJunction();
a = newActionNode();
a->action = (char *) malloc( strlen(action)+1 );
require(a->action!=NULL, "buildAction: cannot alloc space for action\n");
strcpy(a->action, action);
j1->p1 = (Node *) a;
a->next = (Node *) j2;
a->is_predicate = is_predicate;
if (is_predicate) {
PredEntry *predEntry;
char *t;
char *key;
char *u;
int inverted=0;
t=key=(char *)calloc(1,strlen(a->action)+1);
for (u=a->action; *u != '\0' ; u++) {
if (*u != ' ') {
if (t==key && *u=='!') {
inverted=!inverted;
} else {
*t++=*u;
};
};
};
*t='\0';
predEntry=(PredEntry *)hash_get(Pname,key);
a->predEntry=predEntry;
if (predEntry != NULL) a->inverted=inverted;
} else {
/* MR12c */ char *strStart=a->action;
/* MR12c */ char *strEnd;
/* MR12c */ strEnd=strStart+strlen(strStart)-1;
/* MR12c */ for ( ; strEnd >= strStart && isspace(*strEnd); strEnd--) *strEnd=0;
/* MR12c */ while (*strStart != '\0' && isspace(*strStart)) strStart++;
/* MR12c */ if (ci_strequ(strStart,"nohoist")) {
/* MR12c */ a->noHoist=1;
/* MR12c */ }
}
g.left = (Node *) j1; g.right = (Node *) j2;
a->file = file;
a->line = line;
a->rname = CurRule; /* MR10 */
return g;
}
/*
* Build a token node for the syntax diagram
*
* buildToken(TOKEN) ::= --o-->TOKEN-->o--
*
* Where o is a junction node.
*/
Graph
#ifdef __USE_PROTOS
buildToken( char *text )
#else
buildToken( text )
char *text;
#endif
{
Junction *j1, *j2;
Graph g;
TokNode *t;
require(text!=NULL, "buildToken: invalid token name");
j1 = newJunction();
j2 = newJunction();
t = newTokNode();
t->altstart = CurAltStart;
if ( *text == '"' ) {t->label=FALSE; t->token = addTexpr( text );}
else {t->label=TRUE; t->token = addTname( text );}
j1->p1 = (Node *) t;
t->next = (Node *) j2;
g.left = (Node *) j1; g.right = (Node *) j2;
return g;
}
/*
* Build a wild-card node for the syntax diagram
*
* buildToken(TOKEN) ::= --o-->'.'-->o--
*
* Where o is a junction node.
*/
Graph
#ifdef __USE_PROTOS
buildWildCard( char *text )
#else
buildWildCard( text )
char *text;
#endif
{
Junction *j1, *j2;
Graph g;
TokNode *t;
TCnode *w;
TermEntry *p;
require(text!=NULL, "buildWildCard: invalid token name");
j1 = newJunction();
j2 = newJunction();
t = newTokNode();
/* If the ref a wild card, make a token class for it */
if ( Tnum(WildCardString) == 0 )
{
w = newTCnode;
w->tok = addTname( WildCardString );
set_orel(w->tok, &imag_tokens);
set_orel(w->tok, &tokclasses);
WildCardToken = w->tok;
require((p=(TermEntry *)hash_get(Tname, WildCardString)) != NULL,
"hash table mechanism is broken");
p->classname = 1; /* entry is class name, not token */
p->tclass = w; /* save ptr to this tclass def */
list_add(&tclasses, (char *)w);
}
else {
p=(TermEntry *)hash_get(Tname, WildCardString);
require( p!= NULL, "hash table mechanism is broken");
w = p->tclass;
}
t->token = w->tok;
t->wild_card = 1;
t->tclass = w;
t->altstart = CurAltStart;
j1->p1 = (Node *) t;
t->next = (Node *) j2;
g.left = (Node *) j1; g.right = (Node *) j2;
return g;
}
void
#ifdef __USE_PROTOS
setUpperRange(TokNode *t, char *text)
#else
setUpperRange(t, text)
TokNode *t;
char *text;
#endif
{
require(t!=NULL, "setUpperRange: NULL token node");
require(text!=NULL, "setUpperRange: NULL token string");
if ( *text == '"' ) {t->upper_range = addTexpr( text );}
else {t->upper_range = addTname( text );}
}
/*
* Build a rule reference node of the syntax diagram
*
* buildRuleRef(RULE) ::= --o-->RULE-->o--
*
* Where o is a junction node.
*
* If rule 'text' has been defined already, don't alloc new space to store string.
* Set r->text to point to old copy in string table.
*/
Graph
#ifdef __USE_PROTOS
buildRuleRef( char *text )
#else
buildRuleRef( text )
char *text;
#endif
{
Junction *j1, *j2;
Graph g;
RuleRefNode *r;
RuleEntry *p;
require(text!=NULL, "buildRuleRef: invalid rule name");
j1 = newJunction();
j2 = newJunction();
r = newRNode();
r->altstart = CurAltStart;
r->assign = NULL;
if ( (p=(RuleEntry *)hash_get(Rname, text)) != NULL ) r->text = p->str;
else r->text = mystrdup( text );
j1->p1 = (Node *) r;
r->next = (Node *) j2;
g.left = (Node *) j1; g.right = (Node *) j2;
return g;
}
/*
* Or two subgraphs into one graph via:
*
* Or(G1, G2) ::= --o-G1-o--
* | ^
* v |
* o-G2-o
*
* Set the altnum of junction starting G2 to 1 + altnum of junction starting G1.
* If, however, the G1 altnum is 0, make it 1 and then
* make G2 altnum = G1 altnum + 1.
*/
Graph
#ifdef __USE_PROTOS
Or( Graph g1, Graph g2 )
#else
Or( g1, g2 )
Graph g1;
Graph g2;
#endif
{
Graph g;
require(g1.left != NULL, "Or: invalid graph");
require(g2.left != NULL && g2.right != NULL, "Or: invalid graph");
((Junction *)g1.left)->p2 = g2.left;
((Junction *)g2.right)->p1 = g1.right;
/* set altnums */
if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
((Junction *)g2.left)->altnum = ((Junction *)g1.left)->altnum + 1;
g.left = g2.left;
g.right = g1.right;
return g;
}
/*
* Catenate two subgraphs
*
* Cat(G1, G2) ::= --o-G1-o-->o-G2-o--
* Cat(NULL,G2)::= --o-G2-o--
* Cat(G1,NULL)::= --o-G1-o--
*/
Graph
#ifdef __USE_PROTOS
Cat( Graph g1, Graph g2 )
#else
Cat( g1, g2 )
Graph g1;
Graph g2;
#endif
{
Graph g;
if ( g1.left == NULL && g1.right == NULL ) return g2;
if ( g2.left == NULL && g2.right == NULL ) return g1;
((Junction *)g1.right)->p1 = g2.left;
g.left = g1.left;
g.right = g2.right;
return g;
}
/*
* Make a subgraph an optional block
*
* makeOpt(G) ::= --o-->o-G-o-->o--
* | ^
* v |
* o-------o
*
* Note that this constructs {A|B|...|Z} as if (A|B|...|Z|) was found.
*
* The node on the far right is added so that every block owns its own
* EndBlk node.
*/
Graph
#ifdef __USE_PROTOS
makeOpt( Graph g1, int approx, char * pFirstSetSymbol )
#else
makeOpt( g1, approx, pFirstSetSymbol )
Graph g1;
int approx;
char * pFirstSetSymbol;
#endif
{
Junction *j1,*j2,*p;
Graph g;
require(g1.left != NULL && g1.right != NULL, "makeOpt: invalid graph");
j1 = newJunction();
j2 = newJunction();
((Junction *)g1.right)->p1 = (Node *) j2; /* add node to G at end */
/* MR21
*
* There is code in genBlk which recognizes the node created
* by emptyAlt() as a special case and bypasses it. We don't
* want this to happen for the optBlk.
*/
g = emptyAlt3(); /* MR21 */
if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
((Junction *)g.left)->altnum = ((Junction *)g1.left)->altnum + 1;
for(p=(Junction *)g1.left; p->p2!=NULL; p=(Junction *)p->p2)
{;} /* find last alt */
p->p2 = g.left; /* add optional alternative */
((Junction *)g.right)->p1 = (Node *)j2; /* opt alt points to EndBlk */
g1.right = (Node *)j2;
SetBlk(g1, aOptBlk, approx, pFirstSetSymbol);
j1->p1 = g1.left; /* add generic node in front */
g.left = (Node *) j1;
g.right = g1.right;
return g;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?