📄 build.c
字号:
/* * 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-1998 */#include <stdio.h>#include <ctype.h>#ifdef __cplusplus#ifndef __STDC__#define __STDC__#endif#endif#include "set.h"#include "syn.h"#include "hash.h"#include "generic.h"#include "dlgdef.h"#define SetBlk(g, t, approx) { \ ((Junction *)g.left)->jtype = t; \ ((Junction *)g.left)->approx = approx; \ ((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 __STDC__addParm( Node *p, char *parm )#elseaddParm( 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 __STDC__buildAction( char *action, int file, int line, int is_predicate )#elsebuildAction( 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 __STDC__buildToken( char *text )#elsebuildToken( 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 __STDC__buildWildCard( char *text )#elsebuildWildCard( 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 __STDC__setUpperRange(TokNode *t, char *text)#elsesetUpperRange(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 __STDC__buildRuleRef( char *text )#elsebuildRuleRef( 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 __STDC__Or( Graph g1, Graph g2 )#elseOr( 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 __STDC__Cat( Graph g1, Graph g2 )#elseCat( 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 __STDC__makeOpt( Graph g1, int approx )#elsemakeOpt( g1, approx )Graph g1;int approx;#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 */ g = emptyAlt(); if ( ((Junction *)g1.left)->altnum == 0 ) ((Junction *)g1.left)->altnum = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -