Connect flex 2.5.37 to the build and bump __FreeBSD_version.
This commit is contained in:
parent
aec5199f85
commit
ab76bc977a
@ -1206,6 +1206,10 @@ _sed= usr.bin/sed
|
||||
_lex= usr.bin/lex
|
||||
.endif
|
||||
|
||||
.if ${BOOTSTRAPPING} < 1000002
|
||||
_m4= usr.bin/m4
|
||||
.endif
|
||||
|
||||
.if ${BOOTSTRAPPING} < 1000013
|
||||
_yacc= lib/liby \
|
||||
usr.bin/yacc
|
||||
@ -1283,6 +1287,7 @@ bootstrap-tools:
|
||||
usr.bin/rpcgen \
|
||||
${_sed} \
|
||||
${_yacc} \
|
||||
${_m4} \
|
||||
${_lex} \
|
||||
lib/libmd \
|
||||
usr.bin/xinstall \
|
||||
|
@ -58,7 +58,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#undef __FreeBSD_version
|
||||
#define __FreeBSD_version 1000032 /* Master, propagated to newvers */
|
||||
#define __FreeBSD_version 1000033 /* Master, propagated to newvers */
|
||||
|
||||
/*
|
||||
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
|
||||
|
@ -1,38 +0,0 @@
|
||||
Flex carries the copyright used for BSD software, slightly modified
|
||||
because it originated at the Lawrence Berkeley (not Livermore!) Laboratory,
|
||||
which operates under a contract with the Department of Energy:
|
||||
|
||||
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.
|
||||
|
||||
This basically says "do whatever you please with this software except
|
||||
remove this notice or take advantage of the University's (or the flex
|
||||
authors') name".
|
||||
|
||||
Note that the "flex.skl" scanner skeleton carries no copyright notice.
|
||||
You are free to do whatever you please with scanners generated using flex;
|
||||
for them, you are not even bound by the above copyright.
|
@ -1,186 +0,0 @@
|
||||
// $Header: /home/daffy/u0/vern/flex/RCS/FlexLexer.h,v 1.19 96/05/25 20:43:02 vern Exp $
|
||||
// $FreeBSD$
|
||||
|
||||
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
|
||||
// by flex
|
||||
|
||||
// Copyright (c) 1993 The Regents of the University of California.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is derived from software contributed to Berkeley by
|
||||
// Kent Williams and Tom Epperly.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// This file defines FlexLexer, an abstract class which specifies the
|
||||
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
|
||||
// which defines a particular lexer class.
|
||||
//
|
||||
// If you want to create multiple lexer classes, you use the -P flag
|
||||
// to rename each yyFlexLexer to some other xxFlexLexer. You then
|
||||
// include <FlexLexer.h> in your other sources once per lexer class:
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer xxFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer zzFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
// ...
|
||||
|
||||
#ifndef __FLEX_LEXER_H
|
||||
// Never included before - need to define base class.
|
||||
#define __FLEX_LEXER_H
|
||||
#include <iostream>
|
||||
|
||||
extern "C++" {
|
||||
|
||||
struct yy_buffer_state;
|
||||
typedef int yy_state_type;
|
||||
|
||||
class FlexLexer {
|
||||
public:
|
||||
virtual ~FlexLexer() { }
|
||||
|
||||
const char* YYText() { return yytext; }
|
||||
int YYLeng() { return yyleng; }
|
||||
|
||||
virtual void
|
||||
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
|
||||
virtual struct yy_buffer_state*
|
||||
yy_create_buffer( std::istream* s, int size ) = 0;
|
||||
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
|
||||
virtual void yyrestart( std::istream* s ) = 0;
|
||||
|
||||
virtual int yylex() = 0;
|
||||
|
||||
// Call yylex with new input/output sources.
|
||||
int yylex( std::istream* new_in, std::ostream* new_out = 0 )
|
||||
{
|
||||
switch_streams( new_in, new_out );
|
||||
return yylex();
|
||||
}
|
||||
|
||||
// Switch to new input/output streams. A nil stream pointer
|
||||
// indicates "keep the current one".
|
||||
virtual void switch_streams( std::istream* new_in = 0,
|
||||
std::ostream* new_out = 0 ) = 0;
|
||||
|
||||
int lineno() const { return yylineno; }
|
||||
|
||||
int debug() const { return yy_flex_debug; }
|
||||
void set_debug( int flag ) { yy_flex_debug = flag; }
|
||||
|
||||
protected:
|
||||
char* yytext;
|
||||
int yyleng;
|
||||
int yylineno; // only maintained if you use %option yylineno
|
||||
int yy_flex_debug; // only has effect with -d or "%option debug"
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
|
||||
// Either this is the first time through (yyFlexLexerOnce not defined),
|
||||
// or this is a repeated include to define a different flavor of
|
||||
// yyFlexLexer, as discussed in the flex man page.
|
||||
#define yyFlexLexerOnce
|
||||
|
||||
class yyFlexLexer : public FlexLexer {
|
||||
public:
|
||||
// arg_yyin and arg_yyout default to the cin and cout, but we
|
||||
// only make that assignment when initializing in yylex().
|
||||
yyFlexLexer( std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0 );
|
||||
|
||||
virtual ~yyFlexLexer();
|
||||
|
||||
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
|
||||
struct yy_buffer_state* yy_create_buffer( std::istream* s, int size );
|
||||
void yy_delete_buffer( struct yy_buffer_state* b );
|
||||
void yyrestart( std::istream* s );
|
||||
|
||||
virtual int yylex();
|
||||
virtual void switch_streams( std::istream* new_in, std::ostream* new_out );
|
||||
|
||||
protected:
|
||||
virtual int LexerInput( char* buf, int max_size );
|
||||
virtual void LexerOutput( const char* buf, int size );
|
||||
virtual void LexerError( const char* msg );
|
||||
|
||||
void yyunput( int c, char* buf_ptr );
|
||||
int yyinput();
|
||||
|
||||
void yy_load_buffer_state();
|
||||
void yy_init_buffer( struct yy_buffer_state* b, std::istream* s );
|
||||
void yy_flush_buffer( struct yy_buffer_state* b );
|
||||
|
||||
int yy_start_stack_ptr;
|
||||
int yy_start_stack_depth;
|
||||
int* yy_start_stack;
|
||||
|
||||
void yy_push_state( int new_state );
|
||||
void yy_pop_state();
|
||||
int yy_top_state();
|
||||
|
||||
yy_state_type yy_get_previous_state();
|
||||
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
|
||||
int yy_get_next_buffer();
|
||||
|
||||
std::istream* yyin; // input source for default LexerInput
|
||||
std::ostream* yyout; // output sink for default LexerOutput
|
||||
|
||||
struct yy_buffer_state* yy_current_buffer;
|
||||
|
||||
// yy_hold_char holds the character lost when yytext is formed.
|
||||
char yy_hold_char;
|
||||
|
||||
// Number of characters read into yy_ch_buf.
|
||||
int yy_n_chars;
|
||||
|
||||
// Points to current character in buffer.
|
||||
char* yy_c_buf_p;
|
||||
|
||||
int yy_init; // whether we need to initialize
|
||||
int yy_start; // start state number
|
||||
|
||||
// Flag which is used to allow yywrap()'s to do buffer switches
|
||||
// instead of setting up a fresh yyin. A bit of a hack ...
|
||||
int yy_did_buffer_switch_on_eof;
|
||||
|
||||
// The following are not always needed, but may be depending
|
||||
// on use of certain flex features (like REJECT or yymore()).
|
||||
|
||||
yy_state_type yy_last_accepting_state;
|
||||
char* yy_last_accepting_cpos;
|
||||
|
||||
yy_state_type* yy_state_buf;
|
||||
yy_state_type* yy_state_ptr;
|
||||
|
||||
char* yy_full_match;
|
||||
int* yy_full_state;
|
||||
int yy_full_lp;
|
||||
|
||||
int yy_lp;
|
||||
int yy_looking_for_trail_begin;
|
||||
|
||||
int yy_more_flag;
|
||||
int yy_more_len;
|
||||
int yy_more_offset;
|
||||
int yy_prev_more_offset;
|
||||
};
|
||||
|
||||
#endif
|
@ -14,37 +14,51 @@ LINKS+= ${BINDIR}/lex ${BINDIR}/lex++
|
||||
LINKS+= ${BINDIR}/lex ${BINDIR}/flex
|
||||
LINKS+= ${BINDIR}/lex ${BINDIR}/flex++
|
||||
|
||||
SRCS= scan.c ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.y \
|
||||
skel.c sym.c tblcmp.c yylex.c
|
||||
FLEXDIR= ${.CURDIR}/../../contrib/flex
|
||||
|
||||
.PATH: ${FLEXDIR}
|
||||
|
||||
SRCS= buf.c ccl.c dfa.c ecs.c filter.c gen.c main.c misc.c \
|
||||
nfa.c options.c parse.y regex.c scan.c scanflags.c \
|
||||
scanopt.c skel.c sym.c tables.c tables_shared.c \
|
||||
tblcmp.c yylex.c
|
||||
LFLAGS+= -is
|
||||
CFLAGS+= -I. -I${.CURDIR}
|
||||
CFLAGS+= -I. -I${.CURDIR} -I${FLEXDIR} -DHAVE_CONFIG_H
|
||||
INCS= FlexLexer.h
|
||||
INCSDIR= ${INCLUDEDIR}
|
||||
MLINKS+= lex.1 flex.1
|
||||
MLINKS+= lex.1 flex++.1
|
||||
MLINKS+= lex.1 lex++.1
|
||||
|
||||
WARNS?= 2
|
||||
WARNS?= 3
|
||||
|
||||
CLEANFILES= scan.c skel.c
|
||||
GENFILES= parse.c parse.h scan.c skel.c
|
||||
|
||||
SUBDIR= lib
|
||||
|
||||
skel.c: mkskel.sh flex.skl
|
||||
sh ${.CURDIR}/mkskel.sh ${.CURDIR}/flex.skl > skel.c
|
||||
FLEX_VERSION= `awk -f ${.CURDIR}/version.awk ${.CURDIR}/config.h`
|
||||
|
||||
bootstrap: initscan.c
|
||||
@cmp -s ${.CURDIR}/initscan.c scan.c || { \
|
||||
echo "Bootstrapping flex" ; \
|
||||
rm -f scan.c ; \
|
||||
cp -f ${.CURDIR}/initscan.c scan.c ; \
|
||||
skel.c: config.h mkskel.sh flex.skl version.awk
|
||||
sed 's/m4_/m4postproc_/g; s/m4preproc_/m4_/g' \
|
||||
${FLEXDIR}/flex.skl | \
|
||||
m4 -I${FLEXDIR} -P ${FLEX_VERSION} | \
|
||||
sed 's/m4postproc_/m4_/g' | \
|
||||
sh ${FLEXDIR}/mkskel.sh > ${.TARGET}
|
||||
|
||||
bootstrap: ${GENFILES:S/^/init/g}
|
||||
.for _f in ${GENFILES}
|
||||
@diff -I '^#line ' -I '\$$FreeBS[D]: .*\$$' -q \
|
||||
${.CURDIR}/init${_f} ${_f} 2> /dev/null || { \
|
||||
echo "Bootstrapping ${_f}" ; \
|
||||
cp -f ${.CURDIR}/init${_f} ${_f} ; \
|
||||
}
|
||||
.endfor
|
||||
|
||||
test: check
|
||||
check: $(PROG)
|
||||
./$(PROG) $(LFLAGS) -t $(COMPRESSION) $(.CURDIR)/scan.l \
|
||||
| sed s,\"$(.CURDIR)/scan.l",\"scan.l", \
|
||||
| diff -I '\$$FreeBS[D]:.*\$$' $(.CURDIR)/initscan.c -
|
||||
check: ${PROG}
|
||||
./${PROG} ${LFLAGS} -t ${COMPRESSION} ${FLEXDIR}/scan.l | \
|
||||
diff -I '^#line ' -I '\$$FreeBS[D]: .*\$$' ${.CURDIR}/initscan.c -
|
||||
@echo "Check successful"
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
1235
usr.bin/lex/NEWS
1235
usr.bin/lex/NEWS
File diff suppressed because it is too large
Load Diff
@ -1,60 +0,0 @@
|
||||
This is release 2.5 of flex. See "version.h" for the exact patch-level.
|
||||
|
||||
See the file "NEWS" to find out what is new in this Flex release.
|
||||
|
||||
Read the file "INSTALL" for general installation directives. Peek near
|
||||
the beginning of the file "Makefile.in" for special DEFS values. On most
|
||||
systems, you can just run the "configure" script and type "make" to build
|
||||
flex; then "make check" to test whether it built correctly; and if it did,
|
||||
then "make install" to install it.
|
||||
|
||||
If you're feeling adventurous, you can also issue "make bigcheck" (be
|
||||
prepared to wait a while).
|
||||
|
||||
Note that flex is distributed under a copyright very similar to that of
|
||||
BSD Unix, and not under the GNU General Public License (GPL), except for
|
||||
the "configure" script, which is covered by the GPL.
|
||||
|
||||
Many thanks to the 2.5 beta-testers for finding bugs and helping test and
|
||||
increase portability: Stan Adermann, Scott David Daniels, Charles Elliott,
|
||||
Joe Gayda, Chris Meier, James Nordby, Terrence O'Kane, Karsten Pahnke,
|
||||
Francois Pinard, Pat Rankin, Andreas Scherer, Marc Wiese, Nathan Zelle.
|
||||
|
||||
Please send bug reports and feedback to: Vern Paxson (vern@ee.lbl.gov).
|
||||
|
||||
|
||||
The flex distribution consists of the following files:
|
||||
|
||||
README This message
|
||||
|
||||
NEWS Differences between the various releases
|
||||
|
||||
INSTALL General installation information
|
||||
|
||||
COPYING flex's copyright
|
||||
|
||||
conf.in, configure.in, configure, Makefile.in, install.sh,
|
||||
mkinstalldirs
|
||||
elements of the "autoconf" auto-configuration process
|
||||
|
||||
flexdef.h, parse.y, scan.l, ccl.c, dfa.c, ecs.c, gen.c, main.c,
|
||||
misc.c, nfa.c, sym.c, tblcmp.c, yylex.c
|
||||
source files
|
||||
|
||||
version.h version of this flex release
|
||||
|
||||
flex.skl flex scanner skeleton
|
||||
mkskel.sh script for converting flex.skl to C source file skel.c
|
||||
skel.c pre-converted C version of flex.skl
|
||||
|
||||
libmain.c flex library (-lfl) sources
|
||||
libyywrap.c
|
||||
|
||||
initscan.c pre-flex'd version of scan.l
|
||||
|
||||
FlexLexer.h header file for C++ lexer class
|
||||
|
||||
flex.1 user documentation
|
||||
|
||||
MISC/ a directory containing miscellaneous contributions.
|
||||
See MISC/README for details.
|
@ -1,151 +0,0 @@
|
||||
/* ccl - routines for character classes */
|
||||
|
||||
/*-
|
||||
* 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: /home/daffy/u0/vern/flex/RCS/ccl.c,v 2.9 93/09/16 20:32:14 vern Exp $ */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "flexdef.h"
|
||||
|
||||
/* ccladd - add a single character to a ccl */
|
||||
|
||||
void ccladd( cclp, ch )
|
||||
int cclp;
|
||||
int ch;
|
||||
{
|
||||
int ind, len, newpos, i;
|
||||
|
||||
check_char( ch );
|
||||
|
||||
len = ccllen[cclp];
|
||||
ind = cclmap[cclp];
|
||||
|
||||
/* check to see if the character is already in the ccl */
|
||||
|
||||
for ( i = 0; i < len; ++i )
|
||||
if ( ccltbl[ind + i] == ch )
|
||||
return;
|
||||
|
||||
newpos = ind + len;
|
||||
|
||||
if ( newpos >= current_max_ccl_tbl_size )
|
||||
{
|
||||
current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT;
|
||||
|
||||
++num_reallocs;
|
||||
|
||||
ccltbl = reallocate_Character_array( ccltbl,
|
||||
current_max_ccl_tbl_size );
|
||||
}
|
||||
|
||||
ccllen[cclp] = len + 1;
|
||||
ccltbl[newpos] = ch;
|
||||
}
|
||||
|
||||
|
||||
/* cclinit - return an empty ccl */
|
||||
|
||||
int cclinit()
|
||||
{
|
||||
if ( ++lastccl >= current_maxccls )
|
||||
{
|
||||
current_maxccls += MAX_CCLS_INCREMENT;
|
||||
|
||||
++num_reallocs;
|
||||
|
||||
cclmap = reallocate_integer_array( cclmap, current_maxccls );
|
||||
ccllen = reallocate_integer_array( ccllen, current_maxccls );
|
||||
cclng = reallocate_integer_array( cclng, current_maxccls );
|
||||
}
|
||||
|
||||
if ( lastccl == 1 )
|
||||
/* we're making the first ccl */
|
||||
cclmap[lastccl] = 0;
|
||||
|
||||
else
|
||||
/* The new pointer is just past the end of the last ccl.
|
||||
* Since the cclmap points to the \first/ character of a
|
||||
* ccl, adding the length of the ccl to the cclmap pointer
|
||||
* will produce a cursor to the first free space.
|
||||
*/
|
||||
cclmap[lastccl] = cclmap[lastccl - 1] + ccllen[lastccl - 1];
|
||||
|
||||
ccllen[lastccl] = 0;
|
||||
cclng[lastccl] = 0; /* ccl's start out life un-negated */
|
||||
|
||||
return lastccl;
|
||||
}
|
||||
|
||||
|
||||
/* cclnegate - negate the given ccl */
|
||||
|
||||
void cclnegate( cclp )
|
||||
int cclp;
|
||||
{
|
||||
cclng[cclp] = 1;
|
||||
}
|
||||
|
||||
|
||||
/* list_character_set - list the members of a set of characters in CCL form
|
||||
*
|
||||
* Writes to the given file a character-class representation of those
|
||||
* characters present in the given CCL. A character is present if it
|
||||
* has a non-zero value in the cset array.
|
||||
*/
|
||||
|
||||
void list_character_set( file, cset )
|
||||
FILE *file;
|
||||
int cset[];
|
||||
{
|
||||
int i;
|
||||
|
||||
putc( '[', file );
|
||||
|
||||
for ( i = 0; i < csize; ++i )
|
||||
{
|
||||
if ( cset[i] )
|
||||
{
|
||||
int start_char = i;
|
||||
|
||||
putc( ' ', file );
|
||||
|
||||
fputs( readable_form( i ), file );
|
||||
|
||||
while ( ++i < csize && cset[i] )
|
||||
;
|
||||
|
||||
if ( i - 1 > start_char )
|
||||
/* this was a run */
|
||||
fprintf( file, "-%s", readable_form( i - 1 ) );
|
||||
|
||||
putc( ' ', file );
|
||||
}
|
||||
}
|
||||
|
||||
putc( ']', file );
|
||||
}
|
@ -1,26 +1,208 @@
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/* config.h. Generated from conf.in by configure. */
|
||||
/* conf.in. Generated from configure.in by autoheader. */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
/* #undef CRAY_STACKSEG_END */
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
/* #undef size_t */
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
/* #undef C_ALLOCA */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
/* #undef ENABLE_NLS */
|
||||
|
||||
/* Define if you have the <malloc.h> header file. */
|
||||
/* #undef HAVE_MALLOC_H */
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
/* #undef HAVE_ALLOCA_H */
|
||||
|
||||
/* Define if platform-specific command line handling is necessary. */
|
||||
/* #undef NEED_ARGV_FIXUP */
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
/* #undef HAVE_DCGETTEXT */
|
||||
|
||||
/* Define to 1 if you have the `dup2' function. */
|
||||
#define HAVE_DUP2 1
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#define HAVE_FORK 1
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
/* #undef HAVE_GETTEXT */
|
||||
|
||||
/* Define if you have the iconv() function. */
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `isascii' function. */
|
||||
#define HAVE_ISASCII 1
|
||||
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
/* #undef HAVE_LIBINTL_H */
|
||||
|
||||
/* Define to 1 if you have the `m' library (-lm). */
|
||||
#define HAVE_LIBM 1
|
||||
|
||||
/* pthread library */
|
||||
#define HAVE_LIBPTHREAD 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
/* #undef HAVE_MALLOC_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the `pow' function. */
|
||||
#define HAVE_POW 1
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#define HAVE_PTHREAD_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||
and to 0 otherwise. */
|
||||
#define HAVE_REALLOC 1
|
||||
|
||||
/* Define to 1 if you have the `regcomp' function. */
|
||||
#define HAVE_REGCOMP 1
|
||||
|
||||
/* Define to 1 if you have the <regex.h> header file. */
|
||||
#define HAVE_REGEX_H 1
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#define HAVE_VFORK 1
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
/* #undef HAVE_VFORK_H */
|
||||
|
||||
/* Define to 1 if `fork' works. */
|
||||
#define HAVE_WORKING_FORK 1
|
||||
|
||||
/* Define to 1 if `vfork' works. */
|
||||
#define HAVE_WORKING_VFORK 1
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#define HAVE__BOOL 1
|
||||
|
||||
/* Define to the m4 executable name. */
|
||||
#define M4 "m4"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "flex"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "flex-help@lists.sourceforge.net"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "the fast lexical analyser generator"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "the fast lexical analyser generator 2.5.37"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "flex"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2.5.37"
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at runtime.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
/* #undef STACK_DIRECTION */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.5.37"
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#define YYTEXT_POINTER 1
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef pid_t */
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
/* #undef realloc */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
/* #undef vfork */
|
||||
|
1097
usr.bin/lex/dfa.c
1097
usr.bin/lex/dfa.c
File diff suppressed because it is too large
Load Diff
@ -1,227 +0,0 @@
|
||||
/* ecs - equivalence class routines */
|
||||
|
||||
/*-
|
||||
* 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: /home/daffy/u0/vern/flex/RCS/ecs.c,v 2.9 93/12/07 10:18:20 vern Exp $ */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "flexdef.h"
|
||||
|
||||
/* ccl2ecl - convert character classes to set of equivalence classes */
|
||||
|
||||
void ccl2ecl()
|
||||
{
|
||||
int i, ich, newlen, cclp, ccls, cclmec;
|
||||
|
||||
for ( i = 1; i <= lastccl; ++i )
|
||||
{
|
||||
/* We loop through each character class, and for each character
|
||||
* in the class, add the character's equivalence class to the
|
||||
* new "character" class we are creating. Thus when we are all
|
||||
* done, character classes will really consist of collections
|
||||
* of equivalence classes
|
||||
*/
|
||||
|
||||
newlen = 0;
|
||||
cclp = cclmap[i];
|
||||
|
||||
for ( ccls = 0; ccls < ccllen[i]; ++ccls )
|
||||
{
|
||||
ich = ccltbl[cclp + ccls];
|
||||
cclmec = ecgroup[ich];
|
||||
|
||||
if ( cclmec > 0 )
|
||||
{
|
||||
ccltbl[cclp + newlen] = cclmec;
|
||||
++newlen;
|
||||
}
|
||||
}
|
||||
|
||||
ccllen[i] = newlen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cre8ecs - associate equivalence class numbers with class members
|
||||
*
|
||||
* fwd is the forward linked-list of equivalence class members. bck
|
||||
* is the backward linked-list, and num is the number of class members.
|
||||
*
|
||||
* Returned is the number of classes.
|
||||
*/
|
||||
|
||||
int cre8ecs( fwd, bck, num )
|
||||
int fwd[], bck[], num;
|
||||
{
|
||||
int i, j, numcl;
|
||||
|
||||
numcl = 0;
|
||||
|
||||
/* Create equivalence class numbers. From now on, ABS( bck(x) )
|
||||
* is the equivalence class number for object x. If bck(x)
|
||||
* is positive, then x is the representative of its equivalence
|
||||
* class.
|
||||
*/
|
||||
for ( i = 1; i <= num; ++i )
|
||||
if ( bck[i] == NIL )
|
||||
{
|
||||
bck[i] = ++numcl;
|
||||
for ( j = fwd[i]; j != NIL; j = fwd[j] )
|
||||
bck[j] = -numcl;
|
||||
}
|
||||
|
||||
return numcl;
|
||||
}
|
||||
|
||||
|
||||
/* mkeccl - update equivalence classes based on character class xtions
|
||||
*
|
||||
* synopsis
|
||||
* Char ccls[];
|
||||
* int lenccl, fwd[llsiz], bck[llsiz], llsiz, NUL_mapping;
|
||||
* void mkeccl( Char ccls[], int lenccl, int fwd[llsiz], int bck[llsiz],
|
||||
* int llsiz, int NUL_mapping );
|
||||
*
|
||||
* ccls contains the elements of the character class, lenccl is the
|
||||
* number of elements in the ccl, fwd is the forward link-list of equivalent
|
||||
* characters, bck is the backward link-list, and llsiz size of the link-list.
|
||||
*
|
||||
* NUL_mapping is the value which NUL (0) should be mapped to.
|
||||
*/
|
||||
|
||||
void mkeccl( ccls, lenccl, fwd, bck, llsiz, NUL_mapping )
|
||||
Char ccls[];
|
||||
int lenccl, fwd[], bck[], llsiz, NUL_mapping;
|
||||
{
|
||||
int cclp, oldec, newec;
|
||||
int cclm, i, j;
|
||||
static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */
|
||||
|
||||
/* Note that it doesn't matter whether or not the character class is
|
||||
* negated. The same results will be obtained in either case.
|
||||
*/
|
||||
|
||||
cclp = 0;
|
||||
|
||||
while ( cclp < lenccl )
|
||||
{
|
||||
cclm = ccls[cclp];
|
||||
|
||||
if ( NUL_mapping && cclm == 0 )
|
||||
cclm = NUL_mapping;
|
||||
|
||||
oldec = bck[cclm];
|
||||
newec = cclm;
|
||||
|
||||
j = cclp + 1;
|
||||
|
||||
for ( i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i] )
|
||||
{ /* look for the symbol in the character class */
|
||||
for ( ; j < lenccl; ++j )
|
||||
{
|
||||
int ccl_char;
|
||||
|
||||
if ( NUL_mapping && ccls[j] == 0 )
|
||||
ccl_char = NUL_mapping;
|
||||
else
|
||||
ccl_char = ccls[j];
|
||||
|
||||
if ( ccl_char > i )
|
||||
break;
|
||||
|
||||
if ( ccl_char == i && ! cclflags[j] )
|
||||
{
|
||||
/* We found an old companion of cclm
|
||||
* in the ccl. Link it into the new
|
||||
* equivalence class and flag it as
|
||||
* having been processed.
|
||||
*/
|
||||
|
||||
bck[i] = newec;
|
||||
fwd[newec] = i;
|
||||
newec = i;
|
||||
/* Set flag so we don't reprocess. */
|
||||
cclflags[j] = 1;
|
||||
|
||||
/* Get next equivalence class member. */
|
||||
/* continue 2 */
|
||||
goto next_pt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Symbol isn't in character class. Put it in the old
|
||||
* equivalence class.
|
||||
*/
|
||||
|
||||
bck[i] = oldec;
|
||||
|
||||
if ( oldec != NIL )
|
||||
fwd[oldec] = i;
|
||||
|
||||
oldec = i;
|
||||
|
||||
next_pt: ;
|
||||
}
|
||||
|
||||
if ( bck[cclm] != NIL || oldec != bck[cclm] )
|
||||
{
|
||||
bck[cclm] = NIL;
|
||||
fwd[oldec] = NIL;
|
||||
}
|
||||
|
||||
fwd[newec] = NIL;
|
||||
|
||||
/* Find next ccl member to process. */
|
||||
|
||||
for ( ++cclp; cclflags[cclp] && cclp < lenccl; ++cclp )
|
||||
{
|
||||
/* Reset "doesn't need processing" flag. */
|
||||
cclflags[cclp] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mkechar - create equivalence class for single character */
|
||||
|
||||
void mkechar( tch, fwd, bck )
|
||||
int tch, fwd[], bck[];
|
||||
{
|
||||
/* If until now the character has been a proper subset of
|
||||
* an equivalence class, break it away to create a new ec
|
||||
*/
|
||||
|
||||
if ( fwd[tch] != NIL )
|
||||
bck[fwd[tch]] = bck[tch];
|
||||
|
||||
if ( bck[tch] != NIL )
|
||||
fwd[bck[tch]] = fwd[tch];
|
||||
|
||||
fwd[tch] = NIL;
|
||||
bck[tch] = NIL;
|
||||
}
|
1574
usr.bin/lex/flex.skl
1574
usr.bin/lex/flex.skl
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1629
usr.bin/lex/gen.c
1629
usr.bin/lex/gen.c
File diff suppressed because it is too large
Load Diff
1849
usr.bin/lex/initparse.c
Normal file
1849
usr.bin/lex/initparse.c
Normal file
File diff suppressed because it is too large
Load Diff
46
usr.bin/lex/initparse.h
Normal file
46
usr.bin/lex/initparse.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* $FreeBSD$ */
|
||||
#define CHAR 257
|
||||
#define NUMBER 258
|
||||
#define SECTEND 259
|
||||
#define SCDECL 260
|
||||
#define XSCDECL 261
|
||||
#define NAME 262
|
||||
#define PREVCCL 263
|
||||
#define EOF_OP 264
|
||||
#define OPTION_OP 265
|
||||
#define OPT_OUTFILE 266
|
||||
#define OPT_PREFIX 267
|
||||
#define OPT_YYCLASS 268
|
||||
#define OPT_HEADER 269
|
||||
#define OPT_EXTRA_TYPE 270
|
||||
#define OPT_TABLES 271
|
||||
#define CCE_ALNUM 272
|
||||
#define CCE_ALPHA 273
|
||||
#define CCE_BLANK 274
|
||||
#define CCE_CNTRL 275
|
||||
#define CCE_DIGIT 276
|
||||
#define CCE_GRAPH 277
|
||||
#define CCE_LOWER 278
|
||||
#define CCE_PRINT 279
|
||||
#define CCE_PUNCT 280
|
||||
#define CCE_SPACE 281
|
||||
#define CCE_UPPER 282
|
||||
#define CCE_XDIGIT 283
|
||||
#define CCE_NEG_ALNUM 284
|
||||
#define CCE_NEG_ALPHA 285
|
||||
#define CCE_NEG_BLANK 286
|
||||
#define CCE_NEG_CNTRL 287
|
||||
#define CCE_NEG_DIGIT 288
|
||||
#define CCE_NEG_GRAPH 289
|
||||
#define CCE_NEG_LOWER 290
|
||||
#define CCE_NEG_PRINT 291
|
||||
#define CCE_NEG_PUNCT 292
|
||||
#define CCE_NEG_SPACE 293
|
||||
#define CCE_NEG_UPPER 294
|
||||
#define CCE_NEG_XDIGIT 295
|
||||
#define CCL_OP_DIFF 296
|
||||
#define CCL_OP_UNION 297
|
||||
#define BEGIN_REPEAT_POSIX 298
|
||||
#define END_REPEAT_POSIX 299
|
||||
#define BEGIN_REPEAT_FLEX 300
|
||||
#define END_REPEAT_FLEX 301
|
File diff suppressed because it is too large
Load Diff
3738
usr.bin/lex/initskel.c
Normal file
3738
usr.bin/lex/initskel.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -2,12 +2,12 @@
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.PATH: ${.CURDIR}/../../../contrib/flex
|
||||
|
||||
LIB= ln
|
||||
SRCS= libmain.c libyywrap.c
|
||||
NO_PIC=
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
.if ${MK_INSTALLLIB} != "no"
|
||||
LINKS= ${LIBDIR}/libln.a ${LIBDIR}/libl.a
|
||||
LINKS+= ${LIBDIR}/libln.a ${LIBDIR}/libfl.a
|
||||
|
@ -1,16 +0,0 @@
|
||||
/* libmain - flex run-time support library "main" function */
|
||||
|
||||
/* $Header: /home/daffy/u0/vern/flex/RCS/libmain.c,v 1.4 95/09/27 12:47:55 vern Exp $
|
||||
* $FreeBSD$ */
|
||||
|
||||
extern int yylex();
|
||||
|
||||
int main( argc, argv )
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
while ( yylex() != 0 )
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
/* libyywrap - flex run-time support library "yywrap" function */
|
||||
|
||||
/* $Header: /home/daffy/u0/vern/flex/RCS/libyywrap.c,v 1.1 93/10/02 15:23:09 vern Exp $
|
||||
* $FreeBSD$ */
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
1179
usr.bin/lex/main.c
1179
usr.bin/lex/main.c
File diff suppressed because it is too large
Load Diff
@ -1,888 +0,0 @@
|
||||
/* misc - miscellaneous flex routines */
|
||||
|
||||
/*-
|
||||
* 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: /home/daffy/u0/vern/flex/RCS/misc.c,v 2.47 95/04/28 11:39:39 vern Exp $ */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "flexdef.h"
|
||||
|
||||
|
||||
void action_define( defname, value )
|
||||
char *defname;
|
||||
int value;
|
||||
{
|
||||
char buf[MAXLINE];
|
||||
|
||||
if ( (int) strlen( defname ) > MAXLINE / 2 )
|
||||
{
|
||||
format_pinpoint_message( _( "name \"%s\" ridiculously long" ),
|
||||
defname );
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf( buf, "#define %s %d\n", defname, value );
|
||||
add_action( buf );
|
||||
}
|
||||
|
||||
|
||||
void add_action( new_text )
|
||||
char *new_text;
|
||||
{
|
||||
int len = strlen( new_text );
|
||||
|
||||
while ( len + action_index >= action_size - 10 /* slop */ )
|
||||
{
|
||||
int new_size = action_size * 2;
|
||||
|
||||
if ( new_size <= 0 )
|
||||
/* Increase just a little, to try to avoid overflow
|
||||
* on 16-bit machines.
|
||||
*/
|
||||
action_size += action_size / 8;
|
||||
else
|
||||
action_size = new_size;
|
||||
|
||||
action_array =
|
||||
reallocate_character_array( action_array, action_size );
|
||||
}
|
||||
|
||||
strcpy( &action_array[action_index], new_text );
|
||||
|
||||
action_index += len;
|
||||
}
|
||||
|
||||
|
||||
/* allocate_array - allocate memory for an integer array of the given size */
|
||||
|
||||
void *allocate_array( size, element_size )
|
||||
int size;
|
||||
size_t element_size;
|
||||
{
|
||||
void *mem;
|
||||
size_t num_bytes = element_size * size;
|
||||
|
||||
mem = flex_alloc( num_bytes );
|
||||
if ( ! mem )
|
||||
flexfatal(
|
||||
_( "memory allocation failed in allocate_array()" ) );
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
/* all_lower - true if a string is all lower-case */
|
||||
|
||||
int all_lower( str )
|
||||
char *str;
|
||||
{
|
||||
while ( *str )
|
||||
{
|
||||
if ( ! isascii( (Char) *str ) || ! islower( *str ) )
|
||||
return 0;
|
||||
++str;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* all_upper - true if a string is all upper-case */
|
||||
|
||||
int all_upper( str )
|
||||
char *str;
|
||||
{
|
||||
while ( *str )
|
||||
{
|
||||
if ( ! isascii( (Char) *str ) || ! isupper( *str ) )
|
||||
return 0;
|
||||
++str;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* bubble - bubble sort an integer array in increasing order
|
||||
*
|
||||
* synopsis
|
||||
* int v[n], n;
|
||||
* void bubble( v, n );
|
||||
*
|
||||
* description
|
||||
* sorts the first n elements of array v and replaces them in
|
||||
* increasing order.
|
||||
*
|
||||
* passed
|
||||
* v - the array to be sorted
|
||||
* n - the number of elements of 'v' to be sorted
|
||||
*/
|
||||
|
||||
void bubble( v, n )
|
||||
int v[], n;
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
for ( i = n; i > 1; --i )
|
||||
for ( j = 1; j < i; ++j )
|
||||
if ( v[j] > v[j + 1] ) /* compare */
|
||||
{
|
||||
k = v[j]; /* exchange */
|
||||
v[j] = v[j + 1];
|
||||
v[j + 1] = k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* check_char - checks a character to make sure it's within the range
|
||||
* we're expecting. If not, generates fatal error message
|
||||
* and exits.
|
||||
*/
|
||||
|
||||
void check_char( c )
|
||||
int c;
|
||||
{
|
||||
if ( c >= CSIZE )
|
||||
lerrsf( _( "bad character '%s' detected in check_char()" ),
|
||||
readable_form( c ) );
|
||||
|
||||
if ( c >= csize )
|
||||
lerrsf(
|
||||
_( "scanner requires -8 flag to use the character %s" ),
|
||||
readable_form( c ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* clower - replace upper-case letter to lower-case */
|
||||
|
||||
Char clower( c )
|
||||
int c;
|
||||
{
|
||||
return (Char) ((isascii( c ) && isupper( c )) ? tolower( c ) : c);
|
||||
}
|
||||
|
||||
|
||||
/* copy_string - returns a dynamically allocated copy of a string */
|
||||
|
||||
char *copy_string( str )
|
||||
const char *str;
|
||||
{
|
||||
const char *c1;
|
||||
char *c2;
|
||||
char *copy;
|
||||
unsigned int size;
|
||||
|
||||
/* find length */
|
||||
for ( c1 = str; *c1; ++c1 )
|
||||
;
|
||||
|
||||
size = (c1 - str + 1) * sizeof( char );
|
||||
copy = (char *) flex_alloc( size );
|
||||
|
||||
if ( copy == NULL )
|
||||
flexfatal( _( "dynamic memory failure in copy_string()" ) );
|
||||
|
||||
for ( c2 = copy; (*c2++ = *str++) != 0; )
|
||||
;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/* copy_unsigned_string -
|
||||
* returns a dynamically allocated copy of a (potentially) unsigned string
|
||||
*/
|
||||
|
||||
Char *copy_unsigned_string( str )
|
||||
Char *str;
|
||||
{
|
||||
Char *c;
|
||||
Char *copy;
|
||||
|
||||
/* find length */
|
||||
for ( c = str; *c; ++c )
|
||||
;
|
||||
|
||||
copy = allocate_Character_array( c - str + 1 );
|
||||
|
||||
for ( c = copy; (*c++ = *str++) != 0; )
|
||||
;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/* cshell - shell sort a character array in increasing order
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* Char v[n];
|
||||
* int n, special_case_0;
|
||||
* cshell( v, n, special_case_0 );
|
||||
*
|
||||
* description
|
||||
* Does a shell sort of the first n elements of array v.
|
||||
* If special_case_0 is true, then any element equal to 0
|
||||
* is instead assumed to have infinite weight.
|
||||
*
|
||||
* passed
|
||||
* v - array to be sorted
|
||||
* n - number of elements of v to be sorted
|
||||
*/
|
||||
|
||||
void cshell( v, n, special_case_0 )
|
||||
Char v[];
|
||||
int n, special_case_0;
|
||||
{
|
||||
int gap, i, j, jg;
|
||||
Char k;
|
||||
|
||||
for ( gap = n / 2; gap > 0; gap = gap / 2 )
|
||||
for ( i = gap; i < n; ++i )
|
||||
for ( j = i - gap; j >= 0; j = j - gap )
|
||||
{
|
||||
jg = j + gap;
|
||||
|
||||
if ( special_case_0 )
|
||||
{
|
||||
if ( v[jg] == 0 )
|
||||
break;
|
||||
|
||||
else if ( v[j] != 0 && v[j] <= v[jg] )
|
||||
break;
|
||||
}
|
||||
|
||||
else if ( v[j] <= v[jg] )
|
||||
break;
|
||||
|
||||
k = v[j];
|
||||
v[j] = v[jg];
|
||||
v[jg] = k;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* dataend - finish up a block of data declarations */
|
||||
|
||||
void dataend()
|
||||
{
|
||||
if ( datapos > 0 )
|
||||
dataflush();
|
||||
|
||||
/* add terminator for initialization; { for vi */
|
||||
outn( " } ;\n" );
|
||||
|
||||
dataline = 0;
|
||||
datapos = 0;
|
||||
}
|
||||
|
||||
|
||||
/* dataflush - flush generated data statements */
|
||||
|
||||
void dataflush()
|
||||
{
|
||||
outc( '\n' );
|
||||
|
||||
if ( ++dataline >= NUMDATALINES )
|
||||
{
|
||||
/* Put out a blank line so that the table is grouped into
|
||||
* large blocks that enable the user to find elements easily.
|
||||
*/
|
||||
outc( '\n' );
|
||||
dataline = 0;
|
||||
}
|
||||
|
||||
/* Reset the number of characters written on the current line. */
|
||||
datapos = 0;
|
||||
}
|
||||
|
||||
|
||||
/* flexerror - report an error message and terminate */
|
||||
|
||||
void flexerror( msg )
|
||||
const char msg[];
|
||||
{
|
||||
fprintf( stderr, "%s: %s\n", program_name, msg );
|
||||
flexend( 1 );
|
||||
}
|
||||
|
||||
|
||||
/* flexfatal - report a fatal error message and terminate */
|
||||
|
||||
void flexfatal( msg )
|
||||
const char msg[];
|
||||
{
|
||||
fprintf( stderr, _( "%s: fatal internal error, %s\n" ),
|
||||
program_name, msg );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
/* htoi - convert a hexadecimal digit string to an integer value */
|
||||
|
||||
int htoi( str )
|
||||
Char str[];
|
||||
{
|
||||
unsigned int result;
|
||||
|
||||
(void) sscanf( (char *) str, "%x", &result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* lerrif - report an error message formatted with one integer argument */
|
||||
|
||||
void lerrif( msg, arg )
|
||||
const char msg[];
|
||||
int arg;
|
||||
{
|
||||
char errmsg[MAXLINE];
|
||||
(void) sprintf( errmsg, msg, arg );
|
||||
flexerror( errmsg );
|
||||
}
|
||||
|
||||
|
||||
/* lerrsf - report an error message formatted with one string argument */
|
||||
|
||||
void lerrsf( msg, arg )
|
||||
const char msg[], arg[];
|
||||
{
|
||||
char errmsg[MAXLINE];
|
||||
|
||||
(void) sprintf( errmsg, msg, arg );
|
||||
flexerror( errmsg );
|
||||
}
|
||||
|
||||
|
||||
/* line_directive_out - spit out a "#line" statement */
|
||||
|
||||
void line_directive_out( output_file, do_infile )
|
||||
FILE *output_file;
|
||||
int do_infile;
|
||||
{
|
||||
char directive[MAXLINE], filename[MAXLINE];
|
||||
char *s1, *s2, *s3;
|
||||
static char line_fmt[] = "#line %d \"%s\"\n";
|
||||
|
||||
if ( ! gen_line_dirs )
|
||||
return;
|
||||
|
||||
if ( (do_infile && ! infilename) || (! do_infile && ! outfilename) )
|
||||
/* don't know the filename to use, skip */
|
||||
return;
|
||||
|
||||
s1 = do_infile ? infilename : outfilename;
|
||||
s2 = filename;
|
||||
s3 = &filename[sizeof( filename ) - 2];
|
||||
|
||||
while ( s2 < s3 && *s1 )
|
||||
{
|
||||
if ( *s1 == '\\' )
|
||||
/* Escape the '\' */
|
||||
*s2++ = '\\';
|
||||
|
||||
*s2++ = *s1++;
|
||||
}
|
||||
|
||||
*s2 = '\0';
|
||||
|
||||
if ( do_infile )
|
||||
sprintf( directive, line_fmt, linenum, filename );
|
||||
else
|
||||
{
|
||||
if ( output_file == stdout )
|
||||
/* Account for the line directive itself. */
|
||||
++out_linenum;
|
||||
|
||||
sprintf( directive, line_fmt, out_linenum, filename );
|
||||
}
|
||||
|
||||
/* If output_file is nil then we should put the directive in
|
||||
* the accumulated actions.
|
||||
*/
|
||||
if ( output_file )
|
||||
{
|
||||
fputs( directive, output_file );
|
||||
}
|
||||
else
|
||||
add_action( directive );
|
||||
}
|
||||
|
||||
|
||||
/* mark_defs1 - mark the current position in the action array as
|
||||
* representing where the user's section 1 definitions end
|
||||
* and the prolog begins
|
||||
*/
|
||||
void mark_defs1()
|
||||
{
|
||||
defs1_offset = 0;
|
||||
action_array[action_index++] = '\0';
|
||||
action_offset = prolog_offset = action_index;
|
||||
action_array[action_index] = '\0';
|
||||
}
|
||||
|
||||
|
||||
/* mark_prolog - mark the current position in the action array as
|
||||
* representing the end of the action prolog
|
||||
*/
|
||||
void mark_prolog()
|
||||
{
|
||||
action_array[action_index++] = '\0';
|
||||
action_offset = action_index;
|
||||
action_array[action_index] = '\0';
|
||||
}
|
||||
|
||||
|
||||
/* mk2data - generate a data statement for a two-dimensional array
|
||||
*
|
||||
* Generates a data statement initializing the current 2-D array to "value".
|
||||
*/
|
||||
void mk2data( value )
|
||||
int value;
|
||||
{
|
||||
if ( datapos >= NUMDATAITEMS )
|
||||
{
|
||||
outc( ',' );
|
||||
dataflush();
|
||||
}
|
||||
|
||||
if ( datapos == 0 )
|
||||
/* Indent. */
|
||||
out( " " );
|
||||
|
||||
else
|
||||
outc( ',' );
|
||||
|
||||
++datapos;
|
||||
|
||||
out_dec( "%5d", value );
|
||||
}
|
||||
|
||||
|
||||
/* mkdata - generate a data statement
|
||||
*
|
||||
* Generates a data statement initializing the current array element to
|
||||
* "value".
|
||||
*/
|
||||
void mkdata( value )
|
||||
int value;
|
||||
{
|
||||
if ( datapos >= NUMDATAITEMS )
|
||||
{
|
||||
outc( ',' );
|
||||
dataflush();
|
||||
}
|
||||
|
||||
if ( datapos == 0 )
|
||||
/* Indent. */
|
||||
out( " " );
|
||||
else
|
||||
outc( ',' );
|
||||
|
||||
++datapos;
|
||||
|
||||
out_dec( "%5d", value );
|
||||
}
|
||||
|
||||
|
||||
/* myctoi - return the integer represented by a string of digits */
|
||||
|
||||
int myctoi( array )
|
||||
char array[];
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
(void) sscanf( array, "%d", &val );
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/* myesc - return character corresponding to escape sequence */
|
||||
|
||||
Char myesc( array )
|
||||
Char array[];
|
||||
{
|
||||
Char c, esc_char;
|
||||
|
||||
switch ( array[1] )
|
||||
{
|
||||
case 'b': return '\b';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
|
||||
#if __STDC__
|
||||
case 'a': return '\a';
|
||||
case 'v': return '\v';
|
||||
#else
|
||||
case 'a': return '\007';
|
||||
case 'v': return '\013';
|
||||
#endif
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
{ /* \<octal> */
|
||||
int sptr = 1;
|
||||
|
||||
while ( isascii( array[sptr] ) &&
|
||||
isdigit( array[sptr] ) )
|
||||
/* Don't increment inside loop control
|
||||
* because if isdigit() is a macro it might
|
||||
* expand into multiple increments ...
|
||||
*/
|
||||
++sptr;
|
||||
|
||||
c = array[sptr];
|
||||
array[sptr] = '\0';
|
||||
|
||||
esc_char = otoi( array + 1 );
|
||||
|
||||
array[sptr] = c;
|
||||
|
||||
return esc_char;
|
||||
}
|
||||
|
||||
case 'x':
|
||||
{ /* \x<hex> */
|
||||
int sptr = 2;
|
||||
|
||||
while ( isascii( array[sptr] ) &&
|
||||
isxdigit( (char) array[sptr] ) )
|
||||
/* Don't increment inside loop control
|
||||
* because if isdigit() is a macro it might
|
||||
* expand into multiple increments ...
|
||||
*/
|
||||
++sptr;
|
||||
|
||||
c = array[sptr];
|
||||
array[sptr] = '\0';
|
||||
|
||||
esc_char = htoi( array + 2 );
|
||||
|
||||
array[sptr] = c;
|
||||
|
||||
return esc_char;
|
||||
}
|
||||
|
||||
default:
|
||||
return array[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* otoi - convert an octal digit string to an integer value */
|
||||
|
||||
int otoi( str )
|
||||
Char str[];
|
||||
{
|
||||
unsigned int result;
|
||||
|
||||
(void) sscanf( (char *) str, "%o", &result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* out - various flavors of outputing a (possibly formatted) string for the
|
||||
* generated scanner, keeping track of the line count.
|
||||
*/
|
||||
|
||||
void out( str )
|
||||
const char str[];
|
||||
{
|
||||
fputs( str, stdout );
|
||||
out_line_count( str );
|
||||
}
|
||||
|
||||
void out_dec( fmt, n )
|
||||
const char fmt[];
|
||||
int n;
|
||||
{
|
||||
printf( fmt, n );
|
||||
out_line_count( fmt );
|
||||
}
|
||||
|
||||
void out_dec2( fmt, n1, n2 )
|
||||
const char fmt[];
|
||||
int n1, n2;
|
||||
{
|
||||
printf( fmt, n1, n2 );
|
||||
out_line_count( fmt );
|
||||
}
|
||||
|
||||
void out_hex( fmt, x )
|
||||
const char fmt[];
|
||||
unsigned int x;
|
||||
{
|
||||
printf( fmt, x );
|
||||
out_line_count( fmt );
|
||||
}
|
||||
|
||||
void out_line_count( str )
|
||||
const char str[];
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 0; str[i]; ++i )
|
||||
if ( str[i] == '\n' )
|
||||
++out_linenum;
|
||||
}
|
||||
|
||||
void out_str( fmt, str )
|
||||
const char fmt[], str[];
|
||||
{
|
||||
printf( fmt, str );
|
||||
out_line_count( fmt );
|
||||
out_line_count( str );
|
||||
}
|
||||
|
||||
void out_str3( fmt, s1, s2, s3 )
|
||||
const char fmt[], s1[], s2[], s3[];
|
||||
{
|
||||
printf( fmt, s1, s2, s3 );
|
||||
out_line_count( fmt );
|
||||
out_line_count( s1 );
|
||||
out_line_count( s2 );
|
||||
out_line_count( s3 );
|
||||
}
|
||||
|
||||
void out_str_dec( fmt, str, n )
|
||||
const char fmt[], str[];
|
||||
int n;
|
||||
{
|
||||
printf( fmt, str, n );
|
||||
out_line_count( fmt );
|
||||
out_line_count( str );
|
||||
}
|
||||
|
||||
void outc( c )
|
||||
int c;
|
||||
{
|
||||
putc( c, stdout );
|
||||
|
||||
if ( c == '\n' )
|
||||
++out_linenum;
|
||||
}
|
||||
|
||||
void outn( str )
|
||||
const char str[];
|
||||
{
|
||||
puts( str );
|
||||
out_line_count( str );
|
||||
++out_linenum;
|
||||
}
|
||||
|
||||
|
||||
/* readable_form - return the human-readable form of a character
|
||||
*
|
||||
* The returned string is in static storage.
|
||||
*/
|
||||
|
||||
char *readable_form( c )
|
||||
int c;
|
||||
{
|
||||
static char rform[10];
|
||||
|
||||
if ( (c >= 0 && c < 32) || c >= 127 )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case '\b': return "\\b";
|
||||
case '\f': return "\\f";
|
||||
case '\n': return "\\n";
|
||||
case '\r': return "\\r";
|
||||
case '\t': return "\\t";
|
||||
|
||||
#if __STDC__
|
||||
case '\a': return "\\a";
|
||||
case '\v': return "\\v";
|
||||
#endif
|
||||
|
||||
default:
|
||||
(void) sprintf( rform, "\\%.3o",
|
||||
(unsigned int) c );
|
||||
return rform;
|
||||
}
|
||||
}
|
||||
|
||||
else if ( c == ' ' )
|
||||
return "' '";
|
||||
|
||||
else
|
||||
{
|
||||
rform[0] = c;
|
||||
rform[1] = '\0';
|
||||
|
||||
return rform;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* reallocate_array - increase the size of a dynamic array */
|
||||
|
||||
void *reallocate_array( array, size, element_size )
|
||||
void *array;
|
||||
int size;
|
||||
size_t element_size;
|
||||
{
|
||||
void *new_array;
|
||||
size_t num_bytes = element_size * size;
|
||||
|
||||
new_array = flex_realloc( array, num_bytes );
|
||||
if ( ! new_array )
|
||||
flexfatal( _( "attempt to increase array size failed" ) );
|
||||
|
||||
return new_array;
|
||||
}
|
||||
|
||||
|
||||
/* skelout - write out one section of the skeleton file
|
||||
*
|
||||
* Description
|
||||
* Copies skelfile or skel array to stdout until a line beginning with
|
||||
* "%%" or EOF is found.
|
||||
*/
|
||||
void skelout()
|
||||
{
|
||||
char buf_storage[MAXLINE];
|
||||
char *buf = buf_storage;
|
||||
int do_copy = 1;
|
||||
|
||||
/* Loop pulling lines either from the skelfile, if we're using
|
||||
* one, or from the skel[] array.
|
||||
*/
|
||||
while ( skelfile ?
|
||||
(fgets( buf, MAXLINE, skelfile ) != NULL) :
|
||||
((buf = (char *) skel[skel_ind++]) != 0) )
|
||||
{ /* copy from skel array */
|
||||
if ( buf[0] == '%' )
|
||||
{ /* control line */
|
||||
switch ( buf[1] )
|
||||
{
|
||||
case '%':
|
||||
return;
|
||||
|
||||
case '+':
|
||||
do_copy = C_plus_plus;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do_copy = ! C_plus_plus;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
do_copy = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
flexfatal(
|
||||
_( "bad line in skeleton file" ) );
|
||||
}
|
||||
}
|
||||
|
||||
else if ( do_copy )
|
||||
{
|
||||
if ( skelfile )
|
||||
/* Skeleton file reads include final
|
||||
* newline, skel[] array does not.
|
||||
*/
|
||||
out( buf );
|
||||
else
|
||||
outn( buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* transition_struct_out - output a yy_trans_info structure
|
||||
*
|
||||
* outputs the yy_trans_info structure with the two elements, element_v and
|
||||
* element_n. Formats the output with spaces and carriage returns.
|
||||
*/
|
||||
|
||||
void transition_struct_out( element_v, element_n )
|
||||
int element_v, element_n;
|
||||
{
|
||||
out_dec2( " {%4d,%4d },", element_v, element_n );
|
||||
|
||||
datapos += TRANS_STRUCT_PRINT_LENGTH;
|
||||
|
||||
if ( datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH )
|
||||
{
|
||||
outc( '\n' );
|
||||
|
||||
if ( ++dataline % 10 == 0 )
|
||||
outc( '\n' );
|
||||
|
||||
datapos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The following is only needed when building flex's parser using certain
|
||||
* broken versions of bison.
|
||||
*/
|
||||
void *yy_flex_xmalloc( size )
|
||||
int size;
|
||||
{
|
||||
void *result = flex_alloc( (size_t) size );
|
||||
|
||||
if ( ! result )
|
||||
flexfatal(
|
||||
_( "memory allocation failed in yy_flex_xmalloc()" ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* zero_out - set a region of memory to 0
|
||||
*
|
||||
* Sets region_ptr[0] through region_ptr[size_in_bytes - 1] to zero.
|
||||
*/
|
||||
|
||||
void zero_out( region_ptr, size_in_bytes )
|
||||
char *region_ptr;
|
||||
size_t size_in_bytes;
|
||||
{
|
||||
char *rp, *rp_end;
|
||||
|
||||
rp = region_ptr;
|
||||
rp_end = region_ptr + size_in_bytes;
|
||||
|
||||
while ( rp < rp_end )
|
||||
*rp++ = 0;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
cat <<!
|
||||
/* File created from flex.skl via mkskel.sh */
|
||||
|
||||
#include "flexdef.h"
|
||||
|
||||
const char *skel[] = {
|
||||
!
|
||||
|
||||
sed 's/\\/&&/g' $* | sed 's/"/\\"/g' | sed 's/.*/ "&",/'
|
||||
|
||||
cat <<!
|
||||
0
|
||||
};
|
||||
!
|
@ -1,711 +0,0 @@
|
||||
/* nfa - NFA construction routines */
|
||||
|
||||
/*-
|
||||
* 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: /home/daffy/u0/vern/flex/RCS/nfa.c,v 2.17 95/03/04 16:11:42 vern Exp $ */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "flexdef.h"
|
||||
|
||||
|
||||
/* declare functions that have forward references */
|
||||
|
||||
int dupmachine PROTO((int));
|
||||
void mkxtion PROTO((int, int));
|
||||
|
||||
|
||||
/* add_accept - add an accepting state to a machine
|
||||
*
|
||||
* accepting_number becomes mach's accepting number.
|
||||
*/
|
||||
|
||||
void add_accept( mach, accepting_number )
|
||||
int mach, accepting_number;
|
||||
{
|
||||
/* Hang the accepting number off an epsilon state. if it is associated
|
||||
* with a state that has a non-epsilon out-transition, then the state
|
||||
* will accept BEFORE it makes that transition, i.e., one character
|
||||
* too soon.
|
||||
*/
|
||||
|
||||
if ( transchar[finalst[mach]] == SYM_EPSILON )
|
||||
accptnum[finalst[mach]] = accepting_number;
|
||||
|
||||
else
|
||||
{
|
||||
int astate = mkstate( SYM_EPSILON );
|
||||
accptnum[astate] = accepting_number;
|
||||
(void) link_machines( mach, astate );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* copysingl - make a given number of copies of a singleton machine
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* newsng = copysingl( singl, num );
|
||||
*
|
||||
* newsng - a new singleton composed of num copies of singl
|
||||
* singl - a singleton machine
|
||||
* num - the number of copies of singl to be present in newsng
|
||||
*/
|
||||
|
||||
int copysingl( singl, num )
|
||||
int singl, num;
|
||||
{
|
||||
int copy, i;
|
||||
|
||||
copy = mkstate( SYM_EPSILON );
|
||||
|
||||
for ( i = 1; i <= num; ++i )
|
||||
copy = link_machines( copy, dupmachine( singl ) );
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/* dumpnfa - debugging routine to write out an nfa */
|
||||
|
||||
void dumpnfa( state1 )
|
||||
int state1;
|
||||
|
||||
{
|
||||
int sym, tsp1, tsp2, anum, ns;
|
||||
|
||||
fprintf( stderr,
|
||||
_( "\n\n********** beginning dump of nfa with start state %d\n" ),
|
||||
state1 );
|
||||
|
||||
/* We probably should loop starting at firstst[state1] and going to
|
||||
* lastst[state1], but they're not maintained properly when we "or"
|
||||
* all of the rules together. So we use our knowledge that the machine
|
||||
* starts at state 1 and ends at lastnfa.
|
||||
*/
|
||||
|
||||
/* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */
|
||||
for ( ns = 1; ns <= lastnfa; ++ns )
|
||||
{
|
||||
fprintf( stderr, _( "state # %4d\t" ), ns );
|
||||
|
||||
sym = transchar[ns];
|
||||
tsp1 = trans1[ns];
|
||||
tsp2 = trans2[ns];
|
||||
anum = accptnum[ns];
|
||||
|
||||
fprintf( stderr, "%3d: %4d, %4d", sym, tsp1, tsp2 );
|
||||
|
||||
if ( anum != NIL )
|
||||
fprintf( stderr, " [%d]", anum );
|
||||
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
|
||||
fprintf( stderr, _( "********** end of dump\n" ) );
|
||||
}
|
||||
|
||||
|
||||
/* dupmachine - make a duplicate of a given machine
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* copy = dupmachine( mach );
|
||||
*
|
||||
* copy - holds duplicate of mach
|
||||
* mach - machine to be duplicated
|
||||
*
|
||||
* note that the copy of mach is NOT an exact duplicate; rather, all the
|
||||
* transition states values are adjusted so that the copy is self-contained,
|
||||
* as the original should have been.
|
||||
*
|
||||
* also note that the original MUST be contiguous, with its low and high
|
||||
* states accessible by the arrays firstst and lastst
|
||||
*/
|
||||
|
||||
int dupmachine( mach )
|
||||
int mach;
|
||||
{
|
||||
int i, init, state_offset;
|
||||
int state = 0;
|
||||
int last = lastst[mach];
|
||||
|
||||
for ( i = firstst[mach]; i <= last; ++i )
|
||||
{
|
||||
state = mkstate( transchar[i] );
|
||||
|
||||
if ( trans1[i] != NO_TRANSITION )
|
||||
{
|
||||
mkxtion( finalst[state], trans1[i] + state - i );
|
||||
|
||||
if ( transchar[i] == SYM_EPSILON &&
|
||||
trans2[i] != NO_TRANSITION )
|
||||
mkxtion( finalst[state],
|
||||
trans2[i] + state - i );
|
||||
}
|
||||
|
||||
accptnum[state] = accptnum[i];
|
||||
}
|
||||
|
||||
if ( state == 0 )
|
||||
flexfatal( _( "empty machine in dupmachine()" ) );
|
||||
|
||||
state_offset = state - i + 1;
|
||||
|
||||
init = mach + state_offset;
|
||||
firstst[init] = firstst[mach] + state_offset;
|
||||
finalst[init] = finalst[mach] + state_offset;
|
||||
lastst[init] = lastst[mach] + state_offset;
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
|
||||
/* finish_rule - finish up the processing for a rule
|
||||
*
|
||||
* An accepting number is added to the given machine. If variable_trail_rule
|
||||
* is true then the rule has trailing context and both the head and trail
|
||||
* are variable size. Otherwise if headcnt or trailcnt is non-zero then
|
||||
* the machine recognizes a pattern with trailing context and headcnt is
|
||||
* the number of characters in the matched part of the pattern, or zero
|
||||
* if the matched part has variable length. trailcnt is the number of
|
||||
* trailing context characters in the pattern, or zero if the trailing
|
||||
* context has variable length.
|
||||
*/
|
||||
|
||||
void finish_rule( mach, variable_trail_rule, headcnt, trailcnt )
|
||||
int mach, variable_trail_rule, headcnt, trailcnt;
|
||||
{
|
||||
char action_text[MAXLINE];
|
||||
|
||||
add_accept( mach, num_rules );
|
||||
|
||||
/* We did this in new_rule(), but it often gets the wrong
|
||||
* number because we do it before we start parsing the current rule.
|
||||
*/
|
||||
rule_linenum[num_rules] = linenum;
|
||||
|
||||
/* If this is a continued action, then the line-number has already
|
||||
* been updated, giving us the wrong number.
|
||||
*/
|
||||
if ( continued_action )
|
||||
--rule_linenum[num_rules];
|
||||
|
||||
sprintf( action_text, "case %d:\n", num_rules );
|
||||
add_action( action_text );
|
||||
|
||||
if ( variable_trail_rule )
|
||||
{
|
||||
rule_type[num_rules] = RULE_VARIABLE;
|
||||
|
||||
if ( performance_report > 0 )
|
||||
fprintf( stderr,
|
||||
_( "Variable trailing context rule at line %d\n" ),
|
||||
rule_linenum[num_rules] );
|
||||
|
||||
variable_trailing_context_rules = true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
rule_type[num_rules] = RULE_NORMAL;
|
||||
|
||||
if ( headcnt > 0 || trailcnt > 0 )
|
||||
{
|
||||
/* Do trailing context magic to not match the trailing
|
||||
* characters.
|
||||
*/
|
||||
char *scanner_cp = "yy_c_buf_p = yy_cp";
|
||||
char *scanner_bp = "yy_bp";
|
||||
|
||||
add_action(
|
||||
"*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" );
|
||||
|
||||
if ( headcnt > 0 )
|
||||
{
|
||||
sprintf( action_text, "%s = %s + %d;\n",
|
||||
scanner_cp, scanner_bp, headcnt );
|
||||
add_action( action_text );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
sprintf( action_text, "%s -= %d;\n",
|
||||
scanner_cp, trailcnt );
|
||||
add_action( action_text );
|
||||
}
|
||||
|
||||
add_action(
|
||||
"YY_DO_BEFORE_ACTION; /* set up yytext again */\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/* Okay, in the action code at this point yytext and yyleng have
|
||||
* their proper final values for this rule, so here's the point
|
||||
* to do any user action. But don't do it for continued actions,
|
||||
* as that'll result in multiple YY_RULE_SETUP's.
|
||||
*/
|
||||
if ( ! continued_action )
|
||||
add_action( "YY_RULE_SETUP\n" );
|
||||
|
||||
line_directive_out( (FILE *) 0, 1 );
|
||||
}
|
||||
|
||||
|
||||
/* link_machines - connect two machines together
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* new = link_machines( first, last );
|
||||
*
|
||||
* new - a machine constructed by connecting first to last
|
||||
* first - the machine whose successor is to be last
|
||||
* last - the machine whose predecessor is to be first
|
||||
*
|
||||
* note: this routine concatenates the machine first with the machine
|
||||
* last to produce a machine new which will pattern-match first first
|
||||
* and then last, and will fail if either of the sub-patterns fails.
|
||||
* FIRST is set to new by the operation. last is unmolested.
|
||||
*/
|
||||
|
||||
int link_machines( first, last )
|
||||
int first, last;
|
||||
{
|
||||
if ( first == NIL )
|
||||
return last;
|
||||
|
||||
else if ( last == NIL )
|
||||
return first;
|
||||
|
||||
else
|
||||
{
|
||||
mkxtion( finalst[first], last );
|
||||
finalst[first] = finalst[last];
|
||||
lastst[first] = MAX( lastst[first], lastst[last] );
|
||||
firstst[first] = MIN( firstst[first], firstst[last] );
|
||||
|
||||
return first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mark_beginning_as_normal - mark each "beginning" state in a machine
|
||||
* as being a "normal" (i.e., not trailing context-
|
||||
* associated) states
|
||||
*
|
||||
* The "beginning" states are the epsilon closure of the first state
|
||||
*/
|
||||
|
||||
void mark_beginning_as_normal( mach )
|
||||
int mach;
|
||||
{
|
||||
switch ( state_type[mach] )
|
||||
{
|
||||
case STATE_NORMAL:
|
||||
/* Oh, we've already visited here. */
|
||||
return;
|
||||
|
||||
case STATE_TRAILING_CONTEXT:
|
||||
state_type[mach] = STATE_NORMAL;
|
||||
|
||||
if ( transchar[mach] == SYM_EPSILON )
|
||||
{
|
||||
if ( trans1[mach] != NO_TRANSITION )
|
||||
mark_beginning_as_normal(
|
||||
trans1[mach] );
|
||||
|
||||
if ( trans2[mach] != NO_TRANSITION )
|
||||
mark_beginning_as_normal(
|
||||
trans2[mach] );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
flexerror(
|
||||
_( "bad state type in mark_beginning_as_normal()" ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mkbranch - make a machine that branches to two machines
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* branch = mkbranch( first, second );
|
||||
*
|
||||
* branch - a machine which matches either first's pattern or second's
|
||||
* first, second - machines whose patterns are to be or'ed (the | operator)
|
||||
*
|
||||
* Note that first and second are NEITHER destroyed by the operation. Also,
|
||||
* the resulting machine CANNOT be used with any other "mk" operation except
|
||||
* more mkbranch's. Compare with mkor()
|
||||
*/
|
||||
|
||||
int mkbranch( first, second )
|
||||
int first, second;
|
||||
{
|
||||
int eps;
|
||||
|
||||
if ( first == NO_TRANSITION )
|
||||
return second;
|
||||
|
||||
else if ( second == NO_TRANSITION )
|
||||
return first;
|
||||
|
||||
eps = mkstate( SYM_EPSILON );
|
||||
|
||||
mkxtion( eps, first );
|
||||
mkxtion( eps, second );
|
||||
|
||||
return eps;
|
||||
}
|
||||
|
||||
|
||||
/* mkclos - convert a machine into a closure
|
||||
*
|
||||
* synopsis
|
||||
* new = mkclos( state );
|
||||
*
|
||||
* new - a new state which matches the closure of "state"
|
||||
*/
|
||||
|
||||
int mkclos( state )
|
||||
int state;
|
||||
{
|
||||
return mkopt( mkposcl( state ) );
|
||||
}
|
||||
|
||||
|
||||
/* mkopt - make a machine optional
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* new = mkopt( mach );
|
||||
*
|
||||
* new - a machine which optionally matches whatever mach matched
|
||||
* mach - the machine to make optional
|
||||
*
|
||||
* notes:
|
||||
* 1. mach must be the last machine created
|
||||
* 2. mach is destroyed by the call
|
||||
*/
|
||||
|
||||
int mkopt( mach )
|
||||
int mach;
|
||||
{
|
||||
int eps;
|
||||
|
||||
if ( ! SUPER_FREE_EPSILON(finalst[mach]) )
|
||||
{
|
||||
eps = mkstate( SYM_EPSILON );
|
||||
mach = link_machines( mach, eps );
|
||||
}
|
||||
|
||||
/* Can't skimp on the following if FREE_EPSILON(mach) is true because
|
||||
* some state interior to "mach" might point back to the beginning
|
||||
* for a closure.
|
||||
*/
|
||||
eps = mkstate( SYM_EPSILON );
|
||||
mach = link_machines( eps, mach );
|
||||
|
||||
mkxtion( mach, finalst[mach] );
|
||||
|
||||
return mach;
|
||||
}
|
||||
|
||||
|
||||
/* mkor - make a machine that matches either one of two machines
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* new = mkor( first, second );
|
||||
*
|
||||
* new - a machine which matches either first's pattern or second's
|
||||
* first, second - machines whose patterns are to be or'ed (the | operator)
|
||||
*
|
||||
* note that first and second are both destroyed by the operation
|
||||
* the code is rather convoluted because an attempt is made to minimize
|
||||
* the number of epsilon states needed
|
||||
*/
|
||||
|
||||
int mkor( first, second )
|
||||
int first, second;
|
||||
{
|
||||
int eps, orend;
|
||||
|
||||
if ( first == NIL )
|
||||
return second;
|
||||
|
||||
else if ( second == NIL )
|
||||
return first;
|
||||
|
||||
else
|
||||
{
|
||||
/* See comment in mkopt() about why we can't use the first
|
||||
* state of "first" or "second" if they satisfy "FREE_EPSILON".
|
||||
*/
|
||||
eps = mkstate( SYM_EPSILON );
|
||||
|
||||
first = link_machines( eps, first );
|
||||
|
||||
mkxtion( first, second );
|
||||
|
||||
if ( SUPER_FREE_EPSILON(finalst[first]) &&
|
||||
accptnum[finalst[first]] == NIL )
|
||||
{
|
||||
orend = finalst[first];
|
||||
mkxtion( finalst[second], orend );
|
||||
}
|
||||
|
||||
else if ( SUPER_FREE_EPSILON(finalst[second]) &&
|
||||
accptnum[finalst[second]] == NIL )
|
||||
{
|
||||
orend = finalst[second];
|
||||
mkxtion( finalst[first], orend );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
eps = mkstate( SYM_EPSILON );
|
||||
|
||||
first = link_machines( first, eps );
|
||||
orend = finalst[first];
|
||||
|
||||
mkxtion( finalst[second], orend );
|
||||
}
|
||||
}
|
||||
|
||||
finalst[first] = orend;
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
/* mkposcl - convert a machine into a positive closure
|
||||
*
|
||||
* synopsis
|
||||
* new = mkposcl( state );
|
||||
*
|
||||
* new - a machine matching the positive closure of "state"
|
||||
*/
|
||||
|
||||
int mkposcl( state )
|
||||
int state;
|
||||
{
|
||||
int eps;
|
||||
|
||||
if ( SUPER_FREE_EPSILON(finalst[state]) )
|
||||
{
|
||||
mkxtion( finalst[state], state );
|
||||
return state;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
eps = mkstate( SYM_EPSILON );
|
||||
mkxtion( eps, state );
|
||||
return link_machines( state, eps );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mkrep - make a replicated machine
|
||||
*
|
||||
* synopsis
|
||||
* new = mkrep( mach, lb, ub );
|
||||
*
|
||||
* new - a machine that matches whatever "mach" matched from "lb"
|
||||
* number of times to "ub" number of times
|
||||
*
|
||||
* note
|
||||
* if "ub" is INFINITY then "new" matches "lb" or more occurrences of "mach"
|
||||
*/
|
||||
|
||||
int mkrep( mach, lb, ub )
|
||||
int mach, lb, ub;
|
||||
{
|
||||
int base_mach, tail, copy, i;
|
||||
|
||||
base_mach = copysingl( mach, lb - 1 );
|
||||
|
||||
if ( ub == INFINITY )
|
||||
{
|
||||
copy = dupmachine( mach );
|
||||
mach = link_machines( mach,
|
||||
link_machines( base_mach, mkclos( copy ) ) );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tail = mkstate( SYM_EPSILON );
|
||||
|
||||
for ( i = lb; i < ub; ++i )
|
||||
{
|
||||
copy = dupmachine( mach );
|
||||
tail = mkopt( link_machines( copy, tail ) );
|
||||
}
|
||||
|
||||
mach = link_machines( mach, link_machines( base_mach, tail ) );
|
||||
}
|
||||
|
||||
return mach;
|
||||
}
|
||||
|
||||
|
||||
/* mkstate - create a state with a transition on a given symbol
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* state = mkstate( sym );
|
||||
*
|
||||
* state - a new state matching sym
|
||||
* sym - the symbol the new state is to have an out-transition on
|
||||
*
|
||||
* note that this routine makes new states in ascending order through the
|
||||
* state array (and increments LASTNFA accordingly). The routine DUPMACHINE
|
||||
* relies on machines being made in ascending order and that they are
|
||||
* CONTIGUOUS. Change it and you will have to rewrite DUPMACHINE (kludge
|
||||
* that it admittedly is)
|
||||
*/
|
||||
|
||||
int mkstate( sym )
|
||||
int sym;
|
||||
{
|
||||
if ( ++lastnfa >= current_mns )
|
||||
{
|
||||
if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS )
|
||||
lerrif(
|
||||
_( "input rules are too complicated (>= %d NFA states)" ),
|
||||
current_mns );
|
||||
|
||||
++num_reallocs;
|
||||
|
||||
firstst = reallocate_integer_array( firstst, current_mns );
|
||||
lastst = reallocate_integer_array( lastst, current_mns );
|
||||
finalst = reallocate_integer_array( finalst, current_mns );
|
||||
transchar = reallocate_integer_array( transchar, current_mns );
|
||||
trans1 = reallocate_integer_array( trans1, current_mns );
|
||||
trans2 = reallocate_integer_array( trans2, current_mns );
|
||||
accptnum = reallocate_integer_array( accptnum, current_mns );
|
||||
assoc_rule =
|
||||
reallocate_integer_array( assoc_rule, current_mns );
|
||||
state_type =
|
||||
reallocate_integer_array( state_type, current_mns );
|
||||
}
|
||||
|
||||
firstst[lastnfa] = lastnfa;
|
||||
finalst[lastnfa] = lastnfa;
|
||||
lastst[lastnfa] = lastnfa;
|
||||
transchar[lastnfa] = sym;
|
||||
trans1[lastnfa] = NO_TRANSITION;
|
||||
trans2[lastnfa] = NO_TRANSITION;
|
||||
accptnum[lastnfa] = NIL;
|
||||
assoc_rule[lastnfa] = num_rules;
|
||||
state_type[lastnfa] = current_state_type;
|
||||
|
||||
/* Fix up equivalence classes base on this transition. Note that any
|
||||
* character which has its own transition gets its own equivalence
|
||||
* class. Thus only characters which are only in character classes
|
||||
* have a chance at being in the same equivalence class. E.g. "a|b"
|
||||
* puts 'a' and 'b' into two different equivalence classes. "[ab]"
|
||||
* puts them in the same equivalence class (barring other differences
|
||||
* elsewhere in the input).
|
||||
*/
|
||||
|
||||
if ( sym < 0 )
|
||||
{
|
||||
/* We don't have to update the equivalence classes since
|
||||
* that was already done when the ccl was created for the
|
||||
* first time.
|
||||
*/
|
||||
}
|
||||
|
||||
else if ( sym == SYM_EPSILON )
|
||||
++numeps;
|
||||
|
||||
else
|
||||
{
|
||||
check_char( sym );
|
||||
|
||||
if ( useecs )
|
||||
/* Map NUL's to csize. */
|
||||
mkechar( sym ? sym : csize, nextecm, ecgroup );
|
||||
}
|
||||
|
||||
return lastnfa;
|
||||
}
|
||||
|
||||
|
||||
/* mkxtion - make a transition from one state to another
|
||||
*
|
||||
* synopsis
|
||||
*
|
||||
* mkxtion( statefrom, stateto );
|
||||
*
|
||||
* statefrom - the state from which the transition is to be made
|
||||
* stateto - the state to which the transition is to be made
|
||||
*/
|
||||
|
||||
void mkxtion( statefrom, stateto )
|
||||
int statefrom, stateto;
|
||||
{
|
||||
if ( trans1[statefrom] == NO_TRANSITION )
|
||||
trans1[statefrom] = stateto;
|
||||
|
||||
else if ( (transchar[statefrom] != SYM_EPSILON) ||
|
||||
(trans2[statefrom] != NO_TRANSITION) )
|
||||
flexfatal( _( "found too many transitions in mkxtion()" ) );
|
||||
|
||||
else
|
||||
{ /* second out-transition for an epsilon state */
|
||||
++eps2;
|
||||
trans2[statefrom] = stateto;
|
||||
}
|
||||
}
|
||||
|
||||
/* new_rule - initialize for a new rule */
|
||||
|
||||
void new_rule()
|
||||
{
|
||||
if ( ++num_rules >= current_max_rules )
|
||||
{
|
||||
++num_reallocs;
|
||||
current_max_rules += MAX_RULES_INCREMENT;
|
||||
rule_type = reallocate_integer_array( rule_type,
|
||||
current_max_rules );
|
||||
rule_linenum = reallocate_integer_array( rule_linenum,
|
||||
current_max_rules );
|
||||
rule_useful = reallocate_integer_array( rule_useful,
|
||||
current_max_rules );
|
||||
}
|
||||
|
||||
if ( num_rules > MAX_RULE )
|
||||
lerrif( _( "too many rules (> %d)!" ), MAX_RULE );
|
||||
|
||||
rule_linenum[num_rules] = linenum;
|
||||
rule_useful[num_rules] = false;
|
||||
}
|
@ -1,914 +0,0 @@
|
||||
/* 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 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 $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
|
||||
/* 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 __hpux
|
||||
void *alloca ();
|
||||
# else
|
||||
# ifdef __TURBOC__
|
||||
# include <malloc.h>
|
||||
# else
|
||||
char *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;
|
||||
}
|
||||
|
||||
trlcontxt = true;
|
||||
|
||||
eps = mkstate( SYM_EPSILON );
|
||||
$$ = link_machines( $1,
|
||||
link_machines( eps, mkstate( '\n' ) ) );
|
||||
}
|
||||
|
||||
| re
|
||||
{
|
||||
$$ = $1;
|
||||
|
||||
if ( trlcontxt )
|
||||
{
|
||||
if ( lex_compat || (varlength && headcnt == 0) )
|
||||
/* Both head and trail are
|
||||
* variable-length.
|
||||
*/
|
||||
variable_trail_rule = true;
|
||||
else
|
||||
trailcnt = rulelen;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
re : re '|' series
|
||||
{
|
||||
varlength = true;
|
||||
$$ = mkor( $1, $3 );
|
||||
}
|
||||
|
||||
| series
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
re2 : re '/'
|
||||
{
|
||||
/* This rule is written separately so the
|
||||
* reduction will occur before the trailing
|
||||
* series is parsed.
|
||||
*/
|
||||
|
||||
if ( trlcontxt )
|
||||
synerr( "trailing context used twice" );
|
||||
else
|
||||
trlcontxt = true;
|
||||
|
||||
if ( varlength )
|
||||
/* We hope the trailing context is
|
||||
* fixed-length.
|
||||
*/
|
||||
varlength = false;
|
||||
else
|
||||
headcnt = rulelen;
|
||||
|
||||
rulelen = 0;
|
||||
|
||||
current_state_type = STATE_TRAILING_CONTEXT;
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
series : series singleton
|
||||
{
|
||||
/* This is where concatenation of adjacent patterns
|
||||
* gets done.
|
||||
*/
|
||||
$$ = link_machines( $1, $2 );
|
||||
}
|
||||
|
||||
| singleton
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
singleton : singleton '*'
|
||||
{
|
||||
varlength = true;
|
||||
|
||||
$$ = mkclos( $1 );
|
||||
}
|
||||
|
||||
| singleton '+'
|
||||
{
|
||||
varlength = true;
|
||||
$$ = mkposcl( $1 );
|
||||
}
|
||||
|
||||
| singleton '?'
|
||||
{
|
||||
varlength = true;
|
||||
$$ = mkopt( $1 );
|
||||
}
|
||||
|
||||
| singleton '{' NUMBER ',' NUMBER '}'
|
||||
{
|
||||
varlength = true;
|
||||
|
||||
if ( $3 > $5 || $3 < 0 )
|
||||
{
|
||||
synerr( "bad iteration values" );
|
||||
$$ = $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $3 == 0 )
|
||||
{
|
||||
if ( $5 <= 0 )
|
||||
{
|
||||
synerr(
|
||||
"bad iteration values" );
|
||||
$$ = $1;
|
||||
}
|
||||
else
|
||||
$$ = mkopt(
|
||||
mkrep( $1, 1, $5 ) );
|
||||
}
|
||||
else
|
||||
$$ = mkrep( $1, $3, $5 );
|
||||
}
|
||||
}
|
||||
|
||||
| singleton '{' NUMBER ',' '}'
|
||||
{
|
||||
varlength = true;
|
||||
|
||||
if ( $3 <= 0 )
|
||||
{
|
||||
synerr( "iteration value must be positive" );
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
else
|
||||
$$ = mkrep( $1, $3, INFINITY );
|
||||
}
|
||||
|
||||
| singleton '{' NUMBER '}'
|
||||
{
|
||||
/* The singleton could be something like "(foo)",
|
||||
* in which case we have no idea what its length
|
||||
* is, so we punt here.
|
||||
*/
|
||||
varlength = true;
|
||||
|
||||
if ( $3 <= 0 )
|
||||
{
|
||||
synerr( "iteration value must be positive" );
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
else
|
||||
$$ = link_machines( $1,
|
||||
copysingl( $1, $3 - 1 ) );
|
||||
}
|
||||
|
||||
| '.'
|
||||
{
|
||||
if ( ! madeany )
|
||||
{
|
||||
/* Create the '.' character class. */
|
||||
anyccl = cclinit();
|
||||
ccladd( anyccl, '\n' );
|
||||
cclnegate( anyccl );
|
||||
|
||||
if ( useecs )
|
||||
mkeccl( ccltbl + cclmap[anyccl],
|
||||
ccllen[anyccl], nextecm,
|
||||
ecgroup, csize, csize );
|
||||
|
||||
madeany = true;
|
||||
}
|
||||
|
||||
++rulelen;
|
||||
|
||||
$$ = mkstate( -anyccl );
|
||||
}
|
||||
|
||||
| fullccl
|
||||
{
|
||||
if ( ! cclsorted )
|
||||
/* Sort characters for fast searching. We
|
||||
* use a shell sort since this list could
|
||||
* be large.
|
||||
*/
|
||||
cshell( ccltbl + cclmap[$1], ccllen[$1], true );
|
||||
|
||||
if ( useecs )
|
||||
mkeccl( ccltbl + cclmap[$1], ccllen[$1],
|
||||
nextecm, ecgroup, csize, csize );
|
||||
|
||||
++rulelen;
|
||||
|
||||
$$ = mkstate( -$1 );
|
||||
}
|
||||
|
||||
| PREVCCL
|
||||
{
|
||||
++rulelen;
|
||||
|
||||
$$ = mkstate( -$1 );
|
||||
}
|
||||
|
||||
| '"' string '"'
|
||||
{ $$ = $2; }
|
||||
|
||||
| '(' re ')'
|
||||
{ $$ = $2; }
|
||||
|
||||
| CHAR
|
||||
{
|
||||
++rulelen;
|
||||
|
||||
if ( caseins && $1 >= 'A' && $1 <= 'Z' )
|
||||
$1 = clower( $1 );
|
||||
|
||||
$$ = mkstate( $1 );
|
||||
}
|
||||
;
|
||||
|
||||
fullccl : '[' ccl ']'
|
||||
{ $$ = $2; }
|
||||
|
||||
| '[' '^' ccl ']'
|
||||
{
|
||||
cclnegate( $3 );
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
ccl : ccl CHAR '-' CHAR
|
||||
{
|
||||
if ( caseins )
|
||||
{
|
||||
if ( $2 >= 'A' && $2 <= 'Z' )
|
||||
$2 = clower( $2 );
|
||||
if ( $4 >= 'A' && $4 <= 'Z' )
|
||||
$4 = clower( $4 );
|
||||
}
|
||||
|
||||
if ( $2 > $4 )
|
||||
synerr( "negative range in character class" );
|
||||
|
||||
else
|
||||
{
|
||||
for ( i = $2; i <= $4; ++i )
|
||||
ccladd( $1, i );
|
||||
|
||||
/* Keep track if this ccl is staying in
|
||||
* alphabetical order.
|
||||
*/
|
||||
cclsorted = cclsorted && ($2 > lastchar);
|
||||
lastchar = $4;
|
||||
}
|
||||
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
| ccl CHAR
|
||||
{
|
||||
if ( caseins && $2 >= 'A' && $2 <= 'Z' )
|
||||
$2 = clower( $2 );
|
||||
|
||||
ccladd( $1, $2 );
|
||||
cclsorted = cclsorted && ($2 > lastchar);
|
||||
lastchar = $2;
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
| ccl ccl_expr
|
||||
{
|
||||
/* Too hard to properly maintain cclsorted. */
|
||||
cclsorted = false;
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
|
|
||||
{
|
||||
cclsorted = true;
|
||||
lastchar = 0;
|
||||
currccl = $$ = cclinit();
|
||||
}
|
||||
;
|
||||
|
||||
ccl_expr: CCE_ALNUM { CCL_EXPR(isalnum) }
|
||||
| CCE_ALPHA { CCL_EXPR(isalpha) }
|
||||
| CCE_BLANK { CCL_EXPR(IS_BLANK) }
|
||||
| CCE_CNTRL { CCL_EXPR(iscntrl) }
|
||||
| CCE_DIGIT { CCL_EXPR(isdigit) }
|
||||
| CCE_GRAPH { CCL_EXPR(isgraph) }
|
||||
| CCE_LOWER { CCL_EXPR(islower) }
|
||||
| CCE_PRINT { CCL_EXPR(isprint) }
|
||||
| CCE_PUNCT { CCL_EXPR(ispunct) }
|
||||
| CCE_SPACE { CCL_EXPR(isspace) }
|
||||
| CCE_UPPER {
|
||||
if ( caseins )
|
||||
CCL_EXPR(islower)
|
||||
else
|
||||
CCL_EXPR(isupper)
|
||||
}
|
||||
| CCE_XDIGIT { CCL_EXPR(isxdigit) }
|
||||
;
|
||||
|
||||
string : string CHAR
|
||||
{
|
||||
if ( caseins && $2 >= 'A' && $2 <= 'Z' )
|
||||
$2 = clower( $2 );
|
||||
|
||||
++rulelen;
|
||||
|
||||
$$ = link_machines( $1, mkstate( $2 ) );
|
||||
}
|
||||
|
||||
|
|
||||
{ $$ = mkstate( SYM_EPSILON ); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
|
||||
/* build_eof_action - build the "<<EOF>>" action for the active start
|
||||
* conditions
|
||||
*/
|
||||
|
||||
void build_eof_action()
|
||||
{
|
||||
int i;
|
||||
char action_text[MAXLINE];
|
||||
|
||||
for ( i = 1; i <= scon_stk_ptr; ++i )
|
||||
{
|
||||
if ( sceof[scon_stk[i]] )
|
||||
format_pinpoint_message(
|
||||
"multiple <<EOF>> rules for start condition %s",
|
||||
scname[scon_stk[i]] );
|
||||
|
||||
else
|
||||
{
|
||||
sceof[scon_stk[i]] = true;
|
||||
sprintf( action_text, "case YY_STATE_EOF(%s):\n",
|
||||
scname[scon_stk[i]] );
|
||||
add_action( action_text );
|
||||
}
|
||||
}
|
||||
|
||||
line_directive_out( (FILE *) 0, 1 );
|
||||
|
||||
/* This isn't a normal rule after all - don't count it as
|
||||
* such, so we don't have any holes in the rule numbering
|
||||
* (which make generating "rule can never match" warnings
|
||||
* more difficult.
|
||||
*/
|
||||
--num_rules;
|
||||
++num_eof_rules;
|
||||
}
|
||||
|
||||
|
||||
/* format_synerr - write out formatted syntax error */
|
||||
|
||||
void format_synerr( msg, arg )
|
||||
char msg[], arg[];
|
||||
{
|
||||
char errmsg[MAXLINE];
|
||||
|
||||
(void) sprintf( errmsg, msg, arg );
|
||||
synerr( errmsg );
|
||||
}
|
||||
|
||||
|
||||
/* synerr - report a syntax error */
|
||||
|
||||
void synerr( str )
|
||||
char str[];
|
||||
{
|
||||
syntaxerror = true;
|
||||
pinpoint_message( str );
|
||||
}
|
||||
|
||||
|
||||
/* format_warn - write out formatted warning */
|
||||
|
||||
void format_warn( msg, arg )
|
||||
char msg[], arg[];
|
||||
{
|
||||
char warn_msg[MAXLINE];
|
||||
|
||||
(void) sprintf( warn_msg, msg, arg );
|
||||
warn( warn_msg );
|
||||
}
|
||||
|
||||
|
||||
/* warn - report a warning, unless -w was given */
|
||||
|
||||
void warn( str )
|
||||
char str[];
|
||||
{
|
||||
line_warning( str, linenum );
|
||||
}
|
||||
|
||||
/* format_pinpoint_message - write out a message formatted with one string,
|
||||
* pinpointing its location
|
||||
*/
|
||||
|
||||
void format_pinpoint_message( msg, arg )
|
||||
char msg[], arg[];
|
||||
{
|
||||
char errmsg[MAXLINE];
|
||||
|
||||
(void) sprintf( errmsg, msg, arg );
|
||||
pinpoint_message( errmsg );
|
||||
}
|
||||
|
||||
|
||||
/* pinpoint_message - write out a message, pinpointing its location */
|
||||
|
||||
void pinpoint_message( str )
|
||||
char str[];
|
||||
{
|
||||
line_pinpoint( str, linenum );
|
||||
}
|
||||
|
||||
|
||||
/* line_warning - report a warning at a given line, unless -w was given */
|
||||
|
||||
void line_warning( str, line )
|
||||
char str[];
|
||||
int line;
|
||||
{
|
||||
char warning[MAXLINE];
|
||||
|
||||
if ( ! nowarn )
|
||||
{
|
||||
sprintf( warning, "warning, %s", str );
|
||||
line_pinpoint( warning, line );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* line_pinpoint - write out a message, pinpointing it at the given line */
|
||||
|
||||
void line_pinpoint( str, line )
|
||||
char str[];
|
||||
int line;
|
||||
{
|
||||
fprintf( stderr, "\"%s\", line %d: %s\n", infilename, line, str );
|
||||
}
|
||||
|
||||
|
||||
/* yyerror - eat up an error message from the parser;
|
||||
* currently, messages are ignore
|
||||
*/
|
||||
|
||||
void yyerror( msg )
|
||||
char msg[];
|
||||
{
|
||||
}
|
@ -1,711 +0,0 @@
|
||||
/* 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: /home/daffy/u0/vern/flex/RCS/scan.l,v 2.56 95/04/24 12:17:19 vern Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include "flexdef.h"
|
||||
#include "parse.h"
|
||||
|
||||
#define ACTION_ECHO add_action( yytext )
|
||||
#define ACTION_IFDEF(def, should_define) \
|
||||
{ \
|
||||
if ( should_define ) \
|
||||
action_define( def, 1 ); \
|
||||
}
|
||||
|
||||
#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;
|
||||
%}
|
||||
|
||||
%option caseless nodefault outfile="scan.c" stack noyy_top_state
|
||||
%option nostdinit
|
||||
|
||||
%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
|
||||
%x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
|
||||
%x OPTION LINEDIR
|
||||
|
||||
WS [[:blank:]]+
|
||||
OPTWS [[:blank:]]*
|
||||
NOT_WS [^[:blank:]\n]
|
||||
|
||||
NL \r?\n
|
||||
|
||||
NAME ([[:alpha:]_][[:alnum:]_-]*)
|
||||
NOT_NAME [^[:alpha:]_*\n]+
|
||||
|
||||
SCNAME {NAME}
|
||||
|
||||
ESCSEQ (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2}))
|
||||
|
||||
FIRST_CCL_CHAR ([^\\\n]|{ESCSEQ})
|
||||
CCL_CHAR ([^\\\n\]]|{ESCSEQ})
|
||||
CCL_EXPR ("[:"[[:alpha:]]+":]")
|
||||
|
||||
LEXOPT [aceknopr]
|
||||
|
||||
%%
|
||||
static int bracelevel, didadef, indented_code;
|
||||
static int doing_rule_action = false;
|
||||
static int option_sense;
|
||||
|
||||
int doing_codeblock = false;
|
||||
int i;
|
||||
Char nmdef[MAXLINE], myesc();
|
||||
|
||||
|
||||
<INITIAL>{
|
||||
^{WS} indented_code = true; BEGIN(CODEBLOCK);
|
||||
^"/*" ACTION_ECHO; yy_push_state( COMMENT );
|
||||
^#{OPTWS}line{WS} yy_push_state( LINEDIR );
|
||||
^"%s"{NAME}? return SCDECL;
|
||||
^"%x"{NAME}? return XSCDECL;
|
||||
^"%{".*{NL} {
|
||||
++linenum;
|
||||
line_directive_out( (FILE *) 0, 1 );
|
||||
indented_code = false;
|
||||
BEGIN(CODEBLOCK);
|
||||
}
|
||||
|
||||
{WS} /* discard */
|
||||
|
||||
^"%%".* {
|
||||
sectnum = 2;
|
||||
bracelevel = 0;
|
||||
mark_defs1();
|
||||
line_directive_out( (FILE *) 0, 1 );
|
||||
BEGIN(SECT2PROLOG);
|
||||
return SECTEND;
|
||||
}
|
||||
|
||||
^"%pointer".*{NL} yytext_is_array = false; ++linenum;
|
||||
^"%array".*{NL} yytext_is_array = true; ++linenum;
|
||||
|
||||
^"%option" BEGIN(OPTION); return OPTION_OP;
|
||||
|
||||
^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL} ++linenum; /* ignore */
|
||||
^"%"{LEXOPT}{WS}.*{NL} ++linenum; /* ignore */
|
||||
|
||||
^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) );
|
||||
|
||||
^{NAME} {
|
||||
strcpy( nmstr, yytext );
|
||||
didadef = false;
|
||||
BEGIN(PICKUPDEF);
|
||||
}
|
||||
|
||||
{SCNAME} RETURNNAME;
|
||||
^{OPTWS}{NL} ++linenum; /* allows blank lines in section 1 */
|
||||
{OPTWS}{NL} ACTION_ECHO; ++linenum; /* maybe end of comment line */
|
||||
}
|
||||
|
||||
|
||||
<COMMENT>{
|
||||
"*/" ACTION_ECHO; yy_pop_state();
|
||||
"*" ACTION_ECHO;
|
||||
[^*\n]+ ACTION_ECHO;
|
||||
[^*\n]*{NL} ++linenum; ACTION_ECHO;
|
||||
}
|
||||
|
||||
<LINEDIR>{
|
||||
\n yy_pop_state();
|
||||
[[:digit:]]+ linenum = myctoi( yytext );
|
||||
|
||||
\"[^"\n]*\" {
|
||||
flex_free( (void *) infilename );
|
||||
infilename = copy_string( yytext + 1 );
|
||||
infilename[strlen( infilename ) - 1] = '\0';
|
||||
}
|
||||
. /* ignore spurious characters */
|
||||
}
|
||||
|
||||
<CODEBLOCK>{
|
||||
^"%}".*{NL} ++linenum; BEGIN(INITIAL);
|
||||
|
||||
{NAME}|{NOT_NAME}|. ACTION_ECHO;
|
||||
|
||||
{NL} {
|
||||
++linenum;
|
||||
ACTION_ECHO;
|
||||
if ( indented_code )
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<PICKUPDEF>{
|
||||
{WS} /* separates name and definition */
|
||||
|
||||
{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;
|
||||
}
|
||||
|
||||
{NL} {
|
||||
if ( ! didadef )
|
||||
synerr( _( "incomplete name definition" ) );
|
||||
BEGIN(INITIAL);
|
||||
++linenum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<OPTION>{
|
||||
{NL} ++linenum; BEGIN(INITIAL);
|
||||
{WS} option_sense = true;
|
||||
|
||||
"=" return '=';
|
||||
|
||||
no option_sense = ! option_sense;
|
||||
|
||||
7bit csize = option_sense ? 128 : 256;
|
||||
8bit csize = option_sense ? 256 : 128;
|
||||
|
||||
align long_align = option_sense;
|
||||
always-interactive {
|
||||
action_define( "YY_ALWAYS_INTERACTIVE", option_sense );
|
||||
}
|
||||
array yytext_is_array = option_sense;
|
||||
backup backing_up_report = option_sense;
|
||||
batch interactive = ! option_sense;
|
||||
"c++" C_plus_plus = option_sense;
|
||||
caseful|case-sensitive caseins = ! option_sense;
|
||||
caseless|case-insensitive caseins = option_sense;
|
||||
debug ddebug = option_sense;
|
||||
default spprdflt = ! option_sense;
|
||||
ecs useecs = option_sense;
|
||||
fast {
|
||||
useecs = usemecs = false;
|
||||
use_read = fullspd = true;
|
||||
}
|
||||
full {
|
||||
useecs = usemecs = false;
|
||||
use_read = fulltbl = true;
|
||||
}
|
||||
input ACTION_IFDEF("YY_NO_INPUT", ! option_sense);
|
||||
interactive interactive = option_sense;
|
||||
lex-compat lex_compat = option_sense;
|
||||
main {
|
||||
action_define( "YY_MAIN", option_sense );
|
||||
do_yywrap = ! option_sense;
|
||||
}
|
||||
meta-ecs usemecs = option_sense;
|
||||
never-interactive {
|
||||
action_define( "YY_NEVER_INTERACTIVE", option_sense );
|
||||
}
|
||||
perf-report performance_report += option_sense ? 1 : -1;
|
||||
pointer yytext_is_array = ! option_sense;
|
||||
read use_read = option_sense;
|
||||
reject reject_really_used = option_sense;
|
||||
stack action_define( "YY_STACK_USED", option_sense );
|
||||
stdinit do_stdinit = option_sense;
|
||||
stdout use_stdout = option_sense;
|
||||
unput ACTION_IFDEF("YY_NO_UNPUT", ! option_sense);
|
||||
verbose printstats = option_sense;
|
||||
warn nowarn = ! option_sense;
|
||||
yylineno do_yylineno = option_sense;
|
||||
yymore yymore_really_used = option_sense;
|
||||
yywrap do_yywrap = option_sense;
|
||||
|
||||
yy_push_state ACTION_IFDEF("YY_NO_PUSH_STATE", ! option_sense);
|
||||
yy_pop_state ACTION_IFDEF("YY_NO_POP_STATE", ! option_sense);
|
||||
yy_top_state ACTION_IFDEF("YY_NO_TOP_STATE", ! option_sense);
|
||||
|
||||
yy_scan_buffer ACTION_IFDEF("YY_NO_SCAN_BUFFER", ! option_sense);
|
||||
yy_scan_bytes ACTION_IFDEF("YY_NO_SCAN_BYTES", ! option_sense);
|
||||
yy_scan_string ACTION_IFDEF("YY_NO_SCAN_STRING", ! option_sense);
|
||||
|
||||
outfile return OPT_OUTFILE;
|
||||
prefix return OPT_PREFIX;
|
||||
yyclass return OPT_YYCLASS;
|
||||
|
||||
\"[^"\n]*\" {
|
||||
strcpy( nmstr, yytext + 1 );
|
||||
nmstr[strlen( nmstr ) - 1] = '\0';
|
||||
return NAME;
|
||||
}
|
||||
|
||||
(([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|. {
|
||||
format_synerr( _( "unrecognized %%option: %s" ),
|
||||
yytext );
|
||||
BEGIN(RECOVER);
|
||||
}
|
||||
}
|
||||
|
||||
<RECOVER>.*{NL} ++linenum; BEGIN(INITIAL);
|
||||
|
||||
|
||||
<SECT2PROLOG>{
|
||||
^"%{".* ++bracelevel; yyless( 2 ); /* eat only %{ */
|
||||
^"%}".* --bracelevel; yyless( 2 ); /* eat only %} */
|
||||
|
||||
^{WS}.* ACTION_ECHO; /* indented code in prolog */
|
||||
|
||||
^{NOT_WS}.* { /* non-indented code */
|
||||
if ( bracelevel <= 0 )
|
||||
{ /* not in %{ ... %} */
|
||||
yyless( 0 ); /* put it all back */
|
||||
yy_set_bol( 1 );
|
||||
mark_prolog();
|
||||
BEGIN(SECT2);
|
||||
}
|
||||
else
|
||||
ACTION_ECHO;
|
||||
}
|
||||
|
||||
.* ACTION_ECHO;
|
||||
{NL} ++linenum; ACTION_ECHO;
|
||||
|
||||
<<EOF>> {
|
||||
mark_prolog();
|
||||
sectnum = 0;
|
||||
yyterminate(); /* to stop the parser */
|
||||
}
|
||||
}
|
||||
|
||||
<SECT2>{
|
||||
^{OPTWS}{NL} ++linenum; /* allow blank lines in section 2 */
|
||||
|
||||
^{OPTWS}"%{" {
|
||||
indented_code = false;
|
||||
doing_codeblock = true;
|
||||
bracelevel = 1;
|
||||
BEGIN(PERCENT_BRACE_ACTION);
|
||||
}
|
||||
|
||||
^{OPTWS}"<" BEGIN(SC); return '<';
|
||||
^{OPTWS}"^" return '^';
|
||||
\" BEGIN(QUOTE); return '"';
|
||||
"{"/[[:digit:]] BEGIN(NUM); return '{';
|
||||
"$"/([[:blank:]]|{NL}) return '$';
|
||||
|
||||
{WS}"%{" {
|
||||
bracelevel = 1;
|
||||
BEGIN(PERCENT_BRACE_ACTION);
|
||||
|
||||
if ( in_rule )
|
||||
{
|
||||
doing_rule_action = true;
|
||||
in_rule = false;
|
||||
return '\n';
|
||||
}
|
||||
}
|
||||
{WS}"|".*{NL} continued_action = true; ++linenum; return '\n';
|
||||
|
||||
^{WS}"/*" {
|
||||
yyless( yyleng - 2 ); /* put back '/', '*' */
|
||||
bracelevel = 0;
|
||||
continued_action = false;
|
||||
BEGIN(ACTION);
|
||||
}
|
||||
|
||||
^{WS} /* allow indented rules */
|
||||
|
||||
{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);
|
||||
|
||||
if ( in_rule )
|
||||
{
|
||||
doing_rule_action = true;
|
||||
in_rule = false;
|
||||
return '\n';
|
||||
}
|
||||
}
|
||||
|
||||
{OPTWS}{NL} {
|
||||
bracelevel = 0;
|
||||
continued_action = false;
|
||||
BEGIN(ACTION);
|
||||
unput( '\n' ); /* so <ACTION> sees it */
|
||||
|
||||
if ( in_rule )
|
||||
{
|
||||
doing_rule_action = true;
|
||||
in_rule = false;
|
||||
return '\n';
|
||||
}
|
||||
}
|
||||
|
||||
^{OPTWS}"<<EOF>>" |
|
||||
"<<EOF>>" return EOF_OP;
|
||||
|
||||
^"%%".* {
|
||||
sectnum = 3;
|
||||
BEGIN(SECT3);
|
||||
yyterminate(); /* to stop the parser */
|
||||
}
|
||||
|
||||
"["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})* {
|
||||
int cclval;
|
||||
|
||||
strcpy( nmstr, yytext );
|
||||
|
||||
/* Check to see if we've already encountered this
|
||||
* ccl.
|
||||
*/
|
||||
if ( (cclval = ccllookup( (Char *) nmstr )) != 0 )
|
||||
{
|
||||
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 '[';
|
||||
}
|
||||
}
|
||||
|
||||
"{"{NAME}"}" {
|
||||
Char *nmdefptr;
|
||||
Char *ndlookup();
|
||||
|
||||
strcpy( nmstr, yytext + 1 );
|
||||
nmstr[yyleng - 2] = '\0'; /* chop trailing brace */
|
||||
|
||||
if ( (nmdefptr = ndlookup( nmstr )) == 0 )
|
||||
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('(');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[/|*+?.(){}] return (unsigned char) yytext[0];
|
||||
. RETURNCHAR;
|
||||
}
|
||||
|
||||
|
||||
<SC>{
|
||||
[,*] return (unsigned char) yytext[0];
|
||||
">" BEGIN(SECT2); return '>';
|
||||
">"/^ BEGIN(CARETISBOL); return '>';
|
||||
{SCNAME} RETURNNAME;
|
||||
. {
|
||||
format_synerr( _( "bad <start condition>: %s" ),
|
||||
yytext );
|
||||
}
|
||||
}
|
||||
|
||||
<CARETISBOL>"^" BEGIN(SECT2); return '^';
|
||||
|
||||
|
||||
<QUOTE>{
|
||||
[^"\n] RETURNCHAR;
|
||||
\" BEGIN(SECT2); return '"';
|
||||
|
||||
{NL} {
|
||||
synerr( _( "missing quote" ) );
|
||||
BEGIN(SECT2);
|
||||
++linenum;
|
||||
return '"';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<FIRSTCCL>{
|
||||
"^"/[^-\]\n] BEGIN(CCL); return '^';
|
||||
"^"/("-"|"]") return '^';
|
||||
. BEGIN(CCL); RETURNCHAR;
|
||||
}
|
||||
|
||||
<CCL>{
|
||||
-/[^\]\n] return '-';
|
||||
[^\]\n] RETURNCHAR;
|
||||
"]" BEGIN(SECT2); return ']';
|
||||
.|{NL} {
|
||||
synerr( _( "bad character class" ) );
|
||||
BEGIN(SECT2);
|
||||
return ']';
|
||||
}
|
||||
}
|
||||
|
||||
<FIRSTCCL,CCL>{
|
||||
"[:alnum:]" BEGIN(CCL); return CCE_ALNUM;
|
||||
"[:alpha:]" BEGIN(CCL); return CCE_ALPHA;
|
||||
"[:blank:]" BEGIN(CCL); return CCE_BLANK;
|
||||
"[:cntrl:]" BEGIN(CCL); return CCE_CNTRL;
|
||||
"[:digit:]" BEGIN(CCL); return CCE_DIGIT;
|
||||
"[:graph:]" BEGIN(CCL); return CCE_GRAPH;
|
||||
"[:lower:]" BEGIN(CCL); return CCE_LOWER;
|
||||
"[:print:]" BEGIN(CCL); return CCE_PRINT;
|
||||
"[:punct:]" BEGIN(CCL); return CCE_PUNCT;
|
||||
"[:space:]" BEGIN(CCL); return CCE_SPACE;
|
||||
"[:upper:]" BEGIN(CCL); return CCE_UPPER;
|
||||
"[:xdigit:]" BEGIN(CCL); return CCE_XDIGIT;
|
||||
{CCL_EXPR} {
|
||||
format_synerr(
|
||||
_( "bad character class expression: %s" ),
|
||||
yytext );
|
||||
BEGIN(CCL); return CCE_ALNUM;
|
||||
}
|
||||
}
|
||||
|
||||
<NUM>{
|
||||
[[:digit:]]+ {
|
||||
yylval = myctoi( yytext );
|
||||
return NUMBER;
|
||||
}
|
||||
|
||||
"," return ',';
|
||||
"}" BEGIN(SECT2); return '}';
|
||||
|
||||
. {
|
||||
synerr( _( "bad character inside {}'s" ) );
|
||||
BEGIN(SECT2);
|
||||
return '}';
|
||||
}
|
||||
|
||||
{NL} {
|
||||
synerr( _( "missing }" ) );
|
||||
BEGIN(SECT2);
|
||||
++linenum;
|
||||
return '}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<PERCENT_BRACE_ACTION>{
|
||||
{OPTWS}"%}".* bracelevel = 0;
|
||||
|
||||
<ACTION>"/*" ACTION_ECHO; yy_push_state( COMMENT );
|
||||
|
||||
<CODEBLOCK,ACTION>{
|
||||
"reject" {
|
||||
ACTION_ECHO;
|
||||
CHECK_REJECT(yytext);
|
||||
}
|
||||
"yymore" {
|
||||
ACTION_ECHO;
|
||||
CHECK_YYMORE(yytext);
|
||||
}
|
||||
}
|
||||
|
||||
{NAME}|{NOT_NAME}|. ACTION_ECHO;
|
||||
{NL} {
|
||||
++linenum;
|
||||
ACTION_ECHO;
|
||||
if ( bracelevel == 0 ||
|
||||
(doing_codeblock && indented_code) )
|
||||
{
|
||||
if ( doing_rule_action )
|
||||
add_action( "\tYY_BREAK\n" );
|
||||
|
||||
doing_rule_action = doing_codeblock = false;
|
||||
BEGIN(SECT2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
|
||||
<ACTION>{
|
||||
"{" ACTION_ECHO; ++bracelevel;
|
||||
"}" ACTION_ECHO; --bracelevel;
|
||||
[^[:alpha:]_{}"'/\n]+ ACTION_ECHO;
|
||||
{NAME} ACTION_ECHO;
|
||||
"'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
|
||||
\" ACTION_ECHO; BEGIN(ACTION_STRING);
|
||||
{NL} {
|
||||
++linenum;
|
||||
ACTION_ECHO;
|
||||
if ( bracelevel == 0 )
|
||||
{
|
||||
if ( doing_rule_action )
|
||||
add_action( "\tYY_BREAK\n" );
|
||||
|
||||
doing_rule_action = false;
|
||||
BEGIN(SECT2);
|
||||
}
|
||||
}
|
||||
. ACTION_ECHO;
|
||||
}
|
||||
|
||||
<ACTION_STRING>{
|
||||
[^"\\\n]+ ACTION_ECHO;
|
||||
\\. ACTION_ECHO;
|
||||
{NL} ++linenum; ACTION_ECHO;
|
||||
\" ACTION_ECHO; BEGIN(ACTION);
|
||||
. ACTION_ECHO;
|
||||
}
|
||||
|
||||
<COMMENT,ACTION,ACTION_STRING><<EOF>> {
|
||||
synerr( _( "EOF encountered inside an action" ) );
|
||||
yyterminate();
|
||||
}
|
||||
|
||||
|
||||
<SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ} {
|
||||
yylval = myesc( (Char *) yytext );
|
||||
|
||||
if ( YY_START == FIRSTCCL )
|
||||
BEGIN(CCL);
|
||||
|
||||
return CHAR;
|
||||
}
|
||||
|
||||
|
||||
<SECT3>{
|
||||
.*(\n?) ECHO;
|
||||
<<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 && strcmp( file, "-" ) )
|
||||
{
|
||||
infilename = copy_string( file );
|
||||
yyin = fopen( infilename, "r" );
|
||||
|
||||
if ( yyin == NULL )
|
||||
lerrsf( _( "can't open %s" ), file );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
yyin = stdin;
|
||||
infilename = copy_string( "<stdin>" );
|
||||
}
|
||||
|
||||
linenum = 1;
|
||||
}
|
||||
|
||||
|
||||
/* Wrapper routines for accessing the scanner's malloc routines. */
|
||||
|
||||
void *flex_alloc( size )
|
||||
size_t size;
|
||||
{
|
||||
return (void *) malloc( size );
|
||||
}
|
||||
|
||||
void *flex_realloc( ptr, size )
|
||||
void *ptr;
|
||||
size_t size;
|
||||
{
|
||||
return (void *) realloc( ptr, size );
|
||||
}
|
||||
|
||||
void flex_free( ptr )
|
||||
void *ptr;
|
||||
{
|
||||
if ( ptr )
|
||||
free( ptr );
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
/* sym - symbol table routines */
|
||||
|
||||
/*-
|
||||
* 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: /home/daffy/u0/vern/flex/RCS/sym.c,v 2.19 95/03/04 16:11:04 vern Exp $ */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "flexdef.h"
|
||||
|
||||
|
||||
/* declare functions that have forward references */
|
||||
|
||||
int hashfunct PROTO((char[], int));
|
||||
|
||||
|
||||
struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE];
|
||||
struct hash_entry *sctbl[START_COND_HASH_SIZE];
|
||||
struct hash_entry *ccltab[CCL_HASH_SIZE];
|
||||
|
||||
struct hash_entry *findsym();
|
||||
|
||||
|
||||
/* addsym - add symbol and definitions to symbol table
|
||||
*
|
||||
* -1 is returned if the symbol already exists, and the change not made.
|
||||
*/
|
||||
|
||||
int addsym( sym, str_def, int_def, table, table_size )
|
||||
char sym[];
|
||||
char *str_def;
|
||||
int int_def;
|
||||
hash_table table;
|
||||
int table_size;
|
||||
{
|
||||
int hash_val = hashfunct( sym, table_size );
|
||||
struct hash_entry *sym_entry = table[hash_val];
|
||||
struct hash_entry *new_entry;
|
||||
struct hash_entry *successor;
|
||||
|
||||
while ( sym_entry )
|
||||
{
|
||||
if ( ! strcmp( sym, sym_entry->name ) )
|
||||
{ /* entry already exists */
|
||||
return -1;
|
||||
}
|
||||
|
||||
sym_entry = sym_entry->next;
|
||||
}
|
||||
|
||||
/* create new entry */
|
||||
new_entry = (struct hash_entry *)
|
||||
flex_alloc( sizeof( struct hash_entry ) );
|
||||
|
||||
if ( new_entry == NULL )
|
||||
flexfatal( _( "symbol table memory allocation failed" ) );
|
||||
|
||||
if ( (successor = table[hash_val]) != 0 )
|
||||
{
|
||||
new_entry->next = successor;
|
||||
successor->prev = new_entry;
|
||||
}
|
||||
else
|
||||
new_entry->next = NULL;
|
||||
|
||||
new_entry->prev = NULL;
|
||||
new_entry->name = sym;
|
||||
new_entry->str_val = str_def;
|
||||
new_entry->int_val = int_def;
|
||||
|
||||
table[hash_val] = new_entry;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* cclinstal - save the text of a character class */
|
||||
|
||||
void cclinstal( ccltxt, cclnum )
|
||||
Char ccltxt[];
|
||||
int cclnum;
|
||||
{
|
||||
/* We don't bother checking the return status because we are not
|
||||
* called unless the symbol is new.
|
||||
*/
|
||||
Char *copy_unsigned_string();
|
||||
|
||||
(void) addsym( (char *) copy_unsigned_string( ccltxt ),
|
||||
(char *) 0, cclnum,
|
||||
ccltab, CCL_HASH_SIZE );
|
||||
}
|
||||
|
||||
|
||||
/* ccllookup - lookup the number associated with character class text
|
||||
*
|
||||
* Returns 0 if there's no CCL associated with the text.
|
||||
*/
|
||||
|
||||
int ccllookup( ccltxt )
|
||||
Char ccltxt[];
|
||||
{
|
||||
return findsym( (char *) ccltxt, ccltab, CCL_HASH_SIZE )->int_val;
|
||||
}
|
||||
|
||||
|
||||
/* findsym - find symbol in symbol table */
|
||||
|
||||
struct hash_entry *findsym( sym, table, table_size )
|
||||
char sym[];
|
||||
hash_table table;
|
||||
int table_size;
|
||||
{
|
||||
static struct hash_entry empty_entry =
|
||||
{
|
||||
(struct hash_entry *) 0, (struct hash_entry *) 0,
|
||||
(char *) 0, (char *) 0, 0,
|
||||
} ;
|
||||
struct hash_entry *sym_entry =
|
||||
table[hashfunct( sym, table_size )];
|
||||
|
||||
while ( sym_entry )
|
||||
{
|
||||
if ( ! strcmp( sym, sym_entry->name ) )
|
||||
return sym_entry;
|
||||
sym_entry = sym_entry->next;
|
||||
}
|
||||
|
||||
return &empty_entry;
|
||||
}
|
||||
|
||||
|
||||
/* hashfunct - compute the hash value for "str" and hash size "hash_size" */
|
||||
|
||||
int hashfunct( str, hash_size )
|
||||
char str[];
|
||||
int hash_size;
|
||||
{
|
||||
int hashval;
|
||||
int locstr;
|
||||
|
||||
hashval = 0;
|
||||
locstr = 0;
|
||||
|
||||
while ( str[locstr] )
|
||||
{
|
||||
hashval = (hashval << 1) + (unsigned char) str[locstr++];
|
||||
hashval %= hash_size;
|
||||
}
|
||||
|
||||
return hashval;
|
||||
}
|
||||
|
||||
|
||||
/* ndinstal - install a name definition */
|
||||
|
||||
void ndinstal( name, definition )
|
||||
char name[];
|
||||
Char definition[];
|
||||
{
|
||||
char *copy_string();
|
||||
Char *copy_unsigned_string();
|
||||
|
||||
if ( addsym( copy_string( name ),
|
||||
(char *) copy_unsigned_string( definition ), 0,
|
||||
ndtbl, NAME_TABLE_HASH_SIZE ) )
|
||||
synerr( _( "name defined twice" ) );
|
||||
}
|
||||
|
||||
|
||||
/* ndlookup - lookup a name definition
|
||||
*
|
||||
* Returns a nil pointer if the name definition does not exist.
|
||||
*/
|
||||
|
||||
Char *ndlookup( nd )
|
||||
char nd[];
|
||||
{
|
||||
return (Char *) findsym( nd, ndtbl, NAME_TABLE_HASH_SIZE )->str_val;
|
||||
}
|
||||
|
||||
|
||||
/* scextend - increase the maximum number of start conditions */
|
||||
|
||||
void scextend()
|
||||
{
|
||||
current_max_scs += MAX_SCS_INCREMENT;
|
||||
|
||||
++num_reallocs;
|
||||
|
||||
scset = reallocate_integer_array( scset, current_max_scs );
|
||||
scbol = reallocate_integer_array( scbol, current_max_scs );
|
||||
scxclu = reallocate_integer_array( scxclu, current_max_scs );
|
||||
sceof = reallocate_integer_array( sceof, current_max_scs );
|
||||
scname = reallocate_char_ptr_array( scname, current_max_scs );
|
||||
}
|
||||
|
||||
|
||||
/* scinstal - make a start condition
|
||||
*
|
||||
* NOTE
|
||||
* The start condition is "exclusive" if xcluflg is true.
|
||||
*/
|
||||
|
||||
void scinstal( str, xcluflg )
|
||||
char str[];
|
||||
int xcluflg;
|
||||
{
|
||||
char *copy_string();
|
||||
|
||||
/* Generate start condition definition, for use in BEGIN et al. */
|
||||
action_define( str, lastsc );
|
||||
|
||||
if ( ++lastsc >= current_max_scs )
|
||||
scextend();
|
||||
|
||||
scname[lastsc] = copy_string( str );
|
||||
|
||||
if ( addsym( scname[lastsc], (char *) 0, lastsc,
|
||||
sctbl, START_COND_HASH_SIZE ) )
|
||||
format_pinpoint_message(
|
||||
_( "start condition %s declared twice" ),
|
||||
str );
|
||||
|
||||
scset[lastsc] = mkstate( SYM_EPSILON );
|
||||
scbol[lastsc] = mkstate( SYM_EPSILON );
|
||||
scxclu[lastsc] = xcluflg;
|
||||
sceof[lastsc] = false;
|
||||
}
|
||||
|
||||
|
||||
/* sclookup - lookup the number associated with a start condition
|
||||
*
|
||||
* Returns 0 if no such start condition.
|
||||
*/
|
||||
|
||||
int sclookup( str )
|
||||
char str[];
|
||||
{
|
||||
return findsym( str, sctbl, START_COND_HASH_SIZE )->int_val;
|
||||
}
|
@ -1,889 +0,0 @@
|
||||
/* tblcmp - table compression routines */
|
||||
|
||||
/*-
|
||||
* 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: /home/daffy/u0/vern/flex/RCS/tblcmp.c,v 2.11 94/11/05 17:08:28 vern Exp $ */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "flexdef.h"
|
||||
|
||||
|
||||
/* declarations for functions that have forward references */
|
||||
|
||||
void mkentry PROTO((int*, int, int, int, int));
|
||||
void mkprot PROTO((int[], int, int));
|
||||
void mktemplate PROTO((int[], int, int));
|
||||
void mv2front PROTO((int));
|
||||
int tbldiff PROTO((int[], int, int[]));
|
||||
|
||||
|
||||
/* bldtbl - build table entries for dfa state
|
||||
*
|
||||
* synopsis
|
||||
* int state[numecs], statenum, totaltrans, comstate, comfreq;
|
||||
* bldtbl( state, statenum, totaltrans, comstate, comfreq );
|
||||
*
|
||||
* State is the statenum'th dfa state. It is indexed by equivalence class and
|
||||
* gives the number of the state to enter for a given equivalence class.
|
||||
* totaltrans is the total number of transitions out of the state. Comstate
|
||||
* is that state which is the destination of the most transitions out of State.
|
||||
* Comfreq is how many transitions there are out of State to Comstate.
|
||||
*
|
||||
* A note on terminology:
|
||||
* "protos" are transition tables which have a high probability of
|
||||
* either being redundant (a state processed later will have an identical
|
||||
* transition table) or nearly redundant (a state processed later will have
|
||||
* many of the same out-transitions). A "most recently used" queue of
|
||||
* protos is kept around with the hope that most states will find a proto
|
||||
* which is similar enough to be usable, and therefore compacting the
|
||||
* output tables.
|
||||
* "templates" are a special type of proto. If a transition table is
|
||||
* homogeneous or nearly homogeneous (all transitions go to the same
|
||||
* destination) then the odds are good that future states will also go
|
||||
* to the same destination state on basically the same character set.
|
||||
* These homogeneous states are so common when dealing with large rule
|
||||
* sets that they merit special attention. If the transition table were
|
||||
* simply made into a proto, then (typically) each subsequent, similar
|
||||
* state will differ from the proto for two out-transitions. One of these
|
||||
* out-transitions will be that character on which the proto does not go
|
||||
* to the common destination, and one will be that character on which the
|
||||
* state does not go to the common destination. Templates, on the other
|
||||
* hand, go to the common state on EVERY transition character, and therefore
|
||||
* cost only one difference.
|
||||
*/
|
||||
|
||||
void bldtbl( state, statenum, totaltrans, comstate, comfreq )
|
||||
int state[], statenum, totaltrans, comstate, comfreq;
|
||||
{
|
||||
int extptr, extrct[2][CSIZE + 1];
|
||||
int mindiff, minprot, i, d;
|
||||
|
||||
/* If extptr is 0 then the first array of extrct holds the result
|
||||
* of the "best difference" to date, which is those transitions
|
||||
* which occur in "state" but not in the proto which, to date,
|
||||
* has the fewest differences between itself and "state". If
|
||||
* extptr is 1 then the second array of extrct hold the best
|
||||
* difference. The two arrays are toggled between so that the
|
||||
* best difference to date can be kept around and also a difference
|
||||
* just created by checking against a candidate "best" proto.
|
||||
*/
|
||||
|
||||
extptr = 0;
|
||||
|
||||
/* If the state has too few out-transitions, don't bother trying to
|
||||
* compact its tables.
|
||||
*/
|
||||
|
||||
if ( (totaltrans * 100) < (numecs * PROTO_SIZE_PERCENTAGE) )
|
||||
mkentry( state, numecs, statenum, JAMSTATE, totaltrans );
|
||||
|
||||
else
|
||||
{
|
||||
/* "checkcom" is true if we should only check "state" against
|
||||
* protos which have the same "comstate" value.
|
||||
*/
|
||||
int checkcom =
|
||||
comfreq * 100 > totaltrans * CHECK_COM_PERCENTAGE;
|
||||
|
||||
minprot = firstprot;
|
||||
mindiff = totaltrans;
|
||||
|
||||
if ( checkcom )
|
||||
{
|
||||
/* Find first proto which has the same "comstate". */
|
||||
for ( i = firstprot; i != NIL; i = protnext[i] )
|
||||
if ( protcomst[i] == comstate )
|
||||
{
|
||||
minprot = i;
|
||||
mindiff = tbldiff( state, minprot,
|
||||
extrct[extptr] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Since we've decided that the most common destination
|
||||
* out of "state" does not occur with a high enough
|
||||
* frequency, we set the "comstate" to zero, assuring
|
||||
* that if this state is entered into the proto list,
|
||||
* it will not be considered a template.
|
||||
*/
|
||||
comstate = 0;
|
||||
|
||||
if ( firstprot != NIL )
|
||||
{
|
||||
minprot = firstprot;
|
||||
mindiff = tbldiff( state, minprot,
|
||||
extrct[extptr] );
|
||||
}
|
||||
}
|
||||
|
||||
/* We now have the first interesting proto in "minprot". If
|
||||
* it matches within the tolerances set for the first proto,
|
||||
* we don't want to bother scanning the rest of the proto list
|
||||
* to see if we have any other reasonable matches.
|
||||
*/
|
||||
|
||||
if ( mindiff * 100 > totaltrans * FIRST_MATCH_DIFF_PERCENTAGE )
|
||||
{
|
||||
/* Not a good enough match. Scan the rest of the
|
||||
* protos.
|
||||
*/
|
||||
for ( i = minprot; i != NIL; i = protnext[i] )
|
||||
{
|
||||
d = tbldiff( state, i, extrct[1 - extptr] );
|
||||
if ( d < mindiff )
|
||||
{
|
||||
extptr = 1 - extptr;
|
||||
mindiff = d;
|
||||
minprot = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the proto we've decided on as our best bet is close
|
||||
* enough to the state we want to match to be usable.
|
||||
*/
|
||||
|
||||
if ( mindiff * 100 > totaltrans * ACCEPTABLE_DIFF_PERCENTAGE )
|
||||
{
|
||||
/* No good. If the state is homogeneous enough,
|
||||
* we make a template out of it. Otherwise, we
|
||||
* make a proto.
|
||||
*/
|
||||
|
||||
if ( comfreq * 100 >=
|
||||
totaltrans * TEMPLATE_SAME_PERCENTAGE )
|
||||
mktemplate( state, statenum, comstate );
|
||||
|
||||
else
|
||||
{
|
||||
mkprot( state, statenum, comstate );
|
||||
mkentry( state, numecs, statenum,
|
||||
JAMSTATE, totaltrans );
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{ /* use the proto */
|
||||
mkentry( extrct[extptr], numecs, statenum,
|
||||
prottbl[minprot], mindiff );
|
||||
|
||||
/* If this state was sufficiently different from the
|
||||
* proto we built it from, make it, too, a proto.
|
||||
*/
|
||||
|
||||
if ( mindiff * 100 >=
|
||||
totaltrans * NEW_PROTO_DIFF_PERCENTAGE )
|
||||
mkprot( state, statenum, comstate );
|
||||
|
||||
/* Since mkprot added a new proto to the proto queue,
|
||||
* it's possible that "minprot" is no longer on the
|
||||
* proto queue (if it happened to have been the last
|
||||
* entry, it would have been bumped off). If it's
|
||||
* not there, then the new proto took its physical
|
||||
* place (though logically the new proto is at the
|
||||
* beginning of the queue), so in that case the
|
||||
* following call will do nothing.
|
||||
*/
|
||||
|
||||
mv2front( minprot );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* cmptmps - compress template table entries
|
||||
*
|
||||
* Template tables are compressed by using the 'template equivalence
|
||||
* classes', which are collections of transition character equivalence
|
||||
* classes which always appear together in templates - really meta-equivalence
|
||||
* classes.
|
||||
*/
|
||||
|
||||
void cmptmps()
|
||||
{
|
||||
int tmpstorage[CSIZE + 1];
|
||||
int *tmp = tmpstorage, i, j;
|
||||
int totaltrans, trans;
|
||||
|
||||
peakpairs = numtemps * numecs + tblend;
|
||||
|
||||
if ( usemecs )
|
||||
{
|
||||
/* Create equivalence classes based on data gathered on
|
||||
* template transitions.
|
||||
*/
|
||||
nummecs = cre8ecs( tecfwd, tecbck, numecs );
|
||||
}
|
||||
|
||||
else
|
||||
nummecs = numecs;
|
||||
|
||||
while ( lastdfa + numtemps + 1 >= current_max_dfas )
|
||||
increase_max_dfas();
|
||||
|
||||
/* Loop through each template. */
|
||||
|
||||
for ( i = 1; i <= numtemps; ++i )
|
||||
{
|
||||
/* Number of non-jam transitions out of this template. */
|
||||
totaltrans = 0;
|
||||
|
||||
for ( j = 1; j <= numecs; ++j )
|
||||
{
|
||||
trans = tnxt[numecs * i + j];
|
||||
|
||||
if ( usemecs )
|
||||
{
|
||||
/* The absolute value of tecbck is the
|
||||
* meta-equivalence class of a given
|
||||
* equivalence class, as set up by cre8ecs().
|
||||
*/
|
||||
if ( tecbck[j] > 0 )
|
||||
{
|
||||
tmp[tecbck[j]] = trans;
|
||||
|
||||
if ( trans > 0 )
|
||||
++totaltrans;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tmp[j] = trans;
|
||||
|
||||
if ( trans > 0 )
|
||||
++totaltrans;
|
||||
}
|
||||
}
|
||||
|
||||
/* It is assumed (in a rather subtle way) in the skeleton
|
||||
* that if we're using meta-equivalence classes, the def[]
|
||||
* entry for all templates is the jam template, i.e.,
|
||||
* templates never default to other non-jam table entries
|
||||
* (e.g., another template)
|
||||
*/
|
||||
|
||||
/* Leave room for the jam-state after the last real state. */
|
||||
mkentry( tmp, nummecs, lastdfa + i + 1, JAMSTATE, totaltrans );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* expand_nxt_chk - expand the next check arrays */
|
||||
|
||||
void expand_nxt_chk()
|
||||
{
|
||||
int old_max = current_max_xpairs;
|
||||
|
||||
current_max_xpairs += MAX_XPAIRS_INCREMENT;
|
||||
|
||||
++num_reallocs;
|
||||
|
||||
nxt = reallocate_integer_array( nxt, current_max_xpairs );
|
||||
chk = reallocate_integer_array( chk, current_max_xpairs );
|
||||
|
||||
zero_out( (char *) (chk + old_max),
|
||||
(size_t) (MAX_XPAIRS_INCREMENT * sizeof( int )) );
|
||||
}
|
||||
|
||||
|
||||
/* find_table_space - finds a space in the table for a state to be placed
|
||||
*
|
||||
* synopsis
|
||||
* int *state, numtrans, block_start;
|
||||
* int find_table_space();
|
||||
*
|
||||
* block_start = find_table_space( state, numtrans );
|
||||
*
|
||||
* State is the state to be added to the full speed transition table.
|
||||
* Numtrans is the number of out-transitions for the state.
|
||||
*
|
||||
* find_table_space() returns the position of the start of the first block (in
|
||||
* chk) able to accommodate the state
|
||||
*
|
||||
* In determining if a state will or will not fit, find_table_space() must take
|
||||
* into account the fact that an end-of-buffer state will be added at [0],
|
||||
* and an action number will be added in [-1].
|
||||
*/
|
||||
|
||||
int find_table_space( state, numtrans )
|
||||
int *state, numtrans;
|
||||
{
|
||||
/* Firstfree is the position of the first possible occurrence of two
|
||||
* consecutive unused records in the chk and nxt arrays.
|
||||
*/
|
||||
int i;
|
||||
int *state_ptr, *chk_ptr;
|
||||
int *ptr_to_last_entry_in_state;
|
||||
|
||||
/* If there are too many out-transitions, put the state at the end of
|
||||
* nxt and chk.
|
||||
*/
|
||||
if ( numtrans > MAX_XTIONS_FULL_INTERIOR_FIT )
|
||||
{
|
||||
/* If table is empty, return the first available spot in
|
||||
* chk/nxt, which should be 1.
|
||||
*/
|
||||
if ( tblend < 2 )
|
||||
return 1;
|
||||
|
||||
/* Start searching for table space near the end of
|
||||
* chk/nxt arrays.
|
||||
*/
|
||||
i = tblend - numecs;
|
||||
}
|
||||
|
||||
else
|
||||
/* Start searching for table space from the beginning
|
||||
* (skipping only the elements which will definitely not
|
||||
* hold the new state).
|
||||
*/
|
||||
i = firstfree;
|
||||
|
||||
while ( 1 ) /* loops until a space is found */
|
||||
{
|
||||
while ( i + numecs >= current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
|
||||
/* Loops until space for end-of-buffer and action number
|
||||
* are found.
|
||||
*/
|
||||
while ( 1 )
|
||||
{
|
||||
/* Check for action number space. */
|
||||
if ( chk[i - 1] == 0 )
|
||||
{
|
||||
/* Check for end-of-buffer space. */
|
||||
if ( chk[i] == 0 )
|
||||
break;
|
||||
|
||||
else
|
||||
/* Since i != 0, there is no use
|
||||
* checking to see if (++i) - 1 == 0,
|
||||
* because that's the same as i == 0,
|
||||
* so we skip a space.
|
||||
*/
|
||||
i += 2;
|
||||
}
|
||||
|
||||
else
|
||||
++i;
|
||||
|
||||
while ( i + numecs >= current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
}
|
||||
|
||||
/* If we started search from the beginning, store the new
|
||||
* firstfree for the next call of find_table_space().
|
||||
*/
|
||||
if ( numtrans <= MAX_XTIONS_FULL_INTERIOR_FIT )
|
||||
firstfree = i + 1;
|
||||
|
||||
/* Check to see if all elements in chk (and therefore nxt)
|
||||
* that are needed for the new state have not yet been taken.
|
||||
*/
|
||||
|
||||
state_ptr = &state[1];
|
||||
ptr_to_last_entry_in_state = &chk[i + numecs + 1];
|
||||
|
||||
for ( chk_ptr = &chk[i + 1];
|
||||
chk_ptr != ptr_to_last_entry_in_state; ++chk_ptr )
|
||||
if ( *(state_ptr++) != 0 && *chk_ptr != 0 )
|
||||
break;
|
||||
|
||||
if ( chk_ptr == ptr_to_last_entry_in_state )
|
||||
return i;
|
||||
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* inittbl - initialize transition tables
|
||||
*
|
||||
* Initializes "firstfree" to be one beyond the end of the table. Initializes
|
||||
* all "chk" entries to be zero.
|
||||
*/
|
||||
void inittbl()
|
||||
{
|
||||
int i;
|
||||
|
||||
zero_out( (char *) chk, (size_t) (current_max_xpairs * sizeof( int )) );
|
||||
|
||||
tblend = 0;
|
||||
firstfree = tblend + 1;
|
||||
numtemps = 0;
|
||||
|
||||
if ( usemecs )
|
||||
{
|
||||
/* Set up doubly-linked meta-equivalence classes; these
|
||||
* are sets of equivalence classes which all have identical
|
||||
* transitions out of TEMPLATES.
|
||||
*/
|
||||
|
||||
tecbck[1] = NIL;
|
||||
|
||||
for ( i = 2; i <= numecs; ++i )
|
||||
{
|
||||
tecbck[i] = i - 1;
|
||||
tecfwd[i - 1] = i;
|
||||
}
|
||||
|
||||
tecfwd[numecs] = NIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mkdeftbl - make the default, "jam" table entries */
|
||||
|
||||
void mkdeftbl()
|
||||
{
|
||||
int i;
|
||||
|
||||
jamstate = lastdfa + 1;
|
||||
|
||||
++tblend; /* room for transition on end-of-buffer character */
|
||||
|
||||
while ( tblend + numecs >= current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
|
||||
/* Add in default end-of-buffer transition. */
|
||||
nxt[tblend] = end_of_buffer_state;
|
||||
chk[tblend] = jamstate;
|
||||
|
||||
for ( i = 1; i <= numecs; ++i )
|
||||
{
|
||||
nxt[tblend + i] = 0;
|
||||
chk[tblend + i] = jamstate;
|
||||
}
|
||||
|
||||
jambase = tblend;
|
||||
|
||||
base[jamstate] = jambase;
|
||||
def[jamstate] = 0;
|
||||
|
||||
tblend += numecs;
|
||||
++numtemps;
|
||||
}
|
||||
|
||||
|
||||
/* mkentry - create base/def and nxt/chk entries for transition array
|
||||
*
|
||||
* synopsis
|
||||
* int state[numchars + 1], numchars, statenum, deflink, totaltrans;
|
||||
* mkentry( state, numchars, statenum, deflink, totaltrans );
|
||||
*
|
||||
* "state" is a transition array "numchars" characters in size, "statenum"
|
||||
* is the offset to be used into the base/def tables, and "deflink" is the
|
||||
* entry to put in the "def" table entry. If "deflink" is equal to
|
||||
* "JAMSTATE", then no attempt will be made to fit zero entries of "state"
|
||||
* (i.e., jam entries) into the table. It is assumed that by linking to
|
||||
* "JAMSTATE" they will be taken care of. In any case, entries in "state"
|
||||
* marking transitions to "SAME_TRANS" are treated as though they will be
|
||||
* taken care of by wherever "deflink" points. "totaltrans" is the total
|
||||
* number of transitions out of the state. If it is below a certain threshold,
|
||||
* the tables are searched for an interior spot that will accommodate the
|
||||
* state array.
|
||||
*/
|
||||
|
||||
void mkentry( state, numchars, statenum, deflink, totaltrans )
|
||||
int *state;
|
||||
int numchars, statenum, deflink, totaltrans;
|
||||
{
|
||||
int minec, maxec, i, baseaddr;
|
||||
int tblbase, tbllast;
|
||||
|
||||
if ( totaltrans == 0 )
|
||||
{ /* there are no out-transitions */
|
||||
if ( deflink == JAMSTATE )
|
||||
base[statenum] = JAMSTATE;
|
||||
else
|
||||
base[statenum] = 0;
|
||||
|
||||
def[statenum] = deflink;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( minec = 1; minec <= numchars; ++minec )
|
||||
{
|
||||
if ( state[minec] != SAME_TRANS )
|
||||
if ( state[minec] != 0 || deflink != JAMSTATE )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( totaltrans == 1 )
|
||||
{
|
||||
/* There's only one out-transition. Save it for later to fill
|
||||
* in holes in the tables.
|
||||
*/
|
||||
stack1( statenum, minec, state[minec], deflink );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( maxec = numchars; maxec > 0; --maxec )
|
||||
{
|
||||
if ( state[maxec] != SAME_TRANS )
|
||||
if ( state[maxec] != 0 || deflink != JAMSTATE )
|
||||
break;
|
||||
}
|
||||
|
||||
/* Whether we try to fit the state table in the middle of the table
|
||||
* entries we have already generated, or if we just take the state
|
||||
* table at the end of the nxt/chk tables, we must make sure that we
|
||||
* have a valid base address (i.e., non-negative). Note that
|
||||
* negative base addresses dangerous at run-time (because indexing
|
||||
* the nxt array with one and a low-valued character will access
|
||||
* memory before the start of the array.
|
||||
*/
|
||||
|
||||
/* Find the first transition of state that we need to worry about. */
|
||||
if ( totaltrans * 100 <= numchars * INTERIOR_FIT_PERCENTAGE )
|
||||
{
|
||||
/* Attempt to squeeze it into the middle of the tables. */
|
||||
baseaddr = firstfree;
|
||||
|
||||
while ( baseaddr < minec )
|
||||
{
|
||||
/* Using baseaddr would result in a negative base
|
||||
* address below; find the next free slot.
|
||||
*/
|
||||
for ( ++baseaddr; chk[baseaddr] != 0; ++baseaddr )
|
||||
;
|
||||
}
|
||||
|
||||
while ( baseaddr + maxec - minec + 1 >= current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
|
||||
for ( i = minec; i <= maxec; ++i )
|
||||
if ( state[i] != SAME_TRANS &&
|
||||
(state[i] != 0 || deflink != JAMSTATE) &&
|
||||
chk[baseaddr + i - minec] != 0 )
|
||||
{ /* baseaddr unsuitable - find another */
|
||||
for ( ++baseaddr;
|
||||
baseaddr < current_max_xpairs &&
|
||||
chk[baseaddr] != 0; ++baseaddr )
|
||||
;
|
||||
|
||||
while ( baseaddr + maxec - minec + 1 >=
|
||||
current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
|
||||
/* Reset the loop counter so we'll start all
|
||||
* over again next time it's incremented.
|
||||
*/
|
||||
|
||||
i = minec - 1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Ensure that the base address we eventually generate is
|
||||
* non-negative.
|
||||
*/
|
||||
baseaddr = MAX( tblend + 1, minec );
|
||||
}
|
||||
|
||||
tblbase = baseaddr - minec;
|
||||
tbllast = tblbase + maxec;
|
||||
|
||||
while ( tbllast + 1 >= current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
|
||||
base[statenum] = tblbase;
|
||||
def[statenum] = deflink;
|
||||
|
||||
for ( i = minec; i <= maxec; ++i )
|
||||
if ( state[i] != SAME_TRANS )
|
||||
if ( state[i] != 0 || deflink != JAMSTATE )
|
||||
{
|
||||
nxt[tblbase + i] = state[i];
|
||||
chk[tblbase + i] = statenum;
|
||||
}
|
||||
|
||||
if ( baseaddr == firstfree )
|
||||
/* Find next free slot in tables. */
|
||||
for ( ++firstfree; chk[firstfree] != 0; ++firstfree )
|
||||
;
|
||||
|
||||
tblend = MAX( tblend, tbllast );
|
||||
}
|
||||
|
||||
|
||||
/* mk1tbl - create table entries for a state (or state fragment) which
|
||||
* has only one out-transition
|
||||
*/
|
||||
|
||||
void mk1tbl( state, sym, onenxt, onedef )
|
||||
int state, sym, onenxt, onedef;
|
||||
{
|
||||
if ( firstfree < sym )
|
||||
firstfree = sym;
|
||||
|
||||
while ( chk[firstfree] != 0 )
|
||||
if ( ++firstfree >= current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
|
||||
base[state] = firstfree - sym;
|
||||
def[state] = onedef;
|
||||
chk[firstfree] = state;
|
||||
nxt[firstfree] = onenxt;
|
||||
|
||||
if ( firstfree > tblend )
|
||||
{
|
||||
tblend = firstfree++;
|
||||
|
||||
if ( firstfree >= current_max_xpairs )
|
||||
expand_nxt_chk();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mkprot - create new proto entry */
|
||||
|
||||
void mkprot( state, statenum, comstate )
|
||||
int state[], statenum, comstate;
|
||||
{
|
||||
int i, slot, tblbase;
|
||||
|
||||
if ( ++numprots >= MSP || numecs * numprots >= PROT_SAVE_SIZE )
|
||||
{
|
||||
/* Gotta make room for the new proto by dropping last entry in
|
||||
* the queue.
|
||||
*/
|
||||
slot = lastprot;
|
||||
lastprot = protprev[lastprot];
|
||||
protnext[lastprot] = NIL;
|
||||
}
|
||||
|
||||
else
|
||||
slot = numprots;
|
||||
|
||||
protnext[slot] = firstprot;
|
||||
|
||||
if ( firstprot != NIL )
|
||||
protprev[firstprot] = slot;
|
||||
|
||||
firstprot = slot;
|
||||
prottbl[slot] = statenum;
|
||||
protcomst[slot] = comstate;
|
||||
|
||||
/* Copy state into save area so it can be compared with rapidly. */
|
||||
tblbase = numecs * (slot - 1);
|
||||
|
||||
for ( i = 1; i <= numecs; ++i )
|
||||
protsave[tblbase + i] = state[i];
|
||||
}
|
||||
|
||||
|
||||
/* mktemplate - create a template entry based on a state, and connect the state
|
||||
* to it
|
||||
*/
|
||||
|
||||
void mktemplate( state, statenum, comstate )
|
||||
int state[], statenum, comstate;
|
||||
{
|
||||
int i, numdiff, tmpbase, tmp[CSIZE + 1];
|
||||
Char transset[CSIZE + 1];
|
||||
int tsptr;
|
||||
|
||||
++numtemps;
|
||||
|
||||
tsptr = 0;
|
||||
|
||||
/* Calculate where we will temporarily store the transition table
|
||||
* of the template in the tnxt[] array. The final transition table
|
||||
* gets created by cmptmps().
|
||||
*/
|
||||
|
||||
tmpbase = numtemps * numecs;
|
||||
|
||||
if ( tmpbase + numecs >= current_max_template_xpairs )
|
||||
{
|
||||
current_max_template_xpairs += MAX_TEMPLATE_XPAIRS_INCREMENT;
|
||||
|
||||
++num_reallocs;
|
||||
|
||||
tnxt = reallocate_integer_array( tnxt,
|
||||
current_max_template_xpairs );
|
||||
}
|
||||
|
||||
for ( i = 1; i <= numecs; ++i )
|
||||
if ( state[i] == 0 )
|
||||
tnxt[tmpbase + i] = 0;
|
||||
else
|
||||
{
|
||||
transset[tsptr++] = i;
|
||||
tnxt[tmpbase + i] = comstate;
|
||||
}
|
||||
|
||||
if ( usemecs )
|
||||
mkeccl( transset, tsptr, tecfwd, tecbck, numecs, 0 );
|
||||
|
||||
mkprot( tnxt + tmpbase, -numtemps, comstate );
|
||||
|
||||
/* We rely on the fact that mkprot adds things to the beginning
|
||||
* of the proto queue.
|
||||
*/
|
||||
|
||||
numdiff = tbldiff( state, firstprot, tmp );
|
||||
mkentry( tmp, numecs, statenum, -numtemps, numdiff );
|
||||
}
|
||||
|
||||
|
||||
/* mv2front - move proto queue element to front of queue */
|
||||
|
||||
void mv2front( qelm )
|
||||
int qelm;
|
||||
{
|
||||
if ( firstprot != qelm )
|
||||
{
|
||||
if ( qelm == lastprot )
|
||||
lastprot = protprev[lastprot];
|
||||
|
||||
protnext[protprev[qelm]] = protnext[qelm];
|
||||
|
||||
if ( protnext[qelm] != NIL )
|
||||
protprev[protnext[qelm]] = protprev[qelm];
|
||||
|
||||
protprev[qelm] = NIL;
|
||||
protnext[qelm] = firstprot;
|
||||
protprev[firstprot] = qelm;
|
||||
firstprot = qelm;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* place_state - place a state into full speed transition table
|
||||
*
|
||||
* State is the statenum'th state. It is indexed by equivalence class and
|
||||
* gives the number of the state to enter for a given equivalence class.
|
||||
* Transnum is the number of out-transitions for the state.
|
||||
*/
|
||||
|
||||
void place_state( state, statenum, transnum )
|
||||
int *state, statenum, transnum;
|
||||
{
|
||||
int i;
|
||||
int *state_ptr;
|
||||
int position = find_table_space( state, transnum );
|
||||
|
||||
/* "base" is the table of start positions. */
|
||||
base[statenum] = position;
|
||||
|
||||
/* Put in action number marker; this non-zero number makes sure that
|
||||
* find_table_space() knows that this position in chk/nxt is taken
|
||||
* and should not be used for another accepting number in another
|
||||
* state.
|
||||
*/
|
||||
chk[position - 1] = 1;
|
||||
|
||||
/* Put in end-of-buffer marker; this is for the same purposes as
|
||||
* above.
|
||||
*/
|
||||
chk[position] = 1;
|
||||
|
||||
/* Place the state into chk and nxt. */
|
||||
state_ptr = &state[1];
|
||||
|
||||
for ( i = 1; i <= numecs; ++i, ++state_ptr )
|
||||
if ( *state_ptr != 0 )
|
||||
{
|
||||
chk[position + i] = i;
|
||||
nxt[position + i] = *state_ptr;
|
||||
}
|
||||
|
||||
if ( position + numecs > tblend )
|
||||
tblend = position + numecs;
|
||||
}
|
||||
|
||||
|
||||
/* stack1 - save states with only one out-transition to be processed later
|
||||
*
|
||||
* If there's room for another state on the "one-transition" stack, the
|
||||
* state is pushed onto it, to be processed later by mk1tbl. If there's
|
||||
* no room, we process the sucker right now.
|
||||
*/
|
||||
|
||||
void stack1( statenum, sym, nextstate, deflink )
|
||||
int statenum, sym, nextstate, deflink;
|
||||
{
|
||||
if ( onesp >= ONE_STACK_SIZE - 1 )
|
||||
mk1tbl( statenum, sym, nextstate, deflink );
|
||||
|
||||
else
|
||||
{
|
||||
++onesp;
|
||||
onestate[onesp] = statenum;
|
||||
onesym[onesp] = sym;
|
||||
onenext[onesp] = nextstate;
|
||||
onedef[onesp] = deflink;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* tbldiff - compute differences between two state tables
|
||||
*
|
||||
* "state" is the state array which is to be extracted from the pr'th
|
||||
* proto. "pr" is both the number of the proto we are extracting from
|
||||
* and an index into the save area where we can find the proto's complete
|
||||
* state table. Each entry in "state" which differs from the corresponding
|
||||
* entry of "pr" will appear in "ext".
|
||||
*
|
||||
* Entries which are the same in both "state" and "pr" will be marked
|
||||
* as transitions to "SAME_TRANS" in "ext". The total number of differences
|
||||
* between "state" and "pr" is returned as function value. Note that this
|
||||
* number is "numecs" minus the number of "SAME_TRANS" entries in "ext".
|
||||
*/
|
||||
|
||||
int tbldiff( state, pr, ext )
|
||||
int state[], pr, ext[];
|
||||
{
|
||||
int i, *sp = state, *ep = ext, *protp;
|
||||
int numdiff = 0;
|
||||
|
||||
protp = &protsave[numecs * (pr - 1)];
|
||||
|
||||
for ( i = numecs; i > 0; --i )
|
||||
{
|
||||
if ( *++protp == *++sp )
|
||||
*++ep = SAME_TRANS;
|
||||
else
|
||||
{
|
||||
*++ep = *sp;
|
||||
++numdiff;
|
||||
}
|
||||
}
|
||||
|
||||
return numdiff;
|
||||
}
|
13
usr.bin/lex/version.awk
Normal file
13
usr.bin/lex/version.awk
Normal file
@ -0,0 +1,13 @@
|
||||
# $FreeBSD$
|
||||
|
||||
BEGIN {
|
||||
FS = "[ \t\.\"]+"
|
||||
}
|
||||
|
||||
{
|
||||
if ($1 ~ /^#define$/ && $2 ~ /^VERSION$/) {
|
||||
printf("-DFLEX_MAJOR_VERSION=%s\n", $3);
|
||||
printf("-DFLEX_MINOR_VERSION=%s\n", $4);
|
||||
printf("-DFLEX_SUBMINOR_VERSION=%s\n", $5);
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#define FLEX_VERSION "2.5.4"
|
@ -1,218 +0,0 @@
|
||||
/* yylex - scanner front-end for flex */
|
||||
|
||||
/*-
|
||||
* 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: /home/daffy/u0/vern/flex/RCS/yylex.c,v 2.13 95/03/04 16:10:41 vern Exp $ */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <ctype.h>
|
||||
#include "flexdef.h"
|
||||
#include "parse.h"
|
||||
|
||||
|
||||
/* yylex - scan for a regular expression token */
|
||||
|
||||
int yylex()
|
||||
{
|
||||
int toktype;
|
||||
static int beglin = false;
|
||||
extern char *yytext;
|
||||
|
||||
if ( eofseen )
|
||||
toktype = EOF;
|
||||
else
|
||||
toktype = flexscan();
|
||||
|
||||
if ( toktype == EOF || toktype == 0 )
|
||||
{
|
||||
eofseen = 1;
|
||||
|
||||
if ( sectnum == 1 )
|
||||
{
|
||||
synerr( _( "premature EOF" ) );
|
||||
sectnum = 2;
|
||||
toktype = SECTEND;
|
||||
}
|
||||
|
||||
else
|
||||
toktype = 0;
|
||||
}
|
||||
|
||||
if ( trace )
|
||||
{
|
||||
if ( beglin )
|
||||
{
|
||||
fprintf( stderr, "%d\t", num_rules + 1 );
|
||||
beglin = 0;
|
||||
}
|
||||
|
||||
switch ( toktype )
|
||||
{
|
||||
case '<':
|
||||
case '>':
|
||||
case '^':
|
||||
case '$':
|
||||
case '"':
|
||||
case '[':
|
||||
case ']':
|
||||
case '{':
|
||||
case '}':
|
||||
case '|':
|
||||
case '(':
|
||||
case ')':
|
||||
case '-':
|
||||
case '/':
|
||||
case '\\':
|
||||
case '?':
|
||||
case '.':
|
||||
case '*':
|
||||
case '+':
|
||||
case ',':
|
||||
(void) putc( toktype, stderr );
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
(void) putc( '\n', stderr );
|
||||
|
||||
if ( sectnum == 2 )
|
||||
beglin = 1;
|
||||
|
||||
break;
|
||||
|
||||
case SCDECL:
|
||||
fputs( "%s", stderr );
|
||||
break;
|
||||
|
||||
case XSCDECL:
|
||||
fputs( "%x", stderr );
|
||||
break;
|
||||
|
||||
case SECTEND:
|
||||
fputs( "%%\n", stderr );
|
||||
|
||||
/* We set beglin to be true so we'll start
|
||||
* writing out numbers as we echo rules.
|
||||
* flexscan() has already assigned sectnum.
|
||||
*/
|
||||
if ( sectnum == 2 )
|
||||
beglin = 1;
|
||||
|
||||
break;
|
||||
|
||||
case NAME:
|
||||
fprintf( stderr, "'%s'", nmstr );
|
||||
break;
|
||||
|
||||
case CHAR:
|
||||
switch ( yylval )
|
||||
{
|
||||
case '<':
|
||||
case '>':
|
||||
case '^':
|
||||
case '$':
|
||||
case '"':
|
||||
case '[':
|
||||
case ']':
|
||||
case '{':
|
||||
case '}':
|
||||
case '|':
|
||||
case '(':
|
||||
case ')':
|
||||
case '-':
|
||||
case '/':
|
||||
case '\\':
|
||||
case '?':
|
||||
case '.':
|
||||
case '*':
|
||||
case '+':
|
||||
case ',':
|
||||
fprintf( stderr, "\\%c",
|
||||
yylval );
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( ! isascii( yylval ) ||
|
||||
! isprint( yylval ) )
|
||||
fprintf( stderr,
|
||||
"\\%.3o",
|
||||
(unsigned int) yylval );
|
||||
else
|
||||
(void) putc( yylval,
|
||||
stderr );
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NUMBER:
|
||||
fprintf( stderr, "%d", yylval );
|
||||
break;
|
||||
|
||||
case PREVCCL:
|
||||
fprintf( stderr, "[%d]", yylval );
|
||||
break;
|
||||
|
||||
case EOF_OP:
|
||||
fprintf( stderr, "<<EOF>>" );
|
||||
break;
|
||||
|
||||
case OPTION_OP:
|
||||
fprintf( stderr, "%s ", yytext );
|
||||
break;
|
||||
|
||||
case OPT_OUTFILE:
|
||||
case OPT_PREFIX:
|
||||
case CCE_ALNUM:
|
||||
case CCE_ALPHA:
|
||||
case CCE_BLANK:
|
||||
case CCE_CNTRL:
|
||||
case CCE_DIGIT:
|
||||
case CCE_GRAPH:
|
||||
case CCE_LOWER:
|
||||
case CCE_PRINT:
|
||||
case CCE_PUNCT:
|
||||
case CCE_SPACE:
|
||||
case CCE_UPPER:
|
||||
case CCE_XDIGIT:
|
||||
fprintf( stderr, "%s", yytext );
|
||||
break;
|
||||
|
||||
case 0:
|
||||
fprintf( stderr, _( "End Marker\n" ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf( stderr,
|
||||
_( "*Something Weird* - tok: %d val: %d\n" ),
|
||||
toktype, yylval );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return toktype;
|
||||
}
|
Loading…
Reference in New Issue
Block a user