[comp.sources.amiga] v90i229: flex 2.3 - fast lexical analyzer generator, Part02/13

amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (08/20/90)

Submitted-by: loftus@wpllabs.uucp (William P Loftus)
Posting-number: Volume 90, Issue 229
Archive-name: unix/flex-2.3/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 13)."
# Contents:  Changes misc.c parse.y scan.l
# Wrapped by tadguy@abcfd20 on Sun Aug 19 18:41:42 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Changes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Changes'\"
else
echo shar: Extracting \"'Changes'\" \(11046 characters\)
sed "s/^X//" >'Changes' <<'END_OF_FILE'
XChanges between 2.3 (full) release of 28Jun90 and 2.2 (alpha) release:
X
X    User-visible:
X
X	- A lone <<EOF>> rule (that is, one which is not qualified with
X	  a list of start conditions) now specifies the EOF action for
X	  *all* start conditions which haven't already had <<EOF>> actions
X	  given.  To specify an end-of-file action for just the initial
X	  state, use <INITIAL><<EOF>>.
X
X	- -d debug output is now contigent on the global yy_flex_debug
X	  being set to a non-zero value, which it is by default.
X
X	- A new macro, YY_USER_INIT, is provided for the user to specify
X	  initialization action to be taken on the first call to the
X	  scanner.  This action is done before the scanner does its
X	  own initialization.
X
X	- yy_new_buffer() has been added as an alias for yy_create_buffer()
X
X	- Comments beginning with '#' and extending to the end of the line
X	  now work, but have been deprecated (in anticipation of making
X	  flex recognize #line directives).
X
X	- The funky restrictions on when semi-colons could follow the
X	  YY_NEW_FILE and yyless macros have been removed.  They now
X	  behave identically to functions.
X
X	- A bug in the sample redefinition of YY_INPUT in the documentation
X	  has been corrected.
X
X	- A bug in the sample simple tokener in the documentation has
X	  been corrected.
X
X	- The documentation on the incompatibilities between flex and
X	  lex has been reordered so that the discussion of yylineno
X	  and input() come first, as it's anticipated that these will
X	  be the most common source of headaches.
X
X
X    Things which didn't used to be documented but now are:
X
X	- flex interprets "^foo|bar" differently from lex.  flex interprets
X	  it as "match either a 'foo' or a 'bar', providing it comes at the
X	  beginning of a line", whereas lex interprets it as "match either
X	  a 'foo' at the beginning of a line, or a 'bar' anywhere".
X
X	- flex initializes the global "yyin" on the first call to the
X	  scanner, while lex initializes it at compile-time.
X
X	- yy_switch_to_buffer() can be used in the yywrap() macro/routine.
X
X	- flex scanners do not use stdio for their input, and hence when
X	  writing an interactive scanner one must explictly call fflush()
X	  after writing out a prompt.
X
X	- flex scanner can be made reentrant (after a fashion) by using
X	  "yyrestart( yyin );".  This is useful for interactive scanners
X	  which have interrupt handlers that long-jump out of the scanner.
X
X	- a defense of why yylineno is not supported is included, along
X	  with a suggestion on how to convert scanners which rely on it.
X
X
X    Other changes:
X
X	- Prototypes and proper declarations of void routines have
X	  been added to the flex source code, courtesy of Kevin B. Kenny.
X
X	- Routines dealing with memory allocation now use void* pointers
X	  instead of char* - see Makefile for porting implications.
X
X	- Error-checking is now done when flex closes a file.
X
X	- Various lint tweaks were added to reduce the number of gripes.
X
X	- Makefile has been further parameterized to aid in porting.
X
X	- Support for SCO Unix added.
X
X	- Flex now sports the latest & greatest UC copyright notice
X	  (which is only slightly different from the previous one).
X
X	- A note has been added to flexdoc.1 mentioning work in progress
X	  on modifying flex to generate straight C code rather than a
X	  table-driven automaton, with an email address of whom to contact
X	  if you are working along similar lines.
X
X
XChanges between 2.2 Patch #3 (30Mar90) and 2.2 Patch #2:
X
X	- fixed bug which caused -I scanners to bomb
X
X
XChanges between 2.2 Patch #2 (27Mar90) and 2.2 Patch #1:
X
X	- fixed bug writing past end of input buffer in yyunput()
X	- fixed bug detecting NUL's at the end of a buffer
X
X
XChanges between 2.2 Patch #1 (23Mar90) and 2.2 (alpha) release:
X
X	- Makefile fixes: definition of MAKE variable for systems
X	  which don't have it; installation of flexdoc.1 along with
X	  flex.1; fixed two bugs which could cause "bigtest" to fail.
X
X	- flex.skel fix for compiling with g++.
X
X	- README and flexdoc.1 no longer list an out-of-date BITNET address
X	  for contacting me.
X
X	- minor typos and formatting changes to flex.1 and flexdoc.1.
X
X
XChanges between 2.2 (alpha) release of March '90 and previous release:
X
X    User-visible:
X
X	- Full user documentation now available.
X
X	- Support for 8-bit scanners.
X
X	- Scanners now accept NUL's.
X
X	- A facility has been added for dealing with multiple
X	  input buffers.
X
X	- Two manual entries now.  One which fully describes flex
X	  (rather than just its differences from lex), and the
X	  other for quick(er) reference.
X
X	- A number of changes to bring flex closer into compliance
X	  with the latest POSIX lex draft:
X
X		%t support
X		flex now accepts multiple input files and concatenates
X		    them together to form its input
X		previous -c (compress) flag renamed -C
X		do-nothing -c and -n flags added
X		Any indented code or code within %{}'s in section 2 is
X		    now copied to the output
X
X	- yyleng is now a bona fide global integer.
X
X	- -d debug information now gives the line number of the
X	  matched rule instead of which number rule it was from
X	  the beginning of the file.
X
X	- -v output now includes a summary of the flags used to generate
X	  the scanner.
X
X	- unput() and yyrestart() are now globally callable.
X
X	- yyrestart() no longer closes the previous value of yyin.
X
X	- C++ support; generated scanners can be compiled with C++ compiler.
X
X	- Primitive -lfl library added, containing default main()
X	  which calls yylex().  A number of routines currently living
X	  in the scanner skeleton will probably migrate to here
X	  in the future (in particular, yywrap() will probably cease
X	  to be a macro and instead be a function in the -lfl library).
X
X	- Hexadecimal (\x) escape sequences added.
X
X	- Support for MS-DOS, VMS, and Turbo-C integrated.
X
X	- The %used/%unused operators have been deprecated.  They
X	  may go away soon.
X
X
X    Other changes:
X
X	- Makefile enhanced for easier testing and installation.
X	- The parser has been tweaked to detect some erroneous
X	  constructions which previously were missed.
X	- Scanner input buffer overflow is now detected.
X	- Bugs with missing "const" declarations fixed.
X	- Out-of-date Minix/Atari patches provided.
X	- Scanners no longer require printf() unless FLEX_DEBUG is being used.
X	- A subtle input() bug has been fixed.
X	- Line numbers for "continued action" rules (those following
X	  the special '|' action) are now correct.
X	- unput() bug fixed; had been causing problems porting flex to VMS.
X	- yymore() handling rewritten to fix bug with interaction
X	  between yymore() and trailing context.
X	- EOF in actions now generates an error message.
X	- Bug involving -CFe and generating equivalence classes fixed.
X	- Bug which made -CF be treated as -Cf fixed.
X	- Support for SysV tmpnam() added.
X	- Unused #define's for scanner no longer generated.
X	- Error messages which are associated with a particular input
X	  line are now all identified with their input line in standard
X	  format.
X	- % directives which are valid to lex but not to flex are
X	  now ignored instead of generating warnings.
X	- -DSYS_V flag can now also be specified -DUSG for System V
X	  compilation.
X
X
XChanges between 2.1 beta-test release of June '89 and previous release:
X
X    User-visible:
X
X	- -p flag generates a performance report to stderr.  The report
X	  consists of comments regarding features of the scanner rules
X	  which result in slower scanners.
X
X	- -b flag generates backtracking information to lex.backtrack.
X	  This is a list of scanner states which require backtracking
X	  and the characters on which they do so.  By adding rules
X	  one can remove backtracking states.  If all backtracking states
X	  are eliminated, the generated scanner will run faster.
X	  Backtracking is not yet documented in the manual entry.
X
X	- Variable trailing context now works, i.e., one can have
X	  rules like "(foo)*/[ \t]*bletch".  Some trailing context
X	  patterns still cannot be properly matched and generate
X	  error messages.  These are patterns where the ending of the
X	  first part of the rule matches the beginning of the second
X	  part, such as "zx*/xy*", where the 'x*' matches the 'x' at
X	  the beginning of the trailing context.  Lex won't get these
X	  patterns right either.
X
X	- Faster scanners.
X
X	- End-of-file rules.  The special rule "<<EOF>>" indicates
X	  actions which are to be taken when an end-of-file is
X	  encountered and yywrap() returns non-zero (i.e., indicates
X	  no further files to process).  See manual entry for example.
X
X	- The -r (reject used) flag is gone.  flex now scans the input
X	  for occurrences of the string "REJECT" to determine if the
X	  action is needed.  It tries to be intelligent about this but
X	  can be fooled.  One can force the presence or absence of
X	  REJECT by adding a line in the first section of the form
X	  "%used REJECT" or "%unused REJECT".
X
X	- yymore() has been implemented.  Similarly to REJECT, flex
X	  detects the use of yymore(), which can be overridden using
X	  "%used" or "%unused".
X
X	- Patterns like "x{0,3}" now work (i.e., with lower-limit == 0).
X
X	- Removed '\^x' for ctrl-x misfeature.
X
X	- Added '\a' and '\v' escape sequences.
X
X	- \<digits> now works for octal escape sequences; previously
X	  \0<digits> was required.
X
X	- Better error reporting; line numbers are associated with rules.
X
X	- yyleng is a macro; it cannot be accessed outside of the
X	  scanner source file.
X
X	- yytext and yyleng should not be modified within a flex action.
X
X	- Generated scanners #define the name FLEX_SCANNER.
X
X	- Rules are internally separated by YY_BREAK in lex.yy.c rather
X	  than break, to allow redefinition.
X
X	- The macro YY_USER_ACTION can be redefined to provide an action
X	  which is always executed prior to the matched rule's action.
X	
X	- yyrestart() is a new action which can be used to restart
X	  the scanner after it has seen an end-of-file (a "real" one,
X	  that is, one for which yywrap() returned non-zero).  It takes
X	  a FILE* argument indicating a new file to scan and sets
X	  things up so that a subsequent call to yylex() will start
X	  scanning that file.
X
X	- Internal scanner names all preceded by "yy_"
X
X	- lex.yy.c is deleted if errors are encountered during processing.
X
X	- Comments may be put in the first section of the input by preceding
X	  them with '#'.
X
X
X
X    Other changes:
X
X	- Some portability-related bugs fixed, in particular for machines
X	  with unsigned characters or sizeof( int* ) != sizeof( int ).
X	  Also, tweaks for VMS and Microsoft C (MS-DOS), and identifiers all
X	  trimmed to be 31 or fewer characters.  Shortened file names
X	  for dinosaur OS's.  Checks for allocating > 64K memory
X	  on 16 bit'ers.  Amiga tweaks.  Compiles using gcc on a Sun-3.
X	- Compressed and fast scanner skeletons merged.
X	- Skeleton header files done away with.
X	- Generated scanner uses prototypes and "const" for __STDC__.
X	- -DSV flag is now -DSYS_V for System V compilation.
X	- Removed all references to FTL language.
X	- Software now covered by BSD Copyright.
X	- flex will replace lex in subsequent BSD releases.
END_OF_FILE
if test 11046 -ne `wc -c <'Changes'`; then
    echo shar: \"'Changes'\" unpacked with wrong size!
fi
# end of 'Changes'
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'\" \(14248 characters\)
sed "s/^X//" >'misc.c' <<'END_OF_FILE'
X/* misc - miscellaneous flex 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: WPL:Generators/flex-2.3/RCS/misc.c,v 1.2 90/07/15 01:18:35 loftus Exp $ (LBL)";
X#endif
X
X#include <ctype.h>
X#include "flexdef.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
X/* declare functions that have forward references */
X
Xvoid dataflush PROTO(());
Xint otoi PROTO((Char []));
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
Xvoid 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
Xvoid *allocate_array( size, element_size )
Xint size, element_size;
X
X    {
X    register void *mem;
X
X    /* on 16-bit int machines (e.g., 80286) we might be trying to
X     * allocate more than a signed int can hold, and that won't
X     * work.  Cheap test:
X     */
X    if ( element_size * size <= 0 )
X        flexfatal( "request for < 1 byte in allocate_array()" );
X
X    mem = (void *) 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/* all_lower - true if a string is all lower-case
X *
X * synopsis:
X *    Char *str;
X *    int all_lower();
X *    true/false = all_lower( str );
X */
X
Xint all_lower( str )
Xregister Char *str;
X
X    {
X    while ( *str )
X	{
X	if ( ! isascii( *str ) || ! islower( *str ) )
X	    return ( 0 );
X	++str;
X	}
X
X    return ( 1 );
X    }
X
X
X/* all_upper - true if a string is all upper-case
X *
X * synopsis:
X *    Char *str;
X *    int all_upper();
X *    true/false = all_upper( str );
X */
X
Xint all_upper( str )
Xregister Char *str;
X
X    {
X    while ( *str )
X	{
X	if ( ! isascii( *str ) || ! isupper( (char) *str ) )
X	    return ( 0 );
X	++str;
X	}
X
X    return ( 1 );
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
Xvoid bubble( v, n )
Xint 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();
X *    int c;
X *    c = clower( c );
X */
X
XChar clower( c )
Xregister int c;
X
X    {
X    return ( (isascii( c ) && 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
Xchar *copy_string( str )
Xregister 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/* copy_unsigned_string -
X *    returns a dynamically allocated copy of a (potentially) unsigned string
X *
X * synopsis
X *    Char *str, *copy, *copy_unsigned_string();
X *    copy = copy_unsigned_string( str );
X */
X
XChar *copy_unsigned_string( str )
Xregister 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 = (Char *) malloc( (unsigned) ((c - str + 1) * sizeof( Char )) );
X
X    if ( copy == NULL )
X	flexfatal( "dynamic memory failure in copy_unsigned_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, special_case_0;
X *   cshell( v, n, special_case_0 );
X *
X * description
X *   does a shell sort of the first n elements of array v.
X *   If special_case_0 is true, then any element equal to 0
X *   is instead assumed to have infinite weight.
X *
X * passed
X *   v - array to be sorted
X *   n - number of elements of v to be sorted
X */
X
Xvoid cshell( v, n, special_case_0 )
XChar v[];
Xint n, special_case_0;
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 ( special_case_0 )
X		    {
X		    if ( v[jg] == 0 )
X			break;
X
X		    else if ( v[j] != 0 && v[j] <= v[jg] )
X			break;
X		    }
X
X		else 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 */
X
Xvoid dataend()
X
X    {
X    if ( datapos > 0 )
X	dataflush();
X
X    /* add terminator for initialization */
X    puts( "    } ;\n" );
X
X    dataline = 0;
X    datapos = 0;
X    }
X
X
X
X/* dataflush - flush generated data statements
X *
X * synopsis
X *    dataflush();
X */
X
Xvoid 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
X/* flexerror - report an error message and terminate
X *
X * synopsis
X *    char msg[];
X *    flexerror( msg );
X */
X
Xvoid flexerror( msg )
Xchar msg[];
X
X    {
X    fprintf( stderr, "%s: %s\n", program_name, msg );
X
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
Xvoid flexfatal( msg )
Xchar msg[];
X
X    {
X    fprintf( stderr, "%s: fatal internal error, %s\n", program_name, msg );
X    flexend( 1 );
X    }
X
X
X/* flex_gettime - return current time
X *
X * synopsis
X *    char *flex_gettime(), *time_str;
X *    time_str = flex_gettime();
X *
X * note
X *    the routine name has the "flex_" prefix because of name clashes
X *    with Turbo-C
X */
X
X/* include sys/types.h to use time_t and make lint happy */
X
X#ifndef MS_DOS
X#ifndef VMS
X#include <sys/types.h>
X#else
X#include <types.h>
X#endif
X#endif
X
X#ifdef MS_DOS
X#include <time.h>
Xtypedef long time_t;
X#endif
X
X#ifdef AMIGA
X#include <time.h>
X#endif
X
Xchar *flex_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
Xvoid lerrif( msg, arg )
Xchar msg[];
Xint 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
Xvoid lerrsf( msg, arg )
Xchar msg[], arg[];
X
X    {
X    char errmsg[MAXLINE];
X
X    (void) sprintf( errmsg, msg, arg );
X    flexerror( errmsg );
X    }
X
X
X/* htoi - convert a hexadecimal digit string to an integer value
X *
X * synopsis:
X *    int val, htoi();
X *    Char str[];
X *    val = htoi( str );
X */
X
Xint htoi( str )
XChar str[];
X
X    {
X    int result;
X
X    (void) sscanf( (char *) str, "%x", &result );
X
X    return ( result );
X    }
X
X
X/* line_directive_out - spit out a "# line" statement */
X
Xvoid 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 */
Xvoid mk2data( value )
Xint 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 */
Xvoid mkdata( value )
Xint 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
Xint myctoi( array )
XChar array[];
X
X    {
X    int val = 0;
X
X    (void) sscanf( (char *) 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
XChar myesc( array )
XChar array[];
X
X    {
X    switch ( array[1] )
X	{
X	case 'a': return ( '\a' );
X	case 'b': return ( '\b' );
X	case 'f': return ( '\f' );
X	case 'n': return ( '\n' );
X	case 'r': return ( '\r' );
X	case 't': return ( '\t' );
X	case 'v': return ( '\v' );
X
X	case 'x':
X	    /* fall through */
X
X	case '0':
X	case '1':
X	case '2':
X	case '3':
X	case '4':
X	case '5':
X	case '6':
X	case '7':
X	case '8':
X	case '9':
X
X	    { /* \<octal> or \x<hex> */
X	    Char c, esc_char;
X	    register int sptr = 1;
X
X	    if ( array[1] == 'x' )
X		++sptr;
X
X	    while ( isascii( array[sptr] ) && isdigit( array[sptr] ) )
X		/* don't increment inside loop control because if
X		 * isdigit() is a macro it will expand it to two
X		 * increments ...
X		 */
X		++sptr;
X
X	    c = array[sptr];
X	    array[sptr] = '\0';
X
X	    if ( array[1] == 'x' )
X		esc_char = htoi( array + 2 );
X	    else
X		esc_char = otoi( array + 1 );
X
X	    array[sptr] = c;
X
X	    return ( esc_char );
X	    }
X
X	default:
X	    return ( array[1] );
X	}
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
Xint otoi( str )
XChar str[];
X
X    {
X    int result;
X
X    (void) sscanf( (char *) str, "%o", &result );
X
X    return ( result );
X    }
X
X
X/* readable_form - return the the human-readable form of a character
X *
X * synopsis:
X *    int c;
X *    char *readable_form();
X *    <string> = readable_form( c );
X *
X * The returned string is in static storage.
X */
X
Xchar *readable_form( c )
Xregister int c;
X
X    {
X    static char rform[10];
X
X    if ( (c >= 0 && c < 32) || c >= 127 )
X	{
X	switch ( c )
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	    default:
X		(void) sprintf( rform, "\\%.3o", c );
X		return ( rform );
X	    }
X	}
X
X    else if ( c == ' ' )
X	return ( "' '" );
X
X    else
X	{
X	rform[0] = c;
X	rform[1] = '\0';
X
X	return ( rform );
X	}
X    }
X
X
X/* reallocate_array - increase the size of a dynamic array */
X
Xvoid *reallocate_array( array, size, element_size )
Xvoid *array;
Xint size, element_size;
X
X    {
X    register void *new_array;
X
X    /* same worry as in allocate_array(): */
X    if ( size * element_size <= 0 )
X        flexfatal( "attempt to increase array size by less than 1 byte" );
X
X    new_array =
X	(void *) realloc( (char *)array, (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 */
Xvoid 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
Xvoid transition_struct_out( element_v, element_n )
Xint 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	putchar( '\n' );
X
X	if ( ++dataline % 10 == 0 )
X	    putchar( '\n' );
X
X	datapos = 0;
X	}
X    }
END_OF_FILE
if test 14248 -ne `wc -c <'misc.c'`; then
    echo shar: \"'misc.c'\" unpacked with wrong size!
fi
# end of 'misc.c'
fi
if test -f 'parse.y' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'parse.y'\"
else
echo shar: Extracting \"'parse.y'\" \(14546 characters\)
sed "s/^X//" >'parse.y' <<'END_OF_FILE'
X
X/* parse.y - parser for flex input */
X
X%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP
X
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: WPL:Generators/flex-2.3/RCS/parse.y,v 1.2 90/07/15 01:16:53 loftus Exp $ (LBL)";
X#endif
X
X#include "flexdef.h"
X
Xint pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
Xint trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
XChar clower();
Xvoid build_eof_action();
Xvoid yyerror( char * );
X
Xstatic int madeany = false;  /* whether we've made the '.' character class */
Xint previous_continued_action;	/* whether the previous rule's action was '|' */
X
X%}
X
X%%
Xgoal            :  initlex sect1 sect1end sect2 initforrule
X			{ /* add default rule */
X			int def_rule;
X
X			pat = cclinit();
X			cclnegate( pat );
X
X			def_rule = mkstate( -pat );
X
X			finish_rule( def_rule, false, 0, 0 );
X
X			for ( i = 1; i <= lastsc; ++i )
X			    scset[i] = mkbranch( scset[i], def_rule );
X
X			if ( spprdflt )
X			    fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )",
X				   temp_action_file );
X			else
X			    fputs( "ECHO", temp_action_file );
X
X			fputs( ";\n\tYY_BREAK\n", temp_action_file );
X			}
X		;
X
Xinitlex         :
X			{
X			/* initialize for processing rules */
X
X			/* create default DFA start condition */
X			scinstal( "INITIAL", false );
X			}
X		;
X
Xsect1		:  sect1 startconddecl WHITESPACE namelist1 '\n'
X		|
X		|  error '\n'
X			{ synerr( "unknown error processing section 1" ); }
X		;
X
Xsect1end	:  SECTEND
X		;
X
Xstartconddecl   :  SCDECL
X			{
X			/* these productions are separate from the s1object
X			 * rule because the semantics must be done before
X			 * we parse the remainder of an s1object
X			 */
X
X			xcluflg = false;
X			}
X
X		|  XSCDECL
X			{ xcluflg = true; }
X		;
X
Xnamelist1	:  namelist1 WHITESPACE NAME
X			{ scinstal( nmstr, xcluflg ); }
X
X		|  NAME
X			{ scinstal( nmstr, xcluflg ); }
X
X		|  error
X                        { synerr( "bad start condition list" ); }
X		;
X
Xsect2           :  sect2 initforrule flexrule '\n'
X		|
X		;
X
Xinitforrule     :
X			{
X			/* initialize for a parse of one rule */
X			trlcontxt = variable_trail_rule = varlength = false;
X			trailcnt = headcnt = rulelen = 0;
X			current_state_type = STATE_NORMAL;
X			previous_continued_action = continued_action;
X			new_rule();
X			}
X		;
X
Xflexrule        :  scon '^' rule
X                        {
X			pat = $3;
X			finish_rule( pat, variable_trail_rule,
X				     headcnt, trailcnt );
X
X			for ( i = 1; i <= actvp; ++i )
X			    scbol[actvsc[i]] =
X				mkbranch( scbol[actvsc[i]], pat );
X
X			if ( ! bol_needed )
X			    {
X			    bol_needed = true;
X
X			    if ( performance_report )
X				pinpoint_message( 
X			    "'^' operator results in sub-optimal performance" );
X			    }
X			}
X
X		|  scon rule
X                        {
X			pat = $2;
X			finish_rule( pat, variable_trail_rule,
X				     headcnt, trailcnt );
X
X			for ( i = 1; i <= actvp; ++i )
X			    scset[actvsc[i]] =
X				mkbranch( scset[actvsc[i]], pat );
X			}
X
X                |  '^' rule
X			{
X			pat = $2;
X			finish_rule( pat, variable_trail_rule,
X				     headcnt, trailcnt );
X
X			/* add to all non-exclusive start conditions,
X			 * including the default (0) start condition
X			 */
X
X			for ( i = 1; i <= lastsc; ++i )
X			    if ( ! scxclu[i] )
X				scbol[i] = mkbranch( scbol[i], pat );
X
X			if ( ! bol_needed )
X			    {
X			    bol_needed = true;
X
X			    if ( performance_report )
X				pinpoint_message(
X			    "'^' operator results in sub-optimal performance" );
X			    }
X			}
X
X                |  rule
X			{
X			pat = $1;
X			finish_rule( pat, variable_trail_rule,
X				     headcnt, trailcnt );
X
X			for ( i = 1; i <= lastsc; ++i )
X			    if ( ! scxclu[i] )
X				scset[i] = mkbranch( scset[i], pat );
X			}
X
X                |  scon EOF_OP
X			{ build_eof_action(); }
X
X                |  EOF_OP
X			{
X			/* this EOF applies to all start conditions
X			 * which don't already have EOF actions
X			 */
X			actvp = 0;
X
X			for ( i = 1; i <= lastsc; ++i )
X			    if ( ! sceof[i] )
X				actvsc[++actvp] = i;
X
X			if ( actvp == 0 )
X			    pinpoint_message(
X		"warning - all start conditions already have <<EOF>> rules" );
X
X			else
X			    build_eof_action();
X			}
X
X                |  error
X			{ synerr( "unrecognized rule" ); }
X		;
X
Xscon            :  '<' namelist2 '>'
X		;
X
Xnamelist2       :  namelist2 ',' NAME
X                        {
X			if ( (scnum = sclookup( nmstr )) == 0 )
X			    format_pinpoint_message(
X				"undeclared start condition %s", nmstr );
X
X			else
X			    actvsc[++actvp] = scnum;
X			}
X
X		|  NAME
X			{
X			if ( (scnum = sclookup( nmstr )) == 0 )
X			    format_pinpoint_message(
X				"undeclared start condition %s", nmstr );
X			else
X			    actvsc[actvp = 1] = scnum;
X			}
X
X		|  error
X			{ synerr( "bad start condition list" ); }
X		;
X
Xrule            :  re2 re
X			{
X			if ( transchar[lastst[$2]] != SYM_EPSILON )
X			    /* provide final transition \now/ so it
X			     * will be marked as a trailing context
X			     * state
X			     */
X			    $2 = link_machines( $2, mkstate( SYM_EPSILON ) );
X
X			mark_beginning_as_normal( $2 );
X			current_state_type = STATE_NORMAL;
X
X			if ( previous_continued_action )
X			    {
X			    /* we need to treat this as variable trailing
X			     * context so that the backup does not happen
X			     * in the action but before the action switch
X			     * statement.  If the backup happens in the
X			     * action, then the rules "falling into" this
X			     * one's action will *also* do the backup,
X			     * erroneously.
X			     */
X			    if ( ! varlength || headcnt != 0 )
X				{
X				fprintf( stderr,
X    "%s: warning - trailing context rule at line %d made variable because\n",
X					 program_name, linenum );
X				fprintf( stderr,
X					 "      of preceding '|' action\n" );
X				}
X
X			    /* mark as variable */
X			    varlength = true;
X			    headcnt = 0;
X			    }
X
X			if ( varlength && headcnt == 0 )
X			    { /* variable trailing context rule */
X			    /* mark the first part of the rule as the accepting
X			     * "head" part of a trailing context rule
X			     */
X			    /* by the way, we didn't do this at the beginning
X			     * of this production because back then
X			     * current_state_type was set up for a trail
X			     * rule, and add_accept() can create a new
X			     * state ...
X			     */
X			    add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK );
X			    variable_trail_rule = true;
X			    }
X			
X			else
X			    trailcnt = rulelen;
X
X			$$ = link_machines( $1, $2 );
X			}
X
X		|  re2 re '$'
X			{ synerr( "trailing context used twice" ); }
X
X		|  re '$'
X                        {
X			if ( trlcontxt )
X			    {
X			    synerr( "trailing context used twice" );
X			    $$ = mkstate( SYM_EPSILON );
X			    }
X
X			else if ( previous_continued_action )
X			    {
X			    /* see the comment in the rule for "re2 re"
X			     * above
X			     */
X			    if ( ! varlength || headcnt != 0 )
X				{
X				fprintf( stderr,
X    "%s: warning - trailing context rule at line %d made variable because\n",
X					 program_name, linenum );
X				fprintf( stderr,
X					 "      of preceding '|' action\n" );
X				}
X
X			    /* mark as variable */
X			    varlength = true;
X			    headcnt = 0;
X			    }
X
X			trlcontxt = true;
X
X			if ( ! varlength )
X			    headcnt = rulelen;
X
X			++rulelen;
X			trailcnt = 1;
X
X			eps = mkstate( SYM_EPSILON );
X			$$ = link_machines( $1,
X				 link_machines( eps, mkstate( '\n' ) ) );
X			}
X
X		|  re
X			{
X		        $$ = $1;
X
X			if ( trlcontxt )
X			    {
X			    if ( varlength && headcnt == 0 )
X				/* both head and trail are variable-length */
X				variable_trail_rule = true;
X			    else
X				trailcnt = rulelen;
X			    }
X		        }
X		;
X
X
Xre              :  re '|' series
X                        {
X			varlength = true;
X			$$ = mkor( $1, $3 );
X			}
X
X		|  series
X			{ $$ = $1; }
X		;
X
X
Xre2		:  re '/'
X			{
X			/* this rule is written separately so
X			 * the reduction will occur before the trailing
X			 * series is parsed
X			 */
X
X			if ( trlcontxt )
X			    synerr( "trailing context used twice" );
X			else
X			    trlcontxt = true;
X
X			if ( varlength )
X			    /* we hope the trailing context is fixed-length */
X			    varlength = false;
X			else
X			    headcnt = rulelen;
X
X			rulelen = 0;
X
X			current_state_type = STATE_TRAILING_CONTEXT;
X			$$ = $1;
X			}
X		;
X
Xseries          :  series singleton
X                        {
X			/* this is where concatenation of adjacent patterns
X			 * gets done
X			 */
X			$$ = link_machines( $1, $2 );
X			}
X
X		|  singleton
X			{ $$ = $1; }
X		;
X
Xsingleton       :  singleton '*'
X                        {
X			varlength = true;
X
X			$$ = mkclos( $1 );
X			}
X
X		|  singleton '+'
X			{
X			varlength = true;
X
X			$$ = mkposcl( $1 );
X			}
X
X		|  singleton '?'
X			{
X			varlength = true;
X
X			$$ = mkopt( $1 );
X			}
X
X		|  singleton '{' NUMBER ',' NUMBER '}'
X			{
X			varlength = true;
X
X			if ( $3 > $5 || $3 < 0 )
X			    {
X			    synerr( "bad iteration values" );
X			    $$ = $1;
X			    }
X			else
X			    {
X			    if ( $3 == 0 )
X				$$ = mkopt( mkrep( $1, $3, $5 ) );
X			    else
X				$$ = mkrep( $1, $3, $5 );
X			    }
X			}
X
X		|  singleton '{' NUMBER ',' '}'
X			{
X			varlength = true;
X
X			if ( $3 <= 0 )
X			    {
X			    synerr( "iteration value must be positive" );
X			    $$ = $1;
X			    }
X
X			else
X			    $$ = mkrep( $1, $3, INFINITY );
X			}
X
X		|  singleton '{' NUMBER '}'
X			{
X			/* the singleton could be something like "(foo)",
X			 * in which case we have no idea what its length
X			 * is, so we punt here.
X			 */
X			varlength = true;
X
X			if ( $3 <= 0 )
X			    {
X			    synerr( "iteration value must be positive" );
X			    $$ = $1;
X			    }
X
X			else
X			    $$ = link_machines( $1, copysingl( $1, $3 - 1 ) );
X			}
X
X		|  '.'
X			{
X			if ( ! madeany )
X			    {
X			    /* create the '.' character class */
X			    anyccl = cclinit();
X			    ccladd( anyccl, '\n' );
X			    cclnegate( anyccl );
X
X			    if ( useecs )
X				mkeccl( ccltbl + cclmap[anyccl],
X					ccllen[anyccl], nextecm,
X					ecgroup, csize, csize );
X
X			    madeany = true;
X			    }
X
X			++rulelen;
X
X			$$ = mkstate( -anyccl );
X			}
X
X		|  fullccl
X			{
X			if ( ! cclsorted )
X			    /* sort characters for fast searching.  We use a
X			     * shell sort since this list could be large.
X			     */
X			    cshell( ccltbl + cclmap[$1], ccllen[$1], true );
X
X			if ( useecs )
X			    mkeccl( ccltbl + cclmap[$1], ccllen[$1],
X				    nextecm, ecgroup, csize, csize );
X
X			++rulelen;
X
X			$$ = mkstate( -$1 );
X			}
X
X		|  PREVCCL
X			{
X			++rulelen;
X
X			$$ = mkstate( -$1 );
X			}
X
X		|  '"' string '"'
X			{ $$ = $2; }
X
X		|  '(' re ')'
X			{ $$ = $2; }
X
X		|  CHAR
X			{
X			++rulelen;
X
X			if ( caseins && $1 >= 'A' && $1 <= 'Z' )
X			    $1 = clower( $1 );
X
X			$$ = mkstate( $1 );
X			}
X		;
X
Xfullccl		:  '[' ccl ']'
X			{ $$ = $2; }
X
X		|  '[' '^' ccl ']'
X			{
X			/* *Sigh* - to be compatible Unix lex, negated ccls
X			 * match newlines
X			 */
X#ifdef NOTDEF
X			ccladd( $3, '\n' ); /* negated ccls don't match '\n' */
X			cclsorted = false; /* because we added the newline */
X#endif
X			cclnegate( $3 );
X			$$ = $3;
X			}
X		;
X
Xccl             :  ccl CHAR '-' CHAR
X                        {
X			if ( $2 > $4 )
X			    synerr( "negative range in character class" );
X
X			else
X			    {
X			    if ( caseins )
X				{
X				if ( $2 >= 'A' && $2 <= 'Z' )
X				    $2 = clower( $2 );
X				if ( $4 >= 'A' && $4 <= 'Z' )
X				    $4 = clower( $4 );
X				}
X
X			    for ( i = $2; i <= $4; ++i )
X			        ccladd( $1, i );
X
X			    /* keep track if this ccl is staying in alphabetical
X			     * order
X			     */
X			    cclsorted = cclsorted && ($2 > lastchar);
X			    lastchar = $4;
X			    }
X
X			$$ = $1;
X			}
X
X		|  ccl CHAR
X		        {
X			if ( caseins )
X			    if ( $2 >= 'A' && $2 <= 'Z' )
X				$2 = clower( $2 );
X
X			ccladd( $1, $2 );
X			cclsorted = cclsorted && ($2 > lastchar);
X			lastchar = $2;
X			$$ = $1;
X			}
X
X		|
X			{
X			cclsorted = true;
X			lastchar = 0;
X			$$ = cclinit();
X			}
X		;
X
Xstring		:  string CHAR
X                        {
X			if ( caseins )
X			    if ( $2 >= 'A' && $2 <= 'Z' )
X				$2 = clower( $2 );
X
X			++rulelen;
X
X			$$ = link_machines( $1, mkstate( $2 ) );
X			}
X
X		|
X			{ $$ = mkstate( SYM_EPSILON ); }
X		;
X
X%%
X
X
X/* build_eof_action - build the "<<EOF>>" action for the active start
X *                    conditions
X */
X
Xvoid build_eof_action()
X
X    {
X    register int i;
X
X    for ( i = 1; i <= actvp; ++i )
X	{
X	if ( sceof[actvsc[i]] )
X	    format_pinpoint_message(
X		"multiple <<EOF>> rules for start condition %s",
X		    scname[actvsc[i]] );
X
X	else
X	    {
X	    sceof[actvsc[i]] = true;
X	    fprintf( temp_action_file, "case YY_STATE_EOF(%s):\n",
X		     scname[actvsc[i]] );
X	    }
X	}
X
X    line_directive_out( temp_action_file );
X    }
X
X
X/* synerr - report a syntax error */
X
Xvoid synerr( str )
Xchar str[];
X
X    {
X    syntaxerror = true;
X    pinpoint_message( str );
X    }
X
X
X/* format_pinpoint_message - write out a message formatted with one string,
X *			     pinpointing its location
X */
X
Xvoid format_pinpoint_message( msg, arg )
Xchar msg[], arg[];
X
X    {
X    char errmsg[MAXLINE];
X
X    (void) sprintf( errmsg, msg, arg );
X    pinpoint_message( errmsg );
X    }
X
X
X/* pinpoint_message - write out a message, pinpointing its location */
X
Xvoid pinpoint_message( str )
Xchar str[];
X
X    {
X    fprintf( stderr, "\"%s\", line %d: %s\n", infilename, linenum, str );
X    }
X
X
X/* yyerror - eat up an error message from the parser;
X *	     currently, messages are ignore
X */
X
Xvoid yyerror( msg )
Xchar msg[];
X
X    {
X    }
END_OF_FILE
if test 14546 -ne `wc -c <'parse.y'`; then
    echo shar: \"'parse.y'\" unpacked with wrong size!
fi
# end of 'parse.y'
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'\" \(12444 characters\)
sed "s/^X//" >'scan.l' <<'END_OF_FILE'
X
X/* scan.l - scanner for flex input */
X
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: WPL:Generators/flex-2.3/RCS/scan.l,v 1.2 90/07/15 01:16:31 loftus Exp $ (LBL)";
X#endif
X
X#undef yywrap
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, (char *) yytext ); \
X	return ( NAME );
X
X#define PUT_BACK_STRING(str, start) \
X	for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \
X	    unput((str)[i])
X
X#define CHECK_REJECT(str) \
X	if ( all_upper( str ) ) \
X	    reject = true;
X
X#define CHECK_YYMORE(str) \
X	if ( all_lower( str ) ) \
X	    yymore_used = true;
X%}
X
X%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
X%x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT
X%x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2 XLATION
X
XWS		[ \t\f]+
XOPTWS		[ \t\f]*
XNOT_WS		[^ \t\f\n]
X
XNAME		[a-z_][a-z_0-9-]*
XNOT_NAME	[^a-z_\n]+
X
XSCNAME		{NAME}
X
XESCSEQ		\\([^\n]|[0-9]{1,3}|x[0-9a-f]{1,2})
X
X%%
X    static int bracelevel, didadef;
X    int i, indented_code, checking_used, new_xlation;
X    int doing_codeblock = false;
X    Char nmdef[MAXLINE], myesc();
X
X^{WS}			indented_code = true; BEGIN(CODEBLOCK);
X^#.*\n			++linenum; /* treat as a comment */
X^"/*"			ECHO; BEGIN(C_COMMENT);
X^"%s"{NAME}?		return ( SCDECL );
X^"%x"{NAME}?		return ( XSCDECL );
X^"%{".*\n		{
X			++linenum;
X			line_directive_out( stdout );
X			indented_code = false;
X			BEGIN(CODEBLOCK);
X			}
X
X{WS}			return ( WHITESPACE );
X
X^"%%".*			{
X			sectnum = 2;
X			line_directive_out( stdout );
X			BEGIN(SECT2PROLOG);
X			return ( SECTEND );
X			}
X
X^"%used"		{
X	pinpoint_message( "warning - %%used/%%unused have been deprecated" );
X			checking_used = REALLY_USED; BEGIN(USED_LIST);
X			}
X^"%unused"		{
X			checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
X	pinpoint_message( "warning - %%used/%%unused have been deprecated" );
X			checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
X			}
X
X
X^"%"[aeknopt]" ".*\n	{
X#ifdef NOTDEF
X			fprintf( stderr,
X			     "old-style lex command at line %d ignored:\n\t%s",
X				 linenum, yytext );
X#endif
X			++linenum;
X			}
X
X^"%"[cr]{OPTWS}		/* ignore old lex directive */
X
X%t{OPTWS}\n		{
X			++linenum;
X			xlation =
X			    (int *) malloc( sizeof( int ) * (unsigned) csize );
X
X			if ( ! xlation )
X			    flexfatal(
X				"dynamic memory failure building %t table" );
X
X			for ( i = 0; i < csize; ++i )
X			    xlation[i] = 0;
X
X			num_xlations = 0;
X
X			BEGIN(XLATION);
X			}
X
X^"%"[^sxanpekotcru{}]{OPTWS}	synerr( "unrecognized '%' directive" );
X
X^{NAME}			{
X			(void) strcpy( nmstr, (char *) yytext );
X			didadef = false;
X			BEGIN(PICKUPDEF);
X			}
X
X{SCNAME}		RETURNNAME;
X^{OPTWS}\n		++linenum; /* allows blank lines in section 1 */
X{OPTWS}\n		++linenum; return ( '\n' );
X.			synerr( "illegal character" ); BEGIN(RECOVER);
X
X
X<C_COMMENT>"*/"		ECHO; BEGIN(INITIAL);
X<C_COMMENT>"*/".*\n	++linenum; ECHO; BEGIN(INITIAL);
X<C_COMMENT>[^*\n]+	ECHO;
X<C_COMMENT>"*"		ECHO;
X<C_COMMENT>\n		++linenum; ECHO;
X
X
X<CODEBLOCK>^"%}".*\n	++linenum; BEGIN(INITIAL);
X<CODEBLOCK>"reject"	ECHO; CHECK_REJECT(yytext);
X<CODEBLOCK>"yymore"	ECHO; CHECK_YYMORE(yytext);
X<CODEBLOCK>{NAME}|{NOT_NAME}|.	ECHO;
X<CODEBLOCK>\n		{
X			++linenum;
X			ECHO;
X			if ( indented_code )
X			    BEGIN(INITIAL);
X			}
X
X
X<PICKUPDEF>{WS}		/* separates name and definition */
X
X<PICKUPDEF>{NOT_WS}.*	{
X			(void) strcpy( (char *) nmdef, (char *) yytext );
X
X			for ( i = strlen( (char *) 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(INITIAL);
X			++linenum;
X			}
X
X<RECOVER>.*\n		++linenum; BEGIN(INITIAL); RETURNNAME;
X
X
X<USED_LIST>\n		++linenum; BEGIN(INITIAL);
X<USED_LIST>{WS}
X<USED_LIST>"reject"	{
X			if ( all_upper( yytext ) )
X			    reject_really_used = checking_used;
X			else
X			    synerr( "unrecognized %used/%unused construct" );
X			}
X<USED_LIST>"yymore"	{
X			if ( all_lower( yytext ) )
X			    yymore_really_used = checking_used;
X			else
X			    synerr( "unrecognized %used/%unused construct" );
X			}
X<USED_LIST>{NOT_WS}+	synerr( "unrecognized %used/%unused construct" );
X
X
X<XLATION>"%t"{OPTWS}\n	++linenum; BEGIN(INITIAL);
X<XLATION>^{OPTWS}[0-9]+	++num_xlations; new_xlation = true;
X<XLATION>^.		synerr( "bad row in translation table" );
X<XLATION>{WS}		/* ignore whitespace */
X
X<XLATION>{ESCSEQ}	{
X			xlation[myesc( yytext )] =
X				(new_xlation ? num_xlations : -num_xlations);
X			new_xlation = false;
X			}
X<XLATION>.		{
X			xlation[yytext[0]] =
X				(new_xlation ? num_xlations : -num_xlations);
X			new_xlation = false;
X			}
X
X<XLATION>\n		++linenum;
X
X
X<SECT2PROLOG>.*\n/{NOT_WS}	{
X			++linenum;
X			ACTION_ECHO;
X			MARK_END_OF_PROLOG;
X			BEGIN(SECT2);
X			}
X
X<SECT2PROLOG>.*\n	++linenum; ACTION_ECHO;
X
X<SECT2PROLOG><<EOF>>	MARK_END_OF_PROLOG; yyterminate();
X
X<SECT2>^{OPTWS}\n	++linenum; /* allow blank lines in section 2 */
X
X<SECT2>^({WS}|"%{")	{
X			indented_code = (yytext[0] != '%');
X			doing_codeblock = true;
X			bracelevel = 1;
X
X			if ( indented_code )
X			    ACTION_ECHO;
X
X			BEGIN(CODEBLOCK_2);
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	continued_action = true; ++linenum; return ( '\n' );
X
X<SECT2>{WS}		{
X			/* this rule is separate from the one below because
X			 * otherwise we get variable trailing context, so
X			 * we can't build the scanner using -{f,F}
X			 */
X			bracelevel = 0;
X			continued_action = false;
X			BEGIN(ACTION);
X			return ( '\n' );
X			}
X
X<SECT2>{OPTWS}/\n	{
X			bracelevel = 0;
X			continued_action = false;
X			BEGIN(ACTION);
X			return ( '\n' );
X			}
X
X<SECT2>^{OPTWS}\n	++linenum; return ( '\n' );
X
X<SECT2>"<<EOF>>"	return ( EOF_OP );
X
X<SECT2>^"%%".*		{
X			sectnum = 3;
X			BEGIN(SECT3);
X			return ( EOF ); /* to stop the parser */
X			}
X
X<SECT2>"["([^\\\]\n]|{ESCSEQ})+"]"	{
X			int cclval;
X
X			(void) strcpy( nmstr, (char *) yytext );
X
X			/* check to see if we've already encountered this ccl */
X			if ( (cclval = ccllookup( (Char *) 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( (Char *) nmstr, lastccl + 1 );
X
X			    /* push back everything but the leading bracket
X			     * so the ccl can be rescanned
X			     */
X			    PUT_BACK_STRING((Char *) 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, (char *) 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 ( (int) 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,CODEBLOCK_2>{OPTWS}"%}".*		bracelevel = 0;
X<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"reject"	{
X			ACTION_ECHO;
X			CHECK_REJECT(yytext);
X			}
X<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"yymore"	{
X			ACTION_ECHO;
X			CHECK_YYMORE(yytext);
X			}
X<PERCENT_BRACE_ACTION,CODEBLOCK_2>{NAME}|{NOT_NAME}|.	ACTION_ECHO;
X<PERCENT_BRACE_ACTION,CODEBLOCK_2>\n			{
X			++linenum;
X			ACTION_ECHO;
X			if ( bracelevel == 0 ||
X			     (doing_codeblock && indented_code) )
X			    {
X			    if ( ! doing_codeblock )
X				fputs( "\tYY_BREAK\n", temp_action_file );
X			    
X			    doing_codeblock = false;
X			    BEGIN(SECT2);
X			    }
X			}
X
X
X	/* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
X<ACTION>"{"		ACTION_ECHO; ++bracelevel;
X<ACTION>"}"		ACTION_ECHO; --bracelevel;
X<ACTION>[^a-z_{}"'/\n]+	ACTION_ECHO;
X<ACTION>{NAME}		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<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<ACTION,ACTION_COMMENT,ACTION_STRING><<EOF>>	{
X			synerr( "EOF encountered inside an action" );
X			yyterminate();
X			}
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?)		ECHO;
X%%
X
X
Xint yywrap()
X
X    {
X    if ( --num_input_files > 0 )
X	{
X	set_input_file( *++input_files );
X	return ( 0 );
X	}
X
X    else
X	return ( 1 );
X    }
X
X
X/* set_input_file - open the given file (if NULL, stdin) for scanning */
X
Xvoid set_input_file( file )
Xchar *file;
X
X    {
X    if ( file )
X	{
X	infilename = file;
X	yyin = fopen( infilename, "r" );
X
X	if ( yyin == NULL )
X	    lerrsf( "can't open %s", file );
X	}
X
X    else
X	{
X	yyin = stdin;
X	infilename = "<stdin>";
X	}
X    }
END_OF_FILE
if test 12444 -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 13\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 13 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.