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.