pcctsast.cpp
来自「本工具提供一个词法分析器和语法分析器的集成开发环境」· C++ 代码 · 共 663 行 · 第 1/2 页
CPP
663 行
SList *list = new SList; PCCTS_AST *p; for (p=this; p!=NULL; p=p->right()) { list->add(p); } return list;}#endifvoid 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()"// MR9PCCTS_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 mem\n"); // 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]='\0'; scanner->input = input; scanner->p = input; stringscan_advance(scanner);}void PCCTS_AST::stringscan_advance(StringLexer *scanner){ if ( *(scanner->p) == '\0' ) 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 = '\0'; 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 '\0' : 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>";}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?