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

📄 gen.c

📁 生成C++的词法/语法分析的Flex语法分析器
💻 C
📖 第 1 页 / 共 2 页
字号:
    else if ( fulltbl )	{	do_indent();	printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n",		NUL_ec );	indent_puts( "yy_is_jam = (yy_current_state <= 0);" );	}    else if ( fullspd )	{	do_indent();	printf( "register int yy_c = %d;\n", NUL_ec );	indent_puts(	    "register const struct yy_trans_info *yy_trans_info;\n" );	indent_puts( "yy_trans_info = &yy_current_state[yy_c];" );	indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );	indent_puts( "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" );	}    else	{	char NUL_ec_str[20];	(void) sprintf( NUL_ec_str, "%d", NUL_ec );	gen_next_compressed_state( NUL_ec_str );	if ( reject )	    indent_puts( "*yy_state_ptr++ = yy_current_state;" );	do_indent(); 	printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate );	}    /* if we've entered an accepting state, backtrack; note that     * compressed tables have *already* done such backtracking, so     * we needn't bother with it again     */    if ( need_backtracking && (fullspd || fulltbl) )	{	putchar( '\n' );	indent_puts( "if ( ! yy_is_jam )" );	indent_up();	indent_puts( "{" );	gen_backtracking();	indent_puts( "}" );	indent_down();	}    }/* generate the code to find the start state */void gen_start_state()    {    if ( fullspd )	indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];",		bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" );    else	{	indent_puts( "yy_current_state = yy_start;" );	if ( bol_needed )	    {	    indent_puts( "if ( yy_bp[-1] == '\\n' )" );	    indent_up();	    indent_puts( "++yy_current_state;" );	    indent_down();	    }	if ( reject )	    {	    /* set up for storing up states */	    indent_puts( "yy_state_ptr = yy_state_buf;" );	    indent_puts( "*yy_state_ptr++ = yy_current_state;" );	    }	}    }/* gentabs - generate data statements for the transition tables * * synopsis *    gentabs(); */void gentabs()    {    int i, j, k, *accset, nacc, *acc_array, total_states;    int end_of_buffer_action = num_rules + 1;    /* *everything* is done in terms of arrays starting at 1, so provide     * a null entry for the zero element of all C arrays     */    static char C_char_decl[] =	"static const YY_CHAR %s[%d] =\n    {   0,\n";    acc_array = allocate_integer_array( current_max_dfas );    nummt = 0;    /* the compressed table format jams by entering the "jam state",     * losing information about the previous state in the process.     * In order to recover the previous state, we effectively need     * to keep backtracking information.     */    ++num_backtracking;    if ( reject )	{	/* write out accepting list and pointer list	 *	 * first we generate the "yy_acclist" array.  In the process, we compute	 * the indices that will go into the "yy_accept" array, and save the	 * indices in the dfaacc array	 */	int EOB_accepting_list[2];	/* set up accepting structures for the End Of Buffer state */	EOB_accepting_list[0] = 0;	EOB_accepting_list[1] = end_of_buffer_action;	accsiz[end_of_buffer_state] = 1;	dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;	printf( C_short_decl, "yy_acclist", max( numas, 1 ) + 1 );	j = 1;	/* index into "yy_acclist" array */	for ( i = 1; i <= lastdfa; ++i )	    {	    acc_array[i] = j;	    if ( accsiz[i] != 0 )		{		accset = dfaacc[i].dfaacc_set;		nacc = accsiz[i];		if ( trace )		    fprintf( stderr, "state # %d accepts: ", i );		for ( k = 1; k <= nacc; ++k )		    {		    int accnum = accset[k];		    ++j;		    if ( variable_trailing_context_rules &&			 ! (accnum & YY_TRAILING_HEAD_MASK) &&			 accnum > 0 && accnum <= num_rules &&			 rule_type[accnum] == RULE_VARIABLE )			{			/* special hack to flag accepting number as part			 * of trailing context rule			 */			accnum |= YY_TRAILING_MASK;			}		    mkdata( accnum );		    if ( trace )			{			fprintf( stderr, "[%d]", accset[k] );			if ( k < nacc )			    fputs( ", ", stderr );			else			    putc( '\n', stderr );			}		    }		}	    }	/* add accepting number for the "jam" state */	acc_array[i] = j;	dataend();	}    else	{	dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;	for ( i = 1; i <= lastdfa; ++i )	    acc_array[i] = dfaacc[i].dfaacc_state;	/* add accepting number for jam state */	acc_array[i] = 0;	}    /* spit out "yy_accept" array.  If we're doing "reject", it'll be pointers     * into the "yy_acclist" array.  Otherwise it's actual accepting numbers.     * In either case, we just dump the numbers.     */    /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays     * beginning at 0 and for "jam" state     */    k = lastdfa + 2;    if ( reject )	/* we put a "cap" on the table associating lists of accepting	 * numbers with state numbers.  This is needed because we tell	 * where the end of an accepting list is by looking at where	 * the list for the next state starts.	 */	++k;    printf( C_short_decl, "yy_accept", k );    for ( i = 1; i <= lastdfa; ++i )	{	mkdata( acc_array[i] );	if ( ! reject && trace && acc_array[i] )	    fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] );	}    /* add entry for "jam" state */    mkdata( acc_array[i] );    if ( reject )	/* add "cap" for the list */	mkdata( acc_array[i] );    dataend();    if ( useecs )	genecs();    if ( usemecs )	{	/* write out meta-equivalence classes (used to index templates with) */	if ( trace )	    fputs( "\n\nMeta-Equivalence Classes:\n", stderr );	printf( C_char_decl, "yy_meta", numecs + 1 );	for ( i = 1; i <= numecs; ++i )	    {	    if ( trace )		fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) );	    mkdata( abs( tecbck[i] ) );	    }	dataend();	}    total_states = lastdfa + numtemps;    printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,	    "yy_base", total_states + 1 );    for ( i = 1; i <= lastdfa; ++i )	{	register int d = def[i];	if ( base[i] == JAMSTATE )	    base[i] = jambase;	if ( d == JAMSTATE )	    def[i] = jamstate;	else if ( d < 0 )	    {	    /* template reference */	    ++tmpuses;	    def[i] = lastdfa - d + 1;	    }	mkdata( base[i] );	}    /* generate jam state's base index */    mkdata( base[i] );    for ( ++i /* skip jam state */; i <= total_states; ++i )	{	mkdata( base[i] );	def[i] = jamstate;	}    dataend();    printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,	    "yy_def", total_states + 1 );    for ( i = 1; i <= total_states; ++i )	mkdata( def[i] );    dataend();    printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,	    "yy_nxt", tblend + 1 );    for ( i = 1; i <= tblend; ++i )	{	if ( nxt[i] == 0 || chk[i] == 0 )	    nxt[i] = jamstate;	/* new state is the JAM state */	mkdata( nxt[i] );	}    dataend();    printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,	    "yy_chk", tblend + 1 );    for ( i = 1; i <= tblend; ++i )	{	if ( chk[i] == 0 )	    ++nummt;	mkdata( chk[i] );	}    dataend();    }/* write out a formatted string (with a secondary string argument) at the * current indentation level, adding a final newline */void indent_put2s( fmt, arg )char fmt[], arg[];    {    do_indent();    printf( fmt, arg );    putchar( '\n' );    }/* write out a string at the current indentation level, adding a final * newline */void indent_puts( str )char str[];    {    do_indent();    puts( str );    }/* make_tables - generate transition tables * * synopsis *     make_tables(); * * Generates transition tables and finishes generating output file */void make_tables()    {    register int i;    int did_eof_rule = false;    skelout();    /* first, take care of YY_DO_BEFORE_ACTION depending on yymore being used */    set_indent( 2 );    if ( yymore_used )	{	indent_puts( "yy___text -= yy_more_len; \\" );	indent_puts( "yy___leng = yy_cp - yy___text; \\" );	}    else	indent_puts( "yy___leng = yy_cp - yy_bp; \\" );    set_indent( 0 );        skelout();    printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );    if ( fullspd )	{ /* need to define the transet type as a size large	   * enough to hold the biggest offset	   */	int total_table_size = tblend + numecs + 1;	char *trans_offset_type =	    total_table_size > MAX_SHORT ? "long" : "short";	set_indent( 0 );	indent_puts( "struct yy_trans_info" );	indent_up();        indent_puts( "{" );        indent_puts( "short yy_verify;" );        /* in cases where its sister yy_verify *is* a "yes, there is a	 * transition", yy_nxt is the offset (in records) to the next state.	 * In most cases where there is no transition, the value of yy_nxt	 * is irrelevant.  If yy_nxt is the -1th  record of a state, though,	 * then yy_nxt is the action number for that state         */        indent_put2s( "%s yy_nxt;", trans_offset_type );        indent_puts( "};" );	indent_down();	indent_puts( "typedef const struct yy_trans_info *yy_state_type;" );	}        else	indent_puts( "typedef int yy_state_type;" );    if ( fullspd )	genctbl();    else if ( fulltbl )	genftbl();    else	gentabs();    if ( num_backtracking > 0 )	{	indent_puts( "static yy_state_type yy_last_accepting_state;" );	indent_puts( "static YY_CHAR *yy_last_accepting_cpos;\n" );	}    if ( nultrans )	{	printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 );	for ( i = 1; i <= lastdfa; ++i )	    {	    if ( fullspd )		{		if ( nultrans )		    printf( "    &yy_transition[%d],\n", base[i] );		else		    printf( "    0,\n" );		}	    	    else		mkdata( nultrans[i] );	    }	dataend();	}	{ /* spit out table mapping rules to line numbers */	printf("#if YY_%s_DEBUG != 0\n",lexer_name);	printf( C_short_decl, "yy_rule_linenum", num_rules );	for ( i = 1; i < num_rules; ++i )	    mkdata( rule_linenum[i] );	dataend();	puts("#endif");	}    if ( reject )	{	/* declare state buffer variables */	puts(	"static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );	puts( "static YY_CHAR *yy_full_match;" );	puts( "static int yy_lp;" );	if ( variable_trailing_context_rules )	    {	    puts( "static int yy_looking_for_trail_begin = 0;" );	    puts( "static int yy_full_lp;" );	    puts( "static int *yy_full_state;" ); 	    printf( "#define YY_TRAILING_MASK 0x%x\n", 		    (unsigned int) YY_TRAILING_MASK );	    printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n", 		    (unsigned int) YY_TRAILING_HEAD_MASK );	    }	puts( "#define REJECT \\" );        puts( "{ \\" );        puts(	"*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );        puts(	    "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );	if ( variable_trailing_context_rules )	    {	    puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );	    puts(		"yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );	    puts(	    "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );	    }        puts( "++yy_lp; \\" );        puts( "goto find_rule; \\" );        puts( "}" );	}        else	{	puts( "/* the intent behind this definition is that it'll catch" );	puts( " * any uses of REJECT which flex missed" );	puts( " */" );	puts( "#define REJECT reject_used_but_not_detected" );	}        if ( yymore_used )	{	indent_puts( "static int yy_more_flag = 0;" );	indent_puts( "static int yy_doing_yy_more = 0;" );	indent_puts( "static int yy_more_len = 0;" );	indent_puts(	    "#define yymore() { yy_more_flag = 1; }" );	indent_puts(	    "#define YY_MORE_ADJ (yy_doing_yy_more ? yy_more_len : 0)" );	}    else	{	indent_puts( "#define yymore() yymore_used_but_not_detected" );	indent_puts( "#define YY_MORE_ADJ 0" );	}    skelout();    if ( ferror( temp_action_file ) )	flexfatal( "error occurred when writing temporary action file" );    else if ( fclose( temp_action_file ) )	flexfatal( "error occurred when closing temporary action file" );    temp_action_file = fopen( action_file_name, "r" );    if ( temp_action_file == NULL )	flexfatal( "could not re-open temporary action file" );    /* copy prolog from action_file to output file */    action_out();    skelout();    set_indent( 2 );    if ( yymore_used )	{	indent_puts( "yy_more_len = 0;" );	indent_puts( "yy_doing_yy_more = yy_more_flag;" );	indent_puts( "if ( yy_doing_yy_more )" );	indent_up();	indent_puts( "{" );	indent_puts( "yy_more_len = yy___leng;" );	indent_puts( "yy_more_flag = 0;" );	indent_puts( "}" );	indent_down();	}    skelout();    gen_start_state();    /* note, don't use any indentation */    puts( "yy_match:" );    gen_next_match();    skelout();    set_indent( 2 );    gen_find_action();    /* copy actions from action_file to output file */    skelout();    indent_up();    gen_bt_action();    action_out();    /* generate cases for any missing EOF rules */    for ( i = 1; i <= lastsc; ++i )	if ( ! sceof[i] )	    {	    do_indent();	    printf( "case YY_STATE_EOF(%s):\n", scname[i] );	    did_eof_rule = true;	    }        if ( did_eof_rule )	{	indent_up();	indent_puts( "yyterminate();" );	indent_down();	}    /* generate code for handling NUL's, if needed */    /* first, deal with backtracking and setting up yy_cp if the scanner     * finds that it should JAM on the NUL     */    skelout();    set_indent( 7 );    if ( fullspd || fulltbl )	indent_puts( "yy_cp = yy_c_buf_p;" );        else	{ /* compressed table */	if ( ! reject && ! interactive )	    {	    /* do the guaranteed-needed backtrack to figure out the match */	    indent_puts( "yy_cp = yy_last_accepting_cpos;" );	    indent_puts( "yy_current_state = yy_last_accepting_state;" );	    }	}    /* generate code for yy_get_previous_state() */    set_indent( 1 );    skelout();    if ( bol_needed )	indent_puts( "register YY_CHAR *yy_bp = yy___text;\n" );    gen_start_state();    set_indent( 2 );    skelout();    gen_next_state( true );    set_indent( 1 );    skelout();    gen_NUL_trans();    skelout();    /* copy remainder of input to output */    line_directive_out( stdout );    (void) flexscan(); /* copy remainder of input to output */    }

⌨️ 快捷键说明

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