📄 yydebug.c
字号:
wprintw (Stack_window, "a (a)bort parse by reading EOI \n");
wprintw (Stack_window, "b modify or examine (b)reakpoint \n");
wprintw (Stack_window, "d set (d)elay time for go mode \n");
wprintw (Stack_window, "f read (f)ile \n");
wprintw (Stack_window, "g (g)o (any key stops parse) \n");
wprintw (Stack_window, "i change (i)nput file \n");
wmove (Stack_window, 0, 39 );
wprintw (Stack_window, "l (l)og output to file");
wmove (Stack_window, 1, 39 );
wprintw (Stack_window, "n (n)oninteractive mode");
wmove (Stack_window, 2, 39 );
wprintw (Stack_window, "q (q)uit (exit to dos)");
wmove (Stack_window, 3, 39 );
wprintw (Stack_window, "r (r)efresh stack window");
wmove (Stack_window, 4, 39 );
wprintw (Stack_window, "w (w)rite screen to file or device\n");
wmove (Stack_window, 5, 39 );
wprintw (Stack_window, "x Show current and prev. le(X)eme\n");
wmove (Stack_window, 7, (78-29)/2 );
wprintw (Stack_window, "Space or Enter to single step" );
wrefresh (Stack_window );
}
PUBLIC int yy_nextoken()
{
/* Input a token from yylex() and echo to both the token and comment
* windows. Yy_comment() writes to the log file too. Break if the input
* breakpoint is set and the required token has just been read. The token
* name is centered in the token window if it's short enough. It's
* truncated at TOKEN_WIDTH characters otherwise.
*/
static int tok = -1; /* current token */
char *str;
char *lexeme;
char buf[ TOKEN_WIDTH ];
extern char *Yy_stok[]; /* Generated by occs and llama */
extern int yylex P(( void ));
if( tok >= 0 && (Interactive || Log) )
yycomment( "Advance past %s\n", Yy_stok[tok] );
lexeme = ((tok = Abort ? 0 : yylex()) == 0) ? "" : yytext;
if( Interactive || Log )
yycomment( "Read %s <%s>\n", str = Yy_stok[tok], lexeme );
if( Interactive )
{
/* clear, then update, the token window */
concat( TOKEN_WIDTH, buf, str, " ", lexeme, NULL );
scrollok( Token_window, TRUE );
NEWLINE ( Token_window );
scrollok( Token_window, FALSE );
wprintw ( Token_window, "%0.*s", TOKEN_WIDTH - 2, buf );
wrefresh( Token_window );
if( L_breakpoint != -1 && L_breakpoint <= yylineno )
{
L_breakpoint = -1;
Singlestep = 1;
yy_pstack( 0, 1 );
}
else if( ( *I_breakpoint &&
( ( isdigit(*I_breakpoint) && tok == atoi(I_breakpoint) )
|| !strcmp( lexeme, I_breakpoint)
|| !strcmp( Yy_stok[tok], I_breakpoint)
)
)
)
{
Singlestep = 1;
yy_pstack( 0, 1 );
}
}
delay();
return tok;
}
/*----------------------------------------------------------------------*/
PUBLIC void yy_break( production_number )
int production_number;
{
/* Handles production-number breakpoints. If a break is required, start
* single stepping and print the stack. Stack breakpoints are handled in
* yy_pstack and input breakpoints are done in yy_nextoken().
*
* If production_number == -1, a break is forced regardless of the value
* of P_breakpoint;
*/
if( production_number == P_breakpoint || production_number == -1 )
{
Singlestep = 1;
yy_pstack( 0, 1 );
}
}
/*----------------------------------------------------------------------*/
PRIVATE int breakpoint()
{
/* Set up a breakpoint by prompting the user for any required information.
* Return true if we have to redraw the stack window because a help screen
* was printed there.
*/
int type;
char **p;
char buf[80];
int rval = 0;
static char *text[] =
{
"Select a breakpoint type (i,l,p,or s) or command (c or l):",
"Type: Description: Enter breakpoint as follows:",
" i input.....................number for token value",
" or string for lexeme or token name",
" l input line read...........line number",
" p reduce by production......number for production number",
" s top-of-stack symbol.......number for state-stack item",
" or string for symbol-stack item",
" c = clear all breakpoints",
" d = display (list) all breakpoints",
NULL
};
if( !yyprompt("Enter type or command, ? for help, ESC aborts: ", buf,0) )
return 1;
if( *buf == '?' )
{
rval = 1;
werase (Stack_window);
wmove (Stack_window, 0, 0);
for( p = text; *p; p )
wprintw(Stack_window, "%s\n", *p++ );
wrefresh (Stack_window);
if( !yyprompt("Enter breakpoint type or command, ESC aborts: ", buf,0))
return rval;
}
if( (type = *buf) == 'p' )
{
if( yyprompt("Production number or ESC to cancel: ", buf, 1 ))
{
if( !isdigit( *buf ))
yyprompt("Must be a number, press any key to continue.", buf,0);
else
P_breakpoint = atoi( buf );
}
}
else if( type == 'l' )
{
if( yyprompt("Input line number or ESC to cancel: ", buf, 1 ))
L_breakpoint = atoi( buf );
}
else if( type == 'i' || type == 's' )
{
if( yyprompt("Symbol value or ESC to cancel: ", buf, 1 ))
strncpy( type == 'i' ? I_breakpoint : S_breakpoint, buf, BRKLEN );
}
else
{
switch( type )
{
case 'c':
P_breakpoint = -1;
L_breakpoint = -1;
*S_breakpoint = 0;
*I_breakpoint = 0;
break;
case 'd':
rval = 1;
werase (Stack_window);
wmove (Stack_window, 0, 0);
wprintw(Stack_window,
P_breakpoint == -1 ? "Production = none\n"
: "Production = %d\n", P_breakpoint);
wprintw(Stack_window, "Stack = %s\n",
*S_breakpoint ? S_breakpoint : "none" );
wprintw(Stack_window, "Input = %s\n",
*I_breakpoint ? I_breakpoint : "none" );
wprintw(Stack_window,
I_breakpoint == 0 ? "Input line = none\n"
: "Input line = %d\n", I_breakpoint);
wrefresh(Stack_window);
NEWLINE (Prompt_window);
presskey();
break;
default:
yyprompt("Illegal command or type, Press any key.", buf, 0);
break;
}
}
return rval;
}
PRIVATE int new_input_file( buf )
char *buf;
{
/* Open up a new input file. Input must come from a file because the
* keyboard is used to get commands. In theory, you can use both standard
* input and the keyboard (by opening the console as another stream), but I
* had difficulties doing this in a portable way, and eventually gave up.
* It's not that big a deal to require that test input be in a file.
*/
NEWLINE( Prompt_window );
wrefresh( Prompt_window );
if( ii_newfile( buf ) != -1 )
Inp_fm_file = 1;
else
{
wprintw(Prompt_window, "Can't open %s.", buf );
presskey();
}
return Inp_fm_file;
}
/*----------------------------------------------------------------------*/
PRIVATE FILE *to_log( buf )
char *buf;
{
/* Set up everything to log output to a file (open the log file, etc.). */
if( !yyprompt("Log-file name (CR for \"log\", ESC cancels): ", buf,1) )
return NULL;
if( !*buf )
strcpy( buf, "log" );
if( !(Log = fopen( buf, "w")) )
{
NEWLINE(Prompt_window );
wprintw(Prompt_window, "Can't open %s", buf );
presskey();
return NULL;
}
if( !yyprompt("Log comment-window output? (y/n, CR=y): ", buf,0) )
return NULL;
else
No_comment_pix = (*buf == 'n');
if( !yyprompt( "Print stack pictures in log file? (y/n, CR=y): ",buf,0) )
return NULL;
if( !(No_stack_pix = (*buf == 'n')) )
{
if( !yyprompt( "Print stacks horizontally? (y/n, CR=y): ",buf,0) )
return NULL;
if( Horiz_stack_pix = (*buf != 'n') )
{
if( !yyprompt("Print SYMBOL stack (y/n, CR=y): ",buf,0) )
return NULL;
Sym_pix = (*buf != 'n');
if( !yyprompt("Print PARSE stack (y/n, CR=y): ",buf,0) )
return NULL;
Parse_pix = (*buf != 'n');
if( !yyprompt("Print VALUE stack (y/n, CR=y): ",buf,0) )
return NULL;
Attr_pix = (*buf != 'n');
}
}
return Log;
}
/*----------------------------------------------------------------------*/
PRIVATE int input_char( ANSI(void) ) /* void argument illegal under UNIX */
{
/* Get a character from the input window and echo it explicitly. If we've
* compiled under Unix, reset the character-available flag.
*/
int c;
if( (c = wgetch(Prompt_window) & 0x7f) != ESC )
waddch( Prompt_window, c );
UNIX( Char_avail = 0; )
return c;
}
/*----------------------------------------------------------------------*/
PUBLIC int yyprompt( prompt, buf, getstring )
char *prompt, *buf;
int getstring; /* get entire string (as compared to a single character */
{
/* Print a prompt and then wait for a reply, load the typed characters into
* buf. ^H (destructive backspace) is supported. An ESC causes yyprompt()
* to return 0 immediately, otherwise 1 is returned. The ESC is not put
* into the buffer. If "getstring" is true, an entire string is fetched and
* prompt returns when the newline is typed. If "getstring" is false, then
* one character is fetched and yyprompt() returns immediately after getting
* that character. Leading and trailing white space is stripped from the
* line if getstring is true. (You can get a single space character if it's
* false, however.)
*/
register int c;
int y, x;
char *startbuf = buf;
NEWLINE ( Prompt_window );
wprintw ( Prompt_window, "%s", prompt );
wrefresh( Prompt_window );
if( !getstring )
c = *buf++ = input_char();
else
{
while( (c = input_char()) != '\n' && c != ESC )
{
if( isspace(c) && buf==startbuf )
continue; /* skip leading white space */
if( c != '\b' )
*buf++ = c;
else /* handle destructive backspace */
{
getyx( Prompt_window, y, x );
if( buf <= startbuf )
wmove ( Prompt_window, y, x+1 );
else
{
waddch( Prompt_window, ' ' );
wmove ( Prompt_window, y, x );
--buf;
}
}
wrefresh( Prompt_window );
}
while( isspace( buf[-1] ) && buf > startbuf )
--buf; /* Strip trailing white space */
}
*buf = 0;
return (c != ESC);
}
/*----------------------------------------------------------------------*/
PRIVATE void presskey()
{
/* Ask for a key to be pressed and wait for it. Note that this command
* does a refresh, but it intentionally does not clear the window before
* printing the prompt.
*/
wprintw ( Prompt_window, " Press any key: " );
wrefresh( Prompt_window );
input_char();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -