📄 symtab.c
字号:
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 + -