📄 main.c
字号:
yyparse (); /* Parse the entire input file */
if( !( yynerrs || problems()) ) /* If no problems in the input file */
{
VERBOSE( "analyzing grammar" );
first (); /* Find FIRST sets, */
LL( follow(); ) /* FOLLOW sets, */
LL( select(); ) /* and ll(1) select sets if this is llama */
code_header(); /* Print various #defines to output file */
OX( patch(); ) /* Patch up the grammar (if this is occs) */
/* and output the actions. */
ftime( &start_time );
if( Make_parser )
{
VERBOSE( "making tables" );
tables (); /* generate the tables, */
}
ftime ( &end_time );
VERBOSE( "copying driver" );
driver(); /* the parser, */
if( Make_actions )
tail(); /* and the tail end of the source file. */
}
if( Verbose )
{
time = ( end_time.time * 1000) + end_time.millitm ;
time -= (start_time.time * 1000) + start_time.millitm ;
printf( "time required to make tables: %ld.%-03ld seconds\n",
(time/1000), (time%1000));
}
return yynerrs;
}
PRIVATE void symbols( ) /* Print the symbol table */
{
FILE *fd;
if( !(fd = fopen( SYM_FILE, "w")) )
perror( SYM_FILE );
else
{
print_symbols ( fd );
fclose ( fd );
}
}
/*----------------------------------------------------------------------*/
PRIVATE void statistics( fp )
FILE *fp;
{
/* Print various statistics
*/
int conflicts; /* Number of parse-table conflicts */
if( Verbose )
{
fprintf (fp, "\n");
fprintf (fp, "%4d/%-4d terminals\n", USED_TERMS, NUMTERMS );
fprintf (fp, "%4d/%-4d nonterminals\n", USED_NONTERMS, NUMNONTERMS);
fprintf (fp, "%4d/%-4d productions\n", Num_productions, MAXPROD );
LL( fprintf (fp, "%4d actions\n", (Cur_act - MINACT) +1 );)
OX( lr_stats(fp ); )
}
LL( conflicts = 0; )
OX( conflicts = lr_conflicts(fp); )
if( fp == stdout )
fp = stderr;
if( Num_warnings - conflicts > 0 )
fprintf(fp, "%4d warnings\n", Num_warnings - conflicts);
if(yynerrs)
fprintf(fp, "%4d hard errors\n", yynerrs );
}
/*----------------------------------------------------------------------*/
ANSI( PUBLIC void output( char *fmt, ... ) )
KnR ( PUBLIC void output( fmt ) )
KnR ( char *fmt; )
{
/* Works like printf(), but writes to the output file. See also: the
* outc() macro in parser.h
*/
va_list args;
va_start( args, fmt );
vfprintf( Output, fmt, args );
}
/*----------------------------------------------------------------------*/
ANSI( PUBLIC void document( char *fmt, ... ) )
KnR ( PUBLIC void document( fmt ) )
KnR ( char *fmt; )
{
/* Works like printf() but writes to yyout.doc (provided that the file
* is being created.
*/
va_list args;
if( Doc_file )
{
va_start( args, fmt );
vfprintf( Doc_file, fmt, args );
}
}
ANSI( void document_to( FILE *fp ) )
KnR ( void document_to( fp ) )
KnR ( FILE *fp; )
{
/* Change document-file output to the indicated stream, or to previous
* stream if fp=NULL.
*/
static FILE *oldfp;
if( fp )
{
oldfp = Doc_file;
Doc_file = fp;
}
else
Doc_file = oldfp;
}
/*----------------------------------------------------------------------*/
ANSI( PUBLIC void lerror(int fatal, char *fmt, ... ) )
KnR ( PUBLIC void lerror( fatal, fmt ) )
KnR ( int fatal; )
KnR ( char *fmt; )
{
/* This error-processing routine automatically generates a line number for
* the error. If "fatal" is true, exit() is called.
*/
va_list args;
extern int yylineno;
if( fatal == WARNING )
{
++Num_warnings;
if( No_warnings )
return;
fprintf( stdout, "%s WARNING (%s, line %d): ", PROG_NAME,
Input_file_name, yylineno );
}
else if( fatal != NOHDR )
{
++yynerrs;
fprintf( stdout, "%s ERROR (%s, line %d): ", PROG_NAME,
Input_file_name, yylineno );
}
va_start( args, fmt);
vfprintf( stdout, fmt, args );
fflush ( stdout );
# ifndef LLAMA
if( Verbose && Doc_file )
{
if( fatal != NOHDR )
fprintf ( Doc_file, "%s (line %d) ",
fatal==WARNING ? "WARNING" : "ERROR", yylineno);
vfprintf( Doc_file, fmt, args );
}
# endif
if( fatal == FATAL )
exit( EXIT_OTHER );
}
ANSI( PUBLIC void error(int fatal, char *fmt, ... ) )
KnR ( PUBLIC void error( fatal, fmt ) )
KnR ( int fatal; )
KnR ( char *fmt; )
{
/* This error routine works like lerror() except that no line number is
* generated. The global error count is still modified, however.
*/
va_list args;
char *type;
if( fatal == WARNING )
{
++Num_warnings;
if( No_warnings )
return;
type = "WARNING: ";
}
else if( fatal != NOHDR ) /* if NOHDER is true, just act */
{ /* like printf(). */
++yynerrs;
type = "ERROR: ";
fprintf( stdout, type );
}
va_start ( args, fmt );
vfprintf ( stdout, fmt, args );
fflush ( stdout );
OX( if( Verbose && Doc_file ) )
OX( { )
OX( fprintf ( Doc_file, type ); )
OX( vfprintf ( Doc_file, fmt, args ); )
OX( } )
if( fatal == FATAL )
exit( EXIT_OTHER );
}
PUBLIC char *open_errmsg()
{
/* Return an error message that makes sense for a bad open */
switch( errno ) /* defined in stdlib.h */
{
case EACCES: return "File is read only or a directory";
case EEXIST: return "File already exists";
case EMFILE: return "Too many open files";
case ENOENT: return "File not found";
default: return "Reason unknown";
}
}
/*----------------------------------------------------------------------*/
PRIVATE void tail()
{
/* Copy the remainder of input file to standard output. Yyparse will have
* terminated with the input pointer just past the %%. Attribute mapping
* ($$ to Yyval, $N to a stack reference, etc.) is done by the do_dollar()
* call.
*
* On entry, the parser will have read one token too far, so the first
* thing to do is print the current line number and lexeme.
*/
extern int yylineno ; /* LeX generated */
extern char *yytext ; /* LeX generated */
int c, i, sign;
char fname[80], *p; /* field name in $<...>n */
output( "%s", yytext); /* Output newline following %% */
if( !No_lines )
output( "\n#line %d \"%s\"\n", yylineno, Input_file_name );
ii_unterm(); /* Lex will have terminated yytext */
while( (c = ii_advance()) != 0 )
{
if( c == -1 )
{
ii_flush(1);
continue;
}
else if( c == '$' )
{
ii_mark_start();
if( (c = ii_advance()) != '<' )
*fname = '\0';
else /* extract name in $<foo>1 */
{
p = fname;
for(i=sizeof(fname); --i > 0 && (c=ii_advance()) != '>';)
*p++ = c;
*p++ = '\0';
if( c == '>' ) /* truncate name if necessary */
c = ii_advance();
}
if( c == '$' )
output( do_dollar( DOLLAR_DOLLAR, -1, 0, NULL, fname ) );
else
{
if( c != '-' )
sign = 1 ;
else
{
sign = -1;
c = ii_advance();
}
for( i = 0; isdigit(c); c = ii_advance() )
i = (i * 10) + (c - '0');
ii_pushback(1);
output( do_dollar(i * sign, -1, ii_lineno(), NULL, fname ) );
}
}
else if( c != '\r' )
outc( c );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -