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

📄 symtab.c

📁 一个c语言写做的编译器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*@A (C) 1992 Allen I. Holub                                                */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tools/debug.h>
#include <tools/hash.h>
#include <tools/l.h>
#include <tools/compiler.h>
#include <tools/c-code.h>
#include "symtab.h"	   /* Symbol-table definitions.			      */
#include "value.h"	   /* Value definitions.			      */
#include "proto.h"	   /* Prototypes for all functions in this directory. */
#include "label.h"	   /* Labels to use for compiler-generated symbols.   */

#if ( (0 ANSI(+1)) == 0 )  /* If not an ANSI compilers	*/
#define sprintf _sprintf   /* Use ANSI-compatible version out of comp.lib */
#endif
/*----------------------------------------------------------------------*/
PRIVATE symbol	  *Symbol_free = NULL; /* Free-list of recycled symbols.    */
PRIVATE link	  *Link_free   = NULL; /* Free-list of recycled links.	    */
PRIVATE structdef *Struct_free = NULL; /* Free-list of recycled structdefs. */

#define LCHUNK	10	    /* new_link() gets this many nodes at one shot.*/

static  void psym	P((symbol     *sym_p, FILE *fp	));
static  void pstruct	P((structdef *sdef_p, FILE *fp	));
/*----------------------------------------------------------------------*/
PUBLIC	symbol	*new_symbol( name, scope )
char	*name;
int	scope;
{
    symbol *sym_p;

    if( !Symbol_free )					/* Free list is empty.*/
	sym_p = (symbol *) newsym( sizeof(symbol) );
    else						/* Unlink node from   */
    {							/* the free list.     */
	sym_p 	    = Symbol_free;
	Symbol_free = Symbol_free->next ;
	memset( sym_p, 0, sizeof(symbol) );
    }

    strncpy( sym_p->name, name, sizeof(sym_p->name) );
    sym_p->level = scope;
    return sym_p;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
PUBLIC	void	discard_symbol( sym )
symbol	*sym;
{
    /* Discard a single symbol structure and any attached links and args. Note
     * that the args field is recycled for initializers, the process is
     * described later on in the text (see value.c in the code), but you have to
     * test for a different type here. Sorry about the forward reference.
     */

    if( sym )
    {
	if( IS_FUNCT( sym->type ) )
	    discard_symbol_chain( sym->args );	      /* Function arguments. */
	else
	    discard_value( (value *)sym->args );      /* If an initializer.  */

	discard_link_chain( sym->type );	      /* Discard type chain. */

	sym->next   = Symbol_free ;		      /* Put current symbol */
	Symbol_free = sym;			      /* in the free list.  */
    }
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
PUBLIC	void	discard_symbol_chain(sym)   /* Discard an entire cross-linked */
symbol	*sym;				    /* chain of symbols.              */
{
    symbol *p = sym;

    while( sym )
    {
	p = sym->next;
	discard_symbol( sym );
	sym = p;
    }
}
/*----------------------------------------------------------------------*/
PUBLIC link	*new_link( )
{
    /* Return a new link. It's initialized to zeros, so it's a declarator.
     * LCHUNK nodes are allocated from malloc() at one time.
     */

    link *p;
    int   i;

    if( !Link_free )
    {
	if( !(Link_free = (link *) malloc( sizeof(link) * LCHUNK )) )
	{
	    yyerror("INTERNAL, new_link: Out of memory\n");
	    exit( 1 );
	}

	for( p = Link_free, i = LCHUNK; --i > 0; ++p )   /* Executes LCHUNK-1 */
	    p->next = p + 1;			  	 /*	       times. */

	p->next = NULL ;
    }

    p 	       = Link_free;
    Link_free  = Link_free->next;
    memset( p, 0, sizeof(link) );
    return p;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
PUBLIC  void	discard_link_chain( p )
link    *p;
{
    /* Discard all links in the chain. Nothing is removed from the structure
     * table, however. There's no point in discarding the nodes one at a time
     * since they're already linked together, so find the first and last nodes
     * in the input chain and link the whole list directly.
     */

    link *start ;

    if( start = p )
    {
	while( p->next )	/* find last node */
	    p = p->next;

	p->next   = Link_free;
	Link_free = start;
    }
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
PUBLIC	void	discard_link( p )		 /* Discard a single link. */
link	*p;
{
    p->next    = Link_free;
    Link_free  = p;
}
/*----------------------------------------------------------------------*/
PUBLIC	structdef *new_structdef( tag )		/* Allocate a new structdef. */
char	*tag;
{
    structdef *sdef_p;

    if( !Struct_free )
	sdef_p = (structdef *) newsym( sizeof(structdef) );
    else
    {
	sdef_p 	    = Struct_free;
	Struct_free = (structdef *)(Struct_free->fields);
	memset( sdef_p, 0, sizeof(structdef) );
    }
    strncpy( sdef_p->tag, tag, sizeof(sdef_p->tag) );
    return sdef_p;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
#ifdef STRUCTS_ARE_DISCARDED  /* they aren't in the present compiler */

PUBLIC	void	discard_structdef( sdef_p )
structdef	*sdef_p;
{
    /* Discard a structdef and any attached fields, but don't discard linked
     * structure definitions.
     */

    if( sdef_p )
    {
	discard_symbol_chain( sdef_p->fields );
	sdef_p->fields = (symbol *)Struct_free ;
	Struct_free    = sdef_p;
    }
}
#endif

PUBLIC	void	add_declarator( sym, type )
symbol	*sym;
int	type;
{
    /* Add a declarator link to the end of the chain, the head of which is
     * pointed to by sym->type and the tail of which is pointed to by
     * sym->etype. *head must be NULL when the chain is empty. Both pointers
     * are modified as necessary.
     */

    link *link_p;

    if( type == FUNCTION && IS_ARRAY(sym->etype) )
    {
	yyerror("Array of functions is illegal, assuming function pointer\n");
	add_declarator( sym, POINTER );
    }

    link_p           = new_link();	  /* The default class is DECLARATOR. */
    link_p->DCL_TYPE = type;

    if( !sym->type )
	sym->type = sym->etype = link_p;
    else
    {
	sym->etype->next = link_p;
	sym->etype       = link_p;
    }
}

PUBLIC void spec_cpy( dst, src ) /* Copy all initialized fields in src to dst.*/
link *dst, *src;
{
    if( src->NOUN 	) dst->NOUN	= src->NOUN     ;
    if( src->SCLASS	) dst->SCLASS	= src->SCLASS   ;
    if( src->LONG 	) dst->LONG	= src->LONG     ;
    if( src->UNSIGNED	) dst->UNSIGNED = src->UNSIGNED ;
    if( src->STATIC	) dst->STATIC  	= src->STATIC   ;
    if( src->EXTERN	) dst->EXTERN   = src->EXTERN   ;
    if( src->tdef	) dst->tdef     = src->tdef     ;

    if( src->SCLASS == CONSTANT || src->NOUN == STRUCTURE)
	memcpy( &dst->VALUE, &src->VALUE, sizeof(src->VALUE) );
}

PUBLIC	link  *clone_type( tchain, endp )
link  *tchain;		/* input:  Type chain to duplicate.         	  */
link  **endp;		/* output: Pointer to last node in cloned chain.  */
{
    /* Manufacture a clone of the type chain in the input symbol. Return a
     * pointer to the cloned chain, NULL if there were no declarators to clone.
     * The tdef bit in the copy is always cleared.
     */

    link  *last, *head = NULL;

    for(; tchain ; tchain = tchain->next )
    {
	if( !head )					/* 1st node in chain. */
	    head = last = new_link();
	else						/* Subsequent node.   */
	{
	    last->next = new_link();
	    last       = last->next;
	}

	memcpy( last, tchain, sizeof(*last) );
	last->next = NULL;
	last->tdef = 0;
    }

    *endp = last;
    return head;
}

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

PUBLIC	int	the_same_type( p1, p2, relax )
link	*p1, *p2;
int	relax;
{
    /* Return 1 if the types match, 0 if they don't. Ignore the storage class.
     * If "relax" is true and the array declarator is the first link in the
     * chain, then a pointer is considered equivalent to an array.
     */

     if( relax && IS_PTR_TYPE(p1) && IS_PTR_TYPE(p2) )
     {
	p1 = p1->next;
	p2 = p2->next;
     }

     for(; p1 && p2 ; p1 = p1->next, p2 = p2->next)
     {
	if( p1->class != p2->class )
	    return 0;

	if( p1->class == DECLARATOR )
	{
	    if( (p1->DCL_TYPE != p2->DCL_TYPE) ||
			(p1->DCL_TYPE==ARRAY && (p1->NUM_ELE != p2->NUM_ELE)) )
		return 0;
	}
	else						/* this is done last */
	{
	    if( (p1->NOUN     == p2->NOUN     ) && (p1->LONG == p2->LONG ) &&
	        (p1->UNSIGNED == p2->UNSIGNED ) )
	    {
		return ( p1->NOUN==STRUCTURE ) ? p1->V_STRUCT == p2->V_STRUCT
					       : 1 ;
	    }
	    return 0;
	}
     }

     yyerror("INTERNAL the_same_type: Unknown link class\n");
     return 0;
}

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

PUBLIC	int	get_sizeof( p )
link	*p;
{
    /* Return the size in bytes of an object of the the type pointed to by p.
     * Functions are considered to be pointer sized because that's how they're
     * represented internally.
     */

    int size;

    if( p->class == DECLARATOR )

⌨️ 快捷键说明

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