?? main.c
字號:
/*@A (C) 1992 Allen I. Holub */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <signal.h>
#include <malloc.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <process.h>
#include <tools/debug.h>
#include <tools/set.h>
#include <tools/hash.h>
#include <tools/compiler.h>
#include <tools/l.h>
#ifdef LLAMA
# define ALLOCATE
# include "parser.h"
# undef ALLOCATE
#else
# define ALLOCATE
# include "parser.h"
# undef ALLOCATE
#endif
#if (0 MSC(+1) )
#pragma comment(exestr, "(C)" __DATE__ "Allen Holub. All rights reserved.")
#endif
PRIVATE int Warn_exit = 0; /* Set to 1 if -W on command line */
PRIVATE int Num_warnings = 0; /* Total warnings printed */
PRIVATE char *Output_fname = "????"; /* Name of the output file */
PRIVATE FILE *Doc_file = NULL; /* Error log & machine description */
#ifdef MAP_MALLOC
PRIVATE int Malloc_chk = 1; /* Run-time malloc() checking */
PRIVATE int Malloc_verbose = 0; /* " use verbose diagnostics */
#endif
#define VERBOSE(str) if(Verbose){ printf( "%s:\n", (str)); }else
/*----------------------------------------------------------------------*/
void onintr P(( void )); /* local */
void parse_args P(( int argc, char **argv ));
int do_file P(( void ));
void symbols P(( void ));
void statistics P(( FILE *fp ));
void tail P(( void ));
void output P(( char *fmt, ... )); /* public */
void lerror P(( int fatal, char *fmt, ... ));
void error P(( int fatal, char *fmt, ... ));
char *open_errmsg P(( void ));
char *do_dollar P(( int num, int rhs_size, int lineno, PRODUCTION *prod, \
char *fname));
/*----------------------------------------------------------------------
* There are two versions of the following subroutines--used in do_file(),
* depending on whether this is llama or occs.
*
* subroutine: llama version in: occs version in:
*
* file_header() lldriver.c yydriver.c
* code_header() lldriver.c yydriver.c
* driver() lldriver.c yydriver.c
* tables() llcode.c yycode.c
* patch() ----- yypatch.c
* select() llselect.c ------
* do_dollar() lldollar.c yydollar.c
*
* Also, several part of this file are compiled only for llama, others only for
* occs. The llama-specific parts are arguments to LL() macros, the occs-
* specific parts are in OX() macros. We'll look at what the occs-specific
* parts actually do in the next Chapter.
*----------------------------------------------------------------------
*/
PUBLIC void main( argc, argv )
char **argv;
{
MSC( _amblksiz = 2048; ) /* Declared in Microsoft C's malloc.h. */
/* Controls size of malloc() allocation unit. */
signon(); /* Print sign on message */
signal( SIGINT, /* Close output files on Ctrl-Break. */
MSC((void(*)(int))) onintr );
parse_args( argc, argv );
# ifdef MAP_MALLOC
malloc_checking( Malloc_chk, Malloc_verbose );
# endif
if( Debug && !Symbols )
Symbols = 1;
OX( if( Make_parser ) )
OX( { )
OX( if( Verbose == 1 ) )
OX( { )
OX( if( !(Doc_file = fopen( DOC_FILE, "w") ) ) )
OX( ferr( "Can't open log file %s\n", DOC_FILE ); )
OX( } )
OX( else if( Verbose > 1 ) )
OX( Doc_file = stderr; )
OX( } )
if( Use_stdout )
{
Output_fname = "/dev/tty" ;
Output = stdout;
}
else
{
OX( Output_fname = !Make_parser ? ACT_FILE : PARSE_FILE ; )
LL( Output_fname = PARSE_FILE; )
if( (Output = fopen( Output_fname, "w")) == NULL )
error( FATAL, "Can't open output file %s: %s\n",
Output_fname, open_errmsg() );
}
if( (yynerrs = do_file()) == 0) /* Do all the work */
{
if( Symbols )
symbols(); /* Print the symbol table */
statistics( stdout ); /* And any closing-up statistics. */
if( Verbose && Doc_file )
{
OX( statistics( Doc_file ); )
#ifdef MAP_MALLOC
printf("\n%lu bytes (%luK) memory used by malloc\n",
memory_used(), memory_used()/1024L );
#endif
}
}
else
{
if( Output != stdout )
{
fclose( Output );
if( unlink( Output_fname ) == -1 )
perror( Output_fname );
}
}
/* Exit with the number of hard errors (or, if -W was specified, the sum
* of the hard errors and warnings) as an exit status. Doc_file and Output
* are closed implicitly by exit().
*/
exit( yynerrs + (Warn_exit ? Num_warnings : 0) );
}
/*----------------------------------------------------------------------*/
PRIVATE void onintr() /* SIGABRT (Ctrl-Break, ^C) Handler */
{
if( Output != stdout ) /* Destroy parse file so that a */
{ /* subsequent compile will fail */
fclose( Output );
unlink( Output_fname );
}
exit( EXIT_USR_ABRT );
}
/*----------------------------------------------------------------------*/
PRIVATE void parse_args( argc, argv )
int argc;
char **argv;
{
/* Parse the command line, setting global variables as appropriate */
char *p;
static char name_buf[80]; /* Use to assemble default file names */
static char *usage_msg[] =
{
#ifdef LLAMA
"Usage is: llama [-switch] file",
"Create an LL(1) parser from the specification in the",
"input file. Legal command-line switches are:",
"",
"-cN use N as the pairs threshold when (C)ompressing",
"-D enable (D)ebug mode in yyparse.c (implies -s)",
"-f (F)ast, uncompressed, tables",
#else
"Usage is: occs [-switch] file",
"",
"\tCreate an LALR(1) parser from the specification in the",
"\tinput file. Legal command-line switches are:",
"",
"-a Output actions only (see -p)",
"-D enable (D)ebug mode in yyparse.c (implies -s)",
#endif
"-g make static symbols (G)lobal in yyparse.c",
"-l suppress #(L)ine directives",
"-m<file> use <file> for parser te(M)plate",
"-p output parser only (can be used with -T also)",
"-s make (s)ymbol table",
"-S make more-complete (S)ymbol table",
"-t print all (T)ables (and the parser) to standard output",
"-T move large tables from yyout.c to yyoutab.c",
"-v print (V)erbose diagnostics (including symbol table)",
"-V more verbose than -v. Implies -t, & yyout.doc goes to stderr",
"-w suppress all warning messages",
"-W warnings (as well as errors) generate nonzero exit status",
#ifdef MAP_MALLOC
"-M Disable malloc checking at run time\n",
#endif
NULL
};
/* Note that all global variables set by command-line switches are declared
* in parser.h. Space is allocated because a #define ALLOC is present at
* the top of the current file.
*/
for( ++argv,--argc; argc && *(p = *argv) == '-'; ++argv, --argc )
{
while( *++p )
{
switch( *p )
{
OX( case 'a': Make_parser = 0; )
OX( Template = ACT_TEMPL; )
OX( break; )
case 'D': Debug = 1; break;
case 'g': Public = 1; break;
LL( case 'f': Uncompressed = 1; break; )
case 'l': No_lines = 1; break;
case 'm': Template = p + 1; goto out;
#ifdef MAP_MALLOC
case 'M': Malloc_chk = 0; break;
#endif
OX( case 'p': Make_actions = 0; break; )
case 's': Symbols = 1; break;
case 'S': Symbols = 2; break;
case 't': Use_stdout = 1; break;
case 'T': Make_yyoutab = 1; break;
case 'v': Verbose = 1; break;
case 'V': Verbose = 2; break;
case 'w': No_warnings = 1; break;
case 'W': Warn_exit = 1; break;
LL( case 'c': Threshold = atoi( ++p ); )
LL( while( *p && isdigit( p[1] ) ) )
LL( ++p; )
LL( break; )
default :
fprintf(stderr, "<-%c>: illegal argument\n", *p);
printv (stderr, usage_msg );
exit( EXIT_ILLEGAL_ARG );
}
}
out: ;
}
if( Verbose > 1 )
Use_stdout = 1;
if( argc <= 0 ) /* Input from standard input */
No_lines = 1;
else if( argc > 1 )
{
fprintf( stderr, "Too many arguments.\n" );
printv ( stderr, usage_msg );
exit ( EXIT_TOO_MANY );
}
else /* argc == 1, input from file */
{
if( ii_newfile( Input_file_name = *argv ) < 0 )
{
sprintf( name_buf, "%0.70s.%s", *argv, DEF_EXT );
if( ii_newfile( Input_file_name = name_buf ) < 0 )
error( FATAL, "Can't open input file %s or %s: %s\n",
*argv, name_buf, open_errmsg());
}
}
}
/*----------------------------------------------------------------------*/
PRIVATE int do_file()
{
/* Process the input file. Return the number of errors. */
struct timeb start_time, end_time ;
long time;
void nows P((void)); /* declared in parser.lex */
ftime( &start_time ); /* Initialize times now so that the difference */
end_time = start_time; /* between times will be 0 if we don't build the */
/* tables. Note that I'm using structure assign- */
/* ment here. */
init_acts (); /* Initialize the action code. */
file_header(); /* Output #defines that you might want to change */
VERBOSE( "parsing" );
nows (); /* Make lex ignore white space until ws() is called */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -