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.