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

📄 gen.c

📁 flex 词法分析工具 类似于lex 此版本为较早前的版本
💻 C
📖 第 1 页 / 共 3 页
字号:
/* gen - actual generation (writing) of flex scanners *//*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Vern Paxson. *  * The United States Government has rights in this work pursuant * to contract no. DE-AC03-76SF00098 between the United States * Department of Energy and the University of California. * * Redistribution and use in source and binary forms with or without * modification are permitted provided that: (1) source distributions retain * this entire copyright notice and comment, and (2) distributions including * binaries display the following acknowledgement:  ``This product includes * software developed by the University of California, Berkeley and its * contributors'' in the documentation or other materials provided with the * distribution and in all advertising materials mentioning features or use * of this software.  Neither the name of the University nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *//* $Header: /home/daffy/u0/vern/flex/RCS/gen.c,v 2.56 96/05/25 20:43:38 vern Exp $ */#include "flexdef.h"/* declare functions that have forward references */void gen_next_state PROTO((int));void genecs PROTO((void));void indent_put2s PROTO((char [], char []));void indent_puts PROTO((char []));static int indent_level = 0; /* each level is 8 spaces */#define indent_up() (++indent_level)#define indent_down() (--indent_level)#define set_indent(indent_val) indent_level = indent_val/* Almost everything is done in terms of arrays starting at 1, so provide * a null entry for the zero element of all C arrays.  (The exception * to this is that the fast table representation generally uses the * 0 elements of its arrays, too.) */static char C_int_decl[] = "static yyconst int %s[%d] =\n    {   0,\n";static char C_short_decl[] = "static yyconst short int %s[%d] =\n    {   0,\n";static char C_long_decl[] = "static yyconst long int %s[%d] =\n    {   0,\n";static char C_state_decl[] =	"static yyconst yy_state_type %s[%d] =\n    {   0,\n";/* Indent to the current level. */void do_indent()	{	register int i = indent_level * 8;	while ( i >= 8 )		{		outc( '\t' );		i -= 8;		}	while ( i > 0 )		{		outc( ' ' );		--i;		}	}/* Generate the code to keep backing-up information. */void gen_backing_up()	{	if ( reject || num_backing_up == 0 )		return;	if ( fullspd )		indent_puts( "if ( yy_current_state[-1].yy_nxt )" );	else		indent_puts( "if ( yy_accept[yy_current_state] )" );	indent_up();	indent_puts( "{" );	indent_puts( "yy_last_accepting_state = yy_current_state;" );	indent_puts( "yy_last_accepting_cpos = yy_cp;" );	indent_puts( "}" );	indent_down();	}/* Generate the code to perform the backing up. */void gen_bu_action()	{	if ( reject || num_backing_up == 0 )		return;	set_indent( 3 );	indent_puts( "case 0: /* must back up */" );	indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );	indent_puts( "*yy_cp = yy_hold_char;" );	if ( fullspd || fulltbl )		indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );	else		/* Backing-up info for compressed tables is taken \after/		 * yy_cp has been incremented for the next state.		 */		indent_puts( "yy_cp = yy_last_accepting_cpos;" );	indent_puts( "yy_current_state = yy_last_accepting_state;" );	indent_puts( "goto yy_find_action;" );	outc( '\n' );	set_indent( 0 );	}/* genctbl - generates full speed compressed transition table */void genctbl()	{	register int i;	int end_of_buffer_action = num_rules + 1;	/* Table of verify for transition and offset to next state. */	out_dec( "static yyconst struct yy_trans_info yy_transition[%d] =\n",		tblend + numecs + 1 );	outn( "    {" );	/* We want the transition to be represented as the offset to the	 * next state, not the actual state number, which is what it currently	 * is.  The offset is base[nxt[i]] - (base of current state)].  That's	 * just the difference between the starting points of the two involved	 * states (to - from).	 *	 * First, though, we need to find some way to put in our end-of-buffer	 * flags and states.  We do this by making a state with absolutely no	 * transitions.  We put it at the end of the table.	 */	/* We need to have room in nxt/chk for two more slots: One for the	 * action and one for the end-of-buffer transition.  We now *assume*	 * that we're guaranteed the only character we'll try to index this	 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure	 * there's room for jam entries for other characters.	 */	while ( tblend + 2 >= current_max_xpairs )		expand_nxt_chk();	while ( lastdfa + 1 >= current_max_dfas )		increase_max_dfas();	base[lastdfa + 1] = tblend + 2;	nxt[tblend + 1] = end_of_buffer_action;	chk[tblend + 1] = numecs + 1;	chk[tblend + 2] = 1; /* anything but EOB */	/* So that "make test" won't show arb. differences. */	nxt[tblend + 2] = 0;	/* Make sure every state has an end-of-buffer transition and an	 * action #.	 */	for ( i = 0; i <= lastdfa; ++i )		{		int anum = dfaacc[i].dfaacc_state;		int offset = base[i];		chk[offset] = EOB_POSITION;		chk[offset - 1] = ACTION_POSITION;		nxt[offset - 1] = anum;	/* action number */		}	for ( i = 0; i <= tblend; ++i )		{		if ( chk[i] == EOB_POSITION )			transition_struct_out( 0, base[lastdfa + 1] - i );		else if ( chk[i] == ACTION_POSITION )			transition_struct_out( 0, nxt[i] );		else if ( chk[i] > numecs || chk[i] == 0 )			transition_struct_out( 0, 0 );	/* unused slot */		else	/* verify, transition */			transition_struct_out( chk[i],						base[nxt[i]] - (i - chk[i]) );		}	/* Here's the final, end-of-buffer state. */	transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );	transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );	outn( "    };\n" );	/* Table of pointers to start states. */	out_dec(	"static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n",		lastsc * 2 + 1 );	outn( "    {" );	/* } so vi doesn't get confused */	for ( i = 0; i <= lastsc * 2; ++i )		out_dec( "    &yy_transition[%d],\n", base[i] );	dataend();	if ( useecs )		genecs();	}/* Generate equivalence-class tables. */void genecs()	{	register int i, j;	int numrows;	out_str_dec( C_int_decl, "yy_ec", csize );	for ( i = 1; i < csize; ++i )		{		if ( caseins && (i >= 'A') && (i <= 'Z') )			ecgroup[i] = ecgroup[clower( i )];		ecgroup[i] = ABS( ecgroup[i] );		mkdata( ecgroup[i] );		}	dataend();	if ( trace )		{		fputs( _( "\n\nEquivalence Classes:\n\n" ), stderr );		numrows = csize / 8;		for ( j = 0; j < numrows; ++j )			{			for ( i = j; i < csize; i = i + numrows )				{				fprintf( stderr, "%4s = %-2d",					readable_form( i ), ecgroup[i] );				putc( ' ', stderr );				}			putc( '\n', stderr );			}		}	}/* Generate the code to find the action number. */void gen_find_action()	{	if ( fullspd )		indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" );	else if ( fulltbl )		indent_puts( "yy_act = yy_accept[yy_current_state];" );	else if ( reject )		{		indent_puts( "yy_current_state = *--yy_state_ptr;" );		indent_puts( "yy_lp = yy_accept[yy_current_state];" );		outn(		"find_rule: /* we branch to this label when backing up */" );		indent_puts(		"for ( ; ; ) /* until we find what rule we matched */" );		indent_up();		indent_puts( "{" );		indent_puts(		"if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );		indent_up();		indent_puts( "{" );		indent_puts( "yy_act = yy_acclist[yy_lp];" );		if ( variable_trailing_context_rules )			{			indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );			indent_puts( "     yy_looking_for_trail_begin )" );			indent_up();			indent_puts( "{" );			indent_puts(				"if ( yy_act == yy_looking_for_trail_begin )" );			indent_up();			indent_puts( "{" );			indent_puts( "yy_looking_for_trail_begin = 0;" );			indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );			indent_puts( "break;" );			indent_puts( "}" );			indent_down();			indent_puts( "}" );			indent_down();			indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );			indent_up();			indent_puts( "{" );			indent_puts(		"yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );			indent_puts(		"yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );			if ( real_reject )				{				/* Remember matched text in case we back up				 * due to REJECT.				 */				indent_puts( "yy_full_match = yy_cp;" );				indent_puts( "yy_full_state = yy_state_ptr;" );				indent_puts( "yy_full_lp = yy_lp;" );				}			indent_puts( "}" );			indent_down();			indent_puts( "else" );			indent_up();			indent_puts( "{" );			indent_puts( "yy_full_match = yy_cp;" );			indent_puts( "yy_full_state = yy_state_ptr;" );			indent_puts( "yy_full_lp = yy_lp;" );			indent_puts( "break;" );			indent_puts( "}" );			indent_down();			indent_puts( "++yy_lp;" );			indent_puts( "goto find_rule;" );			}		else			{			/* Remember matched text in case we back up due to			 * trailing context plus REJECT.			 */			indent_up();			indent_puts( "{" );			indent_puts( "yy_full_match = yy_cp;" );			indent_puts( "break;" );			indent_puts( "}" );			indent_down();			}		indent_puts( "}" );		indent_down();		indent_puts( "--yy_cp;" );		/* We could consolidate the following two lines with those at		 * the beginning, but at the cost of complaints that we're		 * branching inside a loop.		 */		indent_puts( "yy_current_state = *--yy_state_ptr;" );		indent_puts( "yy_lp = yy_accept[yy_current_state];" );		indent_puts( "}" );		indent_down();		}	else		{ /* compressed */		indent_puts( "yy_act = yy_accept[yy_current_state];" );		if ( interactive && ! reject )			{			/* Do the guaranteed-needed backing up to figure out			 * the match.			 */			indent_puts( "if ( yy_act == 0 )" );			indent_up();			indent_puts( "{ /* have to back up */" );			indent_puts( "yy_cp = yy_last_accepting_cpos;" );			indent_puts(				"yy_current_state = yy_last_accepting_state;" );			indent_puts( "yy_act = yy_accept[yy_current_state];" );			indent_puts( "}" );			indent_down();			}		}	}/* genftbl - generate full transition table */void genftbl()	{	register int i;	int end_of_buffer_action = num_rules + 1;	out_str_dec( long_align ? C_long_decl : C_short_decl,		"yy_accept", lastdfa + 1 );	dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;	for ( i = 1; i <= lastdfa; ++i )		{		register int anum = dfaacc[i].dfaacc_state;		mkdata( anum );		if ( trace && anum )			fprintf( stderr, _( "state # %d accepts: [%d]\n" ),				i, anum );		}	dataend();	if ( useecs )		genecs();	/* Don't have to dump the actual full table entries - they were	 * created on-the-fly.	 */	}/* Generate the code to find the next compressed-table state. */void gen_next_compressed_state( char_map )char *char_map;	{	indent_put2s( "register YY_CHAR yy_c = %s;", char_map );	/* Save the backing-up info \before/ computing the next state	 * because we always compute one more state than needed - we	 * always proceed until we reach a jam state	 */	gen_backing_up();	indent_puts("while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );	indent_up();	indent_puts( "{" );	indent_puts( "yy_current_state = (int) yy_def[yy_current_state];" );	if ( usemecs )		{		/* We've arrange it so that templates are never chained		 * to one another.  This means we can afford to make a		 * very simple test to see if we need to convert to		 * yy_c's meta-equivalence class without worrying		 * about erroneously looking up the meta-equivalence		 * class twice		 */		do_indent();		/* lastdfa + 2 is the beginning of the templates */		out_dec( "if ( yy_current_state >= %d )\n", lastdfa + 2 );		indent_up();		indent_puts( "yy_c = yy_meta[(unsigned int) yy_c];" );		indent_down();		}	indent_puts( "}" );	indent_down();	indent_puts("yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];" );	}/* Generate the code to find the next match. */void gen_next_match()	{	/* NOTE - changes in here should be reflected in gen_next_state() and	 * gen_NUL_trans().	 */	char *char_map = useecs ?				"yy_ec[YY_SC_TO_UI(*yy_cp)]" :				"YY_SC_TO_UI(*yy_cp)";	char *char_map_2 = useecs ?				"yy_ec[YY_SC_TO_UI(*++yy_cp)]" :				"YY_SC_TO_UI(*++yy_cp)";	if ( fulltbl )		{		indent_put2s(	"while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",				char_map );		indent_up();		if ( num_backing_up > 0 )			{			indent_puts( "{" );	/* } for vi */			gen_backing_up();			outc( '\n' );			}		indent_puts( "++yy_cp;" );		if ( num_backing_up > 0 )			/* { for vi */			indent_puts( "}" );		indent_down();		outc( '\n' );		indent_puts( "yy_current_state = -yy_current_state;" );		}	else if ( fullspd )		{		indent_puts( "{" );	/* } for vi */		indent_puts(		"register yyconst struct yy_trans_info *yy_trans_info;\n" );		indent_puts( "register YY_CHAR yy_c;\n" );		indent_put2s( "for ( yy_c = %s;", char_map );		indent_puts(	"      (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->" );		indent_puts( "yy_verify == yy_c;" );		indent_put2s( "      yy_c = %s )", char_map_2 );		indent_up();

⌨️ 快捷键说明

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