Subject: v23i042: Flex, a fast lex replacement, Part06/10 Newsgroups: comp.sources.unix Approved: rsalz@uunet.UU.NET X-Checksum-Snefru: f7ee48d4 ec1d177f 9437dcc3 44a4eec2 Submitted-by: Vern Paxson Posting-number: Volume 23, Issue 42 Archive-name: flex2.3/part06 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: dfa.c flex.skel yylex.c # Wrapped by rsalz@litchi.bbn.com on Wed Oct 10 13:24:02 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 6 (of 10)."' if test -f 'dfa.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dfa.c'\" else echo shar: Extracting \"'dfa.c'\" \(26919 characters\) sed "s/^X//" >'dfa.c' <<'END_OF_FILE' X/* dfa - DFA construction routines */ X X/*- X * Copyright (c) 1990 The Regents of the University of California. X * All rights reserved. X * X * This code is derived from software contributed to Berkeley by X * Vern Paxson. X * X * The United States Government has rights in this work pursuant X * to contract no. DE-AC03-76SF00098 between the United States X * Department of Energy and the University of California. X * X * Redistribution and use in source and binary forms are permitted provided X * that: (1) source distributions retain this entire copyright notice and X * comment, and (2) distributions including binaries display the following X * acknowledgement: ``This product includes software developed by the X * University of California, Berkeley and its contributors'' in the X * documentation or other materials provided with the distribution and in X * all advertising materials mentioning features or use of this software. X * Neither the name of the University nor the names of its contributors may X * be used to endorse or promote products derived from this software without X * specific prior written permission. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. X */ X X#ifndef lint Xstatic char rcsid[] = X "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/dfa.c,v 2.7 90/06/27 23:48:15 vern Exp $ (LBL)"; X#endif X X#include "flexdef.h" X X X/* declare functions that have forward references */ X Xvoid dump_associated_rules PROTO((FILE*, int)); Xvoid dump_transitions PROTO((FILE*, int[])); Xvoid sympartition PROTO((int[], int, int[], int[])); Xint symfollowset PROTO((int[], int, int, int[])); X X X/* check_for_backtracking - check a DFA state for backtracking X * X * synopsis X * int ds, state[numecs]; X * check_for_backtracking( ds, state ); X * X * ds is the number of the state to check and state[] is its out-transitions, X * indexed by equivalence class, and state_rules[] is the set of rules X * associated with this state X */ X Xvoid check_for_backtracking( ds, state ) Xint ds; Xint state[]; X X { X if ( (reject && ! dfaacc[ds].dfaacc_set) || ! dfaacc[ds].dfaacc_state ) X { /* state is non-accepting */ X ++num_backtracking; X X if ( backtrack_report ) X { X fprintf( backtrack_file, "State #%d is non-accepting -\n", ds ); X X /* identify the state */ X dump_associated_rules( backtrack_file, ds ); X X /* now identify it further using the out- and jam-transitions */ X dump_transitions( backtrack_file, state ); X X putc( '\n', backtrack_file ); X } X } X } X X X/* check_trailing_context - check to see if NFA state set constitutes X * "dangerous" trailing context X * X * synopsis X * int nfa_states[num_states+1], num_states; X * int accset[nacc+1], nacc; X * check_trailing_context( nfa_states, num_states, accset, nacc ); X * X * NOTES X * Trailing context is "dangerous" if both the head and the trailing X * part are of variable size \and/ there's a DFA state which contains X * both an accepting state for the head part of the rule and NFA states X * which occur after the beginning of the trailing context. X * When such a rule is matched, it's impossible to tell if having been X * in the DFA state indicates the beginning of the trailing context X * or further-along scanning of the pattern. In these cases, a warning X * message is issued. X * X * nfa_states[1 .. num_states] is the list of NFA states in the DFA. X * accset[1 .. nacc] is the list of accepting numbers for the DFA state. X */ X Xvoid check_trailing_context( nfa_states, num_states, accset, nacc ) Xint *nfa_states, num_states; Xint *accset; Xregister int nacc; X X { X register int i, j; X X for ( i = 1; i <= num_states; ++i ) X { X int ns = nfa_states[i]; X register int type = state_type[ns]; X register int ar = assoc_rule[ns]; X X if ( type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE ) X { /* do nothing */ X } X X else if ( type == STATE_TRAILING_CONTEXT ) X { X /* potential trouble. Scan set of accepting numbers for X * the one marking the end of the "head". We assume that X * this looping will be fairly cheap since it's rare that X * an accepting number set is large. X */ X for ( j = 1; j <= nacc; ++j ) X if ( accset[j] & YY_TRAILING_HEAD_MASK ) X { X fprintf( stderr, X "%s: Dangerous trailing context in rule at line %d\n", X program_name, rule_linenum[ar] ); X return; X } X } X } X } X X X/* dump_associated_rules - list the rules associated with a DFA state X * X * synopisis X * int ds; X * FILE *file; X * dump_associated_rules( file, ds ); X * X * goes through the set of NFA states associated with the DFA and X * extracts the first MAX_ASSOC_RULES unique rules, sorts them, X * and writes a report to the given file X */ X Xvoid dump_associated_rules( file, ds ) XFILE *file; Xint ds; X X { X register int i, j; X register int num_associated_rules = 0; X int rule_set[MAX_ASSOC_RULES + 1]; X int *dset = dss[ds]; X int size = dfasiz[ds]; X X for ( i = 1; i <= size; ++i ) X { X register rule_num = rule_linenum[assoc_rule[dset[i]]]; X X for ( j = 1; j <= num_associated_rules; ++j ) X if ( rule_num == rule_set[j] ) X break; X X if ( j > num_associated_rules ) X { /* new rule */ X if ( num_associated_rules < MAX_ASSOC_RULES ) X rule_set[++num_associated_rules] = rule_num; X } X } X X bubble( rule_set, num_associated_rules ); X X fprintf( file, " associated rule line numbers:" ); X X for ( i = 1; i <= num_associated_rules; ++i ) X { X if ( i % 8 == 1 ) X putc( '\n', file ); X X fprintf( file, "\t%d", rule_set[i] ); X } X X putc( '\n', file ); X } X X X/* dump_transitions - list the transitions associated with a DFA state X * X * synopisis X * int state[numecs]; X * FILE *file; X * dump_transitions( file, state ); X * X * goes through the set of out-transitions and lists them in human-readable X * form (i.e., not as equivalence classes); also lists jam transitions X * (i.e., all those which are not out-transitions, plus EOF). The dump X * is done to the given file. X */ X Xvoid dump_transitions( file, state ) XFILE *file; Xint state[]; X X { X register int i, ec; X int out_char_set[CSIZE]; X X for ( i = 0; i < csize; ++i ) X { X ec = abs( ecgroup[i] ); X out_char_set[i] = state[ec]; X } X X fprintf( file, " out-transitions: " ); X X list_character_set( file, out_char_set ); X X /* now invert the members of the set to get the jam transitions */ X for ( i = 0; i < csize; ++i ) X out_char_set[i] = ! out_char_set[i]; X X fprintf( file, "\n jam-transitions: EOF " ); X X list_character_set( file, out_char_set ); X X putc( '\n', file ); X } X 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[num_rules + 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 Xint *epsclosure( t, ns_addr, accset, nacc_addr, hv_addr ) Xint *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/* increase_max_dfas - increase the maximum number of DFAs */ X Xvoid increase_max_dfas() X 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 dss = reallocate_int_ptr_array( dss, current_max_dfas ); X dfaacc = reallocate_dfaacc_union( dfaacc, current_max_dfas ); X X if ( nultrans ) X nultrans = reallocate_integer_array( nultrans, current_max_dfas ); X } X X X/* ntod - convert an ndfa to a dfa X * X * synopsis X * ntod(); X * X * creates the dfa corresponding to the ndfa we've constructed. the X * dfa starts out in state #1. X */ X Xvoid ntod() X X { X int *accset, ds, nacc, newds; X int sym, hashval, numstates, dsize; X int num_full_table_rows; /* used only for -f */ X int *nset, *dset; X int targptr, totaltrans, i, comstate, comfreq, targ; X int *epsclosure(), snstods(), symlist[CSIZE + 1]; X int num_start_states; X int todo_head, todo_next; X X /* note that the following are indexed by *equivalence classes* X * and not by characters. Since equivalence classes are indexed X * beginning with 1, even if the scanner accepts NUL's, this X * means that (since every character is potentially in its own X * equivalence class) these arrays must have room for indices X * from 1 to CSIZE, so their size must be CSIZE + 1. X */ X int duplist[CSIZE + 1], state[CSIZE + 1]; X int targfreq[CSIZE + 1], targstate[CSIZE + 1]; X X /* this is so find_table_space(...) will know where to start looking in X * chk/nxt for unused records for space to put in the state X */ X if ( fullspd ) X firstfree = 0; X X accset = allocate_integer_array( num_rules + 1 ); X nset = allocate_integer_array( current_max_dfa_size ); X X /* the "todo" queue is represented by the head, which is the DFA X * state currently being processed, and the "next", which is the X * next DFA state number available (not in use). We depend on the X * fact that snstods() returns DFA's \in increasing order/, and thus X * need only know the bounds of the dfas to be processed. X */ X todo_head = todo_next = 0; X X for ( i = 0; i <= csize; ++i ) X { X duplist[i] = NIL; X symlist[i] = false; X } X X for ( i = 0; i <= num_rules; ++i ) X accset[i] = NIL; X X if ( trace ) X { X dumpnfa( scset[1] ); X fputs( "\n\nDFA Dump:\n\n", stderr ); X } X X inittbl(); X X /* check to see whether we should build a separate table for transitions X * on NUL characters. We don't do this for full-speed (-F) scanners, X * since for them we don't have a simple state number lying around with X * which to index the table. We also don't bother doing it for scanners X * unless (1) NUL is in its own equivalence class (indicated by a X * positive value of ecgroup[NUL]), (2) NUL's equilvalence class is X * the last equivalence class, and (3) the number of equivalence classes X * is the same as the number of characters. This latter case comes about X * when useecs is false or when its true but every character still X * manages to land in its own class (unlikely, but it's cheap to check X * for). If all these things are true then the character code needed X * to represent NUL's equivalence class for indexing the tables is X * going to take one more bit than the number of characters, and therefore X * we won't be assured of being able to fit it into a YY_CHAR variable. X * This rules out storing the transitions in a compressed table, since X * the code for interpreting them uses a YY_CHAR variable (perhaps it X * should just use an integer, though; this is worth pondering ... ###). X * X * Finally, for full tables, we want the number of entries in the X * table to be a power of two so the array references go fast (it X * will just take a shift to compute the major index). If encoding X * NUL's transitions in the table will spoil this, we give it its X * own table (note that this will be the case if we're not using X * equivalence classes). X */ X X /* note that the test for ecgroup[0] == numecs below accomplishes X * both (1) and (2) above X */ X if ( ! fullspd && ecgroup[0] == numecs ) X { /* NUL is alone in its equivalence class, which is the last one */ X int use_NUL_table = (numecs == csize); X X if ( fulltbl && ! use_NUL_table ) X { /* we still may want to use the table if numecs is a power of 2 */ X int power_of_two; X X for ( power_of_two = 1; power_of_two <= csize; power_of_two *= 2 ) X if ( numecs == power_of_two ) X { X use_NUL_table = true; X break; X } X } X X if ( use_NUL_table ) X nultrans = allocate_integer_array( current_max_dfas ); X /* from now on, nultrans != nil indicates that we're X * saving null transitions for later, separate encoding X */ X } X X X if ( fullspd ) X { X for ( i = 0; i <= numecs; ++i ) X state[i] = 0; X place_state( state, 0, 0 ); X } X X else if ( fulltbl ) X { X if ( nultrans ) X /* we won't be including NUL's transitions in the table, X * so build it for entries from 0 .. numecs - 1 X */ X num_full_table_rows = numecs; X X else X /* take into account the fact that we'll be including X * the NUL entries in the transition table. Build it X * from 0 .. numecs. X */ X num_full_table_rows = numecs + 1; X X /* declare it "short" because it's a real long-shot that that X * won't be large enough. X */ X printf( "static short int yy_nxt[][%d] =\n {\n", X /* '}' so vi doesn't get too confused */ X num_full_table_rows ); X X /* generate 0 entries for state #0 */ X for ( i = 0; i < num_full_table_rows; ++i ) X mk2data( 0 ); X X /* force ',' and dataflush() next call to mk2data */ X datapos = NUMDATAITEMS; X X /* force extra blank line next dataflush() */ X dataline = NUMDATALINES; X } X X /* create the first states */ X X num_start_states = lastsc * 2; X X for ( i = 1; i <= num_start_states; ++i ) X { X numstates = 1; X X /* for each start condition, make one state for the case when X * we're at the beginning of the line (the '%' operator) and X * one for the case when we're not X */ X if ( i % 2 == 1 ) X nset[numstates] = scset[(i / 2) + 1]; X else X nset[numstates] = mkbranch( scbol[i / 2], scset[i / 2] ); X X nset = epsclosure( nset, &numstates, accset, &nacc, &hashval ); X X if ( snstods( nset, numstates, accset, nacc, hashval, &ds ) ) X { X numas += nacc; X totnst += numstates; X ++todo_next; X X if ( variable_trailing_context_rules && nacc > 0 ) X check_trailing_context( nset, numstates, accset, nacc ); X } X } X X if ( ! fullspd ) X { X if ( ! snstods( nset, 0, accset, 0, 0, &end_of_buffer_state ) ) X flexfatal( "could not create unique end-of-buffer state" ); X X ++numas; X ++num_start_states; X ++todo_next; X } X X while ( todo_head < todo_next ) X { X targptr = 0; X totaltrans = 0; X X for ( i = 1; i <= numecs; ++i ) X state[i] = 0; X X ds = ++todo_head; X X dset = dss[ds]; X dsize = dfasiz[ds]; X X if ( trace ) X fprintf( stderr, "state # %d:\n", ds ); X X sympartition( dset, dsize, symlist, duplist ); X X for ( sym = 1; sym <= numecs; ++sym ) X { X if ( symlist[sym] ) X { X symlist[sym] = 0; X X if ( duplist[sym] == NIL ) X { /* symbol has unique out-transitions */ X numstates = symfollowset( dset, dsize, sym, nset ); X nset = epsclosure( nset, &numstates, accset, X &nacc, &hashval ); X X if ( snstods( nset, numstates, accset, X nacc, hashval, &newds ) ) X { X totnst = totnst + numstates; X ++todo_next; X numas += nacc; X X if ( variable_trailing_context_rules && nacc > 0 ) X check_trailing_context( nset, numstates, X accset, nacc ); X } X X state[sym] = newds; X X if ( trace ) X fprintf( stderr, "\t%d\t%d\n", sym, newds ); X X targfreq[++targptr] = 1; X targstate[targptr] = newds; X ++numuniq; X } X X else X { X /* sym's equivalence class has the same transitions X * as duplist(sym)'s equivalence class X */ X targ = state[duplist[sym]]; X state[sym] = targ; X X if ( trace ) X fprintf( stderr, "\t%d\t%d\n", sym, targ ); X X /* update frequency count for destination state */ X X i = 0; X while ( targstate[++i] != targ ) X ; X X ++targfreq[i]; X ++numdup; X } X X ++totaltrans; X duplist[sym] = NIL; X } X } X X numsnpairs = numsnpairs + totaltrans; X X if ( caseins && ! useecs ) X { X register int j; X X for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j ) X state[i] = state[j]; X } X X if ( ds > num_start_states ) X check_for_backtracking( ds, state ); X X if ( nultrans ) X { X nultrans[ds] = state[NUL_ec]; X state[NUL_ec] = 0; /* remove transition */ X } X X if ( fulltbl ) X { X /* supply array's 0-element */ X if ( ds == end_of_buffer_state ) X mk2data( -end_of_buffer_state ); X else X mk2data( end_of_buffer_state ); X X for ( i = 1; i < num_full_table_rows; ++i ) X /* jams are marked by negative of state number */ X mk2data( state[i] ? state[i] : -ds ); X X /* force ',' and dataflush() next call to mk2data */ X datapos = NUMDATAITEMS; X X /* force extra blank line next dataflush() */ X dataline = NUMDATALINES; X } X X else if ( fullspd ) X place_state( state, ds, totaltrans ); X X else if ( ds == end_of_buffer_state ) X /* special case this state to make sure it does what it's X * supposed to, i.e., jam on end-of-buffer X */ X stack1( ds, 0, 0, JAMSTATE ); X X else /* normal, compressed state */ X { X /* determine which destination state is the most common, and X * how many transitions to it there are X */ X X comfreq = 0; X comstate = 0; X X for ( i = 1; i <= targptr; ++i ) X if ( targfreq[i] > comfreq ) X { X comfreq = targfreq[i]; X comstate = targstate[i]; X } X X bldtbl( state, ds, totaltrans, comstate, comfreq ); X } X } X X if ( fulltbl ) X dataend(); X X else if ( ! fullspd ) X { X cmptmps(); /* create compressed template entries */ X X /* create tables for all the states with only one out-transition */ X while ( onesp > 0 ) X { X mk1tbl( onestate[onesp], onesym[onesp], onenext[onesp], X onedef[onesp] ); X --onesp; X } X X mkdeftbl(); 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[num_rules + 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 Xint snstods( sns, numstates, accset, nacc, hashval, newds_addr ) Xint sns[], numstates, accset[], nacc, hashval, *newds_addr; X X { X int didsort = 0; X register int i, j; X int newds, *oldsns; 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 dss[newds] = (int *) malloc( (unsigned) ((numstates + 1) * sizeof( int )) ); X X if ( ! dss[newds] ) 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 if ( reject ) X dfaacc[newds].dfaacc_set = (int *) 0; X else X dfaacc[newds].dfaacc_state = 0; X 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_set = X (int *) malloc( (unsigned) ((nacc + 1) * sizeof( int )) ); X X if ( ! dfaacc[newds].dfaacc_set ) 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 = num_rules + 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 Xint symfollowset( ds, dsize, transsym, nset ) Xint 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 == 0 ) X ch = NUL_ec; 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 == 0 ) X ch = NUL_ec; 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 ( abs( ecgroup[sym] ) == transsym ) X nset[++numstates] = tsp; X Xbottom: 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 Xvoid sympartition( ds, numstates, symlist, duplist ) Xint ds[], numstates, duplist[]; Xint 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 { X if ( tch > csize && tch <= CSIZE ) X flexerror( "scanner requires -8 flag" ); X X else X flexfatal( X "bad transition character detected in sympartition()" ); X } X X if ( tch >= 0 ) X { /* character transition */ X /* abs() needed for fake %t ec's */ X int ec = abs( ecgroup[tch] ); X X mkechar( ec, dupfwd, duplist ); X symlist[ec] = 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 NUL_ec ); 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 if ( ich == 0 ) X ich = NUL_ec; 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 X if ( ich == 0 ) X ich = NUL_ec; X X symlist[ich] = 1; X } X } X } X } X } END_OF_FILE if test 26919 -ne `wc -c <'dfa.c'`; then echo shar: \"'dfa.c'\" unpacked with wrong size! fi # end of 'dfa.c' fi if test -f 'flex.skel' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'flex.skel'\" else echo shar: Extracting \"'flex.skel'\" \(19796 characters\) sed "s/^X//" >'flex.skel' <<'END_OF_FILE' X/* A lexical scanner generated by flex */ X X/* scanner skeleton version: X * $Header: /usr/fsys/odin/a/vern/flex/RCS/flex.skel,v 2.16 90/08/03 14:09:36 vern Exp $ X */ X X#define FLEX_SCANNER X X#include X X X/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ X#ifdef c_plusplus X#ifndef __cplusplus X#define __cplusplus X#endif X#endif X X X#ifdef __cplusplus X X#include X#include X X/* use prototypes in function declarations */ X#define YY_USE_PROTOS X X/* the "const" storage-class-modifier is valid */ X#define YY_USE_CONST X X#else /* ! __cplusplus */ X X#ifdef __STDC__ X X#ifdef __GNUC__ X#include Xvoid *malloc( size_t ); Xvoid free( void* ); X#else X#include X#endif /* __GNUC__ */ X X#define YY_USE_PROTOS X#define YY_USE_CONST X X#endif /* __STDC__ */ X#endif /* ! __cplusplus */ X X X#ifdef __TURBOC__ X#define YY_USE_CONST X#endif X X X#ifndef YY_USE_CONST X#define const X#endif X X X#ifdef YY_USE_PROTOS X#define YY_PROTO(proto) proto X#else X#define YY_PROTO(proto) () X/* we can't get here if it's an ANSI C compiler, or a C++ compiler, X * so it's got to be a K&R compiler, and therefore there's no standard X * place from which to include these definitions X */ Xchar *malloc(); Xint free(); Xint read(); X#endif X X X/* amount of stuff to slurp up with each read */ X#ifndef YY_READ_BUF_SIZE X#define YY_READ_BUF_SIZE 8192 X#endif X X/* returned upon end-of-file */ X#define YY_END_TOK 0 X X/* copy whatever the last rule matched to the standard output */ X X/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */ X/* this used to be an fputs(), but since the string might contain NUL's, X * we now use fwrite() X */ X#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout ) X X/* gets input and stuffs it into "buf". number of characters read, or YY_NULL, X * is returned in "result". X */ X#define YY_INPUT(buf,result,max_size) \ X if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ X YY_FATAL_ERROR( "read() in flex scanner failed" ); X#define YY_NULL 0 X X/* no semi-colon after return; correct usage is to write "yyterminate();" - X * we don't want an extra ';' after the "return" because that will cause X * some compilers to complain about unreachable statements. X */ X#define yyterminate() return ( YY_NULL ) X X/* report a fatal error */ X X/* The funky do-while is used to turn this macro definition into X * a single C statement (which needs a semi-colon terminator). X * This avoids problems with code like: X * X * if ( something_happens ) X * YY_FATAL_ERROR( "oops, the something happened" ); X * else X * everything_okay(); X * X * Prior to using the do-while the compiler would get upset at the X * "else" because it interpreted the "if" statement as being all X * done when it reached the ';' after the YY_FATAL_ERROR() call. X */ X X#define YY_FATAL_ERROR(msg) \ X do \ X { \ X (void) fputs( msg, stderr ); \ X (void) putc( '\n', stderr ); \ X exit( 1 ); \ X } \ X while ( 0 ) X X/* default yywrap function - always treat EOF as an EOF */ X#define yywrap() 1 X X/* enter a start condition. This macro really ought to take a parameter, X * but we do it the disgusting crufty way forced on us by the ()-less X * definition of BEGIN X */ X#define BEGIN yy_start = 1 + 2 * X X/* action number for EOF rule of a given start state */ X#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) X X/* special action meaning "start processing a new file" */ X#define YY_NEW_FILE \ X do \ X { \ X yy_init_buffer( yy_current_buffer, yyin ); \ X yy_load_buffer_state(); \ X } \ X while ( 0 ) X X/* default declaration of generated scanner - a define so the user can X * easily add parameters X */ X#define YY_DECL int yylex YY_PROTO(( void )) X X/* code executed at the end of each rule */ X#define YY_BREAK break; X X#define YY_END_OF_BUFFER_CHAR 0 X X#ifndef YY_BUF_SIZE X#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */ X#endif X Xtypedef struct yy_buffer_state *YY_BUFFER_STATE; X X%% section 1 definitions go here X X/* done after the current pattern has been matched and before the X * corresponding action - sets up yytext X */ X#define YY_DO_BEFORE_ACTION \ X yytext = yy_bp; \ X%% code to fiddle yytext and yyleng for yymore() goes here X yy_hold_char = *yy_cp; \ X *yy_cp = '\0'; \ X yy_c_buf_p = yy_cp; X X#define EOB_ACT_CONTINUE_SCAN 0 X#define EOB_ACT_END_OF_FILE 1 X#define EOB_ACT_LAST_MATCH 2 X X/* return all but the first 'n' matched characters back to the input stream */ X#define yyless(n) \ X do \ X { \ X /* undo effects of setting up yytext */ \ X *yy_cp = yy_hold_char; \ X yy_c_buf_p = yy_cp = yy_bp + n; \ X YY_DO_BEFORE_ACTION; /* set up yytext again */ \ X } \ X while ( 0 ) X X#define unput(c) yyunput( c, yytext ) X X Xstruct yy_buffer_state X { X FILE *yy_input_file; X X YY_CHAR *yy_ch_buf; /* input buffer */ X YY_CHAR *yy_buf_pos; /* current position in input buffer */ X X /* size of input buffer in bytes, not including room for EOB characters*/ X int yy_buf_size; X X /* number of characters read into yy_ch_buf, not including EOB characters */ X int yy_n_chars; X X int yy_eof_status; /* whether we've seen an EOF on this buffer */ X#define EOF_NOT_SEEN 0 X /* "pending" happens when the EOF has been seen but there's still X * some text process X */ X#define EOF_PENDING 1 X#define EOF_DONE 2 X }; X Xstatic YY_BUFFER_STATE yy_current_buffer; X X/* we provide macros for accessing buffer states in case in the X * future we want to put the buffer states in a more general X * "scanner state" X */ X#define YY_CURRENT_BUFFER yy_current_buffer X X X/* yy_hold_char holds the character lost when yytext is formed */ Xstatic YY_CHAR yy_hold_char; X Xstatic int yy_n_chars; /* number of characters read into yy_ch_buf */ X X X X#ifndef YY_USER_ACTION X#define YY_USER_ACTION X#endif X X#ifndef YY_USER_INIT X#define YY_USER_INIT X#endif X Xextern YY_CHAR *yytext; Xextern int yyleng; Xextern FILE *yyin, *yyout; X XYY_CHAR *yytext; Xint yyleng; X XFILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; X X%% data tables for the DFA go here X X/* these variables are all declared out here so that section 3 code can X * manipulate them X */ X/* points to current character in buffer */ Xstatic YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0; Xstatic int yy_init = 1; /* whether we need to initialize */ Xstatic int yy_start = 0; /* start state number */ X X/* flag which is used to allow yywrap()'s to do buffer switches X * instead of setting up a fresh yyin. A bit of a hack ... X */ Xstatic int yy_did_buffer_switch_on_eof; X Xstatic yy_state_type yy_get_previous_state YY_PROTO(( void )); Xstatic yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); Xstatic int yy_get_next_buffer YY_PROTO(( void )); Xstatic void yyunput YY_PROTO(( YY_CHAR c, YY_CHAR *buf_ptr )); Xvoid yyrestart YY_PROTO(( FILE *input_file )); Xvoid yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); Xvoid yy_load_buffer_state YY_PROTO(( void )); XYY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); Xvoid yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); Xvoid yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); X X#define yy_new_buffer yy_create_buffer X X#ifdef __cplusplus Xstatic int yyinput YY_PROTO(( void )); X#else Xstatic int input YY_PROTO(( void )); X#endif X XYY_DECL X { X register yy_state_type yy_current_state; X register YY_CHAR *yy_cp, *yy_bp; X register int yy_act; X X%% user's declarations go here X X if ( yy_init ) X { X YY_USER_INIT; X X if ( ! yy_start ) X yy_start = 1; /* first start state */ X X if ( ! yyin ) X yyin = stdin; X X if ( ! yyout ) X yyout = stdout; X X if ( yy_current_buffer ) X yy_init_buffer( yy_current_buffer, yyin ); X else X yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); X X yy_load_buffer_state(); X X yy_init = 0; X } X X while ( 1 ) /* loops until end-of-file is reached */ X { X%% yymore()-related code goes here X yy_cp = yy_c_buf_p; X X /* support of yytext */ X *yy_cp = yy_hold_char; X X /* yy_bp points to the position in yy_ch_buf of the start of the X * current run. X */ X yy_bp = yy_cp; X X%% code to set up and find next match goes here X Xyy_find_action: X%% code to find the action number goes here X X YY_DO_BEFORE_ACTION; X YY_USER_ACTION; X Xdo_action: /* this label is used only to access EOF actions */ X X%% debug code goes here X X switch ( yy_act ) X { X%% actions go here X X case YY_END_OF_BUFFER: X { X /* amount of text matched not including the EOB char */ X int yy_amount_of_matched_text = yy_cp - yytext - 1; X X /* undo the effects of YY_DO_BEFORE_ACTION */ X *yy_cp = yy_hold_char; X X /* note that here we test for yy_c_buf_p "<=" to the position X * of the first EOB in the buffer, since yy_c_buf_p will X * already have been incremented past the NUL character X * (since all states make transitions on EOB to the end- X * of-buffer state). Contrast this with the test in yyinput(). X */ X if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) X /* this was really a NUL */ X { X yy_state_type yy_next_state; X X yy_c_buf_p = yytext + yy_amount_of_matched_text; X X yy_current_state = yy_get_previous_state(); X X /* okay, we're now positioned to make the X * NUL transition. We couldn't have X * yy_get_previous_state() go ahead and do it X * for us because it doesn't know how to deal X * with the possibility of jamming (and we X * don't want to build jamming into it because X * then it will run more slowly) X */ X X yy_next_state = yy_try_NUL_trans( yy_current_state ); X X yy_bp = yytext + YY_MORE_ADJ; X X if ( yy_next_state ) X { X /* consume the NUL */ X yy_cp = ++yy_c_buf_p; X yy_current_state = yy_next_state; X goto yy_match; X } X X else X { X%% code to do backtracking for compressed tables and set up yy_cp goes here X goto yy_find_action; X } X } X X else switch ( yy_get_next_buffer() ) X { X case EOB_ACT_END_OF_FILE: X { X yy_did_buffer_switch_on_eof = 0; X X if ( yywrap() ) X { X /* note: because we've taken care in X * yy_get_next_buffer() to have set up yytext, 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 = yytext + YY_MORE_ADJ; X X yy_act = YY_STATE_EOF((yy_start - 1) / 2); X goto do_action; X } X X else X { X if ( ! yy_did_buffer_switch_on_eof ) X YY_NEW_FILE; X } X } X break; X X case EOB_ACT_CONTINUE_SCAN: X yy_c_buf_p = yytext + yy_amount_of_matched_text; X X yy_current_state = yy_get_previous_state(); X X yy_cp = yy_c_buf_p; X yy_bp = yytext + YY_MORE_ADJ; X goto yy_match; X X case EOB_ACT_LAST_MATCH: X yy_c_buf_p = X &yy_current_buffer->yy_ch_buf[yy_n_chars]; X X yy_current_state = yy_get_previous_state(); X X yy_cp = yy_c_buf_p; X yy_bp = yytext + YY_MORE_ADJ; X goto yy_find_action; X } X break; X } X X default: X#ifdef FLEX_DEBUG X printf( "action # %d\n", yy_act ); X#endif X YY_FATAL_ERROR( X "fatal flex scanner internal error--no action found" ); X } X } X } X X X/* yy_get_next_buffer - try to read in a 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_CONTINUE_SCAN - continue scanning from current position X * EOB_ACT_END_OF_FILE - end of file X */ X Xstatic int yy_get_next_buffer() X X { X register YY_CHAR *dest = yy_current_buffer->yy_ch_buf; X register YY_CHAR *source = yytext - 1; /* copy prev. char, too */ X register int number_to_move, i; X int ret_val; X X if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) X YY_FATAL_ERROR( X "fatal flex scanner internal error--end of buffer missed" ); X X /* try to read more data */ X X /* first move last chars to start of buffer */ X number_to_move = yy_c_buf_p - yytext; X X for ( i = 0; i < number_to_move; ++i ) X *(dest++) = *(source++); X X if ( yy_current_buffer->yy_eof_status != EOF_NOT_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 { X int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; X X if ( num_to_read > YY_READ_BUF_SIZE ) X num_to_read = YY_READ_BUF_SIZE; X X else if ( num_to_read <= 0 ) X YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); X X /* read in more data */ X YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), X yy_n_chars, num_to_read ); X } X X if ( yy_n_chars == 0 ) X { X if ( number_to_move == 1 ) X { X ret_val = EOB_ACT_END_OF_FILE; X yy_current_buffer->yy_eof_status = EOF_DONE; X } X X else X { X ret_val = EOB_ACT_LAST_MATCH; X yy_current_buffer->yy_eof_status = EOF_PENDING; X } X } X X else X ret_val = EOB_ACT_CONTINUE_SCAN; X X yy_n_chars += number_to_move; X yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; X yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; X X /* yytext begins at the second character in yy_ch_buf; the first X * character is the one which preceded it before reading in the latest X * buffer; it needs to be kept around in case it's a newline, so X * yy_get_previous_state() will have with '^' rules active X */ X X yytext = &yy_current_buffer->yy_ch_buf[1]; X X return ( ret_val ); X } X X X/* yy_get_previous_state - get the state just before the EOB char was reached X * X * synopsis X * yy_state_type yy_get_previous_state(); X */ X Xstatic yy_state_type yy_get_previous_state() X X { X register yy_state_type yy_current_state; X register YY_CHAR *yy_cp; X X%% code to get the start state into yy_current_state goes here X X for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) X { X%% code to find the next state goes here X } X X return ( yy_current_state ); X } X X X/* yy_try_NUL_trans - try to make a transition on the NUL character X * X * synopsis X * next_state = yy_try_NUL_trans( current_state ); X */ X X#ifdef YY_USE_PROTOS Xstatic yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state ) X#else Xstatic yy_state_type yy_try_NUL_trans( yy_current_state ) Xregister yy_state_type yy_current_state; X#endif X X { X register int yy_is_jam; X%% code to find the next state, and perhaps do backtracking, goes here X X return ( yy_is_jam ? 0 : yy_current_state ); X } X X X#ifdef YY_USE_PROTOS Xstatic void yyunput( YY_CHAR c, register YY_CHAR *yy_bp ) X#else Xstatic void yyunput( c, yy_bp ) XYY_CHAR c; Xregister YY_CHAR *yy_bp; X#endif X X { X register YY_CHAR *yy_cp = yy_c_buf_p; X X /* undo effects of setting up yytext */ X *yy_cp = yy_hold_char; X X if ( yy_cp < yy_current_buffer->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 YY_CHAR *dest = X &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2]; X register YY_CHAR *source = X &yy_current_buffer->yy_ch_buf[number_to_move]; X X while ( source > yy_current_buffer->yy_ch_buf ) X *--dest = *--source; X X yy_cp += dest - source; X yy_bp += dest - source; X yy_n_chars = yy_current_buffer->yy_buf_size; X X if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) X YY_FATAL_ERROR( "flex scanner push-back overflow" ); X } X X if ( yy_cp > yy_bp && yy_cp[-1] == '\n' ) X yy_cp[-2] = '\n'; X X *--yy_cp = c; X X /* note: the formal parameter *must* be called "yy_bp" for this X * macro to now work correctly X */ X YY_DO_BEFORE_ACTION; /* set up yytext again */ X } X X X#ifdef __cplusplus Xstatic int yyinput() X#else Xstatic int input() X#endif X X { X int c; X YY_CHAR *yy_cp = yy_c_buf_p; X X *yy_cp = yy_hold_char; X X if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) X { X /* yy_c_buf_p now points to the character we want to return. X * If this occurs *before* the EOB characters, then it's a X * valid NUL; if not, then we've hit the end of the buffer. X */ X if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) X /* this was really a NUL */ X *yy_c_buf_p = '\0'; X X else X { /* need more input */ X yytext = yy_c_buf_p; X ++yy_c_buf_p; X X switch ( yy_get_next_buffer() ) X { X case EOB_ACT_END_OF_FILE: X { X if ( yywrap() ) X { X yy_c_buf_p = yytext + YY_MORE_ADJ; X return ( EOF ); X } X X YY_NEW_FILE; X X#ifdef __cplusplus X return ( yyinput() ); X#else X return ( input() ); X#endif X } X break; X X case EOB_ACT_CONTINUE_SCAN: X yy_c_buf_p = yytext + YY_MORE_ADJ; X break; X X case EOB_ACT_LAST_MATCH: X#ifdef __cplusplus X YY_FATAL_ERROR( "unexpected last match in yyinput()" ); X#else X YY_FATAL_ERROR( "unexpected last match in input()" ); X#endif X } X } X } X X c = *yy_c_buf_p; X yy_hold_char = *++yy_c_buf_p; X X return ( c ); X } X X X#ifdef YY_USE_PROTOS Xvoid yyrestart( FILE *input_file ) X#else Xvoid yyrestart( input_file ) XFILE *input_file; X#endif X X { X yy_init_buffer( yy_current_buffer, input_file ); X yy_load_buffer_state(); X } X X X#ifdef YY_USE_PROTOS Xvoid yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) X#else Xvoid yy_switch_to_buffer( new_buffer ) XYY_BUFFER_STATE new_buffer; X#endif X X { X if ( yy_current_buffer == new_buffer ) X return; X X if ( yy_current_buffer ) X { X /* flush out information for old buffer */ X *yy_c_buf_p = yy_hold_char; X yy_current_buffer->yy_buf_pos = yy_c_buf_p; X yy_current_buffer->yy_n_chars = yy_n_chars; X } X X yy_current_buffer = new_buffer; X yy_load_buffer_state(); X X /* we don't actually know whether we did this switch during X * EOF (yywrap()) processing, but the only time this flag X * is looked at is after yywrap() is called, so it's safe X * to go ahead and always set it. X */ X yy_did_buffer_switch_on_eof = 1; X } X X X#ifdef YY_USE_PROTOS Xvoid yy_load_buffer_state( void ) X#else Xvoid yy_load_buffer_state() X#endif X X { X yy_n_chars = yy_current_buffer->yy_n_chars; X yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos; X yyin = yy_current_buffer->yy_input_file; X yy_hold_char = *yy_c_buf_p; X } X X X#ifdef YY_USE_PROTOS XYY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) X#else XYY_BUFFER_STATE yy_create_buffer( file, size ) XFILE *file; Xint size; X#endif X X { X YY_BUFFER_STATE b; X X b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) ); X X if ( ! b ) X YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); X X b->yy_buf_size = size; X X /* yy_ch_buf has to be 2 characters longer than the size given because X * we need to put in 2 end-of-buffer characters. X */ X b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) ); X X if ( ! b->yy_ch_buf ) X YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); X X yy_init_buffer( b, file ); X X return ( b ); X } X X X#ifdef YY_USE_PROTOS Xvoid yy_delete_buffer( YY_BUFFER_STATE b ) X#else Xvoid yy_delete_buffer( b ) XYY_BUFFER_STATE b; X#endif X X { X if ( b == yy_current_buffer ) X yy_current_buffer = (YY_BUFFER_STATE) 0; X X free( (char *) b->yy_ch_buf ); X free( (char *) b ); X } X X X#ifdef YY_USE_PROTOS Xvoid yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) X#else Xvoid yy_init_buffer( b, file ) XYY_BUFFER_STATE b; XFILE *file; X#endif X X { X b->yy_input_file = file; 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 b->yy_ch_buf[0] = '\n'; X b->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 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; X b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR; X X b->yy_buf_pos = &b->yy_ch_buf[1]; X X b->yy_eof_status = EOF_NOT_SEEN; X } END_OF_FILE if test 19796 -ne `wc -c <'flex.skel'`; then echo shar: \"'flex.skel'\" unpacked with wrong size! fi # end of 'flex.skel' fi if test -f 'yylex.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'yylex.c'\" else echo shar: Extracting \"'yylex.c'\" \(4244 characters\) sed "s/^X//" >'yylex.c' <<'END_OF_FILE' X/* yylex - scanner front-end for flex */ X X/*- X * Copyright (c) 1990 The Regents of the University of California. X * All rights reserved. X * X * This code is derived from software contributed to Berkeley by X * Vern Paxson. X * X * The United States Government has rights in this work pursuant X * to contract no. DE-AC03-76SF00098 between the United States X * Department of Energy and the University of California. X * X * Redistribution and use in source and binary forms are permitted provided X * that: (1) source distributions retain this entire copyright notice and X * comment, and (2) distributions including binaries display the following X * acknowledgement: ``This product includes software developed by the X * University of California, Berkeley and its contributors'' in the X * documentation or other materials provided with the distribution and in X * all advertising materials mentioning features or use of this software. X * Neither the name of the University nor the names of its contributors may X * be used to endorse or promote products derived from this software without X * specific prior written permission. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. X */ X X#ifndef lint Xstatic char rcsid[] = X "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/yylex.c,v 2.5 90/06/27 23:48:40 vern Exp $ (LBL)"; X#endif X X#include X#include "flexdef.h" X#include "parse.h" X X X/* ANSI C does not guarantee that isascii() is defined */ X#ifndef isascii X#define isascii(c) ((c) <= 0177) X#endif X X X/* yylex - scan for a regular expression token X * X * synopsis X * X * token = yylex(); X * X * token - return token found X */ X Xint yylex() X X { X int toktype; X static int beglin = false; X X if ( eofseen ) X toktype = EOF; X else X toktype = flexscan(); X X if ( toktype == EOF || toktype == 0 ) X { X eofseen = 1; X X if ( sectnum == 1 ) X { X synerr( "premature EOF" ); X sectnum = 2; X toktype = SECTEND; X } X X else if ( sectnum == 2 ) X { X sectnum = 3; X toktype = 0; X } X X else X toktype = 0; X } X X if ( trace ) X { X if ( beglin ) X { X fprintf( stderr, "%d\t", num_rules + 1 ); X beglin = 0; X } X X switch ( toktype ) X { X case '<': X case '>': X case '^': X case '$': X case '"': X case '[': X case ']': X case '{': X case '}': X case '|': X case '(': X case ')': X case '-': X case '/': X case '\\': X case '?': X case '.': X case '*': X case '+': X case ',': X (void) putc( toktype, stderr ); X break; X X case '\n': X (void) putc( '\n', stderr ); X X if ( sectnum == 2 ) X beglin = 1; X X break; X X case SCDECL: X fputs( "%s", stderr ); X break; X X case XSCDECL: X fputs( "%x", stderr ); X break; X X case WHITESPACE: X (void) putc( ' ', stderr ); X break; X X case SECTEND: X fputs( "%%\n", stderr ); X X /* we set beglin to be true so we'll start X * writing out numbers as we echo rules. flexscan() has X * already assigned sectnum X */ X X if ( sectnum == 2 ) X beglin = 1; X X break; X X case NAME: X fprintf( stderr, "'%s'", nmstr ); X break; X X case CHAR: X switch ( yylval ) X { X case '<': X case '>': X case '^': X case '$': X case '"': X case '[': X case ']': X case '{': X case '}': X case '|': X case '(': X case ')': X case '-': X case '/': X case '\\': X case '?': X case '.': X case '*': X case '+': X case ',': X fprintf( stderr, "\\%c", yylval ); X break; X X default: X if ( ! isascii( yylval ) || ! isprint( yylval ) ) X fprintf( stderr, "\\%.3o", yylval ); X else X (void) putc( yylval, stderr ); X break; X } X X break; X X case NUMBER: X fprintf( stderr, "%d", yylval ); X break; X X case PREVCCL: X fprintf( stderr, "[%d]", yylval ); X break; X X case EOF_OP: X fprintf( stderr, "<>" ); X break; X X case 0: X fprintf( stderr, "End Marker" ); X break; X X default: X fprintf( stderr, "*Something Weird* - tok: %d val: %d\n", X toktype, yylval ); X break; X } X } X X return ( toktype ); X } END_OF_FILE if test 4244 -ne `wc -c <'yylex.c'`; then echo shar: \"'yylex.c'\" unpacked with wrong size! fi # end of 'yylex.c' fi echo shar: End of archive 6 \(of 10\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 10 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still must unpack the following archives: echo " " ${MISSING} fi exit 0 exit 0 # Just in case...