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

📄 main.c

📁 its about compiler for LL1 and LR
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -