⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symtab.c

📁 一个c语言写做的编译器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	size = (p->DCL_TYPE==ARRAY) ? p->NUM_ELE * get_sizeof(p->next) : PSIZE;
    else
    {
	switch( p->NOUN )
	{
	case CHAR:	size = CSIZE;  			break;
	case INT:	size = p->LONG ? LSIZE : ISIZE;	break;
	case STRUCTURE:	size = p->V_STRUCT->size;	break;
	case VOID:	size = 0;  			break;
	case LABEL:	size = 0;  			break;
	}
    }

    return size;
}

/*----------------------------------------------------------------------*/

PUBLIC	symbol	*reverse_links( sym )
symbol	*sym;
{
    /* Go through the cross-linked chain of "symbols", reversing the direction
     * of the cross pointers. Return a pointer to the new head of chain
     * (formerly the end of the chain) or NULL if the chain started out empty.
     */

    symbol *previous, *current, *next;

    if( !sym )
	return NULL;

    previous = sym;
    current  = sym->next;

    while( current )
    {
	next		= current->next;
	current->next	= previous;
	previous	= current;
	current		= next;
    }

    sym->next = NULL;
    return previous;
}

PUBLIC	char	*sclass_str( class )	/* Return a string representing the */
int	class;				/* indicated storage class.	    */
{
    return class==CONSTANT   ? "CON" :
	   class==REGISTER   ? "REG" :
	   class==TYPEDEF    ? "TYP" :
	   class==AUTO       ? "AUT" :
	   class==FIXED      ? "FIX" : "BAD SCLASS" ;
}

/*----------------------------------------------------------------------*/

PUBLIC	char	*oclass_str( class )	/* Return a string representing the */
int	class;				/* indicated output storage class.  */
{
    return class==PUB ? "PUB"  :
	   class==PRI ? "PRI"  :
	   class==COM ? "COM"  :
	   class==EXT ? "EXT"  :  "(NO OCLS)" ;
}

/*----------------------------------------------------------------------*/

PUBLIC	char	*noun_str( noun )	/* Return a string representing the */
int	noun;				/* indicated noun.		    */
{
    return noun==INT	    ? "int"    :
	   noun==CHAR	    ? "char"   :
	   noun==VOID	    ? "void"   :
	   noun==LABEL	    ? "label"  :
	   noun==STRUCTURE  ? "struct" : "BAD NOUN" ;
}

/*----------------------------------------------------------------------*/

PUBLIC char  *attr_str( spec_p )	/* Return a string representing all */
specifier *spec_p;			/* attributes in a specifier other  */
{					/* than the noun and storage class. */
    static char str[5];

    str[0] = ( spec_p->_unsigned ) ? 'u' : '.' ;
    str[1] = ( spec_p->_static   ) ? 's' : '.' ;
    str[2] = ( spec_p->_extern   ) ? 'e' : '.' ;
    str[3] = ( spec_p->_long     ) ? 'l' : '.' ;
    str[4] = '\0';

    return str;
}

/*----------------------------------------------------------------------*/

PUBLIC	char	*type_str ( link_p )
link	*link_p;		       /* Return a string representing the    */
{				       /* type represented by the link chain. */
    int		i;
    static char target [ 80 ];
    static char	buf    [ 64 ];
    int		available  = sizeof(target) - 1;

    *buf    = '\0';
    *target = '\0';

    if( !link_p )
	return "(NULL)";

    if( link_p->tdef )
    {
	strcpy( target, "tdef " );
	available -= 5;
    }

    for(; link_p ; link_p = link_p->next )
    {
	if( IS_DECLARATOR(link_p) )
	{
	    switch( link_p->DCL_TYPE )
	    {
	    case POINTER:    i = sprintf(buf, "*" );			break;
	    case ARRAY:	     i = sprintf(buf, "[%d]", link_p->NUM_ELE);	break;
	    case FUNCTION:   i = sprintf(buf, "()" ); 			break;
	    default: 	     i = sprintf(buf, "BAD DECL" );	        break;
	    }
	}
	else  /* it's a specifier */
	{
	    i = sprintf( buf, "%s %s %s %s",    noun_str  ( link_p->NOUN     ),
					        sclass_str( link_p->SCLASS   ),
					        oclass_str( link_p->OCLASS   ),
					        attr_str  ( &link_p->select.s));

	    if( link_p->NOUN==STRUCTURE  || link_p->SCLASS==CONSTANT  )
	    {
		strncat( target, buf, available );
		available -= i;

		if( link_p->NOUN == STRUCTURE )
		    i = sprintf(buf, " %s", link_p->V_STRUCT->tag ?
					    link_p->V_STRUCT->tag : "untagged");

		else if( IS_INT(link_p)  ) sprintf( buf,"=%d", link_p->V_INT  );
		else if( IS_UINT(link_p) ) sprintf( buf,"=%u", link_p->V_UINT );
		else if( IS_LONG(link_p) ) sprintf( buf,"=%ld",link_p->V_LONG );
		else if( IS_ULONG(link_p)) sprintf( buf,"=%lu",link_p->V_ULONG);
		else			   continue;
	    }
	}

	strncat( target, buf, available );
	available -= i;
    }

    return target;
}

/*----------------------------------------------------------------------*/

PUBLIC char *tconst_str( type )
link	*type;		   	   /* Return a string representing the value  */
{				   /* field at the end of the specified type  */
    static char buf[80];	   /* (which must be char*, char, int, long,  */
				   /* unsigned int, or unsigned long). Return */
    buf[0] = '?';	   	   /* "?" if the type isn't any of these.     */
    buf[1] = '\0';

    if( IS_POINTER(type)  &&  IS_CHAR(type->next) )
    {
	sprintf( buf, "%s%d", L_STRING, type->next->V_INT );
    }
    else if( !(IS_AGGREGATE(type) || IS_FUNCT(type)) )
    {
	switch( type->NOUN )
	{
	case CHAR:	sprintf( buf, "'%s' (%d)", bin_to_ascii(
				    type->UNSIGNED ? type->V_UINT
						     : type->V_INT,1),
				    type->UNSIGNED ? type->V_UINT
						     : type->V_INT,1	);
			break;

	case INT:	if( type->LONG )
			{
			    if( type->UNSIGNED )
				sprintf(buf, "%luL", type->V_ULONG);
			    else
				sprintf(buf, "%ldL", type->V_LONG );
			}
			else
			{
			    if( type->UNSIGNED )
				sprintf( buf, "%u", type->V_UINT);
			    else
				sprintf( buf, "%d", type->V_INT );
			}
			break;
	}
    }

    if( *buf == '?' )
	yyerror("Internal, tconst_str: Can't make constant for type %s\n",
							    type_str( type ));
    return buf;
}

/*----------------------------------------------------------------------*/

PUBLIC	char	*sym_chain_str( chain )
symbol	*chain;
{
    /* Return a string listing the names of all symbols in the input chain (or
     * a constant value if the symbol is a constant). Note that this routine
     * can't call type_str() because the second-order recursion messes up the
     * buffers. Since the routine is used only for occasional diagnostics, it's
     * not worth fixing this problem.
     */

    int		i;
    static char buf[80];
    char	*p	= buf;
    int 	avail	= sizeof( buf ) - 1;

    *buf = '\0';
    while( chain && avail > 0 )
    {
	if( IS_CONSTANT(chain->etype) )
	    i = sprintf( p, "%0.*s", avail - 2, "const" );
	else
	    i = sprintf( p, "%0.*s", avail - 2, chain->name );

	p     += i;
	avail -= i;

	if( chain = chain->next )
	{
	    *p++ = ',' ;
	    i -= 2;
	}
    }

    return buf;
}

/*----------------------------------------------------------------------*/

PRIVATE void psym( sym_p, fp )			/* Print one symbol to fp. */
symbol	*sym_p;
FILE	*fp;
{
    fprintf(fp, "%-18.18s %-18.18s %2d %p %s\n",
				 sym_p->name,
				 sym_p->type ? sym_p->rname : "------",
				 sym_p->level,
				 MSC((void far *)) sym_p->next,
				 type_str( sym_p->type ) );
}

/*----------------------------------------------------------------------*/

PRIVATE	void pstruct( sdef_p, fp )	/* Print a structure definition to fp */
structdef    *sdef_p;			/* including all the fields & types.  */
FILE	     *fp;
{
    symbol	*field_p;

    fprintf(fp, "struct <%s> (level %d, %d bytes):\n",
					sdef_p->tag,sdef_p->level,sdef_p->size);

    for( field_p = sdef_p->fields; field_p; field_p=field_p->next )
    {
	fprintf(fp, "    %-20s (offset %d) %s\n",
		       field_p->name, field_p->level, type_str(field_p->type));
    }
}

/*----------------------------------------------------------------------*/

PUBLIC void print_syms( filename )	/* Print the entire symbol table to   */
char	*filename;			/* the named file. Previous contents  */
{					/* of the file (if any) are destroyed.*/
    FILE *fp;

    if( !(fp = fopen(filename,"w")) )
	yyerror("Can't open symbol-table file\n");
    else
    {
	fprintf(fp, "Attributes in type field are:   upel\n"   );
	fprintf(fp, "    unsigned (. for signed)-----+|||\n"   );
	fprintf(fp, "    private  (. for public)------+||\n"   );
	fprintf(fp, "    extern   (. for common)-------+|\n"   );
	fprintf(fp, "    long     (. for short )--------+\n\n" );

        fprintf(fp,"name               rname              lev   next   type\n");
	ptab( Symbol_tab, (ptab_t)psym, fp, 1 );

	fprintf(fp, "\nStructure table:\n\n");
	ptab( Struct_tab, (ptab_t)pstruct, fp, 1 );

	fclose( fp );
    }
}

⌨️ 快捷键说明

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