[comp.sources.unix] v19i056: Flex, a fast LEX replacement, Part02/07

rsalz@uunet.uu.net (Rich Salz) (06/23/89)

Submitted-by: Vern Paxson <vern@csam.lbl.gov>
Posting-number: Volume 19, Issue 56
Archive-name: flex2/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 7)."
# Contents:  flex/flex.skel flex/misc.c flex/parse.y
# Wrapped by rsalz@prune.bbn.com on Thu Jun 22 19:01:44 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'flex/flex.skel' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flex/flex.skel'\"
else
echo shar: Extracting \"'flex/flex.skel'\" \(11297 characters\)
sed "s/^X//" >'flex/flex.skel' <<'END_OF_FILE'
X/* A lexical scanner generated by flex */
X
X/* scanner skeleton version:
X * $Header: flex.skel,v 2.0 89/06/20 15:49:46 vern Locked $
X */
X
X#include <stdio.h>
X
X#define FLEX_SCANNER
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#ifndef YY_BUF_SIZE
X#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of input buffer */
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#define ECHO fputs( yytext, 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), buf, max_size )) < 0 ) \
X	    YY_FATAL_ERROR( "read() in flex scanner failed" );
X#define YY_NULL 0
X#define yyterminate() return ( YY_NULL )
X
X/* report a fatal error */
X#define YY_FATAL_ERROR(msg) \
X	{ \
X	fputs( msg, stderr ); \
X	putc( '\n', stderr ); \
X	exit( 1 ); \
X	}
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 goto new_file
X
X/* default declaration of generated scanner - a define so the user can
X * easily add parameters
X */
X#ifdef __STDC__
X#define YY_DECL int yylex( void )
X#else
X#define YY_DECL int yylex()
X#endif
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/* 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	yy_hold_char = *yy_cp; \
X	*yy_cp = '\0'; \
X	yy_c_buf_p = yy_cp;
X
X/* returns the length of the matched text */
X#define yyleng (yy_cp - yy_bp)
X
X#define EOB_ACT_RESTART_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	{ \
X	*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \
X	yy_c_buf_p = yy_cp = yy_bp + n; \
X	YY_DO_BEFORE_ACTION; /* set up yytext again */ \
X	}
X
X#define unput(c) yyunput( c, yy_bp )
X
X#define YY_USER_ACTION
X
XFILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
Xchar *yytext;
X
X#ifndef __STDC__
X#define const
X#endif
X
X%% section 1 code and the 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 */
Xstatic char *yy_c_buf_p;	/* points to current character in buffer */
Xstatic int yy_init = 1;		/* whether we need to initialize */
Xstatic int yy_start = 0;	/* start state number */
X
X/* true when we've seen an EOF for the current input file */
Xstatic int yy_eof_has_been_seen;
X
Xstatic int yy_n_chars;		/* number of characters read into yy_ch_buf */
X
X/* yy_ch_buf has to be 2 characters longer than YY_BUF_SIZE because we need
X * to put in 2 end-of-buffer characters (this is explained where it is
X * done) at the end of yy_ch_buf
X */
Xstatic char yy_ch_buf[YY_BUF_SIZE + 2];
X
X/* yy_hold_char holds the character lost when yytext is formed */
Xstatic char yy_hold_char;
X
Xstatic yy_state_type yy_last_accepting_state;
Xstatic char *yy_last_accepting_cpos;
X
X#ifdef __STDC__
Xstatic yy_state_type yy_get_previous_state( void );
Xstatic int yy_get_next_buffer( void );
Xstatic void yyunput( int c, char *buf_ptr );
Xstatic int input( void );
Xstatic void yyrestart( FILE *input_file );
X#else
Xstatic yy_state_type yy_get_previous_state();
Xstatic int yy_get_next_buffer();
Xstatic void yyunput();
Xstatic int input();
Xstatic void yyrestart();
X#endif
X
XYY_DECL
X    {
X    register yy_state_type yy_current_state;
X    register char *yy_cp, *yy_bp;
X    register int yy_act;
X
X%% user's declarations go here
X
X    if ( yy_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
Xnew_file:
X	/* this is where we enter upon encountering an end-of-file and
X	 * yywrap() indicating that we should continue processing
X	 */
X
X	/* we put in the '\n' and start reading from [1] so that an
X	 * initial match-at-newline will be true.
X	 */
X
X	yy_ch_buf[0] = '\n';
X	yy_n_chars = 1;
X
X	/* we always need two end-of-buffer characters.  The first causes
X	 * a transition to the end-of-buffer state.  The second causes
X	 * a jam in that state.
X	 */
X	yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
X	yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
X
X	yy_eof_has_been_seen = 0;
X
X	yytext = yy_c_buf_p = &yy_ch_buf[1];
X	yy_hold_char = *yy_c_buf_p;
X	yy_init = 0;
X	}
X
X    while ( 1 )		/* loops until end-of-file is reached */
X	{
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%% yymore()-related code goes here
X
X%% code to set up and find next match goes here
X
X	/* bogus while loop to let YY_BACK_TRACK, EOB_ACT_LAST_MATCH,
X	 * and EOF actions branch here without introducing an optimizer-
X	 * daunting goto
X	 */
X	while ( 1 )
X	    {
X%% code to find the action number goes here
X
X	    YY_DO_BEFORE_ACTION;
X	    YY_USER_ACTION;
X
X#ifdef FLEX_DEBUG
X	    fprintf( stderr, "--accepting rule #%d (\"%s\")\n",
X		     yy_act, yytext );
X#endif
X
Xdo_action:	/* this label is used only to access EOF actions */
X	    switch ( yy_act )
X		{
X%% actions go here
X
X		case YY_END_OF_BUFFER:
X		    /* undo the effects of YY_DO_BEFORE_ACTION */
X		    *yy_cp = yy_hold_char;
X
X		    yytext = yy_bp;
X
X		    switch ( yy_get_next_buffer() )
X			{
X			case EOB_ACT_END_OF_FILE:
X			    {
X			    if ( yywrap() )
X				{
X				/* note: because we've taken care in
X				 * yy_get_next_buffer() to have set up 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;
X
X				yy_act = YY_STATE_EOF((yy_start - 1) / 2);
X				goto do_action;
X				}
X
X			    else
X				YY_NEW_FILE;
X			    }
X			    break;
X
X			case EOB_ACT_RESTART_SCAN:
X			    yy_c_buf_p = yytext;
X			    yy_hold_char = *yy_c_buf_p;
X			    break;
X
X			case EOB_ACT_LAST_MATCH:
X			    yy_c_buf_p = &yy_ch_buf[yy_n_chars];
X
X			    yy_current_state = yy_get_previous_state();
X
X			    yy_cp = yy_c_buf_p;
X			    yy_bp = yytext;
X			    continue; /* go to "YY_DO_BEFORE_ACTION" */
X			}
X		    break;
X
X		default:
X		    printf( "action # %d\n", yy_act );
X		    YY_FATAL_ERROR( "fatal flex scanner internal error" );
X		}
X
X	    break; /* exit bogus while loop */
X	    }
X	}
X    }
X
X
X/* yy_get_next_buffer - try to read in new buffer
X *
X * synopsis
X *     int yy_get_next_buffer();
X *     
X * returns a code representing an action
X *     EOB_ACT_LAST_MATCH - 
X *     EOB_ACT_RESTART_SCAN - restart the scanner
X *     EOB_ACT_END_OF_FILE - end of file
X */
X
Xstatic int yy_get_next_buffer()
X
X    {
X    register char *dest = yy_ch_buf;
X    register 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_ch_buf[yy_n_chars + 1] )
X	{
X	YY_FATAL_ERROR( "NULL in input" );
X	/*NOTREACHED*/
X	}
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_eof_has_been_seen )
X	/* don't do the read, it's not guaranteed to return an EOF,
X	 * just force an EOF
X	 */
X	yy_n_chars = 0;
X
X    else
X	{
X	int num_to_read = 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	/* read in more data */
X	YY_INPUT( (&yy_ch_buf[number_to_move]), yy_n_chars, num_to_read );
X	}
X
X    if ( yy_n_chars == 0 )
X	{
X	if ( number_to_move == 1 )
X	    ret_val = EOB_ACT_END_OF_FILE;
X	else
X	    ret_val = EOB_ACT_LAST_MATCH;
X
X	yy_eof_has_been_seen = 1;
X	}
X
X    else
X	ret_val = EOB_ACT_RESTART_SCAN;
X
X    yy_n_chars += number_to_move;
X    yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
X    yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
X
X    /* yytext begins at the second character in
X     * yy_ch_buf; the first character is the one which
X     * preceded it before reading in the latest buffer;
X     * it needs to be kept around in case it's a
X     * newline, so yy_get_previous_state() will have
X     * with '^' rules active
X     */
X
X    yytext = &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 char *yy_cp;
X
X%% code to get the start state into yy_current_state goes here
X
X    for ( yy_cp = yytext; 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#ifdef __STDC__
Xstatic void yyunput( int c, register char *yy_bp )
X#else
Xstatic void yyunput( c, yy_bp )
Xint c;
Xregister char *yy_bp;
X#endif
X
X    {
X    register char *yy_cp = yy_c_buf_p;
X
X    *yy_cp = yy_hold_char; /* undo effects of setting up yytext */
X
X    if ( yy_cp < yy_ch_buf + 2 )
X	{ /* need to shift things up to make room */
X	register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
X	register char *dest = &yy_ch_buf[YY_BUF_SIZE + 2];
X	register char *source = &yy_ch_buf[number_to_move];
X
X	while ( source > yy_ch_buf )
X	    *--dest = *--source;
X
X	yy_cp += dest - source;
X	yy_bp += dest - source;
X
X	if ( yy_cp < 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    YY_DO_BEFORE_ACTION; /* set up yytext again */
X    }
X
X
Xstatic int input()
X
X    {
X    int c;
X    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	{ /* need more input */
X	yytext = yy_c_buf_p;
X	++yy_c_buf_p;
X
X	switch ( yy_get_next_buffer() )
X	    {
X	    /* this code, unfortunately, is somewhat redundant with
X	     * that above
X	     */
X	    case EOB_ACT_END_OF_FILE:
X		{
X		if ( yywrap() )
X		    {
X		    yy_c_buf_p = yytext;
X		    return ( EOF );
X		    }
X
X		yy_ch_buf[0] = '\n';
X		yy_n_chars = 1;
X		yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
X		yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
X		yy_eof_has_been_seen = 0;
X		yytext = yy_c_buf_p = &yy_ch_buf[1];
X		yy_hold_char = *yy_c_buf_p;
X
X		return ( input() );
X		}
X		break;
X
X	    case EOB_ACT_RESTART_SCAN:
X		yy_c_buf_p = yytext;
X		break;
X
X	    case EOB_ACT_LAST_MATCH:
X		YY_FATAL_ERROR( "unexpected last match in input()" );
X	    }
X	}
X
X    c = *yy_c_buf_p;
X    yy_hold_char = *++yy_c_buf_p;
X
X    return ( c );
X    }
X
X
X#ifdef __STDC__
Xstatic void yyrestart( FILE *input_file )
X#else
Xstatic void yyrestart( input_file )
XFILE *input_file;
X#endif
X
X    {
X    if ( yyin != stdin )
X	fclose( yyin );
X
X    yyin = input_file;
X    yy_init = 1;
X    }
END_OF_FILE
if test 11297 -ne `wc -c <'flex/flex.skel'`; then
    echo shar: \"'flex/flex.skel'\" unpacked with wrong size!
fi
# end of 'flex/flex.skel'
fi
if test -f 'flex/misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flex/misc.c'\"
else
echo shar: Extracting \"'flex/misc.c'\" \(12468 characters\)
sed "s/^X//" >'flex/misc.c' <<'END_OF_FILE'
X/* misc - miscellaneous flex routines */
X
X/*
X * Copyright (c) 1989 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 to
X * contract no. DE-AC03-76SF00098 between the United States Department of
X * Energy and the University of California.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
X
Xstatic char copyright[] =
X    "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
Xstatic char CR_continuation[] = "@(#) All rights reserved.\n";
X
Xstatic char rcsid[] =
X    "@(#) $Header: misc.c,v 2.0 89/06/20 15:50:00 vern Locked $ (LBL)";
X
X#endif
X
X#include <ctype.h>
X#include "flexdef.h"
X
Xchar *malloc(), *realloc();
X
X
X/* action_out - write the actions from the temporary file to lex.yy.c
X *
X * synopsis
X *     action_out();
X *
X *     Copies the action file up to %% (or end-of-file) to lex.yy.c
X */
X
Xaction_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
Xchar *allocate_array( size, element_size )
Xint size, element_size;
X
X    {
X    register char *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 = 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 ( ! 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 ( ! isupper( *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
Xbubble( 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(), c;
X *    c = clower( c );
X */
X
Xchar clower( c )
Xregister char c;
X
X    {
X    return ( isupper(c) ? tolower(c) : c );
X    }
X
X
X/* copy_string - returns a dynamically allocated copy of a string
X *
X * synopsis
X *    char *str, *copy, *copy_string();
X *    copy = copy_string( str );
X */
X
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/* cshell - shell sort a character array in increasing order
X *
X * synopsis
X *
X *   char v[n];
X *   int n;
X *   cshell( v, n );
X *
X * description
X *   does a shell sort of the first n elements of array v.
X *
X * passed
X *   v - array to be sorted
X *   n - number of elements of v to be sorted
X */
Xcshell( v, n )
Xchar v[];
Xint n;
X
X    {
X    int gap, i, j, jg;
X    char k;
X
X    for ( gap = n / 2; gap > 0; gap = gap / 2 )
X	for ( i = gap; i < n; ++i )
X	    for ( j = i - gap; j >= 0; j = j - gap )
X		{
X		jg = j + gap;
X
X		if ( v[j] <= v[jg] )
X		    break;
X
X		k = v[j];
X		v[j] = v[jg];
X		v[jg] = k;
X		}
X    }
X
X
X/* dataend - finish up a block of data declarations
X *
X * synopsis
X *    dataend();
X */
Xdataend()
X
X    {
X    if ( datapos > 0 )
X	dataflush();
X
X    /* add terminator for initialization */
X    puts( "    } ;\n" );
X
X    dataline = 0;
X    }
X
X
X
X/* dataflush - flush generated data statements
X *
X * synopsis
X *    dataflush();
X */
Xdataflush()
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/* 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
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
Xlerrif( 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
Xlerrsf( 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/* flexerror - report an error message and terminate
X *
X * synopsis
X *    char msg[];
X *    flexerror( msg );
X */
X
Xflexerror( msg )
Xchar msg[];
X
X    {
X    fprintf( stderr, "flex: %s\n", 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
Xflexfatal( msg )
Xchar msg[];
X
X    {
X    fprintf( stderr, "flex: fatal internal error %s\n", msg );
X    flexend( 1 );
X    }
X
X
X/* line_directive_out - spit out a "# line" statement */
X
Xline_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 */
Xmk2data( 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 */
Xmkdata( 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( 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 '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	    { /* \<octal> */
X	    char c, esc_char;
X	    register int sptr = 1;
X
X	    while ( 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	    esc_char = otoi( array + 1 );
X	    array[sptr] = c;
X
X	    if ( esc_char == '\0' )
X		{
X		synerr( "escape sequence for null not allowed" );
X		return ( 1 );
X		}
X
X	    return ( esc_char );
X	    }
X
X	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( 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		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
Xchar *reallocate_array( array, size, element_size )
Xchar *array;
Xint size, element_size;
X
X    {
X    register char *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 = realloc( 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 */
Xskelout()
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
Xtransition_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 12468 -ne `wc -c <'flex/misc.c'`; then
    echo shar: \"'flex/misc.c'\" unpacked with wrong size!
fi
# end of 'flex/misc.c'
fi
if test -f 'flex/parse.y' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flex/parse.y'\"
else
echo shar: Extracting \"'flex/parse.y'\" \(13366 characters\)
sed "s/^X//" >'flex/parse.y' <<'END_OF_FILE'
X/* parse.y - parser for flex input */
X
X/*
X * Copyright (c) 1989 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 to
X * contract no. DE-AC03-76SF00098 between the United States Department of
X * Energy and the University of California.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP
X
X%{
X
X#include "flexdef.h"
X
X#ifndef lint
X
Xstatic char copyright[] =
X    "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
Xstatic char CR_continuation[] = "@(#) All rights reserved.\n";
X
Xstatic char rcsid[] =
X    "@(#) $Header: parse.y,v 2.1 89/06/20 17:23:54 vern Exp $ (LBL)";
X
X#endif
X
Xint pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
Xint trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
Xchar clower();
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 '^' re eol 
X                        {
X			pat = link_machines( $3, $4 );
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				fprintf( stderr,
X			"'^' operator results in sub-optimal performance\n" );
X			    }
X			}
X
X		|  scon re eol 
X                        {
X			pat = link_machines( $2, $3 );
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                |  '^' re eol 
X			{
X			pat = link_machines( $2, $3 );
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				fprintf( stderr,
X			"'^' operator results in sub-optimal performance\n" );
X			    }
X			}
X
X                |  re eol 
X			{
X			pat = link_machines( $1, $2 );
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 only to the INITIAL start cond. */
X			actvsc[actvp = 1] = 1;
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			    lerrsf( "undeclared start condition %s", nmstr );
X
X			else
X			    actvsc[++actvp] = scnum;
X			}
X
X		|  NAME
X			{
X			if ( (scnum = sclookup( nmstr )) == 0 )
X			    lerrsf( "undeclared start condition %s", nmstr );
X			else
X			    actvsc[actvp = 1] = scnum;
X			}
X
X		|  error
X			{ synerr( "bad start condition list" ); }
X		;
X
Xeol             :  '$'
X                        {
X			if ( trlcontxt )
X			    {
X			    synerr( "trailing context used twice" );
X			    $$ = mkstate( SYM_EPSILON );
X			    }
X			else
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( eps, mkstate( '\n' ) );
X			    }
X			}
X
X		|
X		        {
X		        $$ = mkstate( SYM_EPSILON );
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
Xre              :  re '|' series
X                        {
X			varlength = true;
X
X			$$ = mkor( $1, $3 );
X			}
X
X		|  re2 series
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    "flex: warning - trailing context rule at line %d made variable because\n",
X					 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			    }
X
X			$$ = link_machines( $1, $2 );
X			}
X
X		|  series
X			{ $$ = $1; }
X		;
X
X
Xre2		:  re '/'
X			{
X			/* this rule is separate from the others for "re" so
X			 * that 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 );
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] );
X
X			if ( useecs )
X			    mkeccl( ccltbl + cclmap[$1], ccllen[$1],
X				    nextecm, ecgroup, 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 ( $1 == '\0' )
X			    synerr( "null in rule" );
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
Xbuild_eof_action()
X
X    {
X    register int i;
X
X    for ( i = 1; i <= actvp; ++i )
X	{
X	if ( sceof[actvsc[i]] )
X	    lerrsf( "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 *
X * synopsis
X *    char str[];
X *    synerr( str );
X */
X
Xsynerr( str )
Xchar str[];
X
X    {
X    syntaxerror = true;
X    fprintf( stderr, "Syntax error at line %d: %s\n", linenum, str );
X    }
X
X
X/* yyerror - eat up an error message from the parser
X *
X * synopsis
X *    char msg[];
X *    yyerror( msg );
X */
X
Xyyerror( msg )
Xchar msg[];
X
X    {
X    }
END_OF_FILE
if test 13366 -ne `wc -c <'flex/parse.y'`; then
    echo shar: \"'flex/parse.y'\" unpacked with wrong size!
fi
# end of 'flex/parse.y'
fi
echo shar: End of archive 2 \(of 7\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.