v14i080: Flex, a lex replacement, Part02/05
Rich Salz
rsalz at uunet.uu.net
Wed May 4 08:02:01 AEST 1988
Submitted-by: Vern Paxson <vern at lbl-csam.arpa>
Posting-number: Volume 14, Issue 80
Archive-name: flex/part02
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 5)."
# Contents: dfa.c flex.fastskel main.c misc.c scan.l
# Wrapped by rsalz at fig.bbn.com on Tue May 3 17:31:27 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'dfa.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'dfa.c'\"
else
echo shar: Extracting \"'dfa.c'\" \(10732 characters\)
sed "s/^X//" >'dfa.c' <<'END_OF_FILE'
X/* dfa - DFA construction routines */
X
X/*
X * Copyright (c) 1987, the University of California
X *
X * The United States Government has rights in this work pursuant to
X * contract no. DE-AC03-76SF00098 between the United States Department of
X * Energy and the University of California.
X *
X * This program may be redistributed. Enhancements and derivative works
X * may be created provided the new works, if made available to the general
X * public, are made available for use by anyone.
X */
X
X#include "flexdef.h"
X
X/* epsclosure - construct the epsilon closure of a set of ndfa states
X *
X * synopsis
X * int t[current_max_dfa_size], numstates, accset[accnum + 1], nacc;
X * int hashval;
X * int *epsclosure();
X * t = epsclosure( t, &numstates, accset, &nacc, &hashval );
X *
X * NOTES
X * the epsilon closure is the set of all states reachable by an arbitrary
X * number of epsilon transitions which themselves do not have epsilon
X * transitions going out, unioned with the set of states which have non-null
X * accepting numbers. t is an array of size numstates of nfa state numbers.
X * Upon return, t holds the epsilon closure and numstates is updated. accset
X * holds a list of the accepting numbers, and the size of accset is given
X * by nacc. t may be subjected to reallocation if it is not large enough
X * to hold the epsilon closure.
X *
X * hashval is the hash value for the dfa corresponding to the state set
X */
X
int *epsclosure( t, ns_addr, accset, nacc_addr, hv_addr )
int *t, *ns_addr, accset[], *nacc_addr, *hv_addr;
X
X {
X register int stkpos, ns, tsp;
X int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum;
X int stkend, nstate;
X static int did_stk_init = false, *stk;
X
X#define MARK_STATE(state) \
X trans1[state] = trans1[state] - MARKER_DIFFERENCE;
X
X#define IS_MARKED(state) (trans1[state] < 0)
X
X#define UNMARK_STATE(state) \
X trans1[state] = trans1[state] + MARKER_DIFFERENCE;
X
X#define CHECK_ACCEPT(state) \
X { \
X nfaccnum = accptnum[state]; \
X if ( nfaccnum != NIL ) \
X accset[++nacc] = nfaccnum; \
X }
X
X#define DO_REALLOCATION \
X { \
X current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \
X ++num_reallocs; \
X t = reallocate_integer_array( t, current_max_dfa_size ); \
X stk = reallocate_integer_array( stk, current_max_dfa_size ); \
X } \
X
X#define PUT_ON_STACK(state) \
X { \
X if ( ++stkend >= current_max_dfa_size ) \
X DO_REALLOCATION \
X stk[stkend] = state; \
X MARK_STATE(state) \
X }
X
X#define ADD_STATE(state) \
X { \
X if ( ++numstates >= current_max_dfa_size ) \
X DO_REALLOCATION \
X t[numstates] = state; \
X hashval = hashval + state; \
X }
X
X#define STACK_STATE(state) \
X { \
X PUT_ON_STACK(state) \
X CHECK_ACCEPT(state) \
X if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \
X ADD_STATE(state) \
X }
X
X if ( ! did_stk_init )
X {
X stk = allocate_integer_array( current_max_dfa_size );
X did_stk_init = true;
X }
X
X nacc = stkend = hashval = 0;
X
X for ( nstate = 1; nstate <= numstates; ++nstate )
X {
X ns = t[nstate];
X
X /* the state could be marked if we've already pushed it onto
X * the stack
X */
X if ( ! IS_MARKED(ns) )
X PUT_ON_STACK(ns)
X
X CHECK_ACCEPT(ns)
X hashval = hashval + ns;
X }
X
X for ( stkpos = 1; stkpos <= stkend; ++stkpos )
X {
X ns = stk[stkpos];
X transsym = transchar[ns];
X
X if ( transsym == SYM_EPSILON )
X {
X tsp = trans1[ns] + MARKER_DIFFERENCE;
X
X if ( tsp != NO_TRANSITION )
X {
X if ( ! IS_MARKED(tsp) )
X STACK_STATE(tsp)
X
X tsp = trans2[ns];
X
X if ( tsp != NO_TRANSITION )
X if ( ! IS_MARKED(tsp) )
X STACK_STATE(tsp)
X }
X }
X }
X
X /* clear out "visit" markers */
X
X for ( stkpos = 1; stkpos <= stkend; ++stkpos )
X {
X if ( IS_MARKED(stk[stkpos]) )
X {
X UNMARK_STATE(stk[stkpos])
X }
X else
X flexfatal( "consistency check failed in epsclosure()" );
X }
X
X *ns_addr = numstates;
X *hv_addr = hashval;
X *nacc_addr = nacc;
X
X return ( t );
X }
X
X
X
X/* increase_max_dfas - increase the maximum number of DFAs */
X
increase_max_dfas()
X
X {
X int old_max = current_max_dfas;
X
X current_max_dfas += MAX_DFAS_INCREMENT;
X
X ++num_reallocs;
X
X base = reallocate_integer_array( base, current_max_dfas );
X def = reallocate_integer_array( def, current_max_dfas );
X dfasiz = reallocate_integer_array( dfasiz, current_max_dfas );
X accsiz = reallocate_integer_array( accsiz, current_max_dfas );
X dhash = reallocate_integer_array( dhash, current_max_dfas );
X todo = reallocate_integer_array( todo, current_max_dfas );
X dss = reallocate_integer_pointer_array( dss, current_max_dfas );
X dfaacc = reallocate_dfaacc_union( dfaacc, current_max_dfas );
X
X /* fix up todo queue */
X if ( todo_next < todo_head )
X { /* queue was wrapped around the end */
X register int i;
X
X for ( i = 0; i < todo_next; ++i )
X todo[old_max + i] = todo[i];
X
X todo_next += old_max;
X }
X }
X
X
X/* snstods - converts a set of ndfa states into a dfa state
X *
X * synopsis
X * int sns[numstates], numstates, newds, accset[accnum + 1], nacc, hashval;
X * int snstods();
X * is_new_state = snstods( sns, numstates, accset, nacc, hashval, &newds );
X *
X * on return, the dfa state number is in newds.
X */
X
int snstods( sns, numstates, accset, nacc, hashval, newds_addr )
int sns[], numstates, accset[], nacc, hashval, *newds_addr;
X
X {
X int didsort = 0;
X register int i, j;
X int newds, *oldsns;
X char *malloc();
X
X for ( i = 1; i <= lastdfa; ++i )
X if ( hashval == dhash[i] )
X {
X if ( numstates == dfasiz[i] )
X {
X oldsns = dss[i];
X
X if ( ! didsort )
X {
X /* we sort the states in sns so we can compare it to
X * oldsns quickly. we use bubble because there probably
X * aren't very many states
X */
X bubble( sns, numstates );
X didsort = 1;
X }
X
X for ( j = 1; j <= numstates; ++j )
X if ( sns[j] != oldsns[j] )
X break;
X
X if ( j > numstates )
X {
X ++dfaeql;
X *newds_addr = i;
X return ( 0 );
X }
X
X ++hshcol;
X }
X
X else
X ++hshsave;
X }
X
X /* make a new dfa */
X
X if ( ++lastdfa >= current_max_dfas )
X increase_max_dfas();
X
X newds = lastdfa;
X
X if ( ! (dss[newds] = (int *) malloc( (unsigned) ((numstates + 1) * sizeof( int )) )) )
X flexfatal( "dynamic memory failure in snstods()" );
X
X /* if we haven't already sorted the states in sns, we do so now, so that
X * future comparisons with it can be made quickly
X */
X
X if ( ! didsort )
X bubble( sns, numstates );
X
X for ( i = 1; i <= numstates; ++i )
X dss[newds][i] = sns[i];
X
X dfasiz[newds] = numstates;
X dhash[newds] = hashval;
X
X if ( nacc == 0 )
X {
X dfaacc[newds].dfaacc_state = 0;
X accsiz[newds] = 0;
X }
X
X else if ( reject )
X {
X /* we sort the accepting set in increasing order so the disambiguating
X * rule that the first rule listed is considered match in the event of
X * ties will work. We use a bubble sort since the list is probably
X * quite small.
X */
X
X bubble( accset, nacc );
X
X dfaacc[newds].dfaacc_state =
X (int) malloc( (unsigned) ((nacc + 1) * sizeof( int )) );
X
X if ( ! dfaacc[newds].dfaacc_state )
X flexfatal( "dynamic memory failure in snstods()" );
X
X /* save the accepting set for later */
X for ( i = 1; i <= nacc; ++i )
X dfaacc[newds].dfaacc_set[i] = accset[i];
X
X accsiz[newds] = nacc;
X }
X
X else
X { /* find lowest numbered rule so the disambiguating rule will work */
X j = accnum + 1;
X
X for ( i = 1; i <= nacc; ++i )
X if ( accset[i] < j )
X j = accset[i];
X
X dfaacc[newds].dfaacc_state = j;
X }
X
X *newds_addr = newds;
X
X return ( 1 );
X }
X
X
X/* symfollowset - follow the symbol transitions one step
X *
X * synopsis
X * int ds[current_max_dfa_size], dsize, transsym;
X * int nset[current_max_dfa_size], numstates;
X * numstates = symfollowset( ds, dsize, transsym, nset );
X */
X
int symfollowset( ds, dsize, transsym, nset )
int ds[], dsize, transsym, nset[];
X
X {
X int ns, tsp, sym, i, j, lenccl, ch, numstates;
X int ccllist;
X
X numstates = 0;
X
X for ( i = 1; i <= dsize; ++i )
X { /* for each nfa state ns in the state set of ds */
X ns = ds[i];
X sym = transchar[ns];
X tsp = trans1[ns];
X
X if ( sym < 0 )
X { /* it's a character class */
X sym = -sym;
X ccllist = cclmap[sym];
X lenccl = ccllen[sym];
X
X if ( cclng[sym] )
X {
X for ( j = 0; j < lenccl; ++j )
X { /* loop through negated character class */
X ch = ccltbl[ccllist + j];
X
X if ( ch > transsym )
X break; /* transsym isn't in negated ccl */
X
X else if ( ch == transsym )
X /* next 2 */ goto bottom;
X }
X
X /* didn't find transsym in ccl */
X nset[++numstates] = tsp;
X }
X
X else
X for ( j = 0; j < lenccl; ++j )
X {
X ch = ccltbl[ccllist + j];
X
X if ( ch > transsym )
X break;
X
X else if ( ch == transsym )
X {
X nset[++numstates] = tsp;
X break;
X }
X }
X }
X
X else if ( sym >= 'A' && sym <= 'Z' && caseins )
X flexfatal( "consistency check failed in symfollowset" );
X
X else if ( sym == SYM_EPSILON )
X { /* do nothing */
X }
X
X else if ( ecgroup[sym] == transsym )
X nset[++numstates] = tsp;
X
bottom:
X ;
X }
X
X return ( numstates );
X }
X
X
X/* sympartition - partition characters with same out-transitions
X *
X * synopsis
X * integer ds[current_max_dfa_size], numstates, duplist[numecs];
X * symlist[numecs];
X * sympartition( ds, numstates, symlist, duplist );
X */
X
sympartition( ds, numstates, symlist, duplist )
int ds[], numstates, duplist[];
int symlist[];
X
X {
X int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich;
X
X /* partitioning is done by creating equivalence classes for those
X * characters which have out-transitions from the given state. Thus
X * we are really creating equivalence classes of equivalence classes.
X */
X
X for ( i = 1; i <= numecs; ++i )
X { /* initialize equivalence class list */
X duplist[i] = i - 1;
X dupfwd[i] = i + 1;
X }
X
X duplist[1] = NIL;
X dupfwd[numecs] = NIL;
X
X for ( i = 1; i <= numstates; ++i )
X {
X ns = ds[i];
X tch = transchar[ns];
X
X if ( tch != SYM_EPSILON )
X {
X if ( tch < -lastccl || tch > CSIZE )
X flexfatal( "bad transition character detected in sympartition()" );
X
X if ( tch > 0 )
X { /* character transition */
X mkechar( ecgroup[tch], dupfwd, duplist );
X symlist[ecgroup[tch]] = 1;
X }
X
X else
X { /* character class */
X tch = -tch;
X
X lenccl = ccllen[tch];
X cclp = cclmap[tch];
X mkeccl( ccltbl + cclp, lenccl, dupfwd, duplist, numecs );
X
X if ( cclng[tch] )
X {
X j = 0;
X
X for ( k = 0; k < lenccl; ++k )
X {
X ich = ccltbl[cclp + k];
X
X for ( ++j; j < ich; ++j )
X symlist[j] = 1;
X }
X
X for ( ++j; j <= numecs; ++j )
X symlist[j] = 1;
X }
X
X else
X for ( k = 0; k < lenccl; ++k )
X {
X ich = ccltbl[cclp + k];
X symlist[ich] = 1;
X }
X }
X }
X }
X }
END_OF_FILE
if test 10732 -ne `wc -c <'dfa.c'`; then
echo shar: \"'dfa.c'\" unpacked with wrong size!
fi
# end of 'dfa.c'
fi
if test -f 'flex.fastskel' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'flex.fastskel'\"
else
echo shar: Extracting \"'flex.fastskel'\" \(9304 characters\)
sed "s/^X//" >'flex.fastskel' <<'END_OF_FILE'
X/* A lexical scanner generated by flex */
X
X#define FLEX_FAST_SKEL
X
X#include "fastskeldef.h"
X
X%% section 1 code and the definition of YY_TRANS_OFFSET_TYPE, if needed, go here
X
X#ifndef FLEX_FULL_TABLE
X /* struct for yy_transition */
X struct yy_trans_info
X {
X /* v is a verify for a transition. */
X short v;
X
X /* In cases where its sister v *is* a "yes, there is a transition",
X * n is* the offset (in records) to the next state. In most cases
X * where there is no transition, the value of n is irrelevant. If n
X * is the -1th record of a state, though, then n is the action
X * number for that state
X */
X YY_TRANS_OFFSET_TYPE n;
X };
X#endif
X
X%% data tables for DFA go here
X
X/* these declarations have to come after the section 1 code or lint gets
X * confused about whether the variables are used
X */
XFILE *yyin = stdin, *yyout = stdout;
X
X/* these variables are all declared out here so that section 3 code can
X * manipulate them
X */
static char *yy_c_buf_p; /* points to current character in buffer */
static char *yy_b_buf_p; /* points to start of current scan */
static int yy_init = 1; /* whether we need to initialize */
static int yy_start; /* start state number */
X
X/* true when we've seen an EOF for the current input file */
static int yy_eof_has_been_seen;
X
static int yy_n_chars; /* number of characters read into yy_ch_buf */
X
X/* yy_ch_buf has to be 2 characters longer than YY_BUF_SIZE because we need
X * to put in 2 end-of-buffer characters (this is explained where it is
X * done) at the end of yy_ch_buf
X */
static char yy_ch_buf[YY_BUF_SIZE + 2];
X
X/* yy_hold_char holds the character lost when yytext is formed */
static char yy_hold_char;
char *yytext;
static int yyleng; /* length of yytext */
X
static YY_CS_TYPE yy_last_accepting_state;
static char *yy_last_accepting_cpos;
X
static YY_CS_TYPE yy_get_previous_state();
static int yy_get_next_buffer();
X
X#define FLEX_USES_BACKTRACKING
X
X#ifdef FLEX_USES_BACKTRACKING
X# ifdef FLEX_FULL_TABLE
X# define YY_BACKTRACKING_ACTION \
X if ( l[yy_current_state] ) \
X { \
X yy_last_accepting_state = yy_current_state; \
X yy_last_accepting_cpos = yy_c_buf_p; \
X }
X# else
X# define YY_BACKTRACKING_ACTION \
X if ( yy_current_state[-1].n ) \
X { \
X yy_last_accepting_state = yy_current_state; \
X yy_last_accepting_cpos = yy_c_buf_p; \
X }
X# endif
X#else
X# define YY_BACKTRACKING_ACTION
X#endif
X
YY_DECL
X {
X register YY_CS_TYPE yy_current_state;
X register int yy_c;
X register struct yy_trans_info *yy_trans_info;
X register int yy_act;
X
X%% user's declarations go here
X
X if ( yy_init )
X {
X yy_start = 1; /* first start state */
X
new_file:
X /* this is where we enter upon encountering and end-of-file and
X * yywrap() indicating that we should continue processing
X */
X
X /* we put in the '\n' and start reading from [1] so that an
X * initial match-at-newline will be true.
X */
X
X yy_ch_buf[0] = '\n';
X yy_n_chars = 1;
X
X /* we always need two end-of-buffer characters. The first causes
X * a transition to the end-of-buffer state. The second causes
X * a jam in that state.
X */
X yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
X yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
X
X yy_eof_has_been_seen = 0;
X
X YY_FAST_INIT;
X yy_init = 0;
X }
X
X while ( 1 ) /* loops until end-of-file is reached */
X {
X /* support of yytext and yyleng */
X YY_DO_BEFORE_SCAN;
X
X /* yy_b_buf_p points to the position in yy_ch_buf of the start of the
X * current run.
X */
X yy_b_buf_p = yy_c_buf_p;
X
X YY_FIND_START_STATE( yy_current_state );
X
X YY_FIND_NEXT_MATCH;
X
X YY_DO_BEFORE_ACTION;
X
X/* we need this label to process the very last action (right before the end of
X * the file)
X */
do_action:
X YY_FIND_ACTION( yy_act );
X
X#ifdef FLEX_DEBUG
X fprintf( stderr, "--accepting rule #%d\n", yy_act );
X#endif
X switch ( yy_act )
X {
X%% actions go here
X
X case YY_BACK_TRACK:
X YY_DO_BEFORE_SCAN; /* undo the effects of YY_DO_BEFORE_ACTION */
X yy_c_buf_p = yy_last_accepting_cpos + 1;
X yy_current_state = yy_last_accepting_state;
X YY_DO_BEFORE_ACTION;
X goto do_action;
X
X case YY_NEW_FILE:
X break; /* begin reading from new file */
X
X case YY_DO_DEFAULT:
X /* we have to eat up one character and recompute yytext and
X * yyleng
X */
X YY_DO_BEFORE_SCAN; /* undo the effects of YY_DO_BEFORE_ACTION */
X ++yy_c_buf_p;
X YY_DO_BEFORE_ACTION;
X YY_DEFAULT_ACTION;
X break;
X
X case YY_END_OF_BUFFER:
X YY_DO_BEFORE_SCAN; /* undo the effects of YY_DO_BEFORE_ACTION */
X
X switch ( yy_get_next_buffer() )
X {
X case EOB_ACT_END_OF_FILE:
X {
X if ( yywrap() )
X {
X /* note: because we've taken care in
X * yy_get_next_buffer() to have set up yy_b_buf_p,
X * we can now set up yy_c_buf_p so that if some
X * total hoser (like flex itself) wants
X * to call the scanner after we return the
X * YY_NULL, it'll still work - another YY_NULL
X * will get returned.
X */
X yy_c_buf_p = yy_b_buf_p;
X return ( YY_NULL );
X }
X
X else
X goto new_file;
X }
X break;
X
X case EOB_ACT_RESTART_SCAN:
X yy_c_buf_p = yy_b_buf_p;
X
X YY_DO_BEFORE_RESTART;
X break;
X
X case EOB_ACT_LAST_MATCH:
X yy_c_buf_p = &yy_ch_buf[yy_n_chars];
X
X yy_current_state = yy_get_previous_state();
X
X YY_DO_BEFORE_ACTION;
X
X goto do_action;
X }
X break;
X
X default:
X printf( "action # %d\n", yy_act );
X YY_FATAL_ERROR( "fatal flex scanner internal error" );
X }
X }
X }
X
X
X/* yy_get_next_buffer - try to read in new buffer
X *
X * synopsis
X * int yy_get_next_buffer();
X *
X * returns a code representing an action
X * EOB_ACT_LAST_MATCH -
X * EOB_ACT_RESTART_SCAN - restart the scanner
X * EOB_ACT_END_OF_FILE - end of file
X */
X
static int yy_get_next_buffer()
X
X {
X if ( yy_c_buf_p != &yy_ch_buf[yy_n_chars + 1] )
X {
X YY_FATAL_ERROR( "NULL in input" );
X /*NOTREACHED*/
X }
X
X else
X { /* try to read more data */
X register char *dest = yy_ch_buf;
X register char *source = yy_b_buf_p - 1; /* copy prev. char, too */
X register int number_to_move, i;
X int ret_val;
X
X /* first move last chars to start of buffer */
X number_to_move = yy_c_buf_p - yy_b_buf_p;
X
X for ( i = 0; i < number_to_move; ++i )
X *(dest++) = *(source++);
X
X if ( yy_eof_has_been_seen )
X /* don't do the read, it's not guaranteed to return an EOF,
X * just force an EOF
X */
X yy_n_chars = 0;
X
X else
X /* read in more data */
X YY_INPUT( (&yy_ch_buf[number_to_move]), yy_n_chars,
X YY_BUF_SIZE - number_to_move - 1 );
X
X if ( yy_n_chars == 0 )
X {
X if ( number_to_move == 1 )
X ret_val = EOB_ACT_END_OF_FILE;
X else
X ret_val = EOB_ACT_LAST_MATCH;
X
X yy_eof_has_been_seen = 1;
X }
X
X else
X ret_val = EOB_ACT_RESTART_SCAN;
X
X yy_n_chars += number_to_move;
X yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
X yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
X
X /* yy_b_buf_p begins at the second character in
X * yy_ch_buf; the first character is the one which
X * preceded it before reading in the latest buffer;
X * it needs to be kept around in case it's a
X * newline, so yy_get_previous_state() will have
X * with '^' rules active
X */
X
X yy_b_buf_p = &yy_ch_buf[1];
X
X return ( ret_val );
X }
X }
X
X
X/* yy_get_previous_state - get the state just before the eob char was reached
X *
X * synopsis
X * YY_CS_TYPE yy_get_previous_state();
X */
X
static YY_CS_TYPE yy_get_previous_state()
X
X {
X register YY_CS_TYPE yy_cur_state;
X register char *yy_temp_char_ptr;
X
X YY_FIND_START_STATE( yy_cur_state );
X
X for ( yy_temp_char_ptr = yy_b_buf_p; yy_temp_char_ptr < yy_c_buf_p; )
X YY_GET_NEXT_STATE;
X
X return ( yy_cur_state );
X }
X
X
static unput( c )
int c;
X
X {
X YY_DO_BEFORE_SCAN; /* undo effects of setting up yytext */
X
X if ( yy_c_buf_p < yy_ch_buf + 2 )
X { /* need to shift things up to make room */
X register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
X register char *dest = &yy_ch_buf[YY_BUF_SIZE + 2];
X register char *source = &yy_ch_buf[number_to_move];
X
X while ( source > yy_ch_buf )
X *--dest = *--source;
X
X yy_c_buf_p += dest - source;
X yy_b_buf_p += dest - source;
X
X if ( yy_c_buf_p < yy_ch_buf + 2 )
X YY_FATAL_ERROR( "flex scanner push-back overflow" );
X }
X
X if ( yy_c_buf_p > yy_b_buf_p && yy_c_buf_p[-1] == '\n' )
X yy_c_buf_p[-2] = '\n';
X
X *--yy_c_buf_p = c;
X
X YY_DO_BEFORE_ACTION; /* set up yytext again */
X }
X
X
static int input()
X
X {
X int c;
X
X YY_DO_BEFORE_SCAN;
X
X if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
X { /* need more input */
X yy_b_buf_p = yy_c_buf_p;
X ++yy_c_buf_p;
X
X switch ( yy_get_next_buffer() )
X {
X /* this code, unfortunately, is somewhat redundant with
X * that above
X */
X case EOB_ACT_END_OF_FILE:
X {
X if ( yywrap() )
X {
X yy_c_buf_p = yy_b_buf_p;
X return ( EOF );
X }
X
X yy_ch_buf[0] = '\n';
X yy_n_chars = 1;
X yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
X yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
X yy_eof_has_been_seen = 0;
X
X YY_FAST_INIT;
X
X return ( input() );
X }
X break;
X
X case EOB_ACT_RESTART_SCAN:
X yy_c_buf_p = yy_b_buf_p;
X break;
X
X case EOB_ACT_LAST_MATCH:
X YY_FATAL_ERROR( "unexpected last match in input()" );
X }
X }
X
X c = *yy_c_buf_p++;
X
X YY_DO_BEFORE_RESTART;
X
X return ( c );
X }
END_OF_FILE
if test 9304 -ne `wc -c <'flex.fastskel'`; then
echo shar: \"'flex.fastskel'\" unpacked with wrong size!
fi
# end of 'flex.fastskel'
fi
if test -f 'main.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'main.c'\"
else
echo shar: Extracting \"'main.c'\" \(12885 characters\)
sed "s/^X//" >'main.c' <<'END_OF_FILE'
X/* flex - tool to generate fast lexical analyzers
X *
X *
X * Copyright (c) 1987, the University of California
X *
X * The United States Government has rights in this work pursuant to
X * contract no. DE-AC03-76SF00098 between the United States Department of
X * Energy and the University of California.
X *
X * This program may be redistributed. Enhancements and derivative works
X * may be created provided the new works, if made available to the general
X * public, are made available for use by anyone.
X *
X *
X * ver date who remarks
X * --- ---- ------ -------------------------------------------------------
X * 04b 30sep87 kg, vp .implemented (part of) Van Jacobson's fast scanner design
X * 04a 27jun86 vp .translated from Ratfor into C
X * 01a 22aug83 vp .written. Original version by Jef Poskanzer.
X */
X
X#include "flexdef.h"
X
X
X/* these globals are all defined and commented in flexdef.h */
int printstats, syntaxerror, eofseen, ddebug, trace, spprdflt;
int interactive, caseins, useecs, fulltbl, usemecs, reject;
int fullspd, gen_line_dirs;
int datapos, dataline, linenum;
XFILE *skelfile = NULL;
char *infilename = NULL;
int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE];
int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp;
int current_mns;
int accnum, *firstst, *lastst, *finalst, *transchar;
int *trans1, *trans2, *accptnum, lastnfa;
int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP];
int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE];
int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1];
int tecbck[CSIZE + 1];
int lastsc, current_max_scs, *scset, *scbol, *scxclu, *actvsc;
int current_max_dfa_size, current_max_xpairs;
int current_max_template_xpairs, current_max_dfas;
int lastdfa, *nxt, *chk, *tnxt;
int *base, *def, tblend, firstfree, numtemps, **dss, *dfasiz;
union dfaacc_union *dfaacc;
int *accsiz, *dhash, *todo, todo_head, todo_next, numas;
int numsnpairs, jambase, jamstate;
int lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse;
int current_max_ccl_tbl_size;
char *ccltbl;
char *starttime, *endtime, nmstr[MAXLINE];
int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs;
int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave;
XFILE *temp_action_file;
int end_of_buffer_state;
char *action_file_name = "/tmp/flexXXXXXX";
X
X
X/* flex - main program
X *
X * synopsis (from the shell)
X * flex [-v] [file ...]
X */
X
main( argc, argv )
int argc;
char **argv;
X
X {
X flexinit( argc, argv );
X
X readin();
X
X if ( ! syntaxerror )
X {
X /* convert the ndfa to a dfa */
X ntod();
X
X /* generate the C state transition tables from the DFA */
X make_tables();
X }
X
X /* note, flexend does not return. It exits with its argument as status. */
X
X flexend( 0 );
X }
X
X
X/* flexend - terminate flex
X *
X * synopsis
X * int status;
X * flexend( status );
X *
X * status is exit status.
X *
X * note
X * This routine does not return.
X */
X
flexend( status )
int status;
X
X {
X int tblsiz;
X char *gettime();
X
X if ( skelfile != NULL )
X (void) fclose( skelfile );
X
X if ( temp_action_file )
X {
X (void) fclose( temp_action_file );
X (void) unlink( action_file_name );
X }
X
X if ( printstats )
X {
X endtime = gettime();
X
X fprintf( stderr, "flex usage statistics:\n" );
X fprintf( stderr, " started at %s, finished at %s\n",
X starttime, endtime );
X
X fprintf( stderr, " %d/%d NFA states\n", lastnfa, current_mns );
X fprintf( stderr, " %d/%d DFA states (%d words)\n", lastdfa,
X current_max_dfas, totnst );
X fprintf( stderr, " %d rules\n", accnum );
X fprintf( stderr, " %d/%d start conditions\n", lastsc,
X current_max_scs );
X fprintf( stderr, " %d epsilon states, %d double epsilon states\n",
X numeps, eps2 );
X
X if ( lastccl == 0 )
X fprintf( stderr, " no character classes\n" );
X else
X fprintf( stderr,
X " %d/%d character classes needed %d/%d words of storage, %d reused\n",
X lastccl, current_maxccls,
X cclmap[lastccl] + ccllen[lastccl] - 1,
X current_max_ccl_tbl_size, cclreuse );
X
X fprintf( stderr, " %d state/nextstate pairs created\n", numsnpairs );
X fprintf( stderr, " %d/%d unique/duplicate transitions\n",
X numuniq, numdup );
X
X if ( fulltbl )
X {
X tblsiz = lastdfa * numecs;
X fprintf( stderr, " %d table entries\n", tblsiz );
X }
X
X else
X {
X tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend;
X
X fprintf( stderr, " %d/%d base/def entries created\n",
X lastdfa + numtemps, current_max_dfas );
X fprintf( stderr, " %d/%d (peak %d) nxt/chk entries created\n",
X tblend, current_max_xpairs, peakpairs );
X fprintf( stderr,
X " %d/%d (peak %d) template nxt/chk entries created\n",
X numtemps * nummecs, current_max_template_xpairs,
X numtemps * numecs );
X fprintf( stderr, " %d empty table entries\n", nummt );
X fprintf( stderr, " %d protos created\n", numprots );
X fprintf( stderr, " %d templates created, %d uses\n",
X numtemps, tmpuses );
X }
X
X if ( useecs )
X {
X tblsiz = tblsiz + CSIZE;
X fprintf( stderr, " %d/%d equivalence classes created\n",
X numecs, CSIZE );
X }
X
X if ( usemecs )
X {
X tblsiz = tblsiz + numecs;
X fprintf( stderr, " %d/%d meta-equivalence classes created\n",
X nummecs, CSIZE );
X }
X
X fprintf( stderr, " %d (%d saved) hash collisions, %d DFAs equal\n",
X hshcol, hshsave, dfaeql );
X fprintf( stderr, " %d sets of reallocations needed\n", num_reallocs );
X fprintf( stderr, " %d total table entries needed\n", tblsiz );
X }
X
X exit( status );
X }
X
X
X/* flexinit - initialize flex
X *
X * synopsis
X * int argc;
X * char **argv;
X * flexinit( argc, argv );
X */
X
flexinit( argc, argv )
int argc;
char **argv;
X
X {
X int i, sawcmpflag, use_stdout;
X char *arg, *skelname = NULL, *gettime(), clower(), *mktemp();
X
X printstats = syntaxerror = trace = spprdflt = interactive = caseins = false;
X ddebug = fulltbl = reject = fullspd = false;
X gen_line_dirs = usemecs = useecs = true;
X
X sawcmpflag = false;
X use_stdout = false;
X
X /* read flags */
X for ( --argc, ++argv; argc ; --argc, ++argv )
X {
X if ( argv[0][0] != '-' || argv[0][1] == '\0' )
X break;
X
X arg = argv[0];
X
X for ( i = 1; arg[i] != '\0'; ++i )
X switch ( arg[i] )
X {
X case 'c':
X if ( i != 1 )
X flexerror( "-c flag must be given separately" );
X
X if ( ! sawcmpflag )
X {
X useecs = false;
X usemecs = false;
X fulltbl = false;
X sawcmpflag = true;
X }
X
X for ( ++i; arg[i] != '\0'; ++i )
X switch ( clower( arg[i] ) )
X {
X case 'e':
X useecs = true;
X break;
X
X case 'F':
X fullspd = true;
X break;
X
X case 'f':
X fulltbl = true;
X break;
X
X case 'm':
X usemecs = true;
X break;
X
X default:
X lerrif( "unknown -c option %c",
X (int) arg[i] );
X break;
X }
X
X goto get_next_arg;
X
X case 'd':
X ddebug = true;
X break;
X
X case 'f':
X useecs = usemecs = false;
X fulltbl = true;
X break;
X
X case 'I':
X interactive = true;
X break;
X
X case 'i':
X caseins = true;
X break;
X
X case 'L':
X gen_line_dirs = false;
X break;
X
X case 'r':
X reject = true;
X break;
X
X case 'F':
X useecs = usemecs = false;
X fullspd = true;
X break;
X
X case 'S':
X if ( i != 1 )
X flexerror( "-S flag must be given separately" );
X
X skelname = arg + i + 1;
X goto get_next_arg;
X
X case 's':
X spprdflt = true;
X break;
X
X case 't':
X use_stdout = true;
X break;
X
X case 'T':
X trace = true;
X break;
X
X case 'v':
X printstats = true;
X break;
X
X default:
X lerrif( "unknown flag %c", (int) arg[i] );
X break;
X }
X
get_next_arg: /* used by -c and -S flags in lieu of a "continue 2" control */
X ;
X }
X
X if ( (fulltbl || fullspd) && usemecs )
X flexerror( "full table and -cm don't make sense together" );
X
X if ( (fulltbl || fullspd) && interactive )
X flexerror( "full table and -I are (currently) incompatible" );
X
X if ( (fulltbl || fullspd) && reject )
X flexerror( "reject (-r) cannot be used with -f or -F" );
X
X if ( fulltbl && fullspd )
X flexerror( "full table and -F are mutually exclusive" );
X
X if ( ! skelname )
X {
X static char skeleton_name_storage[400];
X
X skelname = skeleton_name_storage;
X
X if ( fullspd || fulltbl )
X (void) strcpy( skelname, FAST_SKELETON_FILE );
X else
X (void) strcpy( skelname, DEFAULT_SKELETON_FILE );
X }
X
X if ( ! use_stdout )
X {
X FILE *prev_stdout = freopen( "lex.yy.c", "w", stdout );
X
X if ( prev_stdout == NULL )
X flexerror( "could not create lex.yy.c" );
X }
X
X if ( argc )
X {
X if ( argc > 1 )
X flexerror( "extraneous argument(s) given" );
X
X yyin = fopen( infilename = argv[0], "r" );
X
X if ( yyin == NULL )
X lerrsf( "can't open %s", argv[0] );
X }
X
X else
X yyin = stdin;
X
X lastccl = 0;
X lastsc = 0;
X
X /* initialize the statistics */
X starttime = gettime();
X
X if ( (skelfile = fopen( skelname, "r" )) == NULL )
X lerrsf( "can't open skeleton file %s", skelname );
X
X (void) mktemp( action_file_name );
X
X if ( (temp_action_file = fopen( action_file_name, "w" )) == NULL )
X lerrsf( "can't open temporary action file %s", action_file_name );
X
X lastdfa = lastnfa = accnum = numas = numsnpairs = tmpuses = 0;
X numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0;
X numuniq = numdup = hshsave = eofseen = datapos = dataline = 0;
X onesp = numprots = 0;
X
X linenum = sectnum = 1;
X firstprot = NIL;
X
X /* used in mkprot() so that the first proto goes in slot 1
X * of the proto queue
X */
X lastprot = 1;
X
X if ( useecs )
X {
X /* set up doubly-linked equivalence classes */
X ecgroup[1] = NIL;
X
X for ( i = 2; i <= CSIZE; ++i )
X {
X ecgroup[i] = i - 1;
X nextecm[i - 1] = i;
X }
X
X nextecm[CSIZE] = NIL;
X }
X
X else
X { /* put everything in its own equivalence class */
X for ( i = 1; i <= CSIZE; ++i )
X {
X ecgroup[i] = i;
X nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */
X }
X }
X
X set_up_initial_allocations();
X }
X
X
X/* readin - read in the rules section of the input file(s)
X *
X * synopsis
X * readin();
X */
X
readin()
X
X {
X fputs( "#define YY_DEFAULT_ACTION ", stdout );
X
X if ( spprdflt )
X fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )", stdout );
X else
X fputs( "ECHO", stdout );
X
X fputs( ";\n", stdout );
X
X if ( ddebug )
X puts( "#define FLEX_DEBUG" );
X if ( useecs )
X puts( "#define FLEX_USE_ECS" );
X if ( usemecs )
X puts( "#define FLEX_USE_MECS" );
X if ( interactive )
X puts( "#define FLEX_INTERACTIVE_SCANNER" );
X if ( reject )
X puts( "#define FLEX_REJECT_ENABLED" );
X if ( fulltbl )
X puts( "#define FLEX_FULL_TABLE" );
X
X skelout();
X
X line_directive_out( stdout );
X
X if ( yyparse() )
X lerrif( "fatal parse error at line %d", linenum );
X
X if ( useecs )
X {
X numecs = cre8ecs( nextecm, ecgroup, CSIZE );
X ccl2ecl();
X }
X
X else
X numecs = CSIZE;
X
X }
X
X
X
X/* set_up_initial_allocations - allocate memory for internal tables */
X
set_up_initial_allocations()
X
X {
X current_mns = INITIAL_MNS;
X firstst = allocate_integer_array( current_mns );
X lastst = allocate_integer_array( current_mns );
X finalst = allocate_integer_array( current_mns );
X transchar = allocate_integer_array( current_mns );
X trans1 = allocate_integer_array( current_mns );
X trans2 = allocate_integer_array( current_mns );
X accptnum = allocate_integer_array( current_mns );
X
X current_max_scs = INITIAL_MAX_SCS;
X scset = allocate_integer_array( current_max_scs );
X scbol = allocate_integer_array( current_max_scs );
X scxclu = allocate_integer_array( current_max_scs );
X actvsc = allocate_integer_array( current_max_scs );
X
X current_maxccls = INITIAL_MAXCCLS;
X cclmap = allocate_integer_array( current_maxccls );
X ccllen = allocate_integer_array( current_maxccls );
X cclng = allocate_integer_array( current_maxccls );
X
X current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE;
X ccltbl = allocate_character_array( current_max_ccl_tbl_size );
X
X current_max_dfa_size = INITIAL_MAX_DFA_SIZE;
X
X current_max_xpairs = INITIAL_MAX_XPAIRS;
X nxt = allocate_integer_array( current_max_xpairs );
X chk = allocate_integer_array( current_max_xpairs );
X
X current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS;
X tnxt = allocate_integer_array( current_max_template_xpairs );
X
X current_max_dfas = INITIAL_MAX_DFAS;
X base = allocate_integer_array( current_max_dfas );
X def = allocate_integer_array( current_max_dfas );
X dfasiz = allocate_integer_array( current_max_dfas );
X accsiz = allocate_integer_array( current_max_dfas );
X dhash = allocate_integer_array( current_max_dfas );
X todo = allocate_integer_array( current_max_dfas );
X dss = allocate_integer_pointer_array( current_max_dfas );
X dfaacc = allocate_dfaacc_union( current_max_dfas );
X }
END_OF_FILE
if test 12885 -ne `wc -c <'main.c'`; then
echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
if test -f 'misc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'misc.c'\"
else
echo shar: Extracting \"'misc.c'\" \(9991 characters\)
sed "s/^X//" >'misc.c' <<'END_OF_FILE'
X/* misc - miscellaneous flex routines */
X
X/*
X * Copyright (c) 1987, the University of California
X *
X * The United States Government has rights in this work pursuant to
X * contract no. DE-AC03-76SF00098 between the United States Department of
X * Energy and the University of California.
X *
X * This program may be redistributed. Enhancements and derivative works
X * may be created provided the new works, if made available to the general
X * public, are made available for use by anyone.
X */
X
X#include <ctype.h>
X#include "flexdef.h"
X
char *malloc(), *realloc();
X
X
X/* action_out - write the actions from the temporary file to lex.yy.c
X *
X * synopsis
X * action_out();
X *
X * Copies the action file up to %% (or end-of-file) to lex.yy.c
X */
X
action_out()
X
X {
X char buf[MAXLINE];
X
X while ( fgets( buf, MAXLINE, temp_action_file ) != NULL )
X if ( buf[0] == '%' && buf[1] == '%' )
X break;
X else
X fputs( buf, stdout );
X }
X
X
X/* allocate_array - allocate memory for an integer array of the given size */
X
char *allocate_array( size, element_size )
int size, element_size;
X
X {
X register char *mem = malloc( (unsigned) (element_size * size) );
X
X if ( mem == NULL )
X flexfatal( "memory allocation failed in allocate_array()" );
X
X return ( mem );
X }
X
X
X/* bubble - bubble sort an integer array in increasing order
X *
X * synopsis
X * int v[n], n;
X * bubble( v, n );
X *
X * description
X * sorts the first n elements of array v and replaces them in
X * increasing order.
X *
X * passed
X * v - the array to be sorted
X * n - the number of elements of 'v' to be sorted */
X
bubble( v, n )
int v[], n;
X
X {
X register int i, j, k;
X
X for ( i = n; i > 1; --i )
X for ( j = 1; j < i; ++j )
X if ( v[j] > v[j + 1] ) /* compare */
X {
X k = v[j]; /* exchange */
X v[j] = v[j + 1];
X v[j + 1] = k;
X }
X }
X
X
X/* clower - replace upper-case letter to lower-case
X *
X * synopsis:
X * char clower(), c;
X * c = clower( c );
X */
X
char clower( c )
register char c;
X
X {
X return ( isupper(c) ? tolower(c) : c );
X }
X
X
X/* copy_string - returns a dynamically allocated copy of a string
X *
X * synopsis
X * char *str, *copy, *copy_string();
X * copy = copy_string( str );
X */
X
char *copy_string( str )
register char *str;
X
X {
X register char *c;
X char *copy;
X
X /* find length */
X for ( c = str; *c; ++c )
X ;
X
X copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) );
X
X if ( copy == NULL )
X flexfatal( "dynamic memory failure in copy_string()" );
X
X for ( c = copy; (*c++ = *str++); )
X ;
X
X return ( copy );
X }
X
X
X/* cshell - shell sort a character array in increasing order
X *
X * synopsis
X *
X * char v[n];
X * int n;
X * cshell( v, n );
X *
X * description
X * does a shell sort of the first n elements of array v.
X *
X * passed
X * v - array to be sorted
X * n - number of elements of v to be sorted
X */
cshell( v, n )
char v[];
int n;
X
X {
X int gap, i, j, jg;
X char k;
X
X for ( gap = n / 2; gap > 0; gap = gap / 2 )
X for ( i = gap; i < n; ++i )
X for ( j = i - gap; j >= 0; j = j - gap )
X {
X jg = j + gap;
X
X if ( v[j] <= v[jg] )
X break;
X
X k = v[j];
X v[j] = v[jg];
X v[jg] = k;
X }
X }
X
X
X/* dataend - finish up a block of data declarations
X *
X * synopsis
X * dataend();
X */
dataend()
X
X {
X if ( datapos > 0 )
X dataflush();
X
X /* add terminator for initialization */
X puts( " } ;\n" );
X
X dataline = 0;
X }
X
X
X
X/* dataflush - flush generated data statements
X *
X * synopsis
X * dataflush();
X */
dataflush()
X
X {
X putchar( '\n' );
X
X if ( ++dataline >= NUMDATALINES )
X {
X /* put out a blank line so that the table is grouped into
X * large blocks that enable the user to find elements easily
X */
X putchar( '\n' );
X dataline = 0;
X }
X
X /* reset the number of characters written on the current line */
X datapos = 0;
X }
X
X/* gettime - return current time
X *
X * synopsis
X * char *gettime(), *time_str;
X * time_str = gettime();
X */
X
X/* include sys/types.h to use time_t and make lint happy */
X
X#include <sys/types.h>
X
char *gettime()
X
X {
X time_t t, time();
X char *result, *ctime(), *copy_string();
X
X t = time( (long *) 0 );
X
X result = copy_string( ctime( &t ) );
X
X /* get rid of trailing newline */
X result[24] = '\0';
X
X return ( result );
X }
X
X
X/* lerrif - report an error message formatted with one integer argument
X *
X * synopsis
X * char msg[];
X * int arg;
X * lerrif( msg, arg );
X */
X
lerrif( msg, arg )
char msg[];
int arg;
X
X {
X char errmsg[MAXLINE];
X (void) sprintf( errmsg, msg, arg );
X flexerror( errmsg );
X }
X
X
X/* lerrsf - report an error message formatted with one string argument
X *
X * synopsis
X * char msg[], arg[];
X * lerrsf( msg, arg );
X */
X
lerrsf( msg, arg )
char msg[], arg[];
X
X {
X char errmsg[MAXLINE];
X
X (void) sprintf( errmsg, msg, arg );
X flexerror( errmsg );
X }
X
X
X/* flexerror - report an error message and terminate
X *
X * synopsis
X * char msg[];
X * flexerror( msg );
X */
X
flexerror( msg )
char msg[];
X
X {
X fprintf( stderr, "flex: %s\n", msg );
X flexend( 1 );
X }
X
X
X/* flexfatal - report a fatal error message and terminate
X *
X * synopsis
X * char msg[];
X * flexfatal( msg );
X */
X
flexfatal( msg )
char msg[];
X
X {
X fprintf( stderr, "flex: fatal internal error %s\n", msg );
X flexend( 1 );
X }
X
X
X/* line_directive_out - spit out a "# line" statement */
X
line_directive_out( output_file_name )
XFILE *output_file_name;
X
X {
X if ( infilename && gen_line_dirs )
X fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename );
X }
X
X
X/* mk2data - generate a data statement for a two-dimensional array
X *
X * synopsis
X * int value;
X * mk2data( value );
X *
X * generates a data statement initializing the current 2-D array to "value"
X */
mk2data( value )
int value;
X
X {
X if ( datapos >= NUMDATAITEMS )
X {
X putchar( ',' );
X dataflush();
X }
X
X if ( datapos == 0 )
X /* indent */
X fputs( " ", stdout );
X
X else
X putchar( ',' );
X
X ++datapos;
X
X printf( "%5d", value );
X }
X
X
X/* mkdata - generate a data statement
X *
X * synopsis
X * int value;
X * mkdata( value );
X *
X * generates a data statement initializing the current array element to
X * "value"
X */
mkdata( value )
int value;
X
X {
X if ( datapos >= NUMDATAITEMS )
X {
X putchar( ',' );
X dataflush();
X }
X
X if ( datapos == 0 )
X /* indent */
X fputs( " ", stdout );
X
X else
X putchar( ',' );
X
X ++datapos;
X
X printf( "%5d", value );
X }
X
X
X/* myctoi - return the integer represented by a string of digits
X *
X * synopsis
X * char array[];
X * int val, myctoi();
X * val = myctoi( array );
X *
X */
X
int myctoi( array )
char array[];
X
X {
X int val = 0;
X
X (void) sscanf( array, "%d", &val );
X
X return ( val );
X }
X
X
X/* myesc - return character corresponding to escape sequence
X *
X * synopsis
X * char array[], c, myesc();
X * c = myesc( array );
X *
X */
X
char myesc( array )
char array[];
X
X {
X switch ( array[1] )
X {
X case 'n': return ( '\n' );
X case 't': return ( '\t' );
X case 'f': return ( '\f' );
X case 'r': return ( '\r' );
X case 'b': return ( '\b' );
X
X case '0':
X if ( isdigit(array[2]) )
X { /* \0<octal> */
X char c, esc_char;
X register int sptr = 2;
X
X while ( isdigit(array[sptr]) )
X /* don't increment inside loop control because the
X * macro will expand it to two increments! (Not a
X * problem with the C version of the macro)
X */
X ++sptr;
X
X c = array[sptr];
X array[sptr] = '\0';
X
X esc_char = otoi( array + 2 );
X array[sptr] = c;
X
X if ( esc_char == '\0' )
X {
X synerr( "escape sequence for null not allowed" );
X return ( 1 );
X }
X
X return ( esc_char );
X }
X
X else
X {
X synerr( "escape sequence for null not allowed" );
X return ( 1 );
X }
X
X#ifdef NOTDEF
X case '^':
X {
X register char next_char = array[2];
X
X if ( next_char == '?' )
X return ( 0x7f );
X
X else if ( next_char >= 'A' && next_char <= 'Z' )
X return ( next_char - 'A' + 1 );
X
X else if ( next_char >= 'a' && next_char <= 'z' )
X return ( next_char - 'z' + 1 );
X
X synerr( "illegal \\^ escape sequence" );
X
X return ( 1 );
X }
X#endif
X }
X
X return ( array[1] );
X }
X
X
X/* otoi - convert an octal digit string to an integer value
X *
X * synopsis:
X * int val, otoi();
X * char str[];
X * val = otoi( str );
X */
X
int otoi( str )
char str[];
X
X {
X#ifdef FTLSOURCE
X fortran int gctoi()
X int dummy = 1;
X
X return ( gctoi( str, dummy, 8 ) );
X#else
X int result;
X
X (void) sscanf( str, "%o", &result );
X
X return ( result );
X#endif
X }
X
X
X
X
X/* reallocate_array - increase the size of a dynamic array */
X
char *reallocate_array( array, size, element_size )
char *array;
int size, element_size;
X
X {
X register char *new_array = realloc( array,
X (unsigned) (size * element_size ));
X
X if ( new_array == NULL )
X flexfatal( "attempt to increase array size failed" );
X
X return ( new_array );
X }
X
X
X/* skelout - write out one section of the skeleton file
X *
X * synopsis
X * skelout();
X *
X * DESCRIPTION
X * Copies from skelfile to stdout until a line beginning with "%%" or
X * EOF is found.
X */
skelout()
X
X {
X char buf[MAXLINE];
X
X while ( fgets( buf, MAXLINE, skelfile ) != NULL )
X if ( buf[0] == '%' && buf[1] == '%' )
X break;
X else
X fputs( buf, stdout );
X }
X
X
X/* transition_struct_out - output a yy_trans_info structure
X *
X * synopsis
X * int element_v, element_n;
X * transition_struct_out( element_v, element_n );
X *
X * outputs the yy_trans_info structure with the two elements, element_v and
X * element_n. Formats the output with spaces and carriage returns.
X */
X
transition_struct_out( element_v, element_n )
int element_v, element_n;
X
X {
X printf( "%7d, %5d,", element_v, element_n );
X
X datapos += TRANS_STRUCT_PRINT_LENGTH;
X
X if ( datapos >= 75 )
X {
X printf( "\n" );
X
X if ( ++dataline % 10 == 0 )
X printf( "\n" );
X
X datapos = 0;
X }
X }
END_OF_FILE
if test 9991 -ne `wc -c <'misc.c'`; then
echo shar: \"'misc.c'\" unpacked with wrong size!
fi
# end of 'misc.c'
fi
if test -f 'scan.l' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'scan.l'\"
else
echo shar: Extracting \"'scan.l'\" \(9189 characters\)
sed "s/^X//" >'scan.l' <<'END_OF_FILE'
X/* scan.l - scanner for flex input */
X
X/*
X * Copyright (c) 1987, the University of California
X *
X * The United States Government has rights in this work pursuant to
X * contract no. DE-AC03-76SF00098 between the United States Department of
X * Energy and the University of California.
X *
X * This program may be redistributed. Enhancements and derivative works
X * may be created provided the new works, if made available to the general
X * public, are made available for use by anyone.
X */
X
X%{
X#include "flexdef.h"
X#include "parse.h"
X
X#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext )
X#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" );
X
X#undef YY_DECL
X#define YY_DECL \
X int flexscan()
X
X#define RETURNCHAR \
X yylval = yytext[0]; \
X return ( CHAR );
X
X#define RETURNNAME \
X (void) strcpy( nmstr, yytext ); \
X return ( NAME );
X
X#define PUT_BACK_STRING(str, start) \
X for ( i = strlen( str ) - 1; i >= start; --i ) \
X unput(str[i])
X%}
X
X%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
X%x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT C_COMMENT_2 ACTION_COMMENT
X%x ACTION_STRING PERCENT_BRACE_ACTION
X
WS [ \t]+
X
OPTWS [ \t]*
X
NAME [a-z_][a-z_0-9]*
X
SCNAME {NAME}
X
ESCSEQ \\([^^\n]|"^".|0[0-9]{1,3})
X
X%%
X static int bracelevel, didadef;
X int i, cclval;
X char nmdef[MAXLINE], myesc();
X
X^{WS}.*\n ++linenum; ECHO; /* indented code */
X^#.*\n ++linenum; ECHO; /* treat as a comment */
X^"/*" ECHO; BEGIN(C_COMMENT);
X^"%s"(tart)? return ( SCDECL );
X^"%x" return ( XSCDECL );
X^"%{".*\n ++linenum; line_directive_out( stdout ); BEGIN(CODEBLOCK);
X{WS} return ( WHITESPACE );
X
X^"%%".* {
X sectnum = 2;
X line_directive_out( stdout );
X BEGIN(SECT2PROLOG);
X return ( SECTEND );
X }
X
X^"%"[^sx{%].*\n {
X fprintf( stderr,
X "old-style lex command at line %d ignored:\n\t%s",
X linenum, yytext );
X ++linenum;
X }
X
X^{NAME} {
X (void) strcpy( nmstr, yytext );
X didadef = false;
X BEGIN(PICKUPDEF);
X }
X
X{SCNAME} RETURNNAME;
X^{OPTWS}\n ++linenum; /* allows blank lines in section 1 */
X\n ++linenum; return ( '\n' );
X. synerr( "illegal character" ); BEGIN(RECOVER);
X
X
X<C_COMMENT>"*/" ECHO; BEGIN(0);
X<C_COMMENT>"*/".*\n ++linenum; ECHO; BEGIN(0);
X<C_COMMENT>[^*\n]+ ECHO;
X<C_COMMENT>"*" ECHO;
X<C_COMMENT>\n ++linenum; ECHO;
X
X<CODEBLOCK>^"%}".*\n ++linenum; BEGIN(0);
X<CODEBLOCK>.*\n ++linenum; ECHO;
X
X<PICKUPDEF>{WS} /* separates name and definition */
X
X<PICKUPDEF>[^ \t\n].* {
X (void) strcpy( nmdef, yytext );
X
X for ( i = strlen( nmdef ) - 1;
X i >= 0 &&
X nmdef[i] == ' ' || nmdef[i] == '\t';
X --i )
X ;
X
X nmdef[i + 1] = '\0';
X
X ndinstal( nmstr, nmdef );
X didadef = true;
X }
X
X<PICKUPDEF>\n {
X if ( ! didadef )
X synerr( "incomplete name definition" );
X BEGIN(0);
X ++linenum;
X }
X
X<RECOVER>.*\n ++linenum; BEGIN(0); RETURNNAME;
X
X
X<SECT2PROLOG>.*\n/[^ \t\n] {
X ++linenum;
X ACTION_ECHO;
X MARK_END_OF_PROLOG;
X BEGIN(SECT2);
X }
X
X<SECT2PROLOG>.*\n ++linenum; ACTION_ECHO;
X
X<SECT2>^{OPTWS}\n ++linenum; /* allow blank lines in section 2 */
X
X /* this horrible mess of a rule matches indented lines which
X * do not contain "/*". We need to make the distinction because
X * otherwise this rule will be taken instead of the rule which
X * matches the beginning of comments like this one
X */
X<SECT2>^{WS}([^/\n]|"/"[^*\n])*("/"?)\n {
X synerr( "indented code found outside of action" );
X ++linenum;
X }
X
X<SECT2>"<" BEGIN(SC); return ( '<' );
X<SECT2>^"^" return ( '^' );
X<SECT2>\" BEGIN(QUOTE); return ( '"' );
X<SECT2>"{"/[0-9] BEGIN(NUM); return ( '{' );
X<SECT2>"{"[^0-9\n][^}\n]* BEGIN(BRACEERROR);
X<SECT2>"$"/[ \t\n] return ( '$' );
X
X<SECT2>{WS}"%{" {
X bracelevel = 1;
X BEGIN(PERCENT_BRACE_ACTION);
X return ( '\n' );
X }
X<SECT2>{WS}"|".*\n ++linenum; return ( '\n' );
X
X<SECT2>^{OPTWS}"/*" ACTION_ECHO; BEGIN(C_COMMENT_2);
X
X<SECT2>{WS} { /* needs to be separate from following rule due to
X * bug with trailing context
X */
X bracelevel = 0;
X BEGIN(ACTION);
X return ( '\n' );
X }
X
X<SECT2>{OPTWS}/\n {
X bracelevel = 0;
X BEGIN(ACTION);
X return ( '\n' );
X }
X
X<SECT2>^{OPTWS}\n ++linenum; return ( '\n' );
X
X<SECT2>^"%%".* {
X /* guarantee that the SECT3 rule will have something
X * to match
X */
X yyless(1);
X sectnum = 3;
X BEGIN(SECT3);
X return ( EOF ); /* to stop the parser */
X }
X
X<SECT2>"["([^\\\]\n]|{ESCSEQ})+"]" {
X (void) strcpy( nmstr, yytext );
X
X /* check to see if we've already encountered this ccl */
X if ( (cclval = ccllookup( nmstr )) )
X {
X yylval = cclval;
X ++cclreuse;
X return ( PREVCCL );
X }
X else
X {
X /* we fudge a bit. We know that this ccl will
X * soon be numbered as lastccl + 1 by cclinit
X */
X cclinstal( nmstr, lastccl + 1 );
X
X /* push back everything but the leading bracket
X * so the ccl can be rescanned
X */
X PUT_BACK_STRING(nmstr, 1);
X
X BEGIN(FIRSTCCL);
X return ( '[' );
X }
X }
X
X<SECT2>"{"{NAME}"}" {
X register char *nmdefptr;
X char *ndlookup();
X
X (void) strcpy( nmstr, yytext );
X nmstr[yyleng - 1] = '\0'; /* chop trailing brace */
X
X /* lookup from "nmstr + 1" to chop leading brace */
X if ( ! (nmdefptr = ndlookup( nmstr + 1 )) )
X synerr( "undefined {name}" );
X
X else
X { /* push back name surrounded by ()'s */
X unput(')');
X PUT_BACK_STRING(nmdefptr, 0);
X unput('(');
X }
X }
X
X<SECT2>[/|*+?.()] return ( yytext[0] );
X<SECT2>. RETURNCHAR;
X<SECT2>\n ++linenum; return ( '\n' );
X
X
X<SC>"," return ( ',' );
X<SC>">" BEGIN(SECT2); return ( '>' );
X<SC>">"/"^" BEGIN(CARETISBOL); return ( '>' );
X<SC>{SCNAME} RETURNNAME;
X<SC>. synerr( "bad start condition name" );
X
X<CARETISBOL>"^" BEGIN(SECT2); return ( '^' );
X
X
X<QUOTE>[^"\n] RETURNCHAR;
X<QUOTE>\" BEGIN(SECT2); return ( '"' );
X
X<QUOTE>\n {
X synerr( "missing quote" );
X BEGIN(SECT2);
X ++linenum;
X return ( '"' );
X }
X
X
X<FIRSTCCL>"^"/[^-\n] BEGIN(CCL); return ( '^' );
X<FIRSTCCL>"^"/- return ( '^' );
X<FIRSTCCL>- BEGIN(CCL); yylval = '-'; return ( CHAR );
X<FIRSTCCL>. BEGIN(CCL); RETURNCHAR;
X
X<CCL>-/[^\]\n] return ( '-' );
X<CCL>[^\]\n] RETURNCHAR;
X<CCL>"]" BEGIN(SECT2); return ( ']' );
X
X
X<NUM>[0-9]+ {
X yylval = myctoi( yytext );
X return ( NUMBER );
X }
X
X<NUM>"," return ( ',' );
X<NUM>"}" BEGIN(SECT2); return ( '}' );
X
X<NUM>. {
X synerr( "bad character inside {}'s" );
X BEGIN(SECT2);
X return ( '}' );
X }
X
X<NUM>\n {
X synerr( "missing }" );
X BEGIN(SECT2);
X ++linenum;
X return ( '}' );
X }
X
X
X<BRACEERROR>"}" synerr( "bad name in {}'s" ); BEGIN(SECT2);
X<BRACEERROR>\n synerr( "missing }" ); ++linenum; BEGIN(SECT2);
X
X
X<PERCENT_BRACE_ACTION>{OPTWS}"%}".* bracelevel = 0;
X<PERCENT_BRACE_ACTION>.* ACTION_ECHO;
X<PERCENT_BRACE_ACTION>\n {
X ++linenum;
X ACTION_ECHO;
X if ( bracelevel == 0 )
X {
X fputs( "\tYY_BREAK\n", temp_action_file );
X BEGIN(SECT2);
X }
X }
X
X<ACTION>"{" ACTION_ECHO; ++bracelevel;
X<ACTION>"}" ACTION_ECHO; --bracelevel;
X<ACTION>[^{}"'/\n]+ ACTION_ECHO;
X<ACTION>"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT);
X<ACTION>"'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
X<ACTION>\" ACTION_ECHO; BEGIN(ACTION_STRING);
X<ACTION>\n {
X ++linenum;
X ACTION_ECHO;
X if ( bracelevel == 0 )
X {
X fputs( "\tYY_BREAK\n", temp_action_file );
X BEGIN(SECT2);
X }
X }
X<ACTION>. ACTION_ECHO;
X
X<ACTION_COMMENT>"*/" ACTION_ECHO; BEGIN(ACTION);
X<ACTION_COMMENT>[^*\n]+ ACTION_ECHO;
X<ACTION_COMMENT>"*" ACTION_ECHO;
X<ACTION_COMMENT>\n ++linenum; ACTION_ECHO;
X<ACTION_COMMENT>. ACTION_ECHO;
X
X<C_COMMENT_2>"*/" ACTION_ECHO; BEGIN(SECT2);
X<C_COMMENT_2>"*/".*\n ++linenum; ACTION_ECHO; BEGIN(SECT2);
X<C_COMMENT_2>[^*\n]+ ACTION_ECHO;
X<C_COMMENT_2>"*" ACTION_ECHO;
X<C_COMMENT_2>\n ++linenum; ACTION_ECHO;
X
X<ACTION_STRING>[^"\\\n]+ ACTION_ECHO;
X<ACTION_STRING>\\. ACTION_ECHO;
X<ACTION_STRING>\n ++linenum; ACTION_ECHO;
X<ACTION_STRING>\" ACTION_ECHO; BEGIN(ACTION);
X<ACTION_STRING>. ACTION_ECHO;
X
X
X<SECT2,QUOTE,CCL>{ESCSEQ} {
X yylval = myesc( yytext );
X return ( CHAR );
X }
X
X<FIRSTCCL>{ESCSEQ} {
X yylval = myesc( yytext );
X BEGIN(CCL);
X return ( CHAR );
X }
X
X
X<SECT3>.|\n {
X register int numchars;
X
X /* black magic - we know the names of a flex scanner's
X * internal variables. We cap the input buffer with
X * an end-of-string and dump it to the output.
X */
X YY_DO_BEFORE_SCAN; /* recover from setting up yytext */
X
X#ifdef FLEX_FAST_SKEL
X fputs( yy_c_buf_p + 1, stdout );
X#else
X yy_ch_buf[yy_e_buf_p + 1] = '\0';
X
X /* ignore the first character; it's the second '%'
X * put back by the yyless(1) above
X */
X fputs( yy_ch_buf + yy_c_buf_p + 1, stdout );
X#endif
X
X /* if we don't do this, the data written by write()
X * can get overwritten when stdout is finally flushed
X */
X (void) fflush( stdout );
X
X while ( (numchars = read( fileno(yyin), yy_ch_buf,
X YY_BUF_MAX )) > 0 )
X (void) write( fileno(stdout), yy_ch_buf, numchars );
X
X if ( numchars < 0 )
X flexerror( "fatal read error in section 3" );
X
X return ( EOF );
X }
X%%
END_OF_FILE
if test 9189 -ne `wc -c <'scan.l'`; then
echo shar: \"'scan.l'\" unpacked with wrong size!
fi
# end of 'scan.l'
fi
echo shar: End of archive 2 \(of 5\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
More information about the Comp.sources.unix
mailing list