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

📄 yystate.c

📁 一个c语言写做的编译器的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	error(FATAL, "Internal [stritem], buffer overflow\n" );

    *bp = '\0' ;
    return buf;
}
/*----------------------------------------------------------------------*/
PRIVATE void	pstate( state )
STATE	*state;
{
    /* Print one row of the parse table in human-readable form yyout.doc
     * (stderr if -V is specified).
     */

    int   	i;
    ITEM  	**item;
    ACT		*p;

    document( "State %d:\n", state->num );

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    /* Print the kernel and epsilon items for the current state.  */

    for( i=state->nkitems, item=state->kernel_items  ; --i >= 0 ; ++item )
	document("    %s\n", stritem(*item, (*item)->right_of_dot==0 ));

    for( i=state->neitems, item=state->epsilon_items ; --i >= 0 ; ++item )
	document( "    %s\n", stritem(*item, 1) );

    document( "\n" );

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
    /* Print out the next-state transitions, first the actions,   */
    /* then the gotos.						  */

    for( i = 0; i < (MINTERM+USED_TERMS); ++i )
    {
	if( p = p_action( state->num, i ) )
	{
	    if( p->do_this == 0 )
	    {
		if( p->sym == _EOI_ )
		    document( "    Accept on end of input\n" );
		else
		    error( FATAL, "INTERNAL: state %d, Illegal accept",
								    state->num);
	    }
	    else if( p->do_this < 0 )
		document( "    Reduce by %d on %s\n", -(p->do_this),
							Terms[p->sym]->name );
	    else
		document( "    Shift to %d on %s\n", p->do_this,
							Terms[p->sym]->name );
	}
    }

    for( i = MINNONTERM; i < MINNONTERM + USED_NONTERMS; i++ )
	if( p = p_goto(state->num, i) )
	    document( "    Goto %d on %s\n", p->do_this,
							Terms[i]->name );
    document("\n");
}
/*----------------------------------------------------------------------*/
PRIVATE void	pstate_stdout( state )
STATE	*state;
{
    document_to( stdout );
    pstate( state );
    document_to( NULL );
}
/*----------------------------------------------------------------------*/
PRIVATE void pclosure( kernel, closure_items, nitems )
STATE	*kernel;
ITEM	**closure_items;
int	nitems;
{
    printf( "\n%d items in Closure of ", nitems );
    pstate_stdout( kernel );

    if( nitems > 0 )
    {
	printf( "    -----closure items:----\n" );
	while( --nitems >= 0 )
	    printf( "    %s\n", stritem( *closure_items++, 0) );
    }
}

PRIVATE void	make_yy_lhs( prodtab )
PRODUCTION	**prodtab;
{
    static char *text[] =
    {
	"The Yy_lhs array is used for reductions. It is indexed by production",
	"number and holds the associated left-hand side adjusted so that the",
	"number can be used as an index into Yy_goto.",
	NULL
    };
    PRODUCTION *prod;
    int		i;

    comment ( Output, text );
    output  ( "YYPRIVATE int Yy_lhs[%d] =\n{\n", Num_productions );

    for( i = 0; i < Num_productions; ++i )
    {
	prod = *prodtab++;
	output("\t/* %3d */\t%d", prod->num, ADJ_VAL( prod->lhs->val ) );

	if( i != Num_productions-1 )
	    output(",");

	if( i % 3 == 2 || i == Num_productions-1 )	/* use three columns */
	    output( "\n" );
    }
    output("};\n");
}

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

PRIVATE void	make_yy_reduce( prodtab )
PRODUCTION	**prodtab;
{
    static char *text[] =
    {
	"The Yy_reduce[] array is indexed by production number and holds",
	"the number of symbols on the right-hand side of the production",
	NULL
    };
    PRODUCTION *prod;
    int		i;

    comment ( Output, text );
    output  ( "YYPRIVATE int Yy_reduce[%d] =\n{\n", Num_productions );

    for( i = 0; i < Num_productions; ++i )
    {
	prod = *prodtab++;
	output( "\t/* %3d */\t%d", prod->num, prod->rhs_len );

	if( i != Num_productions-1 )
	    output(",");

	if( i % 3 == 2 || i == Num_productions-1 )	/* use three columns */
	    output( "\n" );
    }
    output("};\n");
}

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

PRIVATE void make_yy_slhs( prodtab )
PRODUCTION	**prodtab;
{
    static char *text[] =
    {
	"Yy_slhs[] is a debugging version of Yy_lhs[]. It is indexed by",
	"production number and evaluates to a string representing the",
	"left-hand side of the production.",
	NULL
    };

    PRODUCTION *prod;
    int		i;

    comment ( Output, text );
    output  ( "YYPRIVATE char *Yy_slhs[%d] =\n{\n", Num_productions );

    for( i = Num_productions; --i >= 0 ; )
    {
	prod = *prodtab++;
	output("\t/* %3d */\t\"%s\"", prod->num, prod->lhs->name );
	output( i != 0 ? ",\n" : "\n" );
    }
    output("};\n");
}

PRIVATE void make_yy_srhs( prodtab )
PRODUCTION	**prodtab;
{
    static char *text[] =
    {
	"Yy_srhs[] is also used for debugging. It is indexed by production",
	"number and evaluates to a string representing the right-hand side of",
	"the production.",
	NULL
    };

    PRODUCTION *prod;
    int		i, j;

    comment ( Output, text );
    output  ( "YYPRIVATE char *Yy_srhs[%d] =\n{\n", Num_productions );

    for( i = Num_productions; --i >= 0 ; )
    {
	prod = *prodtab++;
	output("\t/* %3d */\t\"",  prod->num );

	for( j = 0; j < prod->rhs_len ; ++j )
	{
	    output( "%s", prod->rhs[j]->name );
	    if( j != prod->rhs_len - 1 )
		outc( ' ' );
	}
	output( i != 0 ? "\",\n" : "\"\n" );
    }
    output("};\n");
}

/*----------------------------------------------------------------------
 * The following routines generate compressed parse tables. There's currently
 * no way to do uncompressed tables. The default transition is the error
 * transition.
 */

PRIVATE void	print_reductions()
{
    /* Output the various tables needed to do reductions */

    PRODUCTION	**prodtab;

    if(!(prodtab= (PRODUCTION**) malloc(sizeof(PRODUCTION*) * Num_productions)))
	error(FATAL,"Not enough memory to output LALR(1) reduction tables\n");
    else
	ptab( Symtab, (ptab_t)mkprod, prodtab, 0 );

    make_yy_lhs    ( prodtab );
    make_yy_reduce ( prodtab );

    output("#ifdef YYDEBUG\n");

    make_yy_slhs   ( prodtab );
    make_yy_srhs   ( prodtab );

    output("#endif\n");
    free( prodtab );
}

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

PRIVATE void	mkprod( sym, prodtab )
SYMBOL		*sym;
PRODUCTION	**prodtab;
{
    PRODUCTION	*p;

    if( ISNONTERM(sym) )
	for( p = sym->productions ; p ; p = p->next )
  	{
#ifdef INTERNAL
  		if( p->num >= Num_productions )
  		    error( FATAL,"Internal [mkprod], bad prod. num.\n" );
#endif

	    prodtab[ p->num ] = p ;
  	}
}

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

PRIVATE void	print_tab( table, row_name, col_name, make_private )
ACT	**table;
char	*row_name;	/* Name to use for the row arrays 	  	   */
char	*col_name;	/* Name to use for the row-pointers array 	   */
int	make_private;	/* Make index table private (rows always private)  */
{
    /* Output the action or goto table. */

    int		i, j;
    ACT		*ele, **elep; /* table element and pointer to same	     */
    ACT		*e, **p;
    int		count;        /* # of transitions from this state, always >0 */
    int 	column;
    SET		*redundant = newset();            /* Mark redundant rows */

    static char	*act_text[] =
    {
	"The Yy_action table is action part of the LALR(1) transition",
	"matrix. It's compressed and can be accessed using the yy_next()",
	"subroutine, declared below.",
	"",
	"             Yya000[]={   3,   5,3   ,   2,2   ,   1,1   };",
	"  state number---+        |    | |",
	"  number of pairs in list-+    | |",
	"  input symbol (terminal)------+ |",
	"  action-------------------------+",
	"",
	"  action = yy_next( Yy_action, cur_state, lookahead_symbol );",
	"",
	"	action <  0   -- Reduce by production n,  n == -action.",
	"	action == 0   -- Accept. (ie. Reduce by production 0.)",
	"	action >  0   -- Shift to state n,  n == action.",
	"	action == YYF -- error.",
	NULL
    };
    static char	*goto_text[] =
    {
	"The Yy_goto table is goto part of the LALR(1) transition matrix",
	"",
	" nonterminal = Yy_lhs[ production number by which we just reduced ]",
	"",
	"              Yyg000[]={   3,   5,3   ,   2,2   ,   1,1   };",
	"  uncovered state-+        |    | |",
	"  number of pairs in list--+    | |",
	"  nonterminal-------------------+ |",
	"  goto this state-----------------+",
	"",
	"It's compressed and can be accessed using the yy_next() subroutine,",
	"declared below, like this:",
	"",
	"  goto_state = yy_next( Yy_goto, cur_state, nonterminal );",
	NULL
    };

    comment( Output, table == Actions ? act_text : goto_text );

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     * Modify the matrix so that, if a duplicate rows exists, only one
     * copy of it is kept around. The extra rows are marked as such by setting
     * a bit in the "redundant" set. (The memory used for the chains is just
     * discarded.) The redundant table element is made to point at the row
     * that it duplicates.
     */

    for( elep = table, i = 0; i < Nstates ; ++elep, ++i )
    {
	if( MEMBER( redundant,i ) )
	    continue;

	for( p=elep+1, j=i ; ++j < Nstates ; ++p )
	{
	    if( MEMBER( redundant, j) )
		continue;

	    ele = *elep;	/* pointer to template chain		*/
	    e   = *p;		/* chain to compare against template	*/

	    if( !e || !ele )	/* either or both strings have no elements */
		continue;

	    for( ; ele && e ; ele=ele->next, e=e->next )
		if( (ele->do_this != e->do_this) || (ele->sym != e->sym) )
		    break;

	    if( !e && !ele )
	    {
		/* Then the chains are the same. Mark the chain being compared
		 * as redundant, and modify table[j] to hold a pointer to the
		 * template pointer.
		 */

		ADD( redundant, j );
		table[j] = (ACT *) elep;
	    }
	}
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     * Output the row arrays
     */

    for( elep = table, i = 0 ; i < Nstates ; ++elep, ++i )
    {
	if( !*elep || MEMBER(redundant, i) )
	    continue;
			   /* Count the number of transitions from this state */
	count = 0;
	for( ele = *elep ; ele ; ele = ele->next )
	    ++count;

	output("YYPRIVATE YY_TTYPE %s%03d[]={%2d,", row_name,
						(int)(elep-table), count);
									   /*}*/
        column = 0;
	for( ele = *elep ; ele ; ele = ele->next )
	{
	    ++Npairs;
	    output( "%3d,%-4d", ele->sym, ele->do_this );

	    if( ++column != count )
		outc( ',' );

	    if( column % 5 == 0  )
		output("\n\t\t\t        ");
	}
									/* { */
	output( "};\n" );
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     * Output the index array
     */

    if( make_private )
	output( "\nYYPRIVATE YY_TTYPE *%s[%d] =\n", col_name, Nstates );
    else
	output( "\nYY_TTYPE *%s[%d] =\n", col_name, Nstates );

    output( "{\n/*   0 */  " );						/* } */

    for( elep = table, i = 0 ; i < Nstates ; ++i, ++elep )
    {
	if( MEMBER(redundant, i) )
	    output( "%s%03d", row_name, (int)((ACT **)(*elep) - table) );
	else
	    output( *elep ? "%s%03d" : "  NULL" , row_name, i );

	if( i != Nstates-1 )
	    output( ", " );

	if( i==0  || (i % 8)==0 )
	    output("\n/* %3d */  ", i+1 );
    }
									/* { */
    delset( redundant );            	/* Mark redundant rows */
    output( "\n};\n");
}

#ifdef DEBUG
#ifdef __TURBOC__
#pragma warn -use
#endif

PRIVATE  char 	*strprod( prod )
PRODUCTION	*prod;
{
    /* Return a pointer to a string that holds a representation
     * of a production.
     */

    static char buf[ MAXOBUF ];
    char	*bp;
    int	   	i;

    bp  = buf;
    bp += sprintf( bp, "%s->", prod->lhs->name );

    if( prod->rhs_len <= 0 )
	bp += sprintf( bp, "<epsilon>" );
    else
	for( i = 0; i < prod->rhs_len ; ++i )
	    bp += sprintf(bp, "%s ", prod->rhs[i]->name );

    if( bp - buf >= MAXOBUF )
	error(FATAL, "Internal [strprod], buffer overflow\n" );

    *bp = '\0' ;
    return buf;
}
#endif

⌨️ 快捷键说明

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