home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume19
/
flex2
/
part02
< prev
next >
Wrap
Text File
|
1989-06-21
|
41KB
|
1,917 lines
Subject: v19i056: Flex, a fast LEX replacement, Part02/07
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
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