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

📄 yydebug.c

📁 一个c语言写做的编译器的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    filename = *newargv++ = *argv;
	    break;
	}
	else if( argv[0][1] == 's' )					/* -s */
	    ssize = atoi( &argv[0][2] );      /* Don't copy to *newargv here. */
	else								/* -? */
	    *newargv++ = *argv;
    }

    Stacksize = ( ssize < 1	       )  ? DEFSTACK   :
		( ssize > (SCRNSIZE-6) )  ? SCRNSIZE-6 :
		/* ssize is in bounds */    ssize      ;

    if( filename )
    {
	/* Open input file if one was specified on the command line. */

	if( ii_newfile(filename) != -1 )
	    Inp_fm_file = 1;
	else
	{
	    perror( filename );
	    exit( 1 );
	}
    }
    return newargv - oldargv;
}

ANSI( PRIVATE int prnt_putc(int c, WINDOW *win)  )
KnR ( PRIVATE int prnt_putc(    c,         win)  )
KnR ( int c;					 )
KnR ( WINDOW *win;				 )
{
    /*    All output done through prnt_putc is suppressed in Go mode. Also note
     * that the arguments are reversed from addch(). This reversal lets you use
     * the prnt() subroutine (described in Appendix A), which expects a putc()-
     * like output function. Newlines are suppressed here so that you can have
     * more control over scrolling. Similarly, sequences of white space are
     * replaced by a single space character to conserve space in the window.
     *    Test_c is used to take care of the IBM graphics characters that form
     * the vertical line separating the stream-identification column from the
     * actual output. The c is mapped to a '|' if it's too large to be an ASCII
     * character (so isspace() will work properly).
     */

    static WINDOW *last_win = NULL;
    static int	  last_c    = 0;
    int		  test_c;

    if( Interactive && c != '\n' )
    {
	test_c = (c < 0x7f) ? c : '|';

	if( !(win==last_win && isspace(test_c) && isspace(last_c)) )
	    waddch( win, isspace(test_c) ? ' ' : c );

	last_win = win;
	last_c   = test_c;
    }
    return c;	/* keeps the compiler happy by returning a value a'la putc */
}
/*----------------------------------------------------------------------*/
#ifdef MSDOS

#    define refresh_win(win) /* empty */

#else	/* UNIX */

    PRIVATE	void refresh_win( win )
    WINDOW	*win;
    {
        /* Refresh the windows if you're not in go mode. (If you are, nothing
         * will have been written, so there's not point in doing the refresh.
         */

        if( Interactive )
	    wrefresh( win );
    }
#endif

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

PUBLIC	void yy_output( where, fmt, args )		/* Generate code */
int	where;
char	*fmt;
va_list	args;
{
    /* Works like vprintf(), but sends output to the code window. In the window,
     * it ignores any newlines in the string but prints a newline after every
     * call. All code sent to yycode(), yydata(), and yybss() is funneled
     * here. "where" should be one of the following:
     *
     *		0 : code
     *		1 : data
     *		2 : bss
     *
     * Note that if the three associated streams (yycodeout, yybssout, and
     * yydataout--all declared in the parser output file) are not directed to
     * stdout, output is sent to that stream TOO. Don't modify these to point
     * at stderr (or any other stream that accesses the console: /dev/tty, con,
     * etc.) or you'll mess up the screen.
     *
     * Note that the real yycode(), etc (ie. the ones supplied when YYDEBUG
     * is not defined) don't do anything special with newlines. In particular,
     * they are not inserted automatically at the end of the line. To make both
     * sets of routines compatible, your output strings should all have exactly
     * one newline, placed at the end of the string (don't imbed any in the
     * middle).
     */

    extern FILE	*yycodeout, *yydataout, *yybssout;

    if( Log )
    {
	fprintf( Log,    where == 0  ?  "CODE->" :
		         where == 1  ?  "DATA->" : "BSS-->" );
	prnt ( (prnt_t) fputc, Log, fmt, args );
	fputc( '\n', Log );
    }

    NEWLINE( Code_window );

    prnt_putc( where==0 ? 'C' : where==1 ? 'D' : 'B',	Code_window );
    prnt_putc( VERT,					Code_window );

    prnt( (prnt_t) prnt_putc, Code_window, fmt, args );
    refresh_win( Code_window );

    if( where == 0 && yycodeout != stdout )
	vfprintf( yycodeout, fmt, args );

    if( where == 1 && yydataout != stdout )
	vfprintf( yydataout, fmt, args );

    if( where == 2 && yybssout != stdout )
	vfprintf( yybssout, fmt, args );
}

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ANSI( PUBLIC void yycomment( char *fmt, ...  )	)
KnR ( PUBLIC      yycomment(       fmt	     )	)
KnR ( char *fmt;				)
{
    /* Works like printf() except that it automatically prints a newline
     * IN FRONT OF the string and ignores any \n's in the string itself. Writes
     * into the comment window, and outputs a message to the log file if
     * logging is enabled.
     */

    va_list	  args;
    va_start( args, fmt );

    if( Log && !No_comment_pix )
	prnt( (prnt_t) fputc, Log, fmt, args );

    NEWLINE( Comment_window );
    prnt( (prnt_t) prnt_putc, Comment_window, fmt, args );
    refresh_win( Comment_window );
}

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

ANSI( PUBLIC void yyerror( char *fmt, ...  )	)
KnR ( PUBLIC      yyerror(       fmt	   )	)
KnR ( char *fmt;				)
{
    /* Debugging version of the error routine. Works just like the nondebugging
     * version, but writes to the comment window. Note that yycomment() copies
     * the error message to the Log file. Interactive mode is temporarily
     * enabled to assure that error messages get printed.
     */

    int	     old_interactive;
    va_list  args;
    va_start( args, fmt );

    old_interactive = Interactive;
    Interactive     = 1;

    yycomment( "ERROR, line %d near <%s>\n", yylineno, yytext );

    if( Log )
	prnt( (prnt_t) fputc, Log, fmt, args );

    NEWLINE	( Comment_window );
    prnt	( (prnt_t) prnt_putc, Comment_window, fmt, args );
    refresh_win	( Comment_window );

    Interactive = old_interactive;
    Singlestep  = 1;			/* Force a breakpoint */
    yy_pstack( 0, 1 );
}

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

ANSI( PUBLIC void yy_input( char *fmt, ...  )	)
KnR ( PUBLIC      yy_input(       fmt	     )	)
KnR ( char *fmt;				)
{
    /* This is not an input function; rather, it writes to the INPUT window.
     * It works like printf(). Note that nothing is logged here. The logging
     * is done in nextoken(). Ignores all \n's in the input string.
     */

    va_list	  args;
    va_start( args, fmt );
    prnt( (prnt_t) prnt_putc, Prompt_window, fmt, args );
    refresh_win( Prompt_window );
}

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

PRIVATE	void display_file( name, buf_size, print_lines )
char	*name;			   /* Initially holds the file name, but */
int     buf_size;		   /*       recycled as an input buffer. */
int	print_lines;
{
    /* Display an arbitrary file in the stack window, one page at a time.
     * The stack window is not refreshed by this routine.
     */

    FILE  *fd;
    int	  i;
    int	  lineno = 0;

    if( !(fd = fopen( name, "r")) )
    {
	NEWLINE  ( Prompt_window 			);
	wprintw  ( Prompt_window, "Can't open %s",  name );
	wrefresh ( Prompt_window 			);
	presskey ();
    }
    else		    /* Note that order of evaluation is important in  */
    {			    /* the following while statement. You don't want  */
			    /* to get the line if i goes past 0.	      */

	for( i = Stacksize-1 ;; i = (*name == ' ') ? 1 : Stacksize - 2 )
	{
	    while(  --i >= 0  &&  fgets(name, buf_size, fd) )
	    {
		if( print_lines )
		    wprintw( Stack_window, "%3d:", ++lineno );

		wprintw ( Stack_window, "%s", name );
		wrefresh( Stack_window );
	    }

	    if( i > 0 )
		break;

	    if(!yyprompt("ESC quits. Space scrolls 1 line. Enter for screenful",
								    name, 0) )
		break;
	}
	yyprompt("*** End of file. Press any key to continue ***", name, 0 );
	fclose( fd );
    }
}

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

PRIVATE	void write_screen( filename )
char	*filename;
{
    /* Print the current screen contents to the indicated file. Note that the
     * right edge of the box isn't printed in order to let us have 79-character
     * lines. Otherwise, the saved screen shows up as double-spaced on most
     * printers. The screen image is appended to the end of the file. In MS-DOS,
     * Use "prn:" as the file name if you want to go to the printer.
     *
     * Syserrlist and errno are both defined in <stdlib.h>
     */

    char	buf[2];
    char	*mode = "a";
    int		row, col, y, x;
    FILE	*file;

    if( access( filename, 0 ) == 0 )
	if( !yyprompt("File exists, overwrite or append? (o/a): ", buf, 0) )
	{
	    NEWLINE ( Prompt_window 	  );
	    yy_input( "Aborting command." );
	    presskey();
	    return;
	}
	else
	{
	    if( toupper(*buf) == 'O' )
		mode = "w";
	}

    if( file = fopen( filename, mode) )
	yy_input("...%s %s...",
		    *mode=='w' ? "overwriting" : "appending to", filename );
    else
    {
	yy_input( "Can't open %s.", filename );
  	MSC( yy_input( "(%s)", sys_errlist[errno]);	)
	presskey();
	return;
    }

    getyx( Prompt_window, y, x );

    for( row = 0; row < SCRNSIZE; row++ )
    {
	for( col = 0; col < PRINTWIDTH; col++ )
	{
	    MS  ( fputc( conv( mvinch(row,col) ), file );	)
	    UNIX( fputc(       mvinch(row,col)  , file );	)
	}

	fputc( '\n', file );
    }

    fclose( file );
    wmove( Prompt_window, y, x );
}
PUBLIC	void yy_pstack( do_refresh, print_it )

int	do_refresh;		/* redraw entire window rather than update  */
int	print_it;		/* if true, print the stack to the log file */
{
    /* Print the state, debug, and value stacks.
     *
     * The library routine yypstk() (which returns an empty string by default)
     * is called to print value stack items. It should return a pointer to a
     * string that represents the value-stack contents. Just provide a similarly
     * named routine to print your real value stack. The LLAMA parser passes
     * garbage to yypstk(), so use the default routine in LLAMA. The OCCS parser
     * passes yypstk() a pointer to a value-stack item and it should return a
     * pointer to a string representing attributes of interest. The line should
     * not contain any newlines and it should be at most 58 characters long.
     * If do_refresh is true, the entire stack window is redrawn, otherwise
     * only those parts of the window that have been changed are modified.
     */

    int 	  numele            ;   /* # of elements on the stack	     */
    int	          *toss 	    ;   /* top of state stack	    	     */
    char	  **tods	    ;   /* top of debug stack		     */
    char	  *tovs	    	    ;   /* top of value stack		     */
    int  	  *state  	    ;   /* current state-stack pointer	     */
    char 	  **debug  	    ;   /* current debug-stack pointer	     */
    char	  *value	    ;   /* current value-stack pointer	     */
    int		  width		    ;   /* Width of column in horiz. stack   */
    static int	  times_called = -1 ;   /* # of times this subroutine called */
    char	  *p		    ;
    int		  i		    ;

    state  = *P_sp;
    debug  = *P_dsp;
    numele = Depth - (state - Sstack);
    value  = (Vstack + (Depth - numele) * Vsize);

    if( Log && !No_stack_pix && print_it )
    {
	/* Print the stack contents out to the log file.  */

	if( !Horiz_stack_pix )
	{
	    fprintf(Log, "   +---+------------------+\n");
	    if( numele <= 0 )
		fprintf( Log," * | * |   ************   |   Stack is empty.\n");
	    else
	    {
		toss = state;
		tods = debug;
		tovs = value;
		for(i = numele; --i >= 0; ++toss, ++tods, tovs += Vsize )
		    fprintf( Log, "%3d|%3d| %16.16s | %1.52s\n",
			       toss - state, *toss, *tods, yypstk(tovs, *tods));
	    }

⌨️ 快捷键说明

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