dbgptree.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 644 行 · 第 1/2 页

C
644
字号
    char *text;                 // - text pointer (returned)
    static char buffer[256];    // - buffer (valid until next call)
    boolean type_add;           // - TRUE ==> add type
    PTREE pnode;                // - parse-tree node

    pnode = node->pnode;
    switch( pnode->op ) {
      case PT_ERROR :
        text = PTREE_ERROR_NODE;
        type_add = FALSE;
        break;
      case PT_UNARY :
      case PT_BINARY :
        stpcpy( buffer, DbgOperator( pnode->cgop ) );
        text = buffer;
        type_add = printTypes;
        break;
      case PT_INT_CONSTANT :
        switch( TypedefModifierRemoveOnly( pnode->type )->id ) {
          case TYP_SCHAR :
          case TYP_SSHORT :
          case TYP_SINT :
          case TYP_SLONG :
            sticpy( buffer, pnode->u.int_constant );
            break;
          case TYP_SLONG64 :
          case TYP_ULONG64 :
          { char *buf;
            buffer[0] = '<';
            buf = stxcpy( &buffer[1], pnode->u.int64_constant.u._32[0] );
            *buf='~';
            buf = stxcpy( buf+1, pnode->u.int64_constant.u._32[1] );
            buf[0] = '>';
            buf[1] = '\0';
          } break;
          default :
            stdcpy( buffer, pnode->u.uint_constant );
            break;
        }
        text = buffer;
        type_add = printTypes;
        break;
      case PT_FLOATING_CONSTANT :
        BFCnvFS( pnode->u.floating_constant, buffer, 256 );
        text = buffer;
        type_add = printTypes;
        break;
      case PT_STRING_CONSTANT :
        stvcpy( buffer, pnode->u.string->string, pnode->u.string->len );
        text = buffer;
        type_add = printTypes;
        break;
      case PT_TYPE :
        textType( buffer, pnode->type, "<> " );
        text = buffer;
        type_add = FALSE;
        break;
      case PT_ID :
        text = pnode->u.id.name;
        type_add = FALSE;
        break;
      case PT_SYMBOL :
        if( pnode->cgop == CO_NAME_THIS ) {
            stpcpy( buffer, "this" );
            text = buffer;
        } else if( pnode->cgop == CO_NAME_CDTOR_EXTRA ) {
            stpcpy( buffer, "cdtor_extra" );
            text = buffer;
        } else {
            SYMBOL sym;
            if( pnode->cgop == CO_NAME_PARM_REF ) {
                text = stpcpy( buffer, "parm-ref:" );
            } else {
                text = buffer;
            }
            sym = pnode->u.symcg.symbol;
            if( sym == NULL ) {
                stpcpy( text, "this" );
            } else if( sym->name == NULL ) {
                stpcpy( text, "**NULL**" );
            } else if( sym->name->name == NULL ) {
                stpcpy( text, "**NULL**" );
            } else {
                stpcpy( text, sym->name->name );
            }
            text = buffer;
        }
        type_add = printTypes;
        break;
      case PT_DUP_EXPR :
        text = stpcpy( buffer, "dup[" );
        text = stxcpy( text, (unsigned)pnode->u.subtree[0] );
        stpcpy( text, "]" );
        text = buffer;
        type_add = printTypes;
        break;
      case PT_IC :
        text = stpcpy( buffer, DbgIcOpcode( pnode->u.ic.opcode ) );
        text = stpcpy( text, " " );
        text = stxcpy( text, pnode->u.ic.value.uvalue );
        text = buffer;
        type_add = printTypes;
        break;
    }
    if( type_add && ( pnode->type != NULL ) ) {
        textType( strend( text )
                , pnode->type
                , (pnode->flags & PTF_LVALUE ) ? "<LV> " : "<RV> " );
    }
    if( 0 != node->numb ) {
        char* p;
        p = stpcpy( strend( text ), " {" );
        p = stdcpy( p, node->numb );
        p = stpcpy( p, "}" );
    }
    return text;
}


static void buildSubtree(       // BUILD A SUBTREE
    PTREE root )                // - root of subtree
{
    SUBTREE *subtree;           // - info for subtree

    RingIterBeg( subtrees, subtree ) {
        if( subtree->root == root ) return;
    } RingIterEnd( subtree )
    subtree = RingCarveAlloc( carveSubtree, &subtrees );
    subtree->lines = NULL;
    subtree->root = root;
    subtree->centre = buildNode( root, subtree, NULL );
}


static COL buildNode(           // BUILD A NODE
    PTREE expr,                 // - parse-tree expression
    SUBTREE *subtree,           // - subtree under construction
    LINE *pred )                // - preceding line (or NULL)
{
    NODE *node;                 // - node for expression
    LINE *line;                 // - line entry for node
    COL width;                  // - node width
    COL centre;                 // - trial centre
    COL offset;                 // - centre between operands
    COL bound;                  // - bound for next centre on next line

    if( expr == NULL ) return 0;
    node = CarveAlloc( carveNode );
    node->pnode = expr;
    node->centre = 0;
    node->left = 0;
    node->right = 0;
    if( NULL == expr->decor ) {
        node->numb = 0;
    } else {
        node->numb = addDecorated( node );
    }
    if( ( pred == NULL ) || ( pred == subtree->lines ) ) {
        line = addLine( subtree );
    } else {
        line = pred->next;
    }
    RingAppend( &line->nodes, node );
    width = strlen( textPTREE( node ) );
    switch( expr->op ) {
      case PT_UNARY :
        node->left = buildNode( expr->u.subtree[0], subtree, line );
        break;
      case PT_BINARY :
        node->left = buildNode( expr->u.subtree[0], subtree, line );
        node->right = buildNode( expr->u.subtree[1], subtree, line );
        break;
      case PT_DUP_EXPR :
        buildSubtree( expr->u.subtree[0] );
        break;
    }
    if( node->left == 0 ) {
        centre = node->right;
        bound = centre;
    } else if( node->right == 0 ) {
        centre = node->left;
        bound = centre;
    } else {
        centre = ( node->left + node->right ) / 2;
        bound = node->right;
    }
    offset = line->width + width / 2 + 1;
    if( centre < offset ) {
        centre = offset;
    }
    if( centre < line->bound ) {
        centre = line->bound;
    }
    node->centre = centre;
    line->width = centre - ( width / 2 ) + width;
    line->bound = line->width;
    if( bound != 0 ) {
        if( bound < centre ) {
            bound = centre;
        }
        ++ bound;
        line = line->next;
        if( line->bound < bound ) {
            line->bound = bound;
        }
    }
    return centre;
}


static void printNode(          // PRINT A NODE
    NODE *node )                // - node to be printed
{
    char *text;                 // - text to be printed

    text = textPTREE( node );
    centreText( text, node->centre );
    if( node->left != 0 ) {
        connectLeft( node->centre, node->left );
    }
    if( node->right != 0 ) {
        connectRight( node->centre, node->right );
        if( node->left != 0 ) {
            connectBoth( node->centre, node->left, node->right );
        }
    }
}


static void printSubtree(       // PRINT A SUBTREE
    void *_subtree )          // - subtree to be printed
{
    char buffer[ 256 ];         // - buffer
    char *bptr;                 // - buffer ptr
    LINE *line;                 // - current line
    NODE *node;                 // - current node
    TOKEN_LOCN locn;            // - subtree location
    boolean print_locn;         // - TRUE ==> print location

    SUBTREE *subtree = _subtree;

    begLine();
    if( subtree->next == subtrees ) {
        print_locn = TRUE;
        bptr = stpcpy( buffer, "tree[" );
    } else {
        endLine();
        begLine();
        print_locn = FALSE;
        bptr = stpcpy( buffer, "dup[" );
    }
    bptr = stxcpy( bptr, (unsigned)subtree->root );
    if( print_locn ) {
        PTreeExtractLocn( subtree->root, &locn );
        if( NULL != locn.src_file ) {
            bptr = stpcpy( bptr, " " );
            bptr = stpcpy( bptr, SrcFileName( locn.src_file ) );
            bptr = stpcpy( bptr, " line[" );
            bptr = stdcpy( bptr, locn.line );
            bptr = stpcpy( bptr, "] column[" );
            bptr = stdcpy( bptr, locn.column );
            bptr = stpcpy( bptr, "]" );
        }
    }
    centreText( buffer, subtree->centre );
    connectLeft( subtree->centre, subtree->centre );
    endLine();
    RingIterBeg( subtree->lines, line ) {
        begLine();
        RingIterBeg( line->nodes, node ) {
            printNode( node );
        } RingIterEnd( node );
        endLine();
    } RingIterEnd( line )
}


static void printDecoration(    // PRINT DECORATION FOR A NODE
    void )
{
    DECORATED* dec;             // - decoration entry

    if( NULL != decoration ) {
        printf( "\n Decorated Nodes:\n\n" );
        RingIterBeg( decoration, dec ) {
            PtdPrint( dec->node->numb, dec->node->pnode );
        } RingIterEnd( dec );
    }
}


void DbgPrintPTREE(             // PRINT A PARSE-TREE BEAUTIFULLY
    PTREE root )                // - root of tree to be printed
{
    decor_numb = 0;
    carveNode = CarveCreate( sizeof( NODE ), 16 );
    carveLine = CarveCreate( sizeof( LINE ), 16 );
    carveSubtree = CarveCreate( sizeof( SUBTREE ), 16 );
    carveDecoration = CarveCreate( sizeof( DECORATED ), 16 );
    subtrees = NULL;
    decoration = NULL;
    buildSubtree( root );
    RingWalk( subtrees, &printSubtree );
    printDecoration();
    CarveDestroy( carveNode );
    CarveDestroy( carveLine );
    CarveDestroy( carveSubtree );
    CarveDestroy( carveDecoration );
    prlineFree( &node_line );
    prlineFree( &conn_line );
}


void DbgPrintPTREEtyped(        // PRINT BEAUTIFUL PTREE, WITH TYPES
    PTREE root )                // - root of tree
{
    printTypes = TRUE;
    DbgPrintPTREE( root );
    printTypes = FALSE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?