ptree.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,173 行 · 第 1/5 页
C
2,173 行
/********************************************************************/
{
CPP_FLOAT *fp_rep;
fp_rep = makeFPRep( buff, len );
return PTreeFloatingConstant( fp_rep, id );
}
PTREE PTreeFloatingConstant( CPP_FLOAT *rep, type_id id )
/*******************************************************/
{
PTREE new_tree;
new_tree = allocConstant( PT_FLOATING_CONSTANT, id );
new_tree->u.floating_constant = rep;
new_tree = PTreeCheckFloatRepresentation( new_tree );
return new_tree;
}
PTREE PTreeId( char *id )
/***********************/
{
PTREE new_tree;
new_tree = PTreeAlloc();
new_tree->op = PT_ID;
new_tree->cgop = CO_NAME_NORMAL;
new_tree->u.id.name = id;
new_tree->u.id.scope = NULL;
return new_tree;
}
PTREE PTreeIc( // CREATE PT_IC NODE
unsigned opcode, // - IC opcode
CGVALUE value ) // - IC value
{
PTREE node; // - new node
node = PTreeAlloc();
node->op = PT_IC;
node->u.ic.opcode = opcode;
node->u.ic.value = value;
node->flags |= PTF_LV_CHECKED;
return node;
}
PTREE PTreeIdSym( SYMBOL sym )
/****************************/
{
return PTreeId( sym->name->name );
}
PTREE PTreeThis( void )
/*********************/
{
PTREE node; // - new node
node = PTreeId( CppSpecialName( SPECIAL_THIS ) );
node->cgop = CO_NAME_THIS;
return node;
}
PTREE PTreeCDtorExtra( void )
/***************************/
{
PTREE node; // - new node
node = PTreeId( CppSpecialName( SPECIAL_CDTOR_EXTRA ) );
node->cgop = CO_NAME_CDTOR_EXTRA;
return node;
}
boolean PTreePropogateError( // CHECK AND PROPOGATE ERRORS FROM SUB-TREES
PTREE curr ) // - current node
{
unsigned op; // - current expr op
PTREE left; // - left subtree
PTREE right; // - right subtree
DbgAssert( curr != NULL );
op = curr->op;
if( ptreePTSFlags[ op ] & PTS_OPERATOR ) {
left = curr->u.subtree[0];
if( left != NULL && left->op == PT_ERROR ) {
PTreeErrorNode( curr );
return TRUE;
}
}
if( ptreePTSFlags[ op ] & PTS_BINARY ) {
right = curr->u.subtree[1];
if( right != NULL && right->op == PT_ERROR ) {
PTreeErrorNode( curr );
return TRUE;
}
}
return FALSE;
}
PTREE PTreeTraversePostfix( // TRAVERSE A PTREE IN (LEFT,RIGHT,SELF) ORDER
PTREE tree, // - tree to be traversed
PTREE (*visit_rtn) // - visiting routine
( PTREE curr ) ) // - - addr( current node )
{
PTREE parent;
PTREE temp;
PTREE left;
PTREE right;
/*
The states represent locations in the traditional recursive version
of a postfix traversal function.
postfix( tree )
{
PTREE_LEFT
postfix( tree->left )
PTREE_RIGHT
postfix( tree->right )
PTREE_PROCESS
process( tree )
PTREE_UNWIND
}
note: this routine is heavily used so it has been optimized
to use gotos since the current codegen can't optimize an
assignment of a constant to a variable and an immediate
switch statement to a simple goto. The switch() style has
been preserved for less heavily used traversal routines.
*/
if( tree == NULL || tree->op == PT_ERROR ) {
return tree;
}
parent = NULL;
PTREE_LEFT:
if( tree->flags & PTF_DUP_VISITED ) {
goto PTREE_UNWIND;
} else if( ptreePTSFlags[ tree->op ] & PTS_OPERATOR ) {
left = tree->u.subtree[0];
if( left != NULL ) {
/* has a left subtree; store current parent */
temp = tree;
tree = left;
temp->u.subtree[0] = parent;
temp->flags |= PTF_TRAVERSE_LEFT;
parent = temp;
/* descend to left child node */
goto PTREE_LEFT;
}
/* descend to right child node */
goto PTREE_RIGHT;
} else {
/* no subtrees; process this node */
goto PTREE_PROCESS;
}
PTREE_RIGHT:
if( ptreePTSFlags[ tree->op ] & PTS_BINARY ) {
right = tree->u.subtree[1];
if( right != NULL ) {
/* has a right subtree; store current parent */
temp = tree;
tree = right;
temp->u.subtree[1] = parent;
temp->flags &= ~PTF_TRAVERSE_LEFT;
parent = temp;
/* descend to right child node */
goto PTREE_LEFT;
} else {
/* no right subtree; process this node */
goto PTREE_PROCESS;
}
} else {
/* no right subtree; process this node */
goto PTREE_PROCESS;
}
PTREE_PROCESS:
/* process node; may replace parent's pointer to this node */
tree = (*visit_rtn)( tree );
goto PTREE_UNWIND;
PTREE_UNWIND:
if( parent == NULL ) {
return tree;
}
if( parent->flags & PTF_TRAVERSE_LEFT ) {
parent->flags &= ~PTF_TRAVERSE_LEFT;
/* set child pointer of parent to current subtree */
temp = parent;
parent = temp->u.subtree[0];
temp->u.subtree[0] = tree;
tree = temp;
/* processed a left child; try for right hand child of parent */
goto PTREE_RIGHT;
} else {
/* set child pointer of parent to current subtree */
temp = parent;
parent = temp->u.subtree[1];
temp->u.subtree[1] = tree;
tree = temp;
/* processed a right child; process parent */
goto PTREE_PROCESS;
}
}
// The following is a cut-paste version of PTreeTraversePostfix, with
// traversals to the left of commas eliminated
//
PTREE PTreeTraverseInitRef( // TRAVERSE A PTREE FOR REFERENCE INIT.
PTREE tree, // - tree to be traversed
PTREE (*visit_rtn) // - visiting routine
( PTREE curr ) ) // - - addr( current node )
{
PTREE parent;
PTREE temp;
PTREE left;
PTREE right;
PTREE_STATE state;
/*
The states represent locations in the traditional recursive version
of a postfix traversal function.
postfix( tree )
{
PTREE_LEFT
postfix( tree->left )
PTREE_RIGHT
postfix( tree->right )
PTREE_PROCESS
process( tree )
PTREE_UNWIND
}
*/
if( tree == NULL || tree->op == PT_ERROR ) {
return tree;
}
state = PTREE_LEFT;
parent = NULL;
for(;;) {
switch( state ) {
case PTREE_LEFT:
if( ptreePTSFlags[ tree->op ] & PTS_OPERATOR ) {
left = tree->u.subtree[0];
if( left != NULL
&& !( tree->op == PT_BINARY && tree->cgop == CO_COMMA ) ) {
/* has a left subtree; store current parent */
temp = tree;
tree = left;
temp->u.subtree[0] = parent;
temp->flags |= PTF_TRAVERSE_LEFT;
parent = temp;
/* descend to left child node */
state = PTREE_LEFT;
} else {
/* descend to right child node */
state = PTREE_RIGHT;
}
} else {
/* no subtrees; process this node */
state = PTREE_PROCESS;
}
continue;
case PTREE_RIGHT:
if( ptreePTSFlags[ tree->op ] & PTS_BINARY ) {
right = tree->u.subtree[1];
if( right != NULL ) {
/* has a right subtree; store current parent */
temp = tree;
tree = right;
temp->u.subtree[1] = parent;
temp->flags &= ~PTF_TRAVERSE_LEFT;
parent = temp;
/* descend to right child node */
state = PTREE_LEFT;
} else {
/* no right subtree; process this node */
state = PTREE_PROCESS;
}
} else {
/* no right subtree; process this node */
state = PTREE_PROCESS;
}
continue;
case PTREE_PROCESS:
/* process node; may replace parent's pointer to this node */
tree = (*visit_rtn)( tree );
state = PTREE_UNWIND;
/* fall through */
case PTREE_UNWIND:
if( parent == NULL ) {
break;
}
if( parent->flags & PTF_TRAVERSE_LEFT ) {
parent->flags &= ~PTF_TRAVERSE_LEFT;
/* set child pointer of parent to current subtree */
temp = parent;
parent = temp->u.subtree[0];
temp->u.subtree[0] = tree;
tree = temp;
/* processed a left child; try for right hand child of parent */
state = PTREE_RIGHT;
} else {
/* set child pointer of parent to current subtree */
temp = parent;
parent = temp->u.subtree[1];
temp->u.subtree[1] = tree;
tree = temp;
/* processed a right child; process parent */
state = PTREE_PROCESS;
}
continue;
}
break;
}
return tree;
}
PTREE PTreeTraversePrefix( // TRAVERSE A PTREE IN (SELF,LEFT,RIGHT) ORDER
PTREE tree, // - tree to be traversed
PTREE (*visit_rtn) // - visiting routine
( PTREE curr ) ) // - - addr( current node )
{
PTREE parent;
PTREE temp;
PTREE_STATE state;
/*
The states represent locations in the traditional recursive version
of a prefix traversal function.
prefix( tree )
{
PTREE_PROCESS
process( tree )
PTREE_LEFT
postfix( tree->left )
PTREE_RIGHT
postfix( tree->right )
PTREE_UNWIND
}
*/
if( tree == NULL || tree->op == PT_ERROR ) {
return tree;
}
state = PTREE_PROCESS;
parent = NULL;
for(;;) {
switch( state ) {
case PTREE_PROCESS:
/* process node */
tree = (*visit_rtn)( tree );
state = PTREE_LEFT;
/* fall through */
case PTREE_LEFT:
if( ptreePTSFlags[ tree->op ] & PTS_OPERATOR ) {
if( tree->u.subtree[0] != NULL ) {
/* has a left subtree; store current parent */
temp = tree;
tree = temp->u.subtree[0];
temp->u.subtree[0] = parent;
temp->flags |= PTF_TRAVERSE_LEFT;
parent = temp;
/* descend to left child node */
state = PTREE_PROCESS;
} else {
/* descend to right child node */
state = PTREE_RIGHT;
}
} else {
/* no subtrees; unwind up to parent */
state = PTREE_UNWIND;
}
continue;
case PTREE_RIGHT:
if( ( ptreePTSFlags[ tree->op ] & PTS_BINARY )
&&( tree->u.subtree[1] != NULL ) ) {
/* has a right subtree; store current parent */
temp = tree;
tree = temp->u.subtree[1];
temp->u.subtree[1] = parent;
temp->flags &= ~PTF_TRAVERSE_LEFT;
parent = temp;
/* descend to right child node */
state = PTREE_PROCESS;
} else {
/* no right subtree; unwind up to parent */
state = PTREE_UNWIND;
}
continue;
case PTREE_UNWIND:
if( parent == NULL ) {
break;
}
if( parent->flags & PTF_TRAVERSE_LEFT ) {
parent->flags &= ~PTF_TRAVERSE_LEFT;
/* set child pointer of parent to new node */
temp = parent;
parent = temp->u.subtree[0];
temp->u.subtree[0] = tree;
tree = temp;
/* processed a left child; try for right hand child of parent */
state = PTREE_RIGHT;
} else {
/* set child pointer of parent to new node */
temp = parent;
parent = temp->u.subtree[1];
temp->u.subtree[1] = tree;
tree = temp;
/* processed a right child; unwind to parent */
state = PTREE_UNWIND;
}
continue;
}
break;
}
return tree;
}
static TOKEN_LOCN *extract_locn;
static PTREE set_error_location( PTREE node )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?