pcctsast.cpp
来自「SRI international 发布的OAA框架软件」· C++ 代码 · 共 685 行 · 第 1/2 页
CPP
685 行
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 )
panic("out of memory\n"); // MR23
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=NULL /*MR23*/;
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)
{
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];
char ebuf[100]; /* MR23 Remove static */
while ( isspace(scanner->c) ) { stringscan_advance(scanner); }
if ( isdigit(scanner->c) )
{
int tok = __INT;
while ( isdigit(scanner->c) ) {
*index++ = (char) /* static_cast<char> */ (scanner->c); // MR23
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
}
const char *PCCTS_AST:: /* MR20 const */
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>";
}
//MR23
int PCCTS_AST::printMessage(FILE* pFile, const char* pFormat, ...)
{
va_list marker;
va_start( marker, pFormat );
int iRet = vfprintf(pFile, pFormat, marker);
va_end( marker );
return iRet;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?