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

📄 parse.y

📁 flex 词法分析工具 类似于lex 此版本为较早前的版本
💻 Y
📖 第 1 页 / 共 2 页
字号:
/* parse.y - parser for flex input */%token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS%token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH%token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT%{/*- * 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/parse.y,v 2.28 95/04/21 11:51:51 vern Exp $ *//* Some versions of bison are broken in that they use alloca() but don't * declare it properly.  The following is the patented (just kidding!) * #ifdef chud to fix the problem, courtesy of Francois Pinard. */#ifdef YYBISON/* AIX requires this to be the first thing in the file.  What a piece.  */# ifdef _AIX #pragma alloca# endif#endif#include "flexdef.h"/* The remainder of the alloca() cruft has to come after including flexdef.h, * so HAVE_ALLOCA_H is (possibly) defined. */#ifdef YYBISON# ifdef __GNUC__#  ifndef alloca#   define alloca __builtin_alloca#  endif# else#  if HAVE_ALLOCA_H#   include <alloca.h>#  else#   ifdef __hpuxvoid *alloca ();#   else#    ifdef __TURBOC__#     include <malloc.h>#    elsechar *alloca ();#    endif#   endif#  endif# endif#endif/* Bletch, ^^^^ that was ugly! */int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, rulelen;int trlcontxt, xcluflg, currccl, cclsorted, varlength, variable_trail_rule;int *scon_stk;int scon_stk_ptr;static int madeany = false;  /* whether we've made the '.' character class */int previous_continued_action;	/* whether the previous rule's action was '|' *//* Expand a POSIX character class expression. */#define CCL_EXPR(func) \	{ \	int c; \	for ( c = 0; c < csize; ++c ) \		if ( isascii(c) && func(c) ) \			ccladd( currccl, c ); \	}/* While POSIX defines isblank(), it's not ANSI C. */#define IS_BLANK(c) ((c) == ' ' || (c) == '\t')/* On some over-ambitious machines, such as DEC Alpha's, the default * token type is "long" instead of "int"; this leads to problems with * declaring yylval in flexdef.h.  But so far, all the yacc's I've seen * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the * following should ensure that the default token type is "int". */#define YYSTYPE int%}%%goal		:  initlex sect1 sect1end sect2 initforrule			{ /* add default rule */			int def_rule;			pat = cclinit();			cclnegate( pat );			def_rule = mkstate( -pat );			/* Remember the number of the default rule so we			 * don't generate "can't match" warnings for it.			 */			default_rule = num_rules;			finish_rule( def_rule, false, 0, 0 );			for ( i = 1; i <= lastsc; ++i )				scset[i] = mkbranch( scset[i], def_rule );			if ( spprdflt )				add_action(				"YY_FATAL_ERROR( \"flex scanner jammed\" )" );			else				add_action( "ECHO" );			add_action( ";\n\tYY_BREAK\n" );			}		;initlex		:			{ /* initialize for processing rules */			/* Create default DFA start condition. */			scinstal( "INITIAL", false );			}		;sect1		:  sect1 startconddecl namelist1		|  sect1 options		|		|  error			{ synerr( "unknown error processing section 1" ); }		;sect1end	:  SECTEND			{			check_options();			scon_stk = allocate_integer_array( lastsc + 1 );			scon_stk_ptr = 0;			}		;startconddecl	:  SCDECL			{ xcluflg = false; }		|  XSCDECL			{ xcluflg = true; }		;namelist1	:  namelist1 NAME			{ scinstal( nmstr, xcluflg ); }		|  NAME			{ scinstal( nmstr, xcluflg ); }		|  error			{ synerr( "bad start condition list" ); }		;options		:  OPTION_OP optionlist		;optionlist	:  optionlist option		|		;option		:  OPT_OUTFILE '=' NAME			{			outfilename = copy_string( nmstr );			did_outfilename = 1;			}		|  OPT_PREFIX '=' NAME			{ prefix = copy_string( nmstr ); }		|  OPT_YYCLASS '=' NAME			{ yyclass = copy_string( nmstr ); }		;sect2		:  sect2 scon initforrule flexrule '\n'			{ scon_stk_ptr = $2; }		|  sect2 scon '{' sect2 '}'			{ scon_stk_ptr = $2; }		|		;initforrule	:			{			/* Initialize for a parse of one rule. */			trlcontxt = variable_trail_rule = varlength = false;			trailcnt = headcnt = rulelen = 0;			current_state_type = STATE_NORMAL;			previous_continued_action = continued_action;			in_rule = true;			new_rule();			}		;flexrule	:  '^' rule			{			pat = $2;			finish_rule( pat, variable_trail_rule,				headcnt, trailcnt );			if ( scon_stk_ptr > 0 )				{				for ( i = 1; i <= scon_stk_ptr; ++i )					scbol[scon_stk[i]] =						mkbranch( scbol[scon_stk[i]],								pat );				}			else				{				/* Add to all non-exclusive start conditions,				 * including the default (0) start condition.				 */				for ( i = 1; i <= lastsc; ++i )					if ( ! scxclu[i] )						scbol[i] = mkbranch( scbol[i],									pat );				}			if ( ! bol_needed )				{				bol_needed = true;				if ( performance_report > 1 )					pinpoint_message(			"'^' operator results in sub-optimal performance" );				}			}		|  rule			{			pat = $1;			finish_rule( pat, variable_trail_rule,				headcnt, trailcnt );			if ( scon_stk_ptr > 0 )				{				for ( i = 1; i <= scon_stk_ptr; ++i )					scset[scon_stk[i]] =						mkbranch( scset[scon_stk[i]],								pat );				}			else				{				for ( i = 1; i <= lastsc; ++i )					if ( ! scxclu[i] )						scset[i] =							mkbranch( scset[i],								pat );				}			}		|  EOF_OP			{			if ( scon_stk_ptr > 0 )				build_eof_action();				else				{				/* This EOF applies to all start conditions				 * which don't already have EOF actions.				 */				for ( i = 1; i <= lastsc; ++i )					if ( ! sceof[i] )						scon_stk[++scon_stk_ptr] = i;				if ( scon_stk_ptr == 0 )					warn(			"all start conditions already have <<EOF>> rules" );				else					build_eof_action();				}			}		|  error			{ synerr( "unrecognized rule" ); }		;scon_stk_ptr	:			{ $$ = scon_stk_ptr; }		;scon		:  '<' scon_stk_ptr namelist2 '>'			{ $$ = $2; }		|  '<' '*' '>'			{			$$ = scon_stk_ptr;			for ( i = 1; i <= lastsc; ++i )				{				int j;				for ( j = 1; j <= scon_stk_ptr; ++j )					if ( scon_stk[j] == i )						break;				if ( j > scon_stk_ptr )					scon_stk[++scon_stk_ptr] = i;				}			}		|			{ $$ = scon_stk_ptr; }		;namelist2	:  namelist2 ',' sconname		|  sconname		|  error			{ synerr( "bad start condition list" ); }		;sconname	:  NAME			{			if ( (scnum = sclookup( nmstr )) == 0 )				format_pinpoint_message(					"undeclared start condition %s",					nmstr );			else				{				for ( i = 1; i <= scon_stk_ptr; ++i )					if ( scon_stk[i] == scnum )						{						format_warn(							"<%s> specified twice",							scname[scnum] );						break;						}				if ( i > scon_stk_ptr )					scon_stk[++scon_stk_ptr] = scnum;				}			}		;rule		:  re2 re			{			if ( transchar[lastst[$2]] != SYM_EPSILON )				/* Provide final transition \now/ so it				 * will be marked as a trailing context				 * state.				 */				$2 = link_machines( $2,						mkstate( SYM_EPSILON ) );			mark_beginning_as_normal( $2 );			current_state_type = STATE_NORMAL;			if ( previous_continued_action )				{				/* We need to treat this as variable trailing				 * context so that the backup does not happen				 * in the action but before the action switch				 * statement.  If the backup happens in the				 * action, then the rules "falling into" this				 * one's action will *also* do the backup,				 * erroneously.				 */				if ( ! varlength || headcnt != 0 )					warn(		"trailing context made variable due to preceding '|' action" );				/* Mark as variable. */				varlength = true;				headcnt = 0;				}			if ( lex_compat || (varlength && headcnt == 0) )				{ /* variable trailing context rule */				/* Mark the first part of the rule as the				 * accepting "head" part of a trailing				 * context rule.				 *				 * By the way, we didn't do this at the				 * beginning of this production because back				 * then current_state_type was set up for a				 * trail rule, and add_accept() can create				 * a new state ...				 */				add_accept( $1,					num_rules | YY_TRAILING_HEAD_MASK );				variable_trail_rule = true;				}						else				trailcnt = rulelen;			$$ = link_machines( $1, $2 );			}		|  re2 re '$'			{ synerr( "trailing context used twice" ); }		|  re '$'			{			headcnt = 0;			trailcnt = 1;			rulelen = 1;			varlength = false;			current_state_type = STATE_TRAILING_CONTEXT;			if ( trlcontxt )				{				synerr( "trailing context used twice" );				$$ = mkstate( SYM_EPSILON );				}			else if ( previous_continued_action )				{				/* See the comment in the rule for "re2 re"				 * above.				 */				warn(		"trailing context made variable due to preceding '|' action" );				varlength = true;				}			if ( lex_compat || varlength )				{				/* Again, see the comment in the rule for				 * "re2 re" above.				 */				add_accept( $1,					num_rules | YY_TRAILING_HEAD_MASK );				variable_trail_rule = true;				}

⌨️ 快捷键说明

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