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 + -
显示快捷键?