PCCTSAST.cpp
资源名称:pccts133.zip [点击查看]
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:16k
源码类别:
编译器/解释器
开发平台:
Others
- /*
- * PCCTSAST.C
- *
- * SOFTWARE RIGHTS
- *
- * We reserve no LEGAL rights to SORCERER -- SORCERER is in the public
- * domain. An individual or company may do whatever they wish with
- * source code distributed with SORCERER or the code generated by
- * SORCERER, including the incorporation of SORCERER, or its output, into
- * commerical software.
- *
- * We encourage users to develop software with SORCERER. However, we do
- * ask that credit is given to us for developing SORCERER. 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 SORCERER and have developed a nice tool with the
- * output, please mention that you developed it using SORCERER. 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.
- *
- * SORCERER 1.00B14 and ANTLR 1.33
- * Terence Parr
- * Parr Research Corporation
- * AHPCRC, University of Minnesota
- * 1992-1998
- */
- #define ANTLR_SUPPORT_CODE
- #include "pcctscfg.h"
- #include "PCCTSAST.h"
- #include PCCTS_STDARG_H
- PCCTS_NAMESPACE_STD
- #include <ctype.h>
- //#include "SList.h"
- /* String Scanning/Parsing Stuff */
- char *PCCTS_AST::scan_token_tbl[] = {
- "invalid", /* 0 */
- "LPAREN", /* 1 */
- "RPAREN", /* 2 */
- "PERCENT", /* 3 */
- "INT", /* 4 */
- "COLON", /* 5 */
- "POUND", /* 6 */
- "PERIOD", /* 7 */
- };
- void PCCTS_AST::
- addChild(PCCTS_AST *t)
- {
- if ( t==NULL ) return;
- PCCTS_AST *s = down();
- if ( s!=NULL )
- {
- while ( s->right()!=NULL ) s = s->right();
- s->setRight(t);
- }
- else
- this->setDown(t);
- }
- void PCCTS_AST::
- lisp(FILE *f)
- {
- if ( down() != NULL ) fprintf(f," (");
- lisp_action(f);
- if ( down()!=NULL ) down()->lisp(f);
- if ( down() != NULL ) fprintf(f," )");
- if ( right()!=NULL ) right()->lisp(f);
- }
- /* build a tree (root child1 child2 ... NULL)
- * If root is NULL, simply make the children siblings and return ptr
- * to 1st sibling (child1). If root is not single node, return NULL.
- *
- * Siblings that are actually sibling lists themselves are handled
- * correctly. For example #( NULL, #( NULL, A, B, C), D) results
- * in the tree ( NULL A B C D ).
- *
- * Requires at least two parameters with the last one being NULL. If
- * both are NULL, return NULL.
- *
- * The down() and right() down/right pointers are used to make the tree.
- */
- PCCTS_AST *PCCTS_AST::
- make(PCCTS_AST *rt, ...)
- {
- va_list ap;
- register PCCTS_AST *child, *sibling=NULL, *tail, *w;
- PCCTS_AST *root;
- va_start(ap, rt);
- root = rt;
- if ( root != NULL )
- if ( root->down() != NULL ) return NULL;
- child = va_arg(ap, PCCTS_AST *);
- while ( child != NULL )
- {
- /* find end of child */
- for (w=child; w->right()!=NULL; w=w->right()) {;}
- if ( sibling == NULL ) {sibling = child; tail = w;}
- else {tail->setRight(child); tail = w;}
- child = va_arg(ap, PCCTS_AST *);
- }
- if ( root==NULL ) root = sibling;
- else root->setDown(sibling);
- va_end(ap);
- return root;
- }
- /* The following push and pop routines are only used by ast_find_all() */
- void PCCTS_AST::
- _push(PCCTS_AST **st, int *sp, PCCTS_AST *e)
- {
- (*sp)--;
- require((*sp)>=0, "stack overflow");
- st[(*sp)] = e;
- }
- PCCTS_AST *PCCTS_AST::
- _pop(PCCTS_AST **st, int *sp)
- {
- PCCTS_AST *e = st[*sp];
- (*sp)++;
- require((*sp)<=MaxTreeStackDepth, "stack underflow");
- return e;
- }
- /* Find all occurrences of u in t.
- * 'cursor' must be initialized to 't'. It eventually
- * returns NULL when no more occurrences of 'u' are found.
- */
- PCCTS_AST *PCCTS_AST::
- ast_find_all(PCCTS_AST *u, PCCTS_AST **cursor)
- {
- PCCTS_AST *sib;
- static PCCTS_AST *template_stack[MaxTreeStackDepth];
- static int tsp = MaxTreeStackDepth;
- static int nesting = 0;
- if ( *cursor == NULL ) return NULL;
- if ( *cursor!=this ) sib = *cursor;
- else {
- /* else, first time--start at top of template 't' */
- tsp = MaxTreeStackDepth;
- sib = this;
- /* bottom of stack is always a NULL--"cookie" indicates "done" */
- _push(template_stack, &tsp, NULL);
- }
- keep_looking:
- if ( sib==NULL ) /* hit end of sibling list */
- {
- sib = _pop(template_stack, &tsp);
- if ( sib == NULL ) { *cursor = NULL; return NULL; }
- }
- if ( sib->type() != u->type() )
- {
- /* look for another match */
- if ( sib->down()!=NULL )
- {
- if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
- sib=sib->down();
- goto keep_looking;
- }
- /* nothing below to try, try next sibling */
- sib=sib->right();
- goto keep_looking;
- }
- /* found a matching root node, try to match what's below */
- if ( match_partial(sib, u) )
- {
- /* record sibling cursor so we can pick up next from there */
- if ( sib->down()!=NULL )
- {
- if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
- *cursor = sib->down();
- }
- else if ( sib->right()!=NULL ) *cursor = sib->right();
- else *cursor = _pop(template_stack, &tsp);
- return sib;
- }
- /* no match, keep searching */
- if ( sib->down()!=NULL )
- {
- if ( sib->right()!=NULL ) _push(template_stack, &tsp, sib->right());
- sib=sib->down();
- }
- else sib = sib->right(); /* else, try to right if zip below */
- goto keep_looking;
- }
- /* are two trees exactly alike? */
- int PCCTS_AST::
- match(PCCTS_AST *u)
- {
- PCCTS_AST *t = this;
- PCCTS_AST *sib;
- if ( u==NULL ) return 0;
- for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
- {
- if ( sib->type() != u->type() ) return 0;
- if ( sib->down()!=NULL )
- if ( !sib->down()->match(u->down()) ) return 0;
- }
- return 1;
- }
- /* Is 'u' a subtree of 't' beginning at the root? */
- int PCCTS_AST::
- match_partial(PCCTS_AST *t, PCCTS_AST *u)
- {
- PCCTS_AST *sib;
- if ( u==NULL ) return 1;
- if ( t==NULL ) if ( u!=NULL ) return 0; else return 1;
- for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
- {
- if ( sib->type() != u->type() ) return 0;
- if ( sib->down()!=NULL )
- if ( !match_partial(sib->down(), u->down()) ) return 0;
- }
- return 1;
- }
- /* Walk the template tree 't' (matching against 'this'), filling in the
- * 'labels' array, and setting 'n' according to how many labels were matched.
- */
- int PCCTS_AST::
- scanmatch(ScanAST *t, PCCTS_AST **labels[], int *n)
- {
- ScanAST *sib;
- PCCTS_AST *u = this;
- if ( u==NULL ) return 0;
- for (sib=t; sib!=NULL&&u!=NULL; sib=sib->right(), u=u->right())
- {
- /* make sure tokens match; token of '0' means wildcard match */
- if ( sib->type() != u->type() && sib->type()!=0 ) return 0;
- /* we have a matched token here; set label pointers if exists */
- if ( sib->label_num>0 )
- {
- require(labels!=NULL, "label found in template, but no array of labels");
- (*n)++;
- *(labels[sib->label_num-1]) = u;
- }
- /* match what's below if something there and current node is not wildcard */
- if ( sib->down()!=NULL && sib->type()!=0 )
- {
- if ( sib->down()==NULL ) if ( u->down()!=NULL ) return 0; else return 1;
- if ( !u->down()->scanmatch(sib->down(), labels, n) ) return 0;
- }
- }
- return 1;
- }
- void PCCTS_AST::
- insert_after(PCCTS_AST *b)
- {
- PCCTS_AST *end;
- if ( b==NULL ) return;
- /* find end of b's child list */
- for (end=b; end->right()!=NULL; end=end->right()) {;}
- end->setRight(this->right());
- this->setRight(b);
- }
- void PCCTS_AST::
- append(PCCTS_AST *b)
- {
- PCCTS_AST *end;
- require(b!=NULL, "append: NULL input tree");
- /* find end of child list */
- for (end=this; end->right()!=NULL; end=end->right()) {;}
- end->setRight(b);
- }
- PCCTS_AST *PCCTS_AST::
- tail()
- {
- PCCTS_AST *end;
- /* find end of child list */
- for (end=this; end->right()!=NULL; end=end->right()) {;}
- return end;
- }
- PCCTS_AST *PCCTS_AST::
- bottom()
- {
- PCCTS_AST *end;
- /* find end of child list */
- for (end=this; end->down()!=NULL; end=end->down()) {;}
- return end;
- }
- PCCTS_AST *PCCTS_AST::
- cut_between(PCCTS_AST *a, PCCTS_AST *b)
- {
- PCCTS_AST *end, *ret;
- if (a==NULL||b==NULL) return NULL;
- /* find node pointing to b */
- for (end=a; end->right()!=NULL&&end->right()!=b; end=end->right())
- {;}
- if (end->right()==NULL) return NULL; //ast_cut_between: a,b not connected
- end->setRight(NULL); /* don't want it point to 'b' anymore */
- ret = a->right();
- a->setRight(b);
- return ret;
- }
- #ifdef NOT_YET
- SList *PCCTS_AST::
- to_slist()
- {
- SList *list = new SList;
- PCCTS_AST *p;
- for (p=this; p!=NULL; p=p->right())
- {
- list->add(p);
- }
- return list;
- }
- #endif
- void PCCTS_AST::
- tfree()
- {
- PCCTS_AST *t = this;
- if ( t->down()!=NULL ) t->down()->tfree();
- if ( t->right()!=NULL ) t->right()->tfree();
- delete t;
- }
- int PCCTS_AST::
- nsiblings()
- {
- PCCTS_AST *t = this;
- int n=0;
- while ( t!=NULL )
- {
- n++;
- t = t->right();
- }
- return n;
- }
- PCCTS_AST *PCCTS_AST::
- sibling_index(int i)
- {
- PCCTS_AST *t = this;
- int j=1;
- require(i>0, "sibling_index: i<=0");
- while ( t!=NULL )
- {
- if ( j==i ) return t;
- j++;
- t = t->right();
- }
- return NULL;
- }
- /* Assume this is a root node of a tree--
- * duplicate that node and what's below; ignore siblings of root node.
- */
- // MR9 23-Sep-97 RJV
- // MR9
- // MR9 RJV: Original version only duplicated the node and down elements.
- // MR9 Made copies of the pointers to sibling.
- // MR9 Changed call "down()->deepCopy()" to "down()->deepCopyBushy()"
- // MR9
- PCCTS_AST *PCCTS_AST::
- deepCopy()
- {
- PCCTS_AST *u = this->shallowCopy();
- if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());
- u->setRight(NULL);
- return u;
- }
- /* Copy all nodes including siblings of root. */
- PCCTS_AST *PCCTS_AST::
- deepCopyBushy()
- {
- PCCTS_AST *u = this->shallowCopy();
- /* copy the rest of the tree */
- if ( down()!=NULL ) u->setDown(down()->deepCopyBushy());
- if ( right()!=NULL ) u->setRight(right()->deepCopyBushy());
- return u;
- }
- void PCCTS_AST::
- scanast_free(ScanAST *t)
- {
- if ( t == NULL ) return;
- scanast_free( t->down() );
- scanast_free( t->right() );
- free( (char *) t ); // MR1
- }
- /*
- * scan
- *
- * This function is like scanf(): it attempts to match a template
- * against an input tree. A variable number of tree pointers
- * may be set according to the '%i' labels in the template string.
- * For example:
- *
- * t->ast_scan("#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )",
- * &w, &x, &y, &z);
- *
- * Naturally, you'd want this converted from
- *
- * t->ast_scan("#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4Var) )",
- * &w, &x, &y, &z);
- *
- * by SORCERER.
- *
- * This function call must be done withing a SORCERER file because SORCERER
- * must convert the token references to the associated token number.
- *
- * This functions parses the template and creates trees which are then
- * matched against the input tree. The labels are set as they are
- * encountered; hence, partial matches may leave some pointers set
- * and some NULL. This routines initializes all argument pointers to NULL
- * at the beginning.
- *
- * This function returns the number of labels matched.
- */
- int PCCTS_AST::
- ast_scan(char *templ, ...)
- {
- va_list ap;
- ScanAST *tmpl;
- int n, i, found=0;
- PCCTS_AST ***label_ptrs=NULL;
- va_start(ap, templ);
- /* make a ScanAST tree out of the template */
- tmpl = stringparser_parse_scanast(templ, &n);
- /* make an array out of the labels */
- if ( n>0 )
- {
- label_ptrs = (PCCTS_AST ***) calloc(n, sizeof(PCCTS_AST **));
- require(label_ptrs!=NULL, "scan: out of memory");
- for (i=1; i<=n; i++)
- {
- label_ptrs[i-1] = va_arg(ap, PCCTS_AST **);
- *(label_ptrs[i-1]) = NULL;
- }
- }
- /* match the input tree against the template */
- scanmatch(tmpl, label_ptrs, &found);
- scanast_free(tmpl);
- free( (char *) label_ptrs); // MR1
- return found;
- }
- ScanAST *PCCTS_AST::
- new_scanast(int tok)
- {
- ScanAST *p = (ScanAST *) calloc(1, sizeof(ScanAST));
- //
- // 7-Apr-97 133MR1
- //
- if ( p == NULL ) { // MR1
- fprintf(stderr, "out of memn"); // MR1
- exit(PCCTS_EXIT_FAILURE); // MR1
- }; // MR1
- p->_token = tok;
- return p;
- }
- ScanAST *PCCTS_AST::
- stringparser_parse_scanast(char *templ, int *num_labels)
- {
- StringLexer lex;
- StringParser parser;
- ScanAST *t;
- stringlexer_init(&lex, templ);
- stringparser_init(&parser, &lex);
- t = stringparser_parse_tree(&parser);
- *num_labels = parser.num_labels;
- return t;
- }
- void PCCTS_AST::
- stringparser_match(StringParser *parser, int token)
- {
- if ( parser->token != token ) panic("bad tree in scan()");
- }
- /*
- * Match a tree of the form:
- * (root child1 child2 ... childn)
- * or,
- * node
- *
- * where the elements are integers or labeled integers.
- */
- ScanAST *PCCTS_AST::
- stringparser_parse_tree(StringParser *parser)
- {
- ScanAST *t=NULL, *root, *child, *last;
- if ( parser->token != __POUND )
- {
- return stringparser_parse_element(parser);
- }
- stringparser_match(parser,__POUND);
- parser->token = stringscan_gettok(parser->lexer);
- stringparser_match(parser,__LPAREN);
- parser->token = stringscan_gettok(parser->lexer);
- root = stringparser_parse_element(parser);
- while ( parser->token != __RPAREN )
- {
- child = stringparser_parse_element(parser);
- if ( t==NULL ) { t = child; last = t; }
- else { last->_right = child; last = child; }
- }
- stringparser_match(parser,__RPAREN);
- parser->token = stringscan_gettok(parser->lexer);
- root->_down = t;
- return root;
- }
- ScanAST *PCCTS_AST::
- stringparser_parse_element(StringParser *parser)
- {
- static char ebuf[100];
- int label = 0;
- if ( parser->token == __POUND )
- {
- return stringparser_parse_tree(parser);
- }
- if ( parser->token == __PERCENT )
- {
- parser->token = stringscan_gettok(parser->lexer);
- stringparser_match(parser,__INT);
- label = atoi(parser->lexer->text);
- parser->num_labels++;
- if ( label==0 ) panic("%%0 is an invalid label");
- parser->token = stringscan_gettok(parser->lexer);
- stringparser_match(parser,__COLON);
- parser->token = stringscan_gettok(parser->lexer);
- /* can label tokens and wildcards */
- if ( parser->token != __INT && parser->token != __PERIOD )
- panic("can only label tokens");
- }
- if ( parser->token == __INT )
- {
- ScanAST *p = new_scanast(atoi(parser->lexer->text));
- parser->token = stringscan_gettok(parser->lexer);
- p->label_num = label;
- return p;
- }
- if ( parser->token == __PERIOD )
- {
- ScanAST *p = new_scanast(0); /* token of 0 is wildcard */
- parser->token = stringscan_gettok(parser->lexer);
- p->label_num = label;
- return p;
- }
- sprintf(ebuf, "mismatch token in scan(): %s", scan_token_str(parser->token));
- panic(ebuf);
- return NULL;
- }
- void PCCTS_AST::
- stringparser_init(StringParser *parser, StringLexer *input)
- {
- parser->lexer = input;
- parser->token = stringscan_gettok(parser->lexer);
- parser->num_labels = 0;
- }
- void PCCTS_AST::
- stringlexer_init(StringLexer *scanner, char *input)
- {
- scanner->text[0]=' ';
- scanner->input = input;
- scanner->p = input;
- stringscan_advance(scanner);
- }
- void PCCTS_AST::
- stringscan_advance(StringLexer *scanner)
- {
- if ( *(scanner->p) == ' ' ) scanner->c = __StringScanEOF;
- scanner->c = *(scanner->p)++;
- }
- int PCCTS_AST::
- stringscan_gettok(StringLexer *scanner)
- {
- char *index = &scanner->text[0];
- static char ebuf[100];
- while ( isspace(scanner->c) ) { stringscan_advance(scanner); }
- if ( isdigit(scanner->c) )
- {
- int tok = __INT;
- while ( isdigit(scanner->c) ) {
- *index++ = scanner->c;
- stringscan_advance(scanner);
- }
- *index = ' ';
- return tok;
- }
- switch ( scanner->c )
- {
- case '#' : stringscan_advance(scanner); return __POUND;
- case '(' : stringscan_advance(scanner); return __LPAREN;
- case ')' : stringscan_advance(scanner); return __RPAREN;
- case '%' : stringscan_advance(scanner); return __PERCENT;
- case ':' : stringscan_advance(scanner); return __COLON;
- case '.' : stringscan_advance(scanner); return __PERIOD;
- case ' ' : return __StringScanEOF;
- case __StringScanEOF : return __StringScanEOF;
- default :
- sprintf(ebuf, "invalid char in scan: '%c'", scanner->c);
- panic(ebuf);
- }
- return __StringScanEOF; // never reached
- }
- char *PCCTS_AST::
- scan_token_str(int t)
- {
- if ( VALID_SCAN_TOKEN(t) ) return scan_token_tbl[t];
- else if ( t==__StringScanEOF ) return "<end-of-string>";
- else return "<invalid-token>";
- }