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

📄 scan.l

📁 早期freebsd实现
💻 L
字号:
/* scan.l - scanner for flex input */%{/*- * 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 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: scan.l,v 1.2 94/01/04 14:33:09 vern Exp $ */#include "flexdef.h"#include "parse.h"#define ACTION_ECHO add_action( yytext )#define MARK_END_OF_PROLOG mark_prolog();#define YY_DECL \	int flexscan()#define RETURNCHAR \	yylval = (unsigned char) yytext[0]; \	return CHAR;#define RETURNNAME \	strcpy( nmstr, yytext ); \	return NAME;#define PUT_BACK_STRING(str, start) \	for ( i = strlen( str ) - 1; i >= start; --i ) \		unput((str)[i])#define CHECK_REJECT(str) \	if ( all_upper( str ) ) \		reject = true;#define CHECK_YYMORE(str) \	if ( all_lower( str ) ) \		yymore_used = true;%}%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE%x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT%x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2WS		[ \t]+OPTWS		[ \t]*NOT_WS		[^ \t\n]NL		(\n|\r\n|\n\r)NAME		([a-z_][a-z_0-9-]*)NOT_NAME	[^a-z_*\n]+SCNAME		{NAME}ESCSEQ		(\\([^\n]|[0-9]{1,3}|x[0-9a-f]{1,2}))FIRST_CCL_CHAR	([^\\\n]|{ESCSEQ})CCL_CHAR	([^\\\n\]]|{ESCSEQ})%%	static int bracelevel, didadef, indented_code, checking_used;	int doing_codeblock = false;	int i;	Char nmdef[MAXLINE], myesc();^{WS}			indented_code = true; BEGIN(CODEBLOCK);^"/*"			ACTION_ECHO; BEGIN(C_COMMENT);^"%s"{NAME}?		return SCDECL;^"%x"{NAME}?		return XSCDECL;^"%{".*{NL}		{			++linenum;			line_directive_out( (FILE *) 0 );			indented_code = false;			BEGIN(CODEBLOCK);			}{WS}			return WHITESPACE;^"%%".*			{			sectnum = 2;			bracelevel = 0;			mark_defs1();			line_directive_out( (FILE *) 0 );			BEGIN(SECT2PROLOG);			return SECTEND;			}^"%pointer".*{NL}	{			if ( lex_compat )				warn( "%pointer incompatible with -l option" );			else				yytext_is_array = false;			++linenum;			}^"%array".*{NL}		{			if ( C_plus_plus )				warn( "%array incompatible with -+ option" );			else				yytext_is_array = true;			++linenum;			}^"%used"		{			warn( "%used/%unused have been deprecated" );			checking_used = REALLY_USED; BEGIN(USED_LIST);			}^"%unused"		{			warn( "%used/%unused have been deprecated" );			checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);			}^"%"[aceknopr]{OPTWS}[0-9]*{OPTWS}{NL}	++linenum;	/* ignore */^"%"[^sxanpekotcru{}].*	synerr( "unrecognized '%' directive" );^{NAME}			{			strcpy( nmstr, yytext );			didadef = false;			BEGIN(PICKUPDEF);			}{SCNAME}		RETURNNAME;^{OPTWS}{NL}		++linenum; /* allows blank lines in section 1 */{OPTWS}{NL}		++linenum; return '\n';<C_COMMENT>"*/"		ACTION_ECHO; BEGIN(INITIAL);<C_COMMENT>"*/".*{NL}	++linenum; ACTION_ECHO; BEGIN(INITIAL);<C_COMMENT>[^*\n]+	ACTION_ECHO;<C_COMMENT>"*"		ACTION_ECHO;<C_COMMENT>{NL}		++linenum; ACTION_ECHO;<CODEBLOCK>^"%}".*{NL}	++linenum; BEGIN(INITIAL);<CODEBLOCK>"reject"	ACTION_ECHO; CHECK_REJECT(yytext);<CODEBLOCK>"yymore"	ACTION_ECHO; CHECK_YYMORE(yytext);<CODEBLOCK>{NAME}|{NOT_NAME}|.	ACTION_ECHO;<CODEBLOCK>{NL}		{			++linenum;			ACTION_ECHO;			if ( indented_code )				BEGIN(INITIAL);			}<PICKUPDEF>{WS}		/* separates name and definition */<PICKUPDEF>{NOT_WS}.*	{			strcpy( (char *) nmdef, yytext );			/* Skip trailing whitespace. */			for ( i = strlen( (char *) nmdef ) - 1;			      i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');			      --i )				;			nmdef[i + 1] = '\0';			ndinstal( nmstr, nmdef );			didadef = true;			}<PICKUPDEF>{NL}		{			if ( ! didadef )				synerr( "incomplete name definition" );			BEGIN(INITIAL);			++linenum;			}<RECOVER>.*{NL}		++linenum; BEGIN(INITIAL); RETURNNAME;<USED_LIST>{NL}		++linenum; BEGIN(INITIAL);<USED_LIST>{WS}<USED_LIST>"reject"	{			if ( all_upper( yytext ) )				reject_really_used = checking_used;			else				synerr(				"unrecognized %used/%unused construct" );			}<USED_LIST>"yymore"	{			if ( all_lower( yytext ) )				yymore_really_used = checking_used;			else				synerr(				"unrecognized %used/%unused construct" );			}<USED_LIST>{NOT_WS}+	synerr( "unrecognized %used/%unused construct" );<SECT2PROLOG>^"%{".*	++bracelevel; yyless( 2 );	/* eat only %{ */<SECT2PROLOG>^"%}".*	--bracelevel; yyless( 2 );	/* eat only %} */<SECT2PROLOG>^{WS}.*	ACTION_ECHO;	/* indented code in prolog */<SECT2PROLOG>^{NOT_WS}.*	{	/* non-indented code */			if ( bracelevel <= 0 )				{ /* not in %{ ... %} */				yyless( 0 );	/* put it all back */				mark_prolog();				BEGIN(SECT2);				}			else				ACTION_ECHO;			}<SECT2PROLOG>.*		ACTION_ECHO;<SECT2PROLOG>{NL}	++linenum; ACTION_ECHO;<SECT2PROLOG><<EOF>>	{			mark_prolog();			sectnum = 0;			yyterminate(); /* to stop the parser */			}<SECT2>^{OPTWS}{NL}	++linenum; /* allow blank lines in section 2 */<SECT2>^({WS}|"%{")	{			indented_code = (yytext[0] != '%');			doing_codeblock = true;			bracelevel = 1;			if ( indented_code )				ACTION_ECHO;			BEGIN(CODEBLOCK_2);			}<SECT2>^"<"		BEGIN(SC); return '<';<SECT2>^"^"		return '^';<SECT2>\"		BEGIN(QUOTE); return '"';<SECT2>"{"/[0-9]		BEGIN(NUM); return '{';<SECT2>"{"[^0-9\n][^}\n]*	BEGIN(BRACEERROR);<SECT2>"$"/([ \t]|{NL})	return '$';<SECT2>{WS}"%{"		{			bracelevel = 1;			BEGIN(PERCENT_BRACE_ACTION);			return '\n';			}<SECT2>{WS}"|".*{NL}	continued_action = true; ++linenum; return '\n';<SECT2>{WS}		{			/* This rule is separate from the one below because			 * otherwise we get variable trailing context, so			 * we can't build the scanner using -{f,F}.			 */			bracelevel = 0;			continued_action = false;			BEGIN(ACTION);			return '\n';			}<SECT2>{OPTWS}{NL}	{			bracelevel = 0;			continued_action = false;			BEGIN(ACTION);			unput( '\n' );	/* so <ACTION> sees it */			return '\n';			}<SECT2>"<<EOF>>"	return EOF_OP;<SECT2>^"%%".*		{			sectnum = 3;			BEGIN(SECT3);			yyterminate(); /* to stop the parser */			}<SECT2>"["{FIRST_CCL_CHAR}{CCL_CHAR}*	{			int cclval;			strcpy( nmstr, yytext );			/* Check to see if we've already encountered this			 * ccl.			 */			if ( (cclval = ccllookup( (Char *) nmstr )) )				{				if ( input() != ']' )					synerr( "bad character class" );				yylval = cclval;				++cclreuse;				return PREVCCL;				}			else				{				/* We fudge a bit.  We know that this ccl will				 * soon be numbered as lastccl + 1 by cclinit.				 */				cclinstal( (Char *) nmstr, lastccl + 1 );				/* Push back everything but the leading bracket				 * so the ccl can be rescanned.				 */				yyless( 1 );				BEGIN(FIRSTCCL);				return '[';				}			}<SECT2>"{"{NAME}"}"	{			register Char *nmdefptr;			Char *ndlookup();			strcpy( nmstr, yytext + 1 );			nmstr[yyleng - 2] = '\0';  /* chop trailing brace */			if ( ! (nmdefptr = ndlookup( nmstr )) )				format_synerr( "undefined definition {%s}",						nmstr );			else				{ /* push back name surrounded by ()'s */				int len = strlen( (char *) nmdefptr );				if ( lex_compat || nmdefptr[0] == '^' ||				     (len > 0 && nmdefptr[len - 1] == '$') )					{ /* don't use ()'s after all */					PUT_BACK_STRING((char *) nmdefptr, 0);					if ( nmdefptr[0] == '^' )						BEGIN(CARETISBOL);					}				else					{					unput(')');					PUT_BACK_STRING((char *) nmdefptr, 0);					unput('(');					}				}			}<SECT2>[/|*+?.()]	return (unsigned char) yytext[0];<SECT2>.		RETURNCHAR;<SC>[,*]		return (unsigned char) yytext[0];<SC>">"			BEGIN(SECT2); return '>';<SC>">"/^		BEGIN(CARETISBOL); return '>';<SC>{SCNAME}		RETURNNAME;<SC>.			{			format_synerr( "bad <start condition>: %s", yytext );			}<CARETISBOL>"^"		BEGIN(SECT2); return '^';<QUOTE>[^"\n]		RETURNCHAR;<QUOTE>\"		BEGIN(SECT2); return '"';<QUOTE>{NL}		{			synerr( "missing quote" );			BEGIN(SECT2);			++linenum;			return '"';			}<FIRSTCCL>"^"/[^-\]\n]	BEGIN(CCL); return '^';<FIRSTCCL>"^"/("-"|"]")	return '^';<FIRSTCCL>.		BEGIN(CCL); RETURNCHAR;<CCL>-/[^\]\n]		return '-';<CCL>[^\]\n]		RETURNCHAR;<CCL>"]"		BEGIN(SECT2); return ']';<CCL>.|{NL}		{			synerr( "bad character class" );			BEGIN(SECT2);			return ']';			}<NUM>[0-9]+		{			yylval = myctoi( yytext );			return NUMBER;			}<NUM>","		return ',';<NUM>"}"		BEGIN(SECT2); return '}';<NUM>.			{			synerr( "bad character inside {}'s" );			BEGIN(SECT2);			return '}';			}<NUM>{NL}		{			synerr( "missing }" );			BEGIN(SECT2);			++linenum;			return '}';			}<BRACEERROR>"}"		synerr( "bad name in {}'s" ); BEGIN(SECT2);<BRACEERROR>{NL}	synerr( "missing }" ); ++linenum; BEGIN(SECT2);<CODEBLOCK_2>"/*"	ACTION_ECHO; BEGIN(ACTION_COMMENT);<PERCENT_BRACE_ACTION,CODEBLOCK_2>{OPTWS}"%}".*		bracelevel = 0;<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"reject"	{			ACTION_ECHO;			CHECK_REJECT(yytext);			}<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"yymore"	{			ACTION_ECHO;			CHECK_YYMORE(yytext);			}<PERCENT_BRACE_ACTION,CODEBLOCK_2>{NAME}|{NOT_NAME}|.	ACTION_ECHO;<PERCENT_BRACE_ACTION,CODEBLOCK_2>{NL}			{			++linenum;			ACTION_ECHO;			if ( bracelevel == 0 ||			     (doing_codeblock && indented_code) )				{				if ( ! doing_codeblock )					add_action( "\tYY_BREAK\n" );								doing_codeblock = false;				BEGIN(SECT2);				}			}	/* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */<ACTION>"{"		ACTION_ECHO; ++bracelevel;<ACTION>"}"		ACTION_ECHO; --bracelevel;<ACTION>[^a-z_{}"'/\n]+	ACTION_ECHO;<ACTION>{NAME}		ACTION_ECHO;<ACTION>"/*"		ACTION_ECHO; BEGIN(ACTION_COMMENT);<ACTION>"'"([^'\\\n]|\\.)*"'"	ACTION_ECHO; /* character constant */<ACTION>\"		ACTION_ECHO; BEGIN(ACTION_STRING);<ACTION>{NL}		{			++linenum;			ACTION_ECHO;			if ( bracelevel == 0 )				{				add_action( "\tYY_BREAK\n" );				BEGIN(SECT2);				}			}<ACTION>.		ACTION_ECHO;<ACTION_COMMENT>"*/"	{			ACTION_ECHO;			if ( doing_codeblock )				BEGIN(CODEBLOCK_2);			else				BEGIN(ACTION);			}<ACTION_COMMENT>"*"	ACTION_ECHO;<ACTION_COMMENT>[^*\n]+	ACTION_ECHO;<ACTION_COMMENT>[^*\n]*{NL}	++linenum; ACTION_ECHO;<ACTION_STRING>[^"\\\n]+	ACTION_ECHO;<ACTION_STRING>\\.	ACTION_ECHO;<ACTION_STRING>{NL}	++linenum; ACTION_ECHO;<ACTION_STRING>\"	ACTION_ECHO; BEGIN(ACTION);<ACTION_STRING>.	ACTION_ECHO;<ACTION,ACTION_COMMENT,ACTION_STRING><<EOF>>	{			synerr( "EOF encountered inside an action" );			yyterminate();			}<SECT2,QUOTE,CCL>{ESCSEQ}	{			yylval = myesc( (Char *) yytext );			return CHAR;			}<FIRSTCCL>{ESCSEQ}	{			yylval = myesc( (Char *) yytext );			BEGIN(CCL);			return CHAR;			}<SECT3>.*(\n?)		ECHO;<SECT3><<EOF>>		sectnum = 0; yyterminate();<*>.|\n			format_synerr( "bad character: %s", yytext );%%int yywrap()	{	if ( --num_input_files > 0 )		{		set_input_file( *++input_files );		return 0;		}	else		return 1;	}/* set_input_file - open the given file (if NULL, stdin) for scanning */void set_input_file( file )char *file;	{	if ( file )		{		infilename = file;		yyin = fopen( infilename, "r" );		if ( yyin == NULL )			lerrsf( "can't open %s", file );		}	else		{		yyin = stdin;		infilename = "<stdin>";		}	}/* Wrapper routines for accessing the scanner's malloc routines. */void *flex_alloc( size )unsigned int size;	{	return yy_flex_alloc( size );	}void *flex_realloc( ptr, size )void *ptr;unsigned int size;	{	return yy_flex_realloc( ptr, size );	}void flex_free( ptr )void *ptr;	{	yy_flex_free( ptr );	}

⌨️ 快捷键说明

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