From: Philip Homburg Date: Mon, 11 Jul 2005 12:54:10 +0000 (+0000) Subject: Flex-2.5.4. X-Git-Tag: v3.1.0~633 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=054e68baf67aa7c3eff094f6031f925d7e2a04f8;p=minix.git Flex-2.5.4. --- diff --git a/commands/Makefile b/commands/Makefile index e3a6860a2..75c1f3e94 100755 --- a/commands/Makefile +++ b/commands/Makefile @@ -1,6 +1,7 @@ # Makefile for commands. MAKE = exec make -$(MAKEFLAGS) +FLEX=flex-2.5.4 GZIP=gzip-1.2.4 PYTHON=python-1.5.2 @@ -11,10 +12,12 @@ usage: @false all install:: + cd $(FLEX) && ./configure --prefix=/usr && make $@ cd $(GZIP) && ./configure --prefix=/usr && make $@ cd $(PYTHON) && ./configure --prefix=/usr/local && make $@ clean:: + if [ -f $(FLEX)/Makefile ] ; then cd $(FLEX) && make $@; fi if [ -f $(GZIP)/Makefile ] ; then cd $(GZIP) && make $@; fi if [ -f $(PYTHON)/Makefile ] ; then cd $(PYTHON) && make $@; fi @@ -34,7 +37,6 @@ all install clean:: cd dis88 && $(MAKE) $@ cd elle && $(MAKE) $@ cd elvis && $(MAKE) $@ - cd flex-2.3.7 && $(MAKE) $@ cd ftp && $(MAKE) $@ cd ftpd && $(MAKE) $@ cd ftpd200 && $(MAKE) $@ diff --git a/commands/flex-2.5.4/COPYING b/commands/flex-2.5.4/COPYING new file mode 100644 index 000000000..c041f02c4 --- /dev/null +++ b/commands/flex-2.5.4/COPYING @@ -0,0 +1,38 @@ +Flex carries the copyright used for BSD software, slightly modified +because it originated at the Lawrence Berkeley (not Livermore!) Laboratory, +which operates under a contract with the Department of Energy: + + Copyright (c) 1990 The Regents of the University of California. + All rights reserved. + + This code is derived from software contributed to Berkeley by + Vern Paxson. + + The United States Government has rights in this work pursuant + to contract no. DE-AC03-76SF00098 between the United States + Department of Energy and the University of California. + + Redistribution and use in source and binary forms with or without + modification are permitted provided that: (1) source distributions + retain this entire copyright notice and comment, and (2) + distributions including binaries display the following + acknowledgement: ``This product includes software developed by the + University of California, Berkeley and its contributors'' in the + documentation or other materials provided with the distribution and + in all advertising materials mentioning features or use of this + software. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. + +This basically says "do whatever you please with this software except +remove this notice or take advantage of the University's (or the flex +authors') name". + +Note that the "flex.skl" scanner skeleton carries no copyright notice. +You are free to do whatever you please with scanners generated using flex; +for them, you are not even bound by the above copyright. diff --git a/commands/flex-2.5.4/FlexLexer.h b/commands/flex-2.5.4/FlexLexer.h new file mode 100644 index 000000000..549177b8b --- /dev/null +++ b/commands/flex-2.5.4/FlexLexer.h @@ -0,0 +1,186 @@ +// $Header$ + +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms with or without +// modification are permitted provided that: (1) source distributions retain +// this entire copyright notice and comment, and (2) distributions including +// binaries display the following acknowledgement: ``This product includes +// software developed by the University of California, Berkeley and its +// contributors'' in the documentation or other materials provided with the +// distribution and in all advertising materials mentioning features or use +// of this software. Neither the name of the University nor the names of +// its contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H +#include + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() { return yytext; } + int YYLeng() { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( istream* new_in, ostream* new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( istream* new_in = 0, + ostream* new_out = 0 ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex man page. +#define yyFlexLexerOnce + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( istream* s ); + + virtual int yylex(); + virtual void switch_streams( istream* new_in, ostream* new_out ); + +protected: + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state* b, istream* s ); + void yy_flush_buffer( struct yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + istream* yyin; // input source for default LexerInput + ostream* yyout; // output sink for default LexerOutput + + struct yy_buffer_state* yy_current_buffer; + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +#endif diff --git a/commands/flex-2.5.4/INSTALL b/commands/flex-2.5.4/INSTALL new file mode 100644 index 000000000..6e7ed85d2 --- /dev/null +++ b/commands/flex-2.5.4/INSTALL @@ -0,0 +1,117 @@ +This is a generic INSTALL file for utilities distributions. +If this package does not come with, e.g., installable documentation or +data files, please ignore the references to them below. + +To compile this package: + +1. Configure the package for your system. In the directory that this +file is in, type `./configure'. If you're using `csh' on an old +version of System V, you might need to type `sh configure' instead to +prevent `csh' from trying to execute `configure' itself. + +The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation, and +creates the Makefile(s) (one in each subdirectory of the source +directory). In some packages it creates a C header file containing +system-dependent definitions. It also creates a file `config.status' +that you can run in the future to recreate the current configuration. + +Running `configure' takes a minute or two. While it is running, it +prints some messages that tell what it is doing. If you don't want to +see the messages, run `configure' with its standard output redirected +to `/dev/null'; for example, `./configure >/dev/null'. + +To compile the package in a different directory from the one +containing the source code, you must use a version of `make' that +supports the VPATH variable, such as GNU `make'. `cd' to the directory +where you want the object files and executables to go and run +`configure'. `configure' automatically checks for the source code in +the directory that `configure' is in and in `..'. If for some reason +`configure' is not in the source code directory that you are +configuring, then it will report that it can't find the source code. +In that case, run `configure' with the option `--srcdir=DIR', where +DIR is the directory that contains the source code. + +By default, `make install' will install the package's files in +/usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify +an installation prefix other than /usr/local by giving `configure' the +option `--prefix=PATH'. Alternately, you can do so by giving a value +for the `prefix' variable when you run `make', e.g., + make prefix=/usr/gnu + +You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If +you give `configure' the option `--exec-prefix=PATH' or set the +`make' variable `exec_prefix' to PATH, the package will use PATH as +the prefix for installing programs and libraries. Data files and +documentation will still use the regular prefix. Normally, all files +are installed using the regular prefix. + +Another `configure' option is useful mainly in `Makefile' rules for +updating `config.status' and `Makefile'. The `--no-create' option +figures out the configuration for your system and records it in +`config.status', without actually configuring the package (creating +`Makefile's and perhaps a configuration header file). Later, you can +run `./config.status' to actually configure the package. You can also +give `config.status' the `--recheck' option, which makes it re-run +`configure' with the same arguments you used before. This option is +useful if you change `configure'. + +Some packages pay attention to `--with-PACKAGE' options to `configure', +where PACKAGE is something like `gnu-libc' or `x' (for X windows). +The README should mention any --with- options that the package recognizes. + +`configure' ignores any other arguments that you give it. + +If your system requires unusual options for compilation or linking +that `configure' doesn't know about, you can give `configure' initial +values for some variables by setting them in the environment. In +Bourne-compatible shells, you can do that on the command line like +this: + CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure + +The `make' variables that you might want to override with environment +variables when running `configure' are: + +(For these variables, any value given in the environment overrides the +value that `configure' would choose:) +CC C compiler program. + Default is `cc', or `gcc' if `gcc' is in your PATH. +INSTALL Program to use to install files. + Default is `install' if you have it, `cp' otherwise. + +(For these variables, any value given in the environment is added to +the value that `configure' chooses:) +DEFS Configuration options, in the form `-Dfoo -Dbar ...' + Do not use this variable in packages that create a + configuration header file. +LIBS Libraries to link with, in the form `-lfoo -lbar ...' + +If you need to do unusual things to compile the package, we encourage +you to figure out how `configure' could check whether to do them, and +mail diffs or instructions to the address given in the README so we +can include them in the next release. + +2. Type `make' to compile the package. If you want, you can override +the `make' variables CFLAGS and LDFLAGS like this: + + make CFLAGS=-O2 LDFLAGS=-s + +3. If the package comes with self-tests and you want to run them, +type `make check'. If you're not sure whether there are any, try it; +if `make' responds with something like + make: *** No way to make target `check'. Stop. +then the package does not come with self-tests. + +4. Type `make install' to install programs, data files, and +documentation. + +5. You can remove the program binaries and object files from the +source directory by typing `make clean'. To also remove the +Makefile(s), the header file containing system-dependent definitions +(if the package uses one), and `config.status' (all the files that +`configure' created), type `make distclean'. + +The file `configure.in' is used as a template to create `configure' by +a program called `autoconf'. You will only need it if you want to +regenerate `configure' using a newer version of `autoconf'. diff --git a/commands/flex-2.5.4/MISC/Amiga/README.amiga b/commands/flex-2.5.4/MISC/Amiga/README.amiga new file mode 100644 index 000000000..0efdb9383 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Amiga/README.amiga @@ -0,0 +1,72 @@ + +This file, ./MISC/Amiga/README.amiga, describes the necessary steps to get +the FLEX 2.5.1 program up and running on the Commodore AMIGA with the +help of SAS/C++ 6.51 and SMake 6.50. Also it describes the contents of the +subdirectory ./MISC/Amiga, where `.' denotes the root directory of the +standard installation of FLEX 2.5.1. + + +FILES ADDED FOR INSTALLING FLEX 2.5.1 ON THE AMIGA + +The standard distribution of FLEX 2.5.1 is assumed to be installed on +your AMIGA computer. `Installed' means that all source files from the +original archive are present in a root directory (denoted by `.' in what +follows) and, if appropriate, one or more subdirectories, on your machine. + +The original source files are totally left untouched, the necessary changes +are applied in the form of `change files'. For installing FLEX 2.5.1 on +the AMIGA, several additional files come with this patch. + + -----rw-d 2 738 Apr 3 11:49 config.h + -----rw-d 1 169 Apr 3 11:33 libmain.ch + -----rw-d 1 159 Apr 3 11:33 libyywrap.ch + -----rw-d 1 167 Apr 3 11:33 parse.ych + -----rw-d 6 2840 Apr 3 11:34 README.amiga + -----rw-d 11 5503 Apr 3 11:45 smakefile + Dirs:0 Files:6 Blocks:22 Bytes:9576 + + +HOW TO INSTALL FLEX 2.5.1 ON THE AMIGA + +Copy all files from ./MISC/Amiga to the root directory of the FLEX 2.5.1 +distribution and edit `SMakefile' as it instructs you. There shouldn't be +too many changes necessary. Then say "make bootflex". This creates a +preliminary version of FLEX 2.5.1 without using itself. + +WARNING: Don't say "make flex" yet. Any pre-2.5 version of FLEX will fail +on the file `scan.l' due to some new features only present in FLEX 2.5. + +Then say "make flex". At least once the FLEX program created in the first +step will be used. To make sure that everything is alright, finally say +"make check". If you change the code, you should also say "make bigcheck" +for some more thorough testing. + +When you are satisfied with the results, say "make install". This will +copy the `flex' binary, the `libfl.lib' file, and the `FlexLexer.h' header +to the paths specified in the `SMakefile'. + +Finally, you should say "make clean" to remove all intermediate files from +the root directory. "make veryclean" also removes `flex' and `scan.c'. + + +TROUBLE SHOOTING + +FLEX 2.5.1 was ported to the AMIGA and tested with the following setup: + + AMIGA 2000 + GVP G-Force 030/50/50/8 + SAS/C++ 6.51 + SED 2.05 + BISON 1.22 + WMERGE from the CWEB distribution + +Should you encounter problems with this AMIGA patch for FLEX 2.5.1 or +should you have ideas for further improvements, like using GnuMake instead +of SMake, contact the author of this contribution + +Andreas Scherer +Roland-Stra{\ss}e 16 +52070 Aachen +Germany + + (Internet) diff --git a/commands/flex-2.5.4/MISC/Amiga/SMakefile b/commands/flex-2.5.4/MISC/Amiga/SMakefile new file mode 100644 index 000000000..fc6c1ef60 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Amiga/SMakefile @@ -0,0 +1,195 @@ +# @(#) $Header$ (LBL) + +# If your version of "make" does not define $(MAKE), comment in the +# definition of "MAKE" below. (You only need to do this if you intend +# to do "make bigcheck" or "make dist".) +MAKE = smake + +# Possible values for DEFS: +# +# For flex to always generate 8-bit scanners, add "-DDEFAULT_CSIZE=256" +# to DEFS. +# +# For Vax/VMS, add "-DVMS" to DEFS. +# +# For MS-DOS, add "-DMS_DOS" to DEFS. See the directory MISC/MSDOS for +# additional info. + +CFLAGS = data=far ignore=85 noicons stackextend optimize +DEFS = define=YYBISON=1 define=YY_NEVER_INTERACTIVE=1 +LDFLAGS = noicons +LIBS = + +# Installation targeting. Files will be installed under the tree +# rooted at prefix. flex will be installed in bindir, libfl.lib in +# libdir, FlexLexer.h will be installed in includedir, and the manual +# pages will be installed in mandir with extension manext. +# +# Raw, unformatted troff source will be installed if INSTALLMAN=man, +# nroff preformatted versions will be installed if INSTALLMAN=cat. + +prefix = Programmer:other # Change this for your AMIGA system. +exec_prefix = $(prefix) +bindir = $(exec_prefix)/bin +libdir = $(exec_prefix)/lib +includedir = $(prefix)/include +manext = 1 +mandir = $(prefix)/man/man$(manext) + +# You can define this to be "lex" if you want to replace lex at your site. +FLEX = flex + +INSTALLMAN = man + +SHELL = +srcdir = . +VPATH = + +LN_S = +YACC = bison -y +SED = sed +CC = sc +WMERGE = wmerge # from the CWEB distribution +AR = oml +RANLIB = +INSTALL = copy clone +INSTALL_DATA = $(INSTALL) +INSTALL_PROGRAM = $(INSTALL) + +# You normally do not need to modify anything below this point. +# ------------------------------------------------------------ + +CPPFLAGS = idir=. idir=$(srcdir) $(DEFS) + +.c.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $< + +HEADERS = flexdef.h version.h + +SOURCES = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.y \ + scan.l skel.c sym.c tblcmp.c yylex.c +OBJECTS = ccl.o dfa.o ecs.o gen.o main.o misc.o nfa.o parse.o \ + skel.o sym.o tblcmp.o yylex.o \ + $(libdir)/alloca.o $(libdir)/xmalloc.o + +LIBSRCS = libmain.c libyywrap.c +LIBOBJS = ansilibmain.o ansilibyywrap.o + +LINTSRCS = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.c \ + scan.c skel.c sym.c tblcmp.c yylex.c + +DISTFILES = README NEWS COPYING INSTALL FlexLexer.h \ + configure.in conf.in Makefile.in mkskel.sh skel.c flex.skl \ + $(HEADERS) $(SOURCES) $(LIBSRCS) MISC \ + flex.1 scan.c install.sh mkinstalldirs configure + +DIST_NAME = flex + +# which "flex" to use to generate scan.c from scan.l +FLEX_EXEC = ./$(FLEX) +FLEX_FLAGS = -t $(PERF_REPORT) +COMPRESSION = +PERF_REPORT = -p + +FLEXLIB = libfl.lib + +all: $(FLEX) + +$(FLEX): $(OBJECTS) $(FLEXLIB) scan.o + $(CC) $(CFLAGS) link to $(FLEX) $(LDFLAGS) $(OBJECTS) scan.o $(FLEXLIB) $(LIBS) + +bootflex: $(OBJECTS) $(FLEXLIB) initscan.o + $(CC) $(CFLAGS) link to $(FLEX) $(LDFLAGS) $(OBJECTS) initscan.o $(FLEXLIB) $(LIBS) + +parse.c: ansiparse.y + $(YACC) -d ansiparse.y + $(SED) "/extern char.*malloc/d" parse.tmp + copy parse.tmp parse.c + copy y.tab.h parse.h + @delete y.tab.c y.tab.h parse.tmp +ansiparse.y: $(srcdir)/parse.y parse.ych + $(WMERGE) $(srcdir)/parse.y parse.ych ansiparse.y + +parse.h: parse.c + +scan.c: scan.l + $(FLEX_EXEC) $(FLEX_FLAGS) $(COMPRESSION) $(srcdir)/scan.l >scan.tmp + $(SED) s,\"$(srcdir)/scan.l\",\"scan.l\", scan.c + @delete scan.tmp + +scan.o: scan.c parse.h flexdef.h config.h +initscan.o: initscan.c parse.h flexdef.h config.h +yylex.o: yylex.c parse.h flexdef.h config.h + +skel.c: flex.skl mkskel.sh + $(SHELL) $(srcdir)/mkskel.sh $(srcdir)/flex.skl >skel.c + +main.o: main.c flexdef.h config.h version.h +ccl.o: ccl.c flexdef.h config.h +dfa.o: dfa.c flexdef.h config.h +ecs.o: ecs.c flexdef.h config.h +gen.o: gen.c flexdef.h config.h +misc.o: misc.c flexdef.h config.h +nfa.o: nfa.c flexdef.h config.h +parse.o: parse.c flexdef.h config.h +skel.o: skel.c flexdef.h config.h +sym.o: sym.c flexdef.h config.h +tblcmp.o: tblcmp.c flexdef.h config.h + +alloca.o: alloca.c + $(CC) $(CPPFLAGS) $(CFLAGS) define=xmalloc=yy_flex_xmalloc alloca.c + +alloca.c: $(srcdir)/MISC/alloca.c + @delete alloca.c + copy $(srcdir)/MISC/alloca.c . + +test: check +check: flex + $(FLEX_EXEC) $(FLEX_FLAGS) $(COMPRESSION) $(srcdir)/scan.l > temp_a + $(SED) s,"$(srcdir)/scan.l","scan.l", < temp_a > temp_b + -diff scan.c temp_b -l10000 -w + @delete temp_? + @echo "Check successful, using COMPRESSION='$(COMPRESSION)'" + +bigcheck: + delete scan.c + $(MAKE) COMPRESSION=-C check + delete scan.c + $(MAKE) COMPRESSION=-Ce check + delete scan.c + $(MAKE) COMPRESSION=-Cm check + delete scan.c + $(MAKE) COMPRESSION=-Cfea check + delete scan.c + $(MAKE) COMPRESSION=-CFer check + delete scan.c + $(MAKE) COMPRESSION=-l PERF_REPORT= check + delete scan.c + $(MAKE) + @echo "All checks successful" + +$(FLEXLIB): $(LIBOBJS) + $(AR) $(FLEXLIB) R $(LIBOBJS) + +$(FLEX).man: flex.1 # SMAKE can't `cd', sorry. And, I don't have nroff. +# cd $(srcdir), nroff -man flex.1 >$(FLEX).man + +install: $(FLEX) $(FLEXLIB) + $(INSTALL_PROGRAM) $(FLEX) $(bindir)/$(FLEX) +# @delete $(bindir)/$(FLEX)++ + $(INSTALL_DATA) $(FLEXLIB) $(libdir)/libfl.lib + $(INSTALL_DATA) $(srcdir)/FlexLexer.h $(includedir)/FlexLexer.h + +ansilibmain.o: ansilibmain.c +ansilibmain.c: libmain.c libmain.ch + $(WMERGE) libmain.c libmain.ch ansilibmain.c +ansilibyywrap.o: ansilibyywrap.c +ansilibyywrap.c: libyywrap.c libyywrap.ch + $(WMERGE) libyywrap.c libyywrap.ch ansilibyywrap.c + +clean: + -delete parse.(c|h) ansi\#? \#?.(bak|o|lnk) \ + alloca.c lex.yy.(c|cc) $(FLEXLIB) + +veryclean: clean + -delete $(FLEX) scan.c diff --git a/commands/flex-2.5.4/MISC/Amiga/config.h b/commands/flex-2.5.4/MISC/Amiga/config.h new file mode 100644 index 000000000..8eb279fcf --- /dev/null +++ b/commands/flex-2.5.4/MISC/Amiga/config.h @@ -0,0 +1,25 @@ +/* $Header$ */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if platform-specific command line handling is necessary. */ +#undef NEED_ARGV_FIXUP diff --git a/commands/flex-2.5.4/MISC/Amiga/libmain.ch b/commands/flex-2.5.4/MISC/Amiga/libmain.ch new file mode 100644 index 000000000..e0f5b4090 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Amiga/libmain.ch @@ -0,0 +1,8 @@ +Changes for LIBMAIN.C 2.4.7 by Andreas Scherer, January 19, 1995. +Modified for LIBMAIN.C 2.5.1, April 3, 1995. + +@x l.5 +extern int yylex(); +@y +extern int yylex(void); +@z diff --git a/commands/flex-2.5.4/MISC/Amiga/libyywrap.ch b/commands/flex-2.5.4/MISC/Amiga/libyywrap.ch new file mode 100644 index 000000000..b2d6a3fe3 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Amiga/libyywrap.ch @@ -0,0 +1,8 @@ +Changes for LIBYYWRAP.C 2.4.7 by Andreas Scherer, January 19, 1995. +Modified for LIBYYWRAP.C 2.5.1, April 3, 1995. + +@x l.5 +int yywrap() +@y +int yywrap(void) +@z diff --git a/commands/flex-2.5.4/MISC/Amiga/parse.ych b/commands/flex-2.5.4/MISC/Amiga/parse.ych new file mode 100644 index 000000000..5671a5b1e --- /dev/null +++ b/commands/flex-2.5.4/MISC/Amiga/parse.ych @@ -0,0 +1,8 @@ +Changes for PARSE.Y 2.4.7 by Andreas Scherer, January 20, 1995. +Modified for PARSE.Y 2.5.1, April 3, 1995. + +@x l.60 +char *alloca (); +@y +char *alloca(unsigned int); +@z diff --git a/commands/flex-2.5.4/MISC/Atari/Atari.patches b/commands/flex-2.5.4/MISC/Atari/Atari.patches new file mode 100644 index 000000000..69e9ceb45 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Atari/Atari.patches @@ -0,0 +1,911 @@ +(Message inbox:32) +Date: Mon, 03 Jul 89 21:15:32 CET +From: V61%DHDURZ1.BITNET@lbl.gov +Subject: Flex, bug fix, improvments, patches for Minix & TOS +To: vern@lbl-csam.arpa + +At first I have to thank you for your wonderful program. I had ported the +old version to OS9,TOS (Atari ST) and Minix and the new version 2.1 Beta +to Minix and TOS. + +While porting and using flex I detected a bug and made some improvements. +I have included a shared, compressed and uuencoded file contaning all cdiffs +and additional files (Sorry, but I'm on EBCDIC-Bitnet) and a short discussion +of the changes. Even some of the TOS specific changes might be of general +interest ! + +I posted these cdiffs to the minix discussion group, but I think it's up +to you to post them to the unix-sources group. If you plan to post even +the TOS compiler specific patches please contact me because there might be +further compiler (P.D.) additions. If you have an interest I could also +port the new version to OS9 -- this is a little bit more difficult, because +OS9 uses CR as end of line character (the EOL char. is coded into the +initscan.c tables,...). It is necessary to change all occurences of '\n' to +macros and variables and it's useful to add a new -n options (see commented +line in main.c) + + + +The changes: (1.7.89 RAL) + + - Bug fix: The original flex didn't like trailing spaces in exclusive start + condition lists ! If you add an trailing space to line 68 in scan.l + + "%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE " + + you get a misleading error message: + + "Syntax error at line 69: bad start condition list" + + This bug can either be fixed in parse.y or in scan.l . I have chosen the + last because there the fix is minimal: Just change the rule (line 128) + + "\n" to "{OPTWS}\n" + + - Enhancements: + - new option "-?" that provides some help information about the other + flags (main.c) + - new option "-aTMPPATH" that allows a redefinition of the standard + path for the temporary file (this might be rather large >200k if + F,f options are selected). (main.c, flexdef.h (l.376)) + - hexdump of illegal characters -- this proved to be a useful debugging + tool especialy if invisible control characters occur which weren't + covered by the rules. (scan.l fprintf statement line 129,...) + + - Patches due to TOS + - General: TOS uses CR,LF as end of line char., Flex wants only a single + LF as EOL char. Therefore all I/O must be translated using f* calls. + This is done everywhere besides the YY_INPUT macro (flex.skel (scan.c), + line 31) that uses a low level 'read'. This should be definitly changed + to fread, so that all I/O calls occur on the same level. + - the short action_file_name has been "flexXXXXXX.tmp", but that's too + much for TOS,MSDOS ! I changed it to "flexXXXX.tmp" in main.c (patch + covered by the -a option additions) + - some compilers don't like external names that are ambiguous within + the first 8 characters. I defined macros that change all these long + external names to names that are unique within the first 8 characters. + Just define SHORT_EXTERNAL_NAMES to use this feature (flexdef.h) + - some statement changes that some compiler don't like: + typedef *xxx[] -> typedef **xxx (flexdef.h.,l.308) + "/*" -> '/','*' within a comment in (scan.l, l.209) + - changed short "lexyy.c" to "lex_yy.c" what's more similar to the unix + "lex.yy.c" (main.c). + - a few further really compiler dependent changes provided with + #ifdef ATARI && LATTICE res. TURBO braces. + + - Additional TOS only files + - Makefile.tos: Common makefile for all TOS compilers. If you add further + ones please email me the new makefile. + - flex.lnk: Lattice - GST linker argument extension file + - flex.tlk: Turbo linker argument extension file + + +Additional remarks: + +I didn't add a new initscan.c (= flex -ist scan.l). The current one is good +enough for a first compilation. With this first version of flex you can +rebuild your own scan.c and the final flex version ! + +Minix ST : + - I had to "chmem =70000 cv" (>50000) to get flex linked + - 'memset' (PC 1.3, EFTH40,...) is necessary + - chmem =90000 flex may be sufficient + +Minix PC : + It should be possible to port Flex to Minix PC. The current sizes of flex + are: + Minix ST (ACK) Lattice (TOS) Turbo (TOS) + + size 75300 83305 57957 + compilation time 22' 15' 3'40" + flex -is scan.l 1'49" 43" 30" + + The Minix ST size includes the bad generated code using only a subset of + the 68000 commands, long addresses only and a huge relocation table. + Therefore the PC size will be <64 k ! More serious is the fact that I had + to chmem =90000 flex to get scan.l converted to scan.c . But I never saw + a more complex lex source than scan.l -- so it should be possible to + reduce some array sizes without limitation for all day usage. + + No one volunteered yet for a Minix PC port -- but if someone will try it + I would provide him with a new scan.c and some hints. + +TOS: + Don't forget to adapt the flexskel path within flexdef.h ! + + +Bitnet: V61@DHDURZ1 Ronald Lamprecht +UUCP: ...!unido!DHDURZ1.bitnet!V61 Theoretische Physik +ARPAnet: V61%DHDURZ1.BITNET@CUNYVM.CUNY.EDU (Heidelberg, West Germany) +(Message inbox:36) +Date: Wed, 05 Jul 89 21:16:07 CET +From: V61%DHDURZ1.BITNET@csa2.lbl.gov +Subject: Re: What is TOS +To: vern@lbl-csam.arpa + +TOS is the name of the Atari ST operating system that is very similar +to MSDOS (Both use CR,LF as end of line character). Therefore I have +been astonished that no EOL convertion porblems occur within MSDOS. + +I have been aware of the double buffering when changing read to fread and I +accept your argument of a possible slow down. But if you integrate the other +Atari - TOS changes, please insert a + #ifdef ATARI + fread .... + #else + read .... + #endif +in flex.skel . + +Bitnet: V61@DHDURZ1 Ronald Lamprecht +UUCP: ...!unido!DHDURZ1.bitnet!V61 Theoretische Physik +ARPAnet: V61%DHDURZ1.BITNET@CUNYVM.CUNY.EDU (Heidelberg, West Germany) + + + + +echo x - Makefile_cdiff +sed '/^X/s///' > Makefile_cdiff << '/' +X*** Src_2.1/Makefile Thu Jun 28 00:06:42 1989 +X--- Makefile Thu Jul 3 02:12:48 1989 +X*************** +X*** 5,10 **** +X--- 5,11 ---- +X # Porting considerations: +X # +X # For System V Unix machines, add -DSYS_V to CFLAGS. +X+ # For Minix (ST), add -DSYS_V to CFLAGS +X # For Vax/VMS, add -DSYS_V to CFLAGS. +X # For MS-DOS, add "-DMS_DOS -DSYS_V" to CFLAGS. Create \tmp if not present. +X # You will also want to rename flex.skel to something with a three +X*************** +X*** 21,28 **** +X SKELETON_DIR = /usr/local/lib +X SKELETON_FILE = flex.skel +X SKELFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_DIR)/$(SKELETON_FILE)\" +X! CFLAGS = -O +X! LDFLAGS = -s +X +X FLEX_FLAGS = +X FLEX = ./flex +X--- 22,29 ---- +X SKELETON_DIR = /usr/local/lib +X SKELETON_FILE = flex.skel +X SKELFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_DIR)/$(SKELETON_FILE)\" +X! CFLAGS = -O -DSYS_V +X! LDFLAGS = +X +X FLEX_FLAGS = +X FLEX = ./flex +X*************** +X*** 57,63 **** +X yylex.c +X +X flex : $(FLEXOBJS) +X! $(CC) $(CFLAGS) -o flex $(LDFLAGS) $(FLEXOBJS) +X +X first_flex: +X cp initscan.c scan.c +X--- 58,65 ---- +X yylex.c +X +X flex : $(FLEXOBJS) +X! $(CC) $(CFLAGS) -o flex $(FLEXOBJS) $(LDFLAGS) +X! chmem =150000 flex +X +X first_flex: +X cp initscan.c scan.c +/ +echo x - flex.skel_cdif +sed '/^X/s///' > flex.skel_cdif << '/' +X*** Src_2.1/flex.skel Thu Jun 28 00:19:20 1989 +X--- flex.skel Thu Jul 2 22:18:31 1989 +X*************** +X*** 28,34 **** +X * is returned in "result". +X */ +X #define YY_INPUT(buf,result,max_size) \ +X! if ( (result = read( fileno(yyin), buf, max_size )) < 0 ) \ +X YY_FATAL_ERROR( "read() in flex scanner failed" ); +X #define YY_NULL 0 +X #define yyterminate() return ( YY_NULL ) +X--- 28,34 ---- +X * is returned in "result". +X */ +X #define YY_INPUT(buf,result,max_size) \ +X! if ( (result = fread( buf,1, max_size, yyin )) < 0 ) \ +X YY_FATAL_ERROR( "read() in flex scanner failed" ); +X #define YY_NULL 0 +X #define yyterminate() return ( YY_NULL ) +/ +echo x - flexdef.h_cdif +sed '/^X/s///' > flexdef.h_cdif << '/' +X*** Src_2.1/flexdef.h Thu Jun 28 00:43:27 1989 +X--- flexdef.h Thu Jul 3 02:45:50 1989 +X*************** +X*** 26,31 **** +X--- 26,40 ---- +X +X /* @(#) $Header$ (LBL) */ +X +X+ #ifdef ATARI +X+ #define SYS_V +X+ #define abs(x) ((x) < 0 ? -(x) : (x)) +X+ #define SHORT_FILE_NAMES +X+ #ifdef TURBO +X+ #define SHORT_EXTERNAL_NAMES +X+ #endif +X+ #endif +X+ +X #ifndef FILE +X #include +X #endif +X*************** +X*** 41,47 **** +X #endif +X +X #ifndef VMS +X! char *memset(); +X #else +X /* memset is needed for old versions of the VMS C runtime library */ +X #define memset(s, c, n) \ +X--- 50,58 ---- +X #endif +X +X #ifndef VMS +X! #ifndef ATARI && TURBO +X! char *memset(); +X! #endif +X #else +X /* memset is needed for old versions of the VMS C runtime library */ +X #define memset(s, c, n) \ +X*************** +X*** 81,91 **** +X--- 92,129 ---- +X #define true 1 +X #define false 0 +X +X+ #ifdef ATARI +X+ #define DEFAULT_SKELETON_FILE "D:\\include\\flexskel" +X+ #endif +X+ +X +X #ifndef DEFAULT_SKELETON_FILE +X #define DEFAULT_SKELETON_FILE "flex.skel" +X #endif +X +X+ #ifdef SHORT_EXTERNAL_NAMES +X+ /* avoid long external names that are ambiguous within the first 8 characters */ +X+ #define current_mns c__mns +X+ #define current_max_rules c__max_rules +X+ #define current_max_state_type c__max_state_type +X+ #define current_max_scs c__max_scs +X+ #define current_max_dfa_size c__max__size +X+ #define current_max_xpairs c__max_xpairs +X+ #define current_max_template_xpairs c__max_template_xpairs +X+ #define current_max_dfas c__max_dfas +X+ #define current_maxccls c__maxccles +X+ #define current_max_ccl_tbl_size c__max_ccl_tbl_size +X+ #define indent_puts ind_puts +X+ #define indent_put2s ind_put2s +X+ #define gen_next_compressed_state gen_n_comressed_state +X+ #define gen_next_match gen_n_match +X+ #define gen_next_state gen_n_state +X+ #define variable_trailing_context_rules var_tr_context_rules +X+ #define variable_trailing_rule var_tr_rule +X+ #define backtrack_report backtr_report +X+ #define backtrack_file backtr_file +X+ #endif +X+ +X /* special chk[] values marking the slots taking by end-of-buffer and action +X * numbers +X */ +X*************** +X*** 305,311 **** +X int int_val; +X } ; +X +X! typedef struct hash_entry *hash_table[]; +X +X #define NAME_TABLE_HASH_SIZE 101 +X #define START_COND_HASH_SIZE 101 +X--- 343,349 ---- +X int int_val; +X } ; +X +X! typedef struct hash_entry **hash_table; +X +X #define NAME_TABLE_HASH_SIZE 101 +X #define START_COND_HASH_SIZE 101 +X*************** +X*** 372,378 **** +X extern int datapos, dataline, linenum; +X extern FILE *skelfile, *yyin, *temp_action_file, *backtrack_file; +X extern char *infilename; +X! extern char action_file_name[]; +X +X +X /* variables for stack of states having only one out-transition: +X--- 410,416 ---- +X extern int datapos, dataline, linenum; +X extern FILE *skelfile, *yyin, *temp_action_file, *backtrack_file; +X extern char *infilename; +X! extern char *action_file_name; +X +X +X /* variables for stack of states having only one out-transition: +/ +echo x - main.c_cdiff +sed '/^X/s///' > main.c_cdiff << '/' +X*** Src_2.1/main.c Thu Jun 28 00:30:39 1989 +X--- main.c Thu Jul 3 02:27:47 1989 +X*************** +X*** 81,96 **** +X FILE *temp_action_file; +X FILE *backtrack_file; +X int end_of_buffer_state; +X! #ifndef SHORT_FILE_NAMES +X! char action_file_name[] = "/tmp/flexXXXXXX"; +X! #else +X! char action_file_name[] = "flexXXXXXX.tmp"; +X! #endif +X! +X #ifndef SHORT_FILE_NAMES +X static char outfile[] = "lex.yy.c"; +X #else +X! static char outfile[] = "lexyy.c"; +X #endif +X static int outfile_created = 0; +X +X--- 81,91 ---- +X FILE *temp_action_file; +X FILE *backtrack_file; +X int end_of_buffer_state; +X! char *action_file_name; +X #ifndef SHORT_FILE_NAMES +X static char outfile[] = "lex.yy.c"; +X #else +X! static char outfile[] = "lex_yy.c"; +X #endif +X static int outfile_created = 0; +X +X*************** +X*** 328,333 **** +X--- 323,329 ---- +X { +X int i, sawcmpflag, use_stdout; +X char *arg, *skelname = NULL, *flex_gettime(), clower(), *mktemp(); +X+ char *tmp_action =(char *)0, *malloc(); +X +X printstats = syntaxerror = trace = spprdflt = interactive = caseins = false; +X backtrack_report = performance_report = ddebug = fulltbl = fullspd = false; +X*************** +X*** 349,354 **** +X--- 345,355 ---- +X for ( i = 1; arg[i] != '\0'; ++i ) +X switch ( arg[i] ) +X { +X+ case 'a': +X+ if ( i != 1 ) +X+ flexerror( "-a flag must be given separately" ); +X+ tmp_action = &arg[i+1]; +X+ goto get_next_arg; +X case 'b': +X backtrack_report = true; +X break; +X*************** +X*** 445,452 **** +X printstats = true; +X break; +X +X! default: +X! lerrif( "unknown flag %c", (int) arg[i] ); +X break; +X } +X +X--- 446,458 ---- +X printstats = true; +X break; +X +X! case '?': +X! flexinfo(0); +X! break; +X! +X! default: +X! fprintf(stderr,"flex : unknown flag %c\n", (int) arg[i] ); +X! flexinfo(1); +X break; +X } +X +X*************** +X*** 454,459 **** +X--- 460,493 ---- +X ; +X } +X +X+ +X+ /* if you change the default tmp file names don't forget to change the +X+ initialization for i, too ! +X+ +X+ */ +X+ #ifndef SHORT_FILE_NAMES +X+ i = 10; +X+ if (!tmp_action) i += 5; +X+ #else +X+ i = 12; +X+ #endif +X+ if (tmp_action) +X+ i += strlen(tmp_action) + 1; +X+ if((action_file_name = malloc(i+1)) == (char *)0) +X+ flexerror("No memory for action_file_name"); +X+ *action_file_name = (char) NULL; +X+ if (tmp_action) +X+ strcat(action_file_name,tmp_action); +X+ #ifndef SHORT_FILE_NAMES +X+ else +X+ strcat(action_file_name,"/tmp"); +X+ strcat(action_file_name,"/flexXXXXXX"); +X+ #else +X+ if (tmp_action) +X+ strcat(action_file_name,"/"); +X+ strcat(action_file_name,"flexXXXX.tmp"); +X+ #endif +X+ +X if ( (fulltbl || fullspd) && usemecs ) +X flexerror( "full table and -cm don't make sense together" ); +X +X*************** +X*** 520,526 **** +X if ( (skelfile = fopen( skelname, "r" )) == NULL ) +X lerrsf( "can't open skeleton file %s", skelname ); +X +X! (void) mktemp( action_file_name ); +X +X if ( (temp_action_file = fopen( action_file_name, "w" )) == NULL ) +X lerrsf( "can't open temporary action file %s", action_file_name ); +X--- 554,562 ---- +X if ( (skelfile = fopen( skelname, "r" )) == NULL ) +X lerrsf( "can't open skeleton file %s", skelname ); +X +X! #ifndef ATARI && LATTICE +X! (void) mktemp( action_file_name ); +X! #endif +X +X if ( (temp_action_file = fopen( action_file_name, "w" )) == NULL ) +X lerrsf( "can't open temporary action file %s", action_file_name ); +X*************** +X*** 566,571 **** +X--- 602,640 ---- +X } +X +X +X+ flexinfo(status) +X+ int status; +X+ { +X+ fprintf(stderr,"Syntax : FLEX inp_file\n"); +X+ fprintf(stderr,"Function: fast lexical analyzer generator V%s\n",flex_version); +X+ fprintf(stderr,"Options : a dir_path : directory path for temporary files\n"); +X+ fprintf(stderr," - b : generate backtracking information to lex.backtrack\n"); +X+ fprintf(stderr," - c : compressed table, no equiv., no meta equiv.classes\n"); +X+ fprintf(stderr," e : equivalence classes\n"); +X+ fprintf(stderr," F : fast table\n"); +X+ fprintf(stderr," |f : full table\n"); +X+ fprintf(stderr," |m : meta equivalence classes\n"); +X+ fprintf(stderr," - d : generate debugging scanner\n"); +X+ fprintf(stderr," - F : fast table\n"); +X+ fprintf(stderr," - f : full (not compressed) table\n"); +X+ fprintf(stderr," - I : generate interactive scanner\n"); +X+ fprintf(stderr," - i : generate case-insensitive scanner\n"); +X+ fprintf(stderr," - L : supress #line directives\n"); +X+ /* fprintf(stderr," - n hexnum : generate scanner using as newline char.\n");*/ +X+ fprintf(stderr," - p : generate performance report to stderr\n"); +X+ fprintf(stderr," - S skeleton_path : file path for skeleton file\n"); +X+ fprintf(stderr," - s : suppress echo of unmatched scanner input to stdout\n"); +X+ fprintf(stderr," - T : run flex in trace mode\n"); +X+ #ifdef ATARI +X+ fprintf(stderr," - t : place result on stdout instead of lex_yy.c\n"); +X+ #else +X+ fprintf(stderr," - t : place result on stdout instead of lex.yy.c\n"); +X+ #endif +X+ fprintf(stderr," - v : print statistics of generated scanner\n"); +X+ fprintf(stderr," default = -cem\n"); +X+ exit(status); +X+ } +X+ +X /* readin - read in the rules section of the input file(s) +X * +X * synopsis +/ +echo x - scan.l_cdiff +sed '/^X/s///' > scan.l_cdiff << '/' +X*** Src_2.1/scan.l Thu Jun 30 19:42:00 1989 +X--- scan.l Thu Jul 2 22:19:26 1989 +X*************** +X*** 125,132 **** +X +X {SCNAME} RETURNNAME; +X ^{OPTWS}\n ++linenum; /* allows blank lines in section 1 */ +X! \n ++linenum; return ( '\n' ); +X! . synerr( "illegal character" ); BEGIN(RECOVER); +X +X +X "*/" ECHO; BEGIN(0); +X--- 125,136 ---- +X +X {SCNAME} RETURNNAME; +X ^{OPTWS}\n ++linenum; /* allows blank lines in section 1 */ +X! {OPTWS}\n ++linenum; return ( '\n' ); +X! . { +X! synerr( "illegal character" ); +X! fprintf(stderr,"Char : $%x\n",yytext[yyleng-1]); +X! BEGIN(RECOVER); +X! } +X +X +X "*/" ECHO; BEGIN(0); +X*************** +X*** 206,212 **** +X ^{OPTWS}\n ++linenum; /* allow blank lines in section 2 */ +X +X /* this horrible mess of a rule matches indented lines which +X! * do not contain "/*". We need to make the distinction because +X * otherwise this rule will be taken instead of the rule which +X * matches the beginning of comments like this one +X */ +X--- 210,216 ---- +X ^{OPTWS}\n ++linenum; /* allow blank lines in section 2 */ +X +X /* this horrible mess of a rule matches indented lines which +X! * do not contain '/','*'. We need to make the distinction because +X * otherwise this rule will be taken instead of the rule which +X * matches the beginning of comments like this one +X */ +/ +echo x - Makefile.tos +sed '/^X/s///' > Makefile.tos << '/' +X# make file for "flex" tool +X +X# @(#) $Header$ (LBL) +X +X# Porting considerations: +X# +X# For System V Unix machines, add -DSYS_V to CFLAGS. +X# For Vax/VMS, add -DSYS_V to CFLAGS. +X# For MS-DOS, add "-DMS_DOS -DSYS_V" to CFLAGS. Create \tmp if not present. +X# You will also want to rename flex.skel to something with a three +X# character extension, change SKELETON_FILE below appropriately, +X# For Amiga, add "-DAMIGA -DSYS_V" to CFLAGS. +X# +X# A long time ago, flex was successfully built using Microsoft C and +X# the following options: /AL, /stack:10000, -LARGE, -Ml, -Mt128, -DSYS_V +X +X +X# the first time around use "make first_flex" +X +X# The following definitions must be set according to your compiler - +X# examples for a Lattice Compiler with GST assembler and TURBO C with +X# assembler are provided below and must just be updated (don't forget to +X# update the linker argument extension files (*.lnk,*.tlk), too) : +X# +X#CCPATH = path to compiler directory without trailing \ +X#CHPATH = path to header files without trailing \ +X#CC = filename of the compiler +X#CFLAGS = compiler option flags +X#CIEXT = extension of C sources that should be used for input filenames +X#ASMPATH = path to assembler directory without trailing \ +X#ASM = filename of the assembler +X#AFLAGS = assembler option flags +X#AIEXT = extension of assembler sources that should be used for assembler +X# input filenames +X#AEXT = general assembler filename extension +X#LNKPATH = path to linker directory without trailing \ +X#LINK = filename of the linker +X#LFLAG0 = first option (full pathname of C startupcode) +X#LFLAG1 = further options + option flag for argument extension filename +X#LFLAG2 = further options + option flag for output-filename +X#LNKEXT = extension of linker argument extension file +X#OIEXT = extension of objects that should be used for linker input files +X#OEXT = general object file extension +X +X# Lattice definitions +XCCPATH = d:\latt +XCHPATH = d:\latt\include +XCC = lc.ttp +XCFLAGS = -h -n -cw -cc -i$(CHPATH)\ -g$(CCPATH)\ -dLATTICE -dATARI +XCIEXT = +XASMPATH = d:\gst +XASM = assem.ttp +XAFLAGS = -nolist -errors errors.out +XAIEXT = +XAEXT = .asm +XLNKPATH = d:\gst +XLINK = ld.ttp +XLFLAG0 = +XLFLAG1 = -with +XLFLAG2 = -nolist -sec -mem 200 -prog +XLNKEXT = .lnk +XOIEXT = +XOEXT = .bin +X +X# Turbo definitions +X#CCPATH = d:\turbo +X#CHPATH = d:\turbo\include +X#CC = tcc.prg +X#CFLAGS = -GJMPRZ -H=$(CHPATH)\ -w- -DTURBO -DATARI +X#CIEXT = .c +X#ASMPATH = d:\turbo +X#ASM = mas.prg +X#AFLAGS = +X#AIEXT = .s +X#AEXT = .s +X#LNKPATH = d:\turbo +X#LINK = tlink.ttp +X#LFLAG0 = $(LNKPATH)\lib\tcstart.o +X#LFLAG1 = -I= +X#LFLAG2 = -O= +X#LNKEXT = .tlk +X#OIEXT = .o +X#OEXT = .o +X +X# Other definitions +X# (not used for Atari because of short argument string - defined in flexdef.h +X +XSKELETON_DIR = /usr/lib +XSKELETON_FILE = flex.skel +XSKELFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_DIR)/$(SKELETON_FILE)\" +X +X +XFLEX = d:\etc\flex.ttp +XFLEX_FLAGS = -is +XYACC = d:\etc\yacc.ttp +XRENAME = d:\bin\rename +XDEL = d:\bin\del +X +X# Internal definitions +XLNK = $(LNKPATH)\$(LINK) +X +XFLEXOBJS = \ +X ccl$(OEXT) \ +X dfa$(OEXT) \ +X ecs$(OEXT) \ +X gen$(OEXT) \ +X main$(OEXT) \ +X misc$(OEXT) \ +X nfa$(OEXT) \ +X parse$(OEXT) \ +X scan$(OEXT) \ +X sym$(OEXT) \ +X tblcmp$(OEXT) \ +X yylex$(OEXT) +X +XFLEX_C_SOURCES = \ +X ccl.c \ +X dfa.c \ +X ecs.c \ +X gen.c \ +X main.c \ +X misc.c \ +X nfa.c \ +X parse.c \ +X scan.c \ +X sym.c \ +X tblcmp.c \ +X yylex.c +X +Xflex : $(FLEXOBJS) +X $(LNK) $(LFLAG0) $(LFLAG1)flex$(LNKEXT) $(LFLAG2)flex.ttp +X +Xfirst_flex: +X cp initscan.c scan.c +X make $(MFLAGS) flex +X +Xparse.h parse.c : parse.y +X $(YACC) -d parse.y +X $(DEL) parse.c +X $(RENAME) y_tab.c parse.c +X $(DEL) parse.h +X $(RENAME) y_tab.h parse.h +X +Xscan.c : scan.l +X $(FLEX) $(FLEX_FLAGS) scan.l +X $(RENAME) lex_yy.c scan.c +X +Xscan$(OEXT) : scan.c parse.h flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) scan$(CIEXT) +X +Xmain$(OEXT) : main.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) main$(CIEXT) +X +Xccl$(OEXT) : ccl.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) ccl$(CIEXT) +X +Xdfa$(OEXT) : dfa.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) dfa$(CIEXT) +X +Xecs$(OEXT) : ecs.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) ecs$(CIEXT) +X +Xgen$(OEXT) : gen.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) gen$(CIEXT) +X +Xmisc$(OEXT) : misc.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) misc$(CIEXT) +X +Xnfa$(OEXT) : nfa.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) nfa$(CIEXT) +X +Xparse$(OEXT) : parse.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) parse$(CIEXT) +X +Xsym$(OEXT) : sym.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) sym$(CIEXT) +X +Xtblcmp$(OEXT) : tblcmp.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) tblcmp$(CIEXT) +X +Xyylex$(OEXT) : yylex.c flexdef.h +X $(CCPATH)\$(CC) $(CFLAGS) yylex$(CIEXT) +X +Xflex.man : flex.1 +X nroff -man flex.1 >flex.man +X +Xlint : $(FLEX_C_SOURCES) +X lint $(FLEX_C_SOURCES) > flex.lint +X +Xdistrib : +X mv scan.c initscan.c +X chmod 444 initscan.c +X $(MAKE) $(MFLAGS) clean +X +Xclean : +X rm -f core errs flex *$(OEXT) parse.c *.lint parse.h flex.man tags +X +Xtags : +X ctags $(FLEX_C_SOURCES) +X +Xvms : flex.man +X $(MAKE) $(MFLAGS) distrib +X +Xtest : +X $(FLEX) $(FLEX_FLAGS) scan.l +X $(RENAME) lex_yy.c scan.ctest +X cmp scan.c scan.ctest +X +/ +echo x - Readme2 +sed '/^X/s///' > Readme2 << '/' +XThe changes: (1.7.89 RAL) +X +X - Bug fix: The original flex didn't like trailing spaces in exclusive start +X condition lists ! If you add an trailing space to line 68 in scan.l +X +X "%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE " +X +X you get a misleading error message: +X +X "Syntax error at line 69: bad start condition list" +X +X This bug can either be fixed in parse.y or in scan.l . I have chosen the +X last because there the fix is minimal: Just change the rule (line 128) +X +X "\n" to "{OPTWS}\n" +X +X - Enhancements: +X - new option "-?" that provides some help information about the other +X flags (main.c) +X - new option "-aTMPPATH" that allows a redefinition of the standard +X path for the temporary file (this might be rather large >200k if +X F,f options are selected). (main.c, flexdef.h (l.376)) +X - hexdump of illegal characters -- this proved to be a useful debugging +X tool especialy if invisible control characters occur which weren't +X covered by the rules. (scan.l fprintf statement line 129,...) +X +X - Patches due to TOS +X - General: TOS uses CR,LF as end of line char., Flex wants only a single +X LF as EOL char. Therefore all I/O must be translated using f* calls. +X This is done everywhere besides the YY_INPUT macro (flex.skel (scan.c), +X line 31) that uses a low level 'read'. This should be definitly changed +X to fread, so that all I/O calls occur on the same level. +X - the short action_file_name has been "flexXXXXXX.tmp", but that's too +X much for TOS,MSDOS ! I changed it to "flexXXXX.tmp" in main.c (patch +X covered by the -a option additions) +X - some compilers don't like external names that are ambiguous within +X the first 8 characters. I defined macros that change all these long +X external names to names that are unique within the first 8 characters. +X Just define SHORT_EXTERNAL_NAMES to use this feature (flexdef.h) +X - some statement changes that some compiler don't like: +X typedef *xxx[] -> typedef **xxx (flexdef.h.,l.308) +X "/*" -> '/','*' within a comment in (scan.l, l.209) +X - changed short "lexyy.c" to "lex_yy.c" what's more similar to the unix +X "lex.yy.c" (main.c). +X - a few further really compiler dependent changes provided with +X #ifdef ATARI && LATTICE res. TURBO braces. +X +X - Additional TOS only files +X - Makefile.tos: Common makefile for all TOS compilers. If you add further +X ones please email me the new makefile. +X - flex.lnk: Lattice - GST linker argument extension file +X - flex.tlk: Turbo linker argument extension file +X +X +XAdditional remarks: +X +XI didn't add a new initscan.c (= flex -ist scan.l). The current one is good +Xenough for a first compilation. With this first version of flex you can +Xrebuild your own scan.c and the final flex version ! +X +XMinix ST : +X - I had to "chmem =70000 cv" (>50000) to get flex linked +X - 'memset' (PC 1.3, EFTH40,...) is necessary +X - chmem =90000 flex may be sufficient +X +XMinix PC : +X It should be possible to port Flex to Minix PC. The current sizes of flex +X are: +X Minix ST (ACK) Lattice (TOS) Turbo (TOS) +X +X size 75300 83305 57957 +X compilation time 22' 15' 3'40" +X flex -is scan.l 1'49" 43" 30" +X +X The Minix ST size includes the bad generated code using only a subset of +X the 68000 commands, long addresses only and a huge relocation table. +X Therefore the PC size will be <64 k ! More serious is the fact that I had +X to chmem =90000 flex to get scan.l converted to scan.c . But I never saw +X a more complex lex source than scan.l -- so it should be possible to +X reduce some array sizes without limitation for all day usage. +X +X No one volunteered yet for a Minix PC port -- but if someone will try it +X I would provide him with a new scan.c and some hints. +X +XTOS: +X Don't forget to adapt the flexskel path within flexdef.h ! +X +X +/ +echo x - flex.lnk +sed '/^X/s///' > flex.lnk << '/' +X* +X* +X* linker control file for flex.ttp +X* +X* +X* +XINPUT d:\latt\lib\startup.bin +X* +XINPUT ccl.bin +XINPUT dfa.bin +XINPUT ecs.bin +XINPUT gen.bin +XINPUT misc.bin +XINPUT nfa.bin +XINPUT parse.bin +XINPUT sym.bin +XINPUT tblcmp.bin +XINPUT main.bin +XINPUT yylex.bin +XINPUT scan.bin +X* +XLIBRARY d:\latt\lib\clib.bin +X +/ +echo x - flex.tlk +sed '/^X/s///' > flex.tlk << '/' +Xccl.o +Xdfa.o +Xecs.o +Xgen.o +Xmisc.o +Xnfa.o +Xparse.o +Xsym.o +Xtblcmp.o +Xyylex.o +Xmain.o +Xscan.o +Xd:\turbo\lib\tcstdlib.lib ; standard lib +Xd:\turbo\lib\tcextlib.lib ; extended lib +Xd:\turbo\lib\tctoslib.lib ; TOS lib +Xd:\turbo\lib\tcgemlib.lib ; AES and VDI lib +X-S=200000 +/ diff --git a/commands/flex-2.5.4/MISC/Borland.old/Borland-2.4 b/commands/flex-2.5.4/MISC/Borland.old/Borland-2.4 new file mode 100644 index 000000000..bb18909a5 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Borland.old/Borland-2.4 @@ -0,0 +1,419 @@ +Received: from 128.140.1.1 by ee.lbl.gov for (8.6.9/1.43r) + id HAA01193; Thu, 29 Sep 1994 07:26:54 -0700 +Received: from larry-le0.cc.emory.edu by + emoryu1.cc.emory.edu (5.65/Emory_cc.4.0.1) via SMTP + id AA07292 ; Thu, 29 Sep 94 10:26:41 -0400 +From: tkane01@unix.cc.emory.edu (Terrence O Kane) +Received: by larry.cc.emory.edu (5.0) id AA11757; Thu, 29 Sep 1994 10:26:43 +0500 +Message-Id: <9409291426.AA11757@larry.cc.emory.edu> +Subject: patches and makefile for Borland C 4.02, flex 2.4.7 +To: vern@ee.lbl.gov +Date: Thu, 29 Sep 1994 10:26:42 -0400 (EDT) +X-Mailer: ELM [version 2.4 PL23] +Mime-Version: 1.0 +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: 7bit +Content-Length: 9900 + +Enclosed are unified diffs and a makefile for Borland 4.02 + +The changes in the enclosed are 1) make the size parameters for memory +allocation "size_t", 2) change an include file when the lexer is +compiled within 'extern "C" {...}' in a C++ file, and 3) include pragmas +in the header suitable for BCC 4.02 to hush on warnings. + +The latter is done because of the limit on command line size. A tradeoff +exists between putting pragmas in the header, or #defines in the header - +I put in the pragmas since they're suppoed to be ignored unless +understood - *and* they're enclosed in BCC specific ifdefs, anyway. + +All changes are enclosed in "#ifdef __BORLANDC__". + + + + + +--- misc.c Tue Jan 04 14:33:10 1994 ++++ ../misc.c Wed Sep 28 18:44:32 1994 +@@ -55,15 +55,19 @@ + action_index += len; + } + + + /* allocate_array - allocate memory for an integer array of the given size */ + + void *allocate_array( size, element_size ) ++#ifndef __BORLANDC__ + int size, element_size; ++#else /* __BORLANDC__ */ ++size_t size, element_size; ++#endif /* __BORLANDC__ */ + { + register void *mem; + + /* On 16-bit int machines (e.g., 80286) we might be trying to + * allocate more than a signed int can hold, and that won't + * work. Cheap test: + */ +@@ -634,15 +638,19 @@ + } + + + /* reallocate_array - increase the size of a dynamic array */ + + void *reallocate_array( array, size, element_size ) + void *array; ++#ifndef __BORLANDC__ + int size, element_size; ++#else /* __BORLANDC__ */ ++size_t size, element_size; ++#endif /* __BORLANDC__ */ + { + register void *new_array; + + /* Same worry as in allocate_array(): */ + if ( size * element_size <= 0 ) + flexfatal( + "attempt to increase array size by less than 1 byte" ); +@@ -739,15 +747,19 @@ + } + + + /* The following is only needed when building flex's parser using certain + * broken versions of bison. + */ + void *yy_flex_xmalloc( size ) ++#ifndef __BORLANDC__ + int size; ++#else /* __BORLANDC__ */ ++size_t size; ++#endif /* __BORLANDC__ */ + { + void *result = flex_alloc( size ); + + if ( ! result ) + flexfatal( "memory allocation failed in yy_flex_xmalloc()" ); + + return result; + + + + + +--- skel.c Wed Aug 03 11:38:32 1994 ++++ ../skel.c Wed Sep 28 18:50:58 1994 +@@ -26,15 +26,19 @@ + "", + "#ifdef __cplusplus", + "", + "#include ", + "%+", + "class istream;", + "%*", ++ "#ifndef __BORLANDC__", + "#include ", ++ "#else /* __BORLANDC__ */", ++ "#include ", ++ "#endif /* __BORLANDC__ */", + "", + "/* Use prototypes in function declarations. */", + "#define YY_USE_PROTOS", + "", + "/* The \"const\" storage-class-modifier is valid. */", + "#define YY_USE_CONST", + "", +@@ -240,16 +244,21 @@ + "static int yy_start_stack_depth = 0;", + "static int *yy_start_stack = 0;", + "static void yy_push_state YY_PROTO(( int new_state ));", + "static void yy_pop_state YY_PROTO(( void ));", + "static int yy_top_state YY_PROTO(( void ));", + "%*", + "", ++ "#ifndef __BORLANDC__", + "static void *yy_flex_alloc YY_PROTO(( unsigned int ));", + "static void *yy_flex_realloc YY_PROTO(( void *, unsigned int ));", ++ "#else /* __BORLANDC__ */", ++ "static void *yy_flex_alloc YY_PROTO(( size_t ));", ++ "static void *yy_flex_realloc YY_PROTO(( void *, size_t ));", ++ "#endif /* __BORLANDC__ */", + "static void yy_flex_free YY_PROTO(( void * ));", + "", + "#define yy_new_buffer yy_create_buffer", + "", + "%% yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here", + "", + "#ifndef yytext_ptr", + + + + + +--- initscan.c Wed Aug 03 11:42:46 1994 ++++ ../initscan.c Wed Sep 28 18:51:34 1994 +@@ -16,15 +16,19 @@ + #endif + #endif + + + #ifdef __cplusplus + + #include ++#ifndef __BORLANDC__ + #include ++#else /* __BORLANDC__ */ ++#include ++#endif /* __BORLANDC__ */ + + /* Use prototypes in function declarations. */ + #define YY_USE_PROTOS + + /* The "const" storage-class-modifier is valid. */ + #define YY_USE_CONST + +@@ -220,16 +224,21 @@ + static int yy_start_stack_ptr = 0; + static int yy_start_stack_depth = 0; + static int *yy_start_stack = 0; + static void yy_push_state YY_PROTO(( int new_state )); + static void yy_pop_state YY_PROTO(( void )); + static int yy_top_state YY_PROTO(( void )); + ++#ifndef __BORLANDC__ + static void *yy_flex_alloc YY_PROTO(( unsigned int )); + static void *yy_flex_realloc YY_PROTO(( void *, unsigned int )); ++#else /* __BORLANDC__ */ ++static void *yy_flex_alloc YY_PROTO(( size_t )); ++static void *yy_flex_realloc YY_PROTO(( void *, size_t )); ++#endif /* __BORLANDC__ */ + static void yy_flex_free YY_PROTO(( void * )); + + #define yy_new_buffer yy_create_buffer + + #define INITIAL 0 + #define SECT2 1 + #define SECT2PROLOG 2 + + + + + +--- flexdef.h Tue Jan 04 14:33:14 1994 ++++ ../flexdef.h Wed Sep 28 18:53:44 1994 +@@ -27,14 +27,25 @@ + */ + + /* @(#) $Header$ (LBL) */ + + #include + #include + ++#ifdef __BORLANDC__ ++#include ++ ++#pragma warn -pro ++#pragma warn -rch ++#pragma warn -use ++#pragma warn -aus ++#pragma warn -par ++#pragma warn -pia ++ ++#endif /* __BORLANDC__ */ + #if HAVE_STRING_H + #include + #else + #include + #endif + + #if __STDC__ +@@ -607,19 +618,29 @@ + */ + + extern char nmstr[MAXLINE]; + extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; + extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; + extern int num_backing_up, bol_needed; + ++#ifndef __BORLANDC__ + void *allocate_array PROTO((int, int)); + void *reallocate_array PROTO((void*, int, int)); ++#else /* __BORLANDC__ */ ++void *allocate_array PROTO((size_t, size_t)); ++void *reallocate_array PROTO((void*, size_t, size_t)); ++#endif /* __BORLANDC__ */ + ++#ifndef __BORLANDC__ + void *flex_alloc PROTO((unsigned int)); + void *flex_realloc PROTO((void*, unsigned int)); ++#else /* __BORLANDC__ */ ++void *flex_alloc PROTO((size_t)); ++void *flex_realloc PROTO((void*, size_t)); ++#endif /* __BORLANDC__ */ + void flex_free PROTO((void*)); + + #define allocate_integer_array(size) \ + (int *) allocate_array( size, sizeof( int ) ) + + #define reallocate_integer_array(array,size) \ + (int *) reallocate_array( (void *) array, size, sizeof( int ) ) +@@ -772,15 +793,19 @@ + /* Write out one section of the skeleton file. */ + extern void skelout PROTO((void)); + + /* Output a yy_trans_info structure. */ + extern void transition_struct_out PROTO((int, int)); + + /* Only needed when using certain broken versions of bison to build parse.c. */ ++#ifndef __BORLANDC__ + extern void *yy_flex_xmalloc PROTO(( int )); ++#else /* __BORLANDC__ */ ++extern void *yy_flex_xmalloc PROTO(( size_t )); ++#endif /* __BORLANDC__ */ + + /* Set a region of memory to 0. */ + extern void zero_out PROTO((char *, int)); + + + /* from file nfa.c */ + + + + + +############################################################################### +# Makefile for flex 2.4.7 with Borland C/C++ version 4.02 +# +# This will probably need to be adjusted for your existing lexer/parser +# generators. See definitions for FLEX and YACC near the bottom of the +# makefile. +# +# Copy initscan.c to scan.c to make your first executable. After that, +# you may choose to try alternate compression options for your everyday +# flex executable. +# +# This will build flex with the large model. Don't use huge, but if you +# feel like experimenting with other models, post your success stories to +# comp.compilers, OK? +# +# This makefile does *not* implement the big testing found in "makefile.in". +# +# I also assume the availability of sed and the gnu file utilities on the +# system - they're readily available, so if you don't have them, why not? +# +# +# The resulting generated lexer (the real goal, right?) will compile +# (and run nicely, too) as a .c file, as well as being included such as +# extern "C" { #include "lexyyc" } in a .cplusplus file. +# +############################################################################### + +DEBUG = 1 + +.autodepend + +all: flex.exe + +############################################################################### +# +# standard utilitities? ha. +# + +CC = bcc +CPP = bcc + +############################################################################### +# + +MODEL = l + +!if $(DEBUG) == 1 +!message Building with debug. +debugCompile = -v +debugLink = /v +!else +!message Building without debug. +debugCompile = +debugLink = +!endif + +LOADER = c0$(MODEL).obj +LIBS = c$(MODEL).lib +LINKFLAGS = $(debugLink) + +DATASEG = -dc -Ff +SizeOPT = -Os -G- +Defines = -DSHORT_FILE_NAMES=1 -DHAVE_STRING_H=1 + +COMMON = -A -c -m$(MODEL) $(SizeOPT) $(DATASEG) $(Defines) $(debugCompile) +CFLAGS = -o$@ $(COMMON) +CCFLAGS = -o$@ $(COMMON) -Pcc + +############################################################################### + +.SUFFIXES: .cc + +.cc.obj: + $(CPP) $(CCFLAGS) $< + +.c.obj: + $(CPP) $(CFLAGS) $< + +############################################################################### +# +# source & object files +# + +SRC = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.c \ + scan.c sym.c tblcmp.c yylex.c skel.c + +OBJS = $(SRC:.c=.obj) + +objects: $(OBJS) + @echo $(OBJS) + +############################################################################### +# +# Executable +# + +flex.exe: $(OBJS) + tlink $(LINKFLAGS) @&&! +$(LOADER) $** +$&.exe +$&.map +$(LIBS) +! + +# +############################################################################### +# +# Lex files +# + +FLEX = .\flex +FLEX_FLAGS = -ist + +scan.c: scan.l + $(FLEX) $(FLEX_FLAGS) scan.l >scan.tmp + sed s,\"$(srcdir)/scan.l\",\"scan.l\", scan.c + @rm scan.tmp + +############################################################################### +# +# YACC files +# + +YACC = .\bison +YFLAGS = -vdyl + +parse.c: parse.y + $(YACC) -ydl parse.y + @sed "/extern char.*malloc/d" parse.c + @rm -f y_tab.c + @mv y_tab.h parse.h + +# +# end Makefile +# +############################################################################### + diff --git a/commands/flex-2.5.4/MISC/Borland.old/Turbo-C b/commands/flex-2.5.4/MISC/Borland.old/Turbo-C new file mode 100644 index 000000000..c15ee6783 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Borland.old/Turbo-C @@ -0,0 +1,179 @@ +Received: from 128.84.254.220 by ee.lbl.gov for (8.6.8.1/1.43r) + id PAA27266; Mon, 18 Apr 1994 15:08:26 -0700 +Received: from CLOYD.CS.CORNELL.EDU by thialfi.cs.cornell.edu (5.67/I-1.99E) + id AA28742; Mon, 18 Apr 94 18:08:14 -0400 +Received: from iraun1.ira.uka.de by cloyd.cs.cornell.edu (5.67/I-1.99D) + id AA19613; Mon, 18 Apr 94 18:08:19 -0400 +Received: from t500i2.telematik.informatik. (actually t500i2.telematik.informatik.uni-karlsruhe.de) + by iraun1.ira.uka.de with SMTP (PP); Tue, 19 Apr 1994 00:07:55 +0200 +Received: by t500i2.telematik.informatik.uni-karlsruhe.de (5.57/Ultrix3.0-C) + id AA10269; Tue, 19 Apr 94 00:09:14 +0200 +From: beigl@t500i2.telematik.informatik.uni-karlsruhe.de (Michael Beigl) +Message-Id: <9404182209.AA10269@t500i2.telematik.informatik.uni-karlsruhe.de> +Subject: Makefile-TurboC +To: vern@cs.cornell.edu +Date: Tue, 19 Apr 1994 00:09:13 +0200 (MET DST) +X-Mailer: ELM [version 2.4 PL22] +Mime-Version: 1.0 +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: 7bit +Content-Length: 2739 + +Hello + +Here are some additional adjustments to my Makefile. I was using "pure" DOS +and an old Turbo C++ 1.0 version, so I had some problems with systemtools +like mv etc. and problems with variables in my Makefile. + +Now follows my Makefile +############################################################################ +# make file for "flex" tool + +# @(#) $Header$ (LBL) + +# Porting considerations: +# +# For BSD machines: +# CFLAGS = +# LDFLAGS = -s +# LINK = $(CC) $(CFLAGS) -o flex $(LDFLAGS) $(FLEXOBJS) +# SKELETON_DIR = . +# SKELETON_FILE = flex.skel +# SKELFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_DIR)/$(SKELETON_FILE)\" +# O = o +# YTAB = y.tab +# FLEX = ./flex +# +# For System V Unix or Vax/VMS machines, merely add: +# CFLAGS = -DSYS_V +# +# For MS-DOS, Turbo C: +CC = tcc +# -2+ 286 Options +CFLAGS = -DSYS_V -DMS_DOS -O -G -Z -ml -v -2 +# /3 enable 32 bit processing +# /ye expanded memory swapping +# /yx extended memory swapping +LINK = tlink @flex.lnk/c/x/v/3/ye +SKELETON_DIR = . +SKELETON_FILE = flex.skl +SKELFLAGS = -DDEFAULT_SKELETON_FILE="$(SKELETON_DIR)/$(SKELETON_FILE)" +O = obj +EXE = .exe +YTAB = y_tab +FLEX = flex +YACC = /yacc/byacc + +# +# the first time around use "make first_flex" +# + +FLEX_FLAGS = + +FLEXOBJS = \ + ccl.$O \ + dfa.$O \ + ecs.$O \ + gen.$O \ + main.$O \ + misc.$O \ + nfa.$O \ + parse.$O \ + scan.$O \ + sym.$O \ + tblcmp.$O \ + yylex.$O + +FLEX_C_SOURCES = \ + ccl.c \ + dfa.c \ + ecs.c \ + gen.c \ + main.c \ + misc.c \ + nfa.c \ + parse.c \ + scan.c \ + sym.c \ + tblcmp.c \ + yylex.c + +FLEX_C_SOURCES_1 = \ + ccl.c \ + dfa.c \ + ecs.c \ + gen.c \ + main.c \ + misc.c + +FLEX_C_SOURCES_2 = \ + nfa.c \ + parse.c \ + scan.c \ + sym.c \ + tblcmp.c \ + yylex.c + +flex.exe: $(FLEXOBJS) + $(LINK) + + +flex: $(FLEX_C_SOURCES) + $(CC) $(CFLAGS) -c $(SKELFLAGS) $(FLEX_C_SOURCES_1) + $(CC) $(CFLAGS) -c $(SKELFLAGS) $(FLEX_C_SOURCES_2) + $(LINK) + + +first_flex: + copy initscan.c scan.c + $(MAKE) flex + +parse.h parse.c: parse.y + $(YACC) -d parse.y + @rename $(YTAB).c parse.c + @rename $(YTAB).h parse.h + +scan.c: scan.l + $(FLEX) -ist $(FLEX_FLAGS) scan.l >scan.c + +scan.$O: scan.c parse.h + +main.$O: main.c + $(CC) $(CFLAGS) -c $(SKELFLAGS) main.c + +flex.man: flex.1 + nroff -man flex.1 >flex.man + +lint: $(FLEX_C_SOURCES) + lint $(FLEX_C_SOURCES) > flex.lint + +distrib: + rename scan.c initscan.c + attrib +R -A -H -S initscan.c + $(MAKE) clean + +clean: + del *.obj + del *.lint + del core + del errs + del flex.exe + del parse.c + del parse.h + del flex.man + del tags + +tags: + ctags $(FLEX_C_SOURCES) + +vms: flex.man + $(MAKE) distrib + +test: + $(FLEX) -ist $(FLEX_FLAGS) scan.l | diff scan.c - + +############################################################################ + +I think this Makefile will help some other simple DOS user + + M. Beigl diff --git a/commands/flex-2.5.4/MISC/Borland/Makefile b/commands/flex-2.5.4/MISC/Borland/Makefile new file mode 100644 index 000000000..3b2009098 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Borland/Makefile @@ -0,0 +1,163 @@ +############################################################################### +# Makefile for flex 2.5.0.6 (beta) with Borland C/C++ version 4.02 +# +# This will probably need to be adjusted for your existing lexer/parser +# generators. See definitions for FLEX and YACC near the bottom of the +# makefile. +# +# This makefile builds initflex.exe and flex.exe by default. It +# removes initflex.exe after making flex.exe. After that, you may +# choose to try alternate compression options for your everyday flex +# executable. +# +# This will build flex with the large model. Don't use huge, but if you +# feel like experimenting with other models, post your success stories to +# comp.compilers, OK? +# +# This makefile does *not* implement the big testing found in "makefile.in". +# +# I also assume the availability of sed and the gnu file utilities on the +# system - they're readily available, so if you don't have them, why not? +# +# +# The resulting generated lexer (the real goal, right?) will compile +# (and run nicely, too) as a .c file, as well as being included such as +# extern "C" { #include "lexyyc" } in a .cplusplus file. +# +############################################################################### + +DEBUG = 1 + +.autodepend + +all: initflex.exe flex.exe + rm initflex.exe initflex.map + +############################################################################### +# +# standard utilitities? ha. +# + +CC = bcc +CPP = bcc + +############################################################################### +# + +MODEL = l + +!if $(DEBUG) == 1 +!message Building with debug. +debugCompile = -v +debugLink = /v +!else +!message Building without debug. +debugCompile = +debugLink = +!endif + +LOADER = c0$(MODEL).obj +LIBS = c$(MODEL).lib +LINKFLAGS = $(debugLink) + +DATASEG = -dc -Ff +SizeOPT = -Os -G- +Defines = + +COMMON = -A -c -m$(MODEL) $(SizeOPT) $(DATASEG) $(Defines) $(debugCompile) +CFLAGS = -o$@ $(COMMON) +CCFLAGS = -o$@ $(COMMON) -Pcc + +############################################################################### + +.SUFFIXES: .cc + +.cc.obj: + $(CPP) $(CCFLAGS) $< + +.c.obj: + $(CPP) $(CFLAGS) $< + +############################################################################### +# +# source & object files +# + +BASESRC = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.c \ + sym.c tblcmp.c yylex.c skel.c + +INITSRC = $(BASESRC) initscan.c + +INITOBJS = $(INITSRC:.c=.obj) + +SRC = $(BASESRC) scan.c + +OBJS = $(SRC:.c=.obj) + +objects: $(OBJS) + @echo $(OBJS) + +############################################################################### +# +# Executable +# + +initflex.exe: $(INITOBJS) + tlink $(LINKFLAGS) @&&! +$(LOADER) $** +$&.exe + +$(LIBS) +! + +flex.exe: $(OBJS) + tlink $(LINKFLAGS) @&&! +$(LOADER) $** +$&.exe + +$(LIBS) +! + +# +############################################################################### +# +# Lex files +# + +FLEX = .\initflex +FLEX_FLAGS = -ist + +scan.c: scan.l + $(FLEX) $(FLEX_FLAGS) scan.l >scan.tmp + sed s,\"$(srcdir)/scan.l\",\"scan.l\", scan.c + @rm scan.tmp + +############################################################################### +# +# YACC files +# + +YACC = .\bison +YFLAGS = -vdyl + +parse.c: parse.y + $(YACC) -ydl parse.y + @sed "/extern char.*malloc/d" parse.c + @rm -f y_tab.c + @mv y_tab.h parse.h + +############################################################################### +# +# cleanup +# + +clean: + -rm *.obj *.map initflex.exe + +realclean: clean + -rm flex.exe + +# +# end Makefile +# +############################################################################### diff --git a/commands/flex-2.5.4/MISC/Borland/NOTES b/commands/flex-2.5.4/MISC/Borland/NOTES new file mode 100644 index 000000000..caac3cc99 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Borland/NOTES @@ -0,0 +1,66 @@ +Received: from 128.140.1.1 by ee.lbl.gov for (8.6.9/1.43r) + id PAA03966; Tue, 24 Jan 1995 15:03:57 -0800 +Received: from larry-le0.cc.emory.edu by + emoryu1.cc.emory.edu (5.65/Emory_cc.4.0.1) via SMTP + id AA24158 ; Tue, 24 Jan 95 17:18:18 -0500 +From: tkane01@unix.cc.emory.edu (Terrence O Kane) +Received: by larry.cc.emory.edu (5.0) id AA21979; Tue, 24 Jan 1995 17:17:40 -0500 +Message-Id: <9501242217.AA21979@larry.cc.emory.edu> +Subject: Re: Beta test for DOS +To: vern@ee.lbl.gov (Vern Paxson) +Date: Tue, 24 Jan 1995 17:17:38 -0500 (EST) +In-Reply-To: <199501232138.NAA11430@daffy.ee.lbl.gov> from "Vern Paxson" at Jan 23, 95 01:38:02 pm +X-Mailer: ELM [version 2.4 PL23] +Mime-Version: 1.0 +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: 7bit +Content-Length: 5792 + +Vern, + +I've made flex 2.5.0.6 successfully with no changes to the source +code at all. I'm including the Borland 4.02 makefile and config.h +at the end of this message. + +When you're ready for release, I'll be happy to take care of getting +the appropriate archive files up to Simtel if you wish. + +I have not used this version for any of my "work-related" scanners +yet, but have run the fastwc benchmark. The compiles were for large +memory model and optimization for fastest possible code. The test +machine was a Pentium-90 (hey! timing output was integer!) with +enhanced IDE on a PCI bus and no file system caching. I ran the +test on two different input files. + +(Times are in seconds.) + +The first input was a typical postscript file concatenated 10 times; +by typical, I mean that there were relatively few spaces, lots of lines +with no space, using lots of parentheses. + + lines words characters + 91200 356260 5889240 + + mywc 8.89 + wc1s 15.22 default + wc1 10.82 -Cf + wc2 10.16 -Cf + wc3 9.17 -Cf + wc4 9.22 -Cf + wc5 10.98 -Cf + +The second test run was on a file that consisted of 20 concatenations +of 'misc/flex.man'. + + lines words characters + 69960 305140 2399960 + + mywc 4.01 + wc1s 6.87 + wc1 5.32 + wc2 4.95 + wc3 4.12 + wc4 4.12 + wc5 5.05 + +[[Makefile and config.h moved to separate files -VP]] diff --git a/commands/flex-2.5.4/MISC/Borland/config.h b/commands/flex-2.5.4/MISC/Borland/config.h new file mode 100644 index 000000000..256dd7a47 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Borland/config.h @@ -0,0 +1,29 @@ +/* $Header$ */ +/* ------------------------------------------------ */ +/* version of config.h for Borland C/C++ v4.02 */ +/* flex version 2.5.0.6 (beta) */ +/* ------------------------------------------------ */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if platform-specific command line handling is necessary. */ +#undef NEED_ARGV_FIXUP diff --git a/commands/flex-2.5.4/MISC/EBCDIC b/commands/flex-2.5.4/MISC/EBCDIC new file mode 100644 index 000000000..e4ebd716a --- /dev/null +++ b/commands/flex-2.5.4/MISC/EBCDIC @@ -0,0 +1,48 @@ +Return-Path: Mark_Ganter@liz.com +Received: from 192.216.61.11 by horse.ee.lbl.gov for vern (5.65/1.43r) + id AA02152; Tue, 11 Jan 94 06:19:36 -0800 +Received: from melonville.radiomail.net (mayberry.radiomail.net) by radiomail.net with SMTP id AA20220 + (5.65c+/IDA-1.4.4 for ); Tue, 11 Jan 1994 06:19:35 -0800 +Message-Id: <199401111419.AA20220@radiomail.net> +Received: from liz.com by melonville.radiomail.net with CCGW-1.7(930217); + Tue, 11 Jan 94 06:19:17 +From: Mark_Ganter@liz.com +Date: 11 Jan 94 09:05 +To: vern@horse.ee.lbl.gov +Subject: Re[2]: Flex on an AS400 + + I have no problem at all with being a contact for advice + on porting Flex to EBCDIC. The code was put on an AS400, so + filing the message under /MISC/AS400 is more appropriate. + The port was an interesting, very educational experience. + Thanks again. + + + Mark + +------------------------------------------------------------------------ +Date: Tue, 18 Apr 1995 12:33:48 -0400 +To: "Michael W. Duffy" , Mark_Ganter@liz.com, + vern@ee.lbl.gov (Vern Paxson), slayten@cas.org +From: slayten@cas.org (Steve Layten) +Subject: RE: Porting LEX scanner on EBCDIC machine +X-Mailer: +Content-Length: 918 + +I came in late on this discussion - I don't follow comp.compilers very +closely these days because my job has shifted somewhat. + +I ported (quite some time ago) flex 2.3.6 to an IBM 3090 under MVS, using +the SAS C compiler. The approach I used was, as Vern suggested, was to +translate the tables to reflect EBCDIC-based indices. I haven't even +downloaded flex 2.4 yet, so I don't know what's in the current distribution. +My patches were in the flex 2.3 distribution for a while in the MISC +directory. If you want any more info feel free to drop me a line - I still +have (somewhere) the patches that I created from version 2.3.6. + +Steve Layten +-- +Steven W. Layten, Senior Research Scientist +Chemical Abstracts Service PO BOX 3012, Columbus, OH 43210 +1 614 447 3600 +INET: slayten@cas.org FAX: +1 614 447 3813 +# # Speaking only for myself, and NOT for Chemical Abstracts Service! # # # diff --git a/commands/flex-2.5.4/MISC/MSDOS/MSC70.make b/commands/flex-2.5.4/MISC/MSDOS/MSC70.make new file mode 100644 index 000000000..5980f3a61 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MSDOS/MSC70.make @@ -0,0 +1,115 @@ +# +# make file for "flex" tool +# @(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/Makefile,v 2.9 90/05/26 17:28:44 + vern Exp $ (LBL) +# +# the first time around use "make f_flex" +# +# This makefile is specific for Microsoft's C/C++ compiler (v7), nmake and +# lib +# - Paul Stuart, Jan 93 (pjs@scammell.ecos.tne.oz.au) +# + + +SKELFLAGS = -DDEFAULT_SKELETON_FILE=\"c:/src/flex/flex.skl\" +CFLAGS = -nologo -AL -W2 -F 8000 -Ox -Gt16000 -DMS_DOS -DUSG +LDFLAGS = /nologo /NOI /BATCH /ONERROR:NOEXE /STACK:8000 +FLEX_FLAGS = -ist8 -Sflex.skl + +FLEX = .\flex.exe +CC = cl +YACC = c:\lib\byacc +MAKE = nmake /nologo + +# +# break obj-list into two because of 128 character command-line limit of +# Microsoft's link and lib utilities. +# +FLEXOBJS1 = \ + ccl.obj \ + dfa.obj \ + ecs.obj \ + gen.obj \ + main.obj \ + misc.obj \ + nfa.obj \ + parse.obj + +FLEXOBJS2 = \ + scan.obj \ + sym.obj \ + tblcmp.obj \ + yylex.obj + +FLEX_C_SOURCES = \ + ccl.c \ + dfa.c \ + ecs.c \ + gen.c \ + main.c \ + misc.c \ + nfa.c \ + parse.c \ + scan.c \ + sym.c \ + tblcmp.c \ + yylex.c + +FLEX_LIB_OBJS = \ + libmain.obj + + +all : flex.exe + +# +# lib is used to get around the 128 character command-line limit of 'link'. +# +flex.exe : $(FLEXOBJS1) $(FLEXOBJS2) + lib /nologo tmplib $(FLEXOBJS1); + link $(LDFLAGS) $(FLEXOBJS2),$*.exe,,tmplib; + del tmplib.lib + +f_flex: + copy initscan.c scan.c + touch scan.c + @echo compiling first flex + $(MAKE) flex.exe + del scan.c + @echo using first flex to generate final version... + $(MAKE) flex.exe + +# +# general inference rule +# +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +parse.h parse.c : parse.y + $(YACC) -d parse.y + @mv y_tab.c parse.c + @mv y_tab.h parse.h + +scan.c : scan.l + $(FLEX) $(FLEX_FLAGS) $(COMPRESSION) scan.l >scan.c + + +scan.obj : scan.c parse.h flexdef.h + +main.obj : main.c flexdef.h + $(CC) $(CFLAGS) -c $(SKELFLAGS) main.c + +ccl.obj : ccl.c flexdef.h +dfa.obj : dfa.c flexdef.h +ecs.obj : ecs.c flexdef.h +gen.obj : gen.c flexdef.h +misc.obj : misc.c flexdef.h +nfa.obj : nfa.c flexdef.h +parse.obj : parse.c flexdef.h +sym.obj : sym.c flexdef.h +tblcmp.obj : tblcmp.c flexdef.h +yylex.obj : yylex.c flexdef.h + + +clean : + del *.obj + del *.map diff --git a/commands/flex-2.5.4/MISC/MSDOS/configur.bat b/commands/flex-2.5.4/MISC/MSDOS/configur.bat new file mode 100644 index 000000000..dbea0e467 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MSDOS/configur.bat @@ -0,0 +1,6 @@ +@echo off + +sed -e "s/y\.tab\./parse_tab\./" -e "/sed/ s/'/\"/g" < Makefile.in > Makefile +sed -f MISC/MSDOS/djgpp.sed Makefile.in > Makefile + +update initscan.c scan.c diff --git a/commands/flex-2.5.4/MISC/MSDOS/djgpp.sed b/commands/flex-2.5.4/MISC/MSDOS/djgpp.sed new file mode 100644 index 000000000..b436113b0 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MSDOS/djgpp.sed @@ -0,0 +1,12 @@ +s/y\.tab\./parse_tab\./ +s/@DEFS@/-DMS_DOS/ +s/@LIBS@// +s/@srcdir@/./ +s/@YACC@/bison/ +s/@CC@/gcc/ +s/@RANLIB@/ranlib/ +s/@ALLOCA@// +/^flex/ s/\.bootstrap// +/sed.*extern.*malloc/ c\ + @mv parse_tab.c parse.c +/rm.*parse_tab.c/ d diff --git a/commands/flex-2.5.4/MISC/MVS/MVS.mail b/commands/flex-2.5.4/MISC/MVS/MVS.mail new file mode 100644 index 000000000..5a75e5b57 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/MVS.mail @@ -0,0 +1,56 @@ +(Message inbox:40) +Date: Tue, 17 Jul 1990 11:56 EDT +From: swl26%CAS.BITNET@CORNELLC.cit.cornell.edu +Subject: Re(2): port of flex-2.3 to IBM/MVS +To: vern@cs.cornell.edu + +>Message received. I'm sending this response to +>swl26%CAS.BITNET@CORNELLC.cit.cornell.edu. + +Great -- we can talk. + +>How extensive are the diffs? If they're fairly short then yes, please +>send them. If they're pretty involved then probably not, as I'm not aware +>of many MVS flex users ... + +I've built a context diff file which is ~850 lines. + +Summary of major changes necessary: + + o a new initscan.c -- because MVS is ebcdic, the initial scanner had + to be changed. I built a scanner from scan.l using -Ce, then + hand-manipulated the yy_ec table to fit EBCDIC instead of ASCII + chars. (This is not included in the diff file above.) + + o changes in main and flexdef.h to change how files are handled. (No + dynamic file names, etc.) + + o Some lines had to be shortened to 80 bytes. This mostly impacted + your RCSID lines, which with the full path name were too long. + + o SASC and the linker don't allow externals to be longer than 8 chars. + I thus wrote a Q&D program to shorten all externals. (This would be + a separate file 'fixit.l', which is not included in the diffs.) + + o There are several places where there are tests for 'isascii' (which I + deleted conditionally, using #ifdefs), and tests for 'A' <= x <= 'Z' + which I changed to 'isupper'. + +Many of the changes I've incorporated without impacting other systems. +Others are with 'ifdefs'. Still others (the short external names and new +initscan) are 'isolable' as separate files which would have to be +included with a distribution. + +Obviously, you are not going to want to (even if you can :-) ) worry about +testing new versions in the MVS environment. Likewise, I don't have the +time or resources to provide much support. (I'm not sure my management +would allow any :-( ) + +With all of the above feel free to say "Thanks, but no thanks." If you +want to see the diffs anyway, I will certainly mail them. + +Thanks for your time and efforts. + +Steve Layten +Chemical Abstracts Service, PO Box 3012, Columbus, OH 43210, +1 614 421-3600 +INET: swl26%cas.BITNET@CUNYVM.CUNY.Edu diff --git a/commands/flex-2.5.4/MISC/MVS/MVS.todo b/commands/flex-2.5.4/MISC/MVS/MVS.todo new file mode 100644 index 000000000..b6060eca4 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/MVS.todo @@ -0,0 +1,23 @@ +(Message inbox:47) +Date: Wed, 18 Jul 1990 14:16 EDT +From: swl26%CAS.BITNET@CORNELLC.cit.cornell.edu +Subject: Re(2): Re(2): diffs for mvs port of flex-2.3 +To: vern@cs.cornell.edu + + + +>Thanks, I've successfully unpacked the archive. I may simply distribute +>the diffs as a set of files in the MISC/ directory rather than incorporating +>them into the 2.4 release. Let me know if you don't want me to do so. +> +> Vern + + +Thank you! What you propose is okay. I might suggest, however, that you +look in the diffs for dfa.c, misc.c, and yylex.c, and consider removing +some of the ASCIIisms which are probably unnecessary. The manner in +which I made the changes was pure brute force, and there might be a +better way, but the changes I made there shouldn't hurt anything. + + regards, + Steve diff --git a/commands/flex-2.5.4/MISC/MVS/MVS.uudecode b/commands/flex-2.5.4/MISC/MVS/MVS.uudecode new file mode 100644 index 000000000..2b8e802ae --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/MVS.uudecode @@ -0,0 +1,341 @@ +Received: from CU-ARPA.CS.CORNELL.EDU by loki.cs.cornell.edu (5.61/I-1.91f) + id AA25874; Wed, 18 Jul 90 12:02:22 -0400 +Message-Id: <9007181320.AA24810@cu-arpa.cs.cornell.edu> +Received: from CORNELLC.CIT.CORNELL.EDU by cu-arpa.cs.cornell.edu (5.61+2/1.91d) + id AA24810; Wed, 18 Jul 90 09:20:21 -0400 +Received: from CORNELLC by CORNELLC.cit.cornell.edu (IBM VM SMTP R1.2.1MX) with BSMTP id 6769; Wed, 18 Jul 90 09:18:46 EDT +Received: from CAS.BITNET (MAILER) by CORNELLC (Mailer R2.05X) with BSMTP id + 5378; Wed, 18 Jul 90 09:18:38 EDT +From: swl26%CAS.BITNET@CORNELLC.cit.cornell.edu +Date: Wed, 18 Jul 1990 09:16 EDT +Subject: Re(2): diffs for mvs port of flex-2.3 +In-Reply-To: Your message of Tue, 17 Jul 90 17:42:3 +To: vern@cs.cornell.edu + +Sorry about the trailing blank problem. It's farily common with data sent +through bitnet paths, but ever the optimist ... + +>I think there should be an 'M' at the beginning of the second line. + +This isn't a problem. I believe that the first byte of the line indicates +it's length (in some manner). + +Rather than re-send the data, how about a uudecode that compensates for +the trailing blank problem? I manually mangled the uuencoded file and ran +the following decode, and it seemed to work. + +#! /bin/sh +# This is a shell archive. Remove anything before this line, then feed it +# into a shell via "sh file" or similar. To overwrite existing files, +# type "sh file -c". +# The tool that generated this appeared in the comp.sources.unix newsgroup; +# send mail to comp-sources-unix@uunet.uu.net if you want that tool. +# If this archive is complete, you will see the following message at the end: +# "End of shell archive." +# Contents: uudecode.c +# Wrapped by swl26@swl26aws on Wed Jul 18 08:59:24 1990 +PATH=/bin:/usr/bin:/usr/ucb ; export PATH +if test -f 'uudecode.c' -a "${1}" != "-c" ; then + echo shar: Will not clobber existing file \"'uudecode.c'\" +else +echo shar: Extracting \"'uudecode.c'\" \(6418 characters\) +sed "s/^X//" >'uudecode.c' <<'END_OF_FILE' +X/* #ifndef lint +Xstatic char sccsid[] = "@(#)uudecode.c 5.3-1 (Berkeley) 9/1/87"; +X#endif */ +X +X/* Written by Mark Horton */ +X/* Modified by ajr (Alan J Rosenthatl,flaps@utcsri.UUCP) to use checksums */ +X/* Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for +X compatibility */ +X/* Modified by bcn (Bryce Nesbitt,ucbvax!cogsci!bryce) to fix a misleading +X error message on the Amiga port, to fix a bug that prevented decoding +X certain files, to work even if trailing spaces have been removed from a +X file, to check the filesize (if present), to add some error checking, to +X loop for multiple decodes from a single file, and to handle common +X BITNET mangling. Also kludged around a missing string function in Aztec +X C */ +X +X/* +X * uudecode [input] +X * +X * Decode a file encoded with uuencode. WIll extract multiple encoded +X * modules from a single file. Can deal with most mangled files, including +X * BITNET. +X */ +X +X#include +X#include +X +X#ifdef AMIGA +X#define AMIGA_LATTICE /* Set for Amiga Lattice C */ +X#define MCH_AMIGA +X#define MPU68000 +X#endif +X +X#ifdef unix +X#include +X#include +X#include +X#endif +X +X#define SUMSIZE 64 +X#define DEC(c) (((c) - ' ') & 077) /* single character decode */ +X +Xmain(argc, argv) +Xchar **argv; +X{ +XFILE *in, *out; +Xint through_loop=0; /* Dejavu indicator */ +Xint mode; /* file's mode (from header) */ +Xlong filesize; /* theoretical file size (from header) */ +Xchar dest[128]; +Xchar buf[80]; +X +X#ifdef AMIGA_LATTICE +Xextern int Enable_Abort; +X Enable_Abort=1; +X#endif +X +X /* A filename can be specified to be uudecoded, or nothing can +X be specified, and the input will come from STDIN */ +X +X switch (argc) +X { +X case 1: +X in=stdin; +X break; +X +X case 2: +X if ((in = fopen(argv[1], "r")) == NULL) +X { +X fprintf(stderr, "ERROR: can't find %s\n", argv[1]); +X fprintf(stderr, "USAGE: uudecode [infile]\n"); +X exit(10); +X } +X break; +X +X default: +X fprintf(stderr, "USAGE: uudecode [infile]\n"); +X exit(11); +X break; +X } +X +X /* Loop through file, searching for headers. Decode anything with a +X header, complain if there where no headers. */ +X +Xfor (;;) +X{ +X /* search file for header line */ +X for (;;) +X { +X if (fgets(buf, sizeof buf, in) == NULL) +X { +X if (!through_loop) +X { +X fprintf(stderr, "ERROR: no `begin' line!\n"); +X exit(12); +X } +X else +X { +X exit(0); +X } +X } +X if (strncmp(buf, "begin ", 6) == 0) +X break; +X } +X sscanf(buf, "begin %o %s", &mode, dest); +X +X#ifdef unix +X /* handle ~user/file format */ +X if (dest[0] == '~') +X { +X char *sl; +X struct passwd *getpwnam(); +X char *index(); +X struct passwd *user; +X char dnbuf[100]; +X +X sl = index(dest, '/'); +X if (sl == NULL) +X { +X fprintf(stderr, "Illegal ~user\n"); +X exit(13); +X } +X *sl++ = 0; +X user = getpwnam(dest+1); +X if (user == NULL) +X { +X fprintf(stderr, "No such user as %s\n", dest); +X exit(14); +X } +X strcpy(dnbuf, user->pw_dir); +X strcat(dnbuf, "/"); +X strcat(dnbuf, sl); +X strcpy(dest, dnbuf); +X } +X#endif +X +X /* create output file */ +X if ((out = fopen(dest, "w")) == NULL) +X { +X fprintf(stderr, "ERROR: can't open output file %s\n", dest); +X exit(15); +X } +X#ifdef unix +X chmod(dest, mode); +X#endif +X +X decode(in, out, dest); +X +X if (fgets(buf, sizeof buf, in) == NULL || strncmp(buf,"end",3)) +X { /* don't be overly picky about newline ^ */ +X fprintf(stderr, "ERROR: no `end' line\n"); +X exit(16); +X } +X +X if (!(fgets(buf,sizeof buf,in) == NULL || strncmp(buf,"size ",3))) +X { +X sscanf(buf, "size %ld", &filesize); +X if (ftell(out) != filesize) +X { +X fprintf(stderr, "ERROR: file should have been %ld bytes long but was +X exit(17); +X } +X } +X through_loop = 1; +X} /* forever */ +X} /* main */ +X +X/* +X * Copy from in to out, decoding as you go. +X * If a return or newline is encountered too early in a line, it is +X * assumed that means that some editor has truncated trailing spaces. +X */ +Xdecode(in, out, dest) +XFILE *in; +XFILE *out; +Xchar *dest; +X{ +Xchar buf[81]; +Xchar *bp; +Xint nosum=0; +X#ifndef unix +Xextern errno; +X#endif +Xregister int j; +Xregister int n; +Xint checksum, line; +X +X for (line = 1; ; line++) /* for each input line */ +X { +X if (fgets(buf, sizeof buf, in) == NULL) +X { +X fprintf(stderr, "ERROR: input ended unexpectedly!\n"); +X exit(18); +X } +X +X /* Pad end of lines in case some editor truncated trailing +X spaces */ +X +X for (n=0;n<79;n++) /* search for first \r, \n or \000 */ +X { +X if (buf[n]=='\176') /* If BITNET made a twiddle, */ +X buf[n]='\136'; /* we make a caret */ +X if (buf[n]=='\r'||buf[n]=='\n'||buf[n]=='\000') +X break; +X } +X for (;n<79;n++) /* when found, fill rest of line with space */ +X { +X buf[n]=' '; +X } +X buf[79]=0; /* terminate new string */ +X +X checksum = 0; +X n = DEC(buf[0]); +X if (n <= 0) +X break; /* 0 bytes on a line?? Must be the last line */ +X +X bp = &buf[1]; +X +X /* FOUR input characters go into each THREE output charcters */ +X +X while (n >= 4) +X { +X j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; putc(j, out); checksum += j; +X j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; putc(j, out); checksum += j; +X j = DEC(bp[2]) << 6 | DEC(bp[3]); putc(j, out); checksum += j; +X checksum = checksum % SUMSIZE; +X bp += 4; +X n -= 3; +X } +X +X j = DEC(bp[0]) << 2 | DEC(bp[1]) >> 4; +X checksum += j; +X if (n >= 1) +X putc(j, out); +X j = DEC(bp[1]) << 4 | DEC(bp[2]) >> 2; +X checksum += j; +X if (n >= 2) +X putc(j, out); +X j = DEC(bp[2]) << 6 | DEC(bp[3]); +X checksum += j; +X if (n >= 3) +X putc(j, out); +X checksum = checksum % SUMSIZE; +X bp += 4; +X n -= 3; +X +X#ifndef unix +X /* Error checking under UNIX??? You must be kidding... */ +X /* Check if an error occured while writing to that last line */ +X if (errno) +X { +X fprintf(stderr, "ERROR: error writing to %s\n",dest); +X exit(19); +X } +X#endif +X +X /* The line has been decoded; now check that sum */ +X +X nosum |= !isspace(*bp); +X if (nosum) /* Is there a checksum at all?? */ +X { +X if (checksum != DEC(*bp)) /* Does that checksum match? */ +X { +X fprintf(stderr, "ERROR: checksum mismatch decoding %s, line %d.\ +X } +X } /* sum */ +X } /* line */ +X} /* function */ +X +X#ifdef unix +X/* +X * Return the ptr in sp at which the character c appears; +X * 0 if not found +X */ +Xchar * +Xindex(sp, c) +Xregister char *sp, c; +X{ +X do +X { +X if (*sp == c) +X return(sp); +X } +X while (*sp++); +X +X return(0); +X} +X#endif unix +X + +END_OF_FILE +echo shar: NEWLINE appended to \"'uudecode.c'\" +if test 6419 -ne `wc -c <'uudecode.c'`; then + echo shar: \"'uudecode.c'\" unpacked with wrong size! +fi +# end of 'uudecode.c' +fi +echo shar: End of shell archive. +exit 0 diff --git a/commands/flex-2.5.4/MISC/MVS/README b/commands/flex-2.5.4/MISC/MVS/README new file mode 100644 index 000000000..09741ab05 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/README @@ -0,0 +1,44 @@ +These patches and supplemental programs should allow porting to MVS or MVS/XA +in an EBCDIC envrionment, using SAS C V4.00C. + +Included are: + -rw-r--r-- 1 swl26 1573 Jul 17 14:32 README + -rw-rw-r-- 1 swl26 20861 Jul 17 13:41 diffs + -rw-rw-r-- 1 swl26 5022 Jul 17 14:00 fixit.l + -rw-rw-r-- 1 swl26 97644 Jul 17 13:42 initscan.mvs.c + -rw-rw-r-- 1 swl26 4898 Jul 17 14:08 unfixit.l + +The file "diffs" contains context diffs for changes to flex 2.3. + +The file "fixit.l" contains flex sources for a program to shorten external +variable and function names to 8 characters or less. This is required for the +"dumb" compiler linker used. + +The file "unfixit.l" reverses the changes in "fixit.l", to restore long names. +This is useful when trying to build diff files as created here. + +The file "initscan.mvs.c" is an already "flexed" version of scan.l, in an +EBCDIC environment. + +To install in an MVS environment, use patch to apply the diffs to flex 2.3, +then run "fixit" on all .c, .h, .l, .y, and .skel files. Move the files +to the MVS machine, and compile each of the .c files. (You will need a +"yacc" functional equivalent under MVS to expand parse.y in that +environment.) Link together, and the resulting flex should be ready to +go. To test, run the MVSflex -is8 -Ce on the scan.l, and you should get +back a file which is identical to initscan.mvs.c. + +Enjoy. + +Steven W. Layten +Senior Engineer +Chemical Abstracts Service +PO Box 3012 +2540 Olentangy River Road +Columbus, Ohio 43210 + ++1 614 421 3600 extension 3451 + +INET: swl26%cas.BITNET@CUNYVM.CUNY.Edu +UUCP: osu-cis!chemabs!swl26 +BITNET: swl26@cas.bitnet diff --git a/commands/flex-2.5.4/MISC/MVS/diffs b/commands/flex-2.5.4/MISC/MVS/diffs new file mode 100644 index 000000000..77cf305a8 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/diffs @@ -0,0 +1,854 @@ +diff -c ../Makefile ./Makefile +*** ../Makefile Thu Jun 28 00:44:07 1990 +--- ./Makefile Mon Jul 16 13:57:26 1990 +*************** +*** 39,49 **** + # AUXDIR, manual pages will be installed in MANDIR with extension MANEXT. + # Raw, unformatted troff source will be installed if INSTALLMAN=man, nroff + # preformatted versions will be installed if INSTALLMAN=cat. +! DESTDIR = + BINDIR = /usr/local + LIBDIR = /usr/local/lib + AUXDIR = /usr/local/lib + MANDIR = /usr/man/manl + MANEXT = l + INSTALLMAN = man + +--- 39,50 ---- + # AUXDIR, manual pages will be installed in MANDIR with extension MANEXT. + # Raw, unformatted troff source will be installed if INSTALLMAN=man, nroff + # preformatted versions will be installed if INSTALLMAN=cat. +! DESTDIR = /projects/m751stereo/code/c/swl26 + BINDIR = /usr/local + LIBDIR = /usr/local/lib + AUXDIR = /usr/local/lib + MANDIR = /usr/man/manl ++ INCLUDEDIR = . + MANEXT = l + INSTALLMAN = man + +*************** +*** 52,58 **** + + SKELETON_FILE = $(DESTDIR)$(AUXDIR)/flex.skel + SKELFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_FILE)\" +! CFLAGS = -O + LDFLAGS = -s + + COMPRESSION = +--- 53,59 ---- + + SKELETON_FILE = $(DESTDIR)$(AUXDIR)/flex.skel + SKELFLAGS = -DDEFAULT_SKELETON_FILE=\"$(SKELETON_FILE)\" +! CFLAGS = -O -DUSG -I$(INCLUDEDIR) + LDFLAGS = -s + + COMPRESSION = +diff -c ../ccl.c ./ccl.c +*** ../ccl.c Thu Jun 28 00:44:07 1990 +--- ./ccl.c Mon Jul 16 13:57:27 1990 +*************** +*** 28,37 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + /* ccladd - add a single character to a ccl + * +--- 28,37 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include + + /* ccladd - add a single character to a ccl + * +diff -c ../dfa.c ./dfa.c +*** ../dfa.c Thu Jun 28 00:44:08 1990 +--- ./dfa.c Mon Jul 16 13:57:28 1990 +*************** +*** 28,37 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + + /* declare functions that have forward references */ +--- 28,38 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include +! #include + + + /* declare functions that have forward references */ +*************** +*** 682,688 **** + register int j; + + for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j ) +! state[i] = state[j]; + } + + if ( ds > num_start_states ) +--- 683,692 ---- + register int j; + + for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j ) +! { +! if (isupper(i) ) +! state[i] = state[j]; +! } + } + + if ( ds > num_start_states ) +*************** +*** 958,964 **** + } + } + +! else if ( sym >= 'A' && sym <= 'Z' && caseins ) + flexfatal( "consistency check failed in symfollowset" ); + + else if ( sym == SYM_EPSILON ) +--- 962,968 ---- + } + } + +! else if ( isupper ( sym ) && caseins ) + flexfatal( "consistency check failed in symfollowset" ); + + else if ( sym == SYM_EPSILON ) +Only in .: diffs +Only in .: diffs.new +diff -c ../ecs.c ./ecs.c +*** ../ecs.c Thu Jun 28 00:44:08 1990 +--- ./ecs.c Mon Jul 16 13:57:28 1990 +*************** +*** 28,37 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + /* ccl2ecl - convert character classes to set of equivalence classes + * +--- 28,37 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include + + /* ccl2ecl - convert character classes to set of equivalence classes + * +diff -c ../flex.skel ./flex.skel +*** ../flex.skel Thu Jun 28 00:44:27 1990 +--- ./flex.skel Mon Jul 16 13:57:29 1990 +*************** +*** 1,7 **** + /* A lexical scanner generated by flex */ + + /* scanner skeleton version: +! * $Header$ + */ + + #define FLEX_SCANNER +--- 1,7 ---- + /* A lexical scanner generated by flex */ + + /* scanner skeleton version: +! * $Header$ + */ + + #define FLEX_SCANNER +diff -c ../flexdef.h ./flexdef.h +*** ../flexdef.h Thu Jun 28 00:44:27 1990 +--- ./flexdef.h Mon Jul 16 13:57:30 1990 +*************** +*** 26,32 **** + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +! /* @(#) $Header$ (LBL) */ + + #ifndef FILE + #include +--- 26,32 ---- + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +! /* @(#) $Header$ (LBL) */ + + #ifndef FILE + #include +*************** +*** 45,51 **** + + /* size of input alphabet - should be size of ASCII set */ + #ifndef DEFAULT_CSIZE +! #define DEFAULT_CSIZE 128 + #endif + + #ifndef PROTO +--- 45,51 ---- + + /* size of input alphabet - should be size of ASCII set */ + #ifndef DEFAULT_CSIZE +! #define DEFAULT_CSIZE 256 + #endif + + #ifndef PROTO +*************** +*** 90,96 **** +--- 90,98 ---- + #define SHORT_FILE_NAMES + #endif + ++ #ifndef OSVS + char *malloc(), *realloc(); ++ #endif + + + /* maximum line length we'll have to deal with */ +*************** +*** 116,125 **** + #define true 1 + #define false 0 + +- + #ifndef DEFAULT_SKELETON_FILE + #define DEFAULT_SKELETON_FILE "flex.skel" +! #endif + + /* special chk[] values marking the slots taking by end-of-buffer and action + * numbers +--- 118,132 ---- + #define true 1 + #define false 0 + + #ifndef DEFAULT_SKELETON_FILE ++ #ifdef OSVS ++ #define DEFAULT_SKELETON_FILE "ctri01" ++ #define SYSUT1 "sysut1" ++ #define SYSUT2 "sysut2" ++ #else + #define DEFAULT_SKELETON_FILE "flex.skel" +! #endif /* OSVS */ +! #endif /* DEFAULT_SKELETON_FILE */ + + /* special chk[] values marking the slots taking by end-of-buffer and action + * numbers +*************** +*** 226,233 **** + #define INITIAL_MAX_SCS 40 /* maximum number of start conditions */ + #define MAX_SCS_INCREMENT 40 /* amount to bump by if it's not enough */ + +! #define ONE_STACK_SIZE 500 /* stack of states with only one out-transition */ +! #define SAME_TRANS -1 /* transition is the same as "default" entry for state */ + + /* the following percentages are used to tune table compression: + +--- 233,240 ---- + #define INITIAL_MAX_SCS 40 /* maximum number of start conditions */ + #define MAX_SCS_INCREMENT 40 /* amount to bump by if it's not enough */ + +! #define ONE_STACK_SIZE 500 /*stack of states with only one out-transition*/ +! #define SAME_TRANS -1 /*transition is the same as "default" entry for state */ + + /* the following percentages are used to tune table compression: + +diff -c ../gen.c ./gen.c +*** ../gen.c Thu Jun 28 00:44:28 1990 +--- ./gen.c Mon Jul 16 13:57:32 1990 +*************** +*** 28,37 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + + /* declare functions that have forward references */ +--- 28,37 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include + + + /* declare functions that have forward references */ +*************** +*** 292,298 **** + + indent_puts( "{" ); + +! indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" ); + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_act = yy_acclist[yy_lp];" ); +--- 292,298 ---- + + indent_puts( "{" ); + +! indent_puts("if( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )"); + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_act = yy_acclist[yy_lp];" ); +diff -c ../initscan.c ./initscan.c +*** ../initscan.c Thu Jun 28 00:44:51 1990 +--- ./initscan.c Mon Jul 16 13:57:33 1990 +*************** +*** 1,7 **** + /* A lexical scanner generated by flex */ + + /* scanner skeleton version: +! * $Header$ + */ + + #define FLEX_SCANNER +--- 1,7 ---- + /* A lexical scanner generated by flex */ + + /* scanner skeleton version: +! * $Header$ + */ + + #define FLEX_SCANNER +*************** +*** 193,199 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #undef yywrap +--- 193,199 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #undef yywrap +diff -c ../libmain.c ./libmain.c +*** ../libmain.c Thu Jun 28 00:44:28 1990 +--- ./libmain.c Mon Jul 16 13:57:34 1990 +*************** +*** 1,6 **** + /* libmain - flex run-time support library "main" function */ + +! /* $Header$ */ + + extern int yylex(); + +--- 1,6 ---- + /* libmain - flex run-time support library "main" function */ + +! /* $Header$ */ + + extern int yylex(); + +diff -c ../main.c ./main.c +*** ../main.c Thu Jun 28 00:44:29 1990 +--- ./main.c Mon Jul 16 13:57:34 1990 +*************** +*** 34,44 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + +! #include "flexdef.h" + + static char flex_version[] = "2.3"; + +--- 34,44 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + +! #include + + static char flex_version[] = "2.3"; + +*************** +*** 97,106 **** + char *program_name; + + #ifndef SHORT_FILE_NAMES + static char *outfile = "lex.yy.c"; +! #else + static char *outfile = "lexyy.c"; +! #endif + static int outfile_created = 0; + static int use_stdout; + static char *skelname = NULL; +--- 97,110 ---- + char *program_name; + + #ifndef SHORT_FILE_NAMES ++ #ifdef OSVS ++ static char *outfile = "ctro01"; ++ #else /* not OSVS */ + static char *outfile = "lex.yy.c"; +! #endif /* not OSVS */ +! #else /* SHORT_FILE_NAMES */ + static char *outfile = "lexyy.c"; +! #endif /* SHORT_FILE_NAMES */ + static int outfile_created = 0; + static int use_stdout; + static char *skelname = NULL; +*************** +*** 209,216 **** +--- 213,222 ---- + else if ( fclose( temp_action_file ) ) + flexfatal( "error occurred when closing temporary action file" ); + ++ #ifndef OSVS + else if ( unlink( action_file_name ) ) + flexfatal( "error occurred when deleting temporary action file" ); ++ #endif + } + + if ( status != 0 && outfile_created ) +*************** +*** 221,228 **** +--- 227,236 ---- + else if ( fclose( stdout ) ) + flexfatal( "error occurred when closing output file" ); + ++ #ifndef OSVS + else if ( unlink( outfile ) ) + flexfatal( "error occurred when deleting output file" ); ++ #endif + } + + if ( backtrack_report && backtrack_file ) +*************** +*** 574,583 **** + if ( backtrack_report ) + { + #ifndef SHORT_FILE_NAMES + backtrack_file = fopen( "lex.backtrack", "w" ); +! #else + backtrack_file = fopen( "lex.bck", "w" ); +! #endif + + if ( backtrack_file == NULL ) + flexerror( "could not create lex.backtrack" ); +--- 582,595 ---- + if ( backtrack_report ) + { + #ifndef SHORT_FILE_NAMES ++ #ifdef OSVS ++ backtrack_file = fopen( SYSUT2, "w"); ++ #else /* not OSVS */ + backtrack_file = fopen( "lex.backtrack", "w" ); +! #endif /* OSVS */ +! #else /* SHORT_FILE_NAMES */ + backtrack_file = fopen( "lex.bck", "w" ); +! #endif /* SHORT_FILE_NAMES */ + + if ( backtrack_file == NULL ) + flexerror( "could not create lex.backtrack" ); +*************** +*** 597,604 **** + lerrsf( "can't open skeleton file %s", skelname ); + + #ifdef SYS_V + action_file_name = tmpnam( NULL ); +! #endif + + if ( action_file_name == NULL ) + { +--- 609,620 ---- + lerrsf( "can't open skeleton file %s", skelname ); + + #ifdef SYS_V ++ #ifndef OSVS + action_file_name = tmpnam( NULL ); +! #else /* OSVS */ +! action_file_name = SYSUT1; +! #endif /* OSVS */ +! #endif /* SYS_V */ + + if ( action_file_name == NULL ) + { +*************** +*** 609,615 **** +--- 625,636 ---- + #else + (void) strcpy( temp_action_file_name, "flexXXXXXX.tmp" ); + #endif ++ #ifndef OSVS + (void) mktemp( temp_action_file_name ); ++ #else /* OSVS */ ++ /* should never be executed in OSVS as IF should always be false */ ++ (void) strcpy( temp_action_file_name, SYSUT1 ) ; ++ #endif /* OSVS */ + + action_file_name = temp_action_file_name; + } +diff -c ../misc.c ./misc.c +*** ../misc.c Thu Jun 28 00:44:40 1990 +--- ./misc.c Mon Jul 16 13:57:35 1990 +*************** +*** 28,38 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #include +! #include "flexdef.h" + + + /* ANSI C does not guarantee that isascii() is defined */ +--- 28,38 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #include +! #include + + + /* ANSI C does not guarantee that isascii() is defined */ +*************** +*** 107,113 **** +--- 107,117 ---- + { + while ( *str ) + { ++ #ifdef OSVS ++ if ( ! islower( *str ) ) ++ #else + if ( ! isascii( *str ) || ! islower( *str ) ) ++ #endif + return ( 0 ); + ++str; + } +*************** +*** 130,136 **** +--- 134,144 ---- + { + while ( *str ) + { ++ #ifdef OSVS ++ if ( ! isupper( (char) *str ) ) ++ #else + if ( ! isascii( *str ) || ! isupper( (char) *str ) ) ++ #endif + return ( 0 ); + ++str; + } +*************** +*** 182,188 **** +--- 190,200 ---- + register int c; + + { ++ #ifdef OSVS ++ return ( isupper( c ) ? (Char) tolower( c ) : (Char) c ); ++ #else + return ( (isascii( c ) && isupper( c )) ? tolower( c ) : c ); ++ #endif + } + + +*************** +*** 204,210 **** + for ( c = str; *c; ++c ) + ; + +! copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) ); + + if ( copy == NULL ) + flexfatal( "dynamic memory failure in copy_string()" ); +--- 216,222 ---- + for ( c = str; *c; ++c ) + ; + +! copy = (char *) malloc( (unsigned) ((c - str + 1) * sizeof( char )) ); + + if ( copy == NULL ) + flexfatal( "dynamic memory failure in copy_string()" ); +*************** +*** 392,403 **** +--- 404,421 ---- + + #ifndef MS_DOS + #ifndef VMS ++ #ifndef OSVS + #include ++ #endif /* OSVS */ + #else + #include + #endif + #endif + ++ #ifdef OSVS ++ #include ++ #endif /* OSVS */ ++ + #ifdef MS_DOS + #include + typedef long time_t; +*************** +*** 615,621 **** +--- 633,643 ---- + if ( array[1] == 'x' ) + ++sptr; + ++ #ifdef OSVS ++ while ( isdigit( array[sptr] ) ) ++ #else + while ( isascii( array[sptr] ) && isdigit( array[sptr] ) ) ++ #endif + /* don't increment inside loop control because if + * isdigit() is a macro it will expand it to two + * increments ... +Only in ..: new +diff -c ../nfa.c ./nfa.c +*** ../nfa.c Thu Jun 28 00:44:40 1990 +--- ./nfa.c Mon Jul 16 13:57:36 1990 +*************** +*** 28,37 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + + /* declare functions that have forward references */ +--- 28,37 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include + + + /* declare functions that have forward references */ +*************** +*** 110,116 **** + { + int sym, tsp1, tsp2, anum, ns; + +! fprintf( stderr, "\n\n********** beginning dump of nfa with start state %d\n", + state1 ); + + /* we probably should loop starting at firstst[state1] and going to +--- 110,116 ---- + { + int sym, tsp1, tsp2, anum, ns; + +! fprintf(stderr,"\n\n********* beginning dump of nfa with start state %d\n", + state1 ); + + /* we probably should loop starting at firstst[state1] and going to +diff -c ../parse.y ./parse.y +*** ../parse.y Thu Jun 28 00:44:40 1990 +--- ./parse.y Mon Jul 16 13:57:36 1990 +*************** +*** 32,45 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen; + int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule; + Char clower(); + + static int madeany = false; /* whether we've made the '.' character class */ + int previous_continued_action; /* whether the previous rule's action was '|' */ +--- 32,47 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include + + int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen; + int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule; + Char clower(); ++ void build_eof_action(); ++ void yyerror(); + + static int madeany = false; /* whether we've made the '.' character class */ + int previous_continued_action; /* whether the previous rule's action was '|' */ +diff -c ../scan.l ./scan.l +*** ../scan.l Thu Jun 28 00:44:41 1990 +--- ./scan.l Mon Jul 16 13:57:37 1990 +*************** +*** 30,42 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #undef yywrap + +! #include "flexdef.h" +! #include "parse.h" + + #define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) + #define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); +--- 30,42 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #undef yywrap + +! #include +! #include + + #define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) + #define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); +diff -c ../sym.c ./sym.c +*** ../sym.c Thu Jun 28 00:44:41 1990 +--- ./sym.c Mon Jul 16 13:57:37 1990 +*************** +*** 28,37 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + + /* declare functions that have forward references */ +--- 28,37 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include + + + /* declare functions that have forward references */ +diff -c ../tblcmp.c ./tblcmp.c +*** ../tblcmp.c Thu Jun 28 00:44:41 1990 +--- ./tblcmp.c Mon Jul 16 13:57:38 1990 +*************** +*** 28,37 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include "flexdef.h" + + + /* declarations for functions that have forward references */ +--- 28,37 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + +! #include + + + /* declarations for functions that have forward references */ +diff -c ../yylex.c ./yylex.c +*** ../yylex.c Thu Jun 28 00:44:41 1990 +--- ./yylex.c Mon Jul 16 13:57:38 1990 +*************** +*** 28,39 **** + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #include +! #include "flexdef.h" +! #include "parse.h" + + + /* ANSI C does not guarantee that isascii() is defined */ +--- 28,39 ---- + + #ifndef lint + static char rcsid[] = +! "@(#) $Header$ (LBL)"; + #endif + + #include +! #include +! #include + + + /* ANSI C does not guarantee that isascii() is defined */ +*************** +*** 180,186 **** +--- 180,190 ---- + break; + + default: ++ #ifdef OSVS ++ if ( ! isprint( yylval ) ) ++ #else + if ( ! isascii( yylval ) || ! isprint( yylval ) ) ++ #endif + fprintf( stderr, "\\%.3o", yylval ); + else + (void) putc( yylval, stderr ); diff --git a/commands/flex-2.5.4/MISC/MVS/fixit.l b/commands/flex-2.5.4/MISC/MVS/fixit.l new file mode 100644 index 000000000..3e15b6fa4 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/fixit.l @@ -0,0 +1,138 @@ +%{ +/* fixit.l - convert long external names to names of 8-bytes or less */ +/* + * This program is included to satisfy "dumb" compilers/linkers which + * do not know about externals of names longer than 8 bytes. + * + * Steven W. Layten + * Chemical Abstracts Service + * PO BOX 3012 + * Columbus, OH 43210 + */ +%} +%% +"action_file_name" printf("actfilnm"); +"action_out" printf("actnout"); +"add_accept" printf("addacpt"); +"all_lower" printf("alllower"); +"all_upper" printf("allupper"); +"allocate_array" printf("allocarr"); +"assoc_rule" printf("asscrule"); +"backtrack_file" printf("bktrkfil"); +"backtrack_report" printf("bktrkrep"); +"bol_needed" printf("bol_nded"); +"build_eof_action" printf("bldeofac"); +"cclinstal" printf("cclnstal"); +"ccllookup" printf("ccllookp"); +"cclnegate" printf("cclnegat"); +"cclsorted" printf("cclsrted"); +"check_for_backtracking" printf("ck4bktrk"); +"check_trailing_context" printf("cktrlcnt"); +"continued_action" printf("cntdactn"); +"copy_string" printf("copystrn"); +"copy_unsigned_string" printf("cpunsstr"); +"copyright" printf("cpyrght"); +"copysingl" printf("copysngl"); +"current_max_ccl_tbl_size" printf("c_mx_ccl"); +"current_max_dfa_size" printf("c_mx_dfa"); +"current_max_dfas" printf("c_mxdfas"); +"current_max_rules" printf("curmxrls"); +"current_max_scs" printf("c_mx_scs"); +"current_max_template_xpairs" printf("c_mx_tmp"); +"current_max_xpairs" printf("c_mx_xpr"); +"current_maxccls" printf("c_mxccls"); +"current_mns" printf("curr_mns"); +"current_state_type" printf("cursttyp"); +"dataflush" printf("datflush"); +"dfaacc_union" printf("dfacunin"); +"do_indent" printf("do_indnt"); +"dump_associated_rules" printf("dmpasrl"); +"dump_transitions" printf("dmptrns"); +"dupmachine" printf("dupmach"); +"ecs_from_xlation" printf("ecsfrmxt"); +"end_of_buffer_state" printf("eobstate"); +"epsclosure" printf("epsclos"); +"expand_nxt_chk" printf("expnxtck"); +"find_table_space" printf("fndtblsp"); +"finish_rule" printf("fnshrule"); +"firstfree" printf("firstfre"); +"firstprot" printf("firstprt"); +"flex_gettime" printf("flxgettm"); +"flexerror" printf("flxerror"); +"flexfatal" printf("flxfatal"); +"format_pinpoint_message" printf("fmtptmsg"); +"gen_NUL_trans" printf("gnNULtrn"); +"gen_backtracking" printf("gnbktrkg"); +"gen_bt_action" printf("gnbtactn"); +"gen_find_action" printf("gnfndact"); +"gen_line_dirs" printf("gnlindir"); +"gen_next_compressed_state" printf("gnnxcste"); +"gen_next_match" printf("gnnxmtch"); +"gen_next_state" printf("gnnxtst"); +"gen_start_state" printf("gnstrtst"); +"hash_entry" printf("hshentry"); +"hashfunct" printf("hshfct"); +"increase_max_dfas" printf("incmxdfa"); +"indent_put2s" printf("indput2s"); +"indent_puts" printf("indputs"); +"infilename" printf("infilnam"); +"input_files" printf("inp_fles"); +"interactive" printf("intractv"); +"line_directive_out" printf("lndirout"); +"link_machines" printf("lnkmchns"); +"list_character_set" printf("lst_cset"); +"make_tables" printf("maketbls"); +"mark_beginning_as_normal" printf("mkbgnorm"); +"mktemplate" printf("mktmplat"); +"num_backtracking" printf("nbktrckg"); +"num_input_files" printf("ninfiles"); +"num_reallocs" printf("numraloc"); +"num_rules" printf("numrules"); +"num_xlations" printf("nuxlatns"); +"numsnpairs" printf("numnpair"); +"output_file_name" printf("outfilnm"); +"peakpairs" printf("peakpair"); +"performance_report" printf("perf_rep"); +"pinpoint_message" printf("pptmsg"); +"place_state" printf("plcstate"); +"previous_continued_action" printf("prvctdan"); +"printstats" printf("prtstats"); +"program_name" printf("pgm_name"); +"protcomst" printf("prtcomst"); +"readable_form" printf("rdblefrm"); +"real_reject" printf("realrjct"); +"reallocate_array" printf("rallocar"); +"reject_really_used" printf("rjctused"); +"rule_linenum" printf("rulelnno"); +"rule_type" printf("ruletype"); +"set_input_file" printf("stinpfle"); +"set_up_initial_allocations" printf("setupia"); +"starttime" printf("startime"); +"state_type" printf("ste_type"); +"symfollowset" printf("symfollo"); +"sympartition" printf("sympartn"); +"syntaxerror" printf("syntxerr"); +"temp_action_file" printf("tmpactfl"); +"todo_head" printf("todohead"); +"todo_next" printf("todonext"); +"transchar" printf("trnschar"); +"transition_struct_out" printf("trnstout"); +"trlcontxt" printf("trlcntxt"); +"variable_trail_rule" printf("vtrailrl"); +"variable_trailing_context_rules" printf("vtrlctrl"); +"varlength" printf("varlngth"); +"yy_create_buffer" printf("yycrbffr"); +"yy_delete_buffer" printf("yydlbffr"); +"yy_init_buffer" printf("yyinbffr"); +"yy_load_buffer_state" printf("yyldbfst"); +"yy_switch_to_buffer" printf("yyswtobf"); +"yyerrflag" printf("yyerrflg"); +"yymore_really_used" printf("yymrreus"); +"yymore_used" printf("yymrused"); +"yyrestart" printf("yyrestrt"); +. ECHO; +%% +main() +{ + yylex(); +} diff --git a/commands/flex-2.5.4/MISC/MVS/initscan-mvs.c b/commands/flex-2.5.4/MISC/MVS/initscan-mvs.c new file mode 100644 index 000000000..9aaed4a53 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/initscan-mvs.c @@ -0,0 +1,2672 @@ +/* A lexical scanner generated by flex */ + +/* scanner skeleton version: + * $Header: flex.skel,v 2.13 90/05/26 17:24:13 ve + */ + +#define FLEX_SCANNER + +#include + +#ifdef __STDC__ + +#ifndef DONT_HAVE_STDLIB_H +#include +#else +void *malloc( unsigned ); +void free( void* ); +#endif + +#define YY_USE_PROTOS +#define YY_USE_CONST +#endif + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#ifndef __STDC__ +#include +#endif + +#include + +/* use prototypes in function declarations */ +#define YY_USE_PROTOS + +/* the "const" storage-class-modifier is valid */ +#define YY_USE_CONST + +#endif + + +#ifdef __TURBOC__ +#define YY_USE_CONST +#endif + + +#ifndef YY_USE_CONST +#define const +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +/* there's no standard place to get these definitions */ +char *malloc(); +int free(); +int read(); +#endif + + +/* amount of stuff to slurp up with each read */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* returned upon end-of-file */ +#define YY_END_TOK 0 + +/* copy whatever the last rule matched to the standard output */ + +/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */ +/* this used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite() + */ +#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout ) + +/* gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#define YY_INPUT(buf,result,max_size) \ + if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "read() in flex scanner failed" ); +#define YY_NULL 0 + +/* no semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#define yyterminate() return ( YY_NULL ) + +/* report a fatal error */ + +/* The funky do-while is used to turn this macro definition into + * a single C statement (which needs a semi-colon terminator). + * This avoids problems with code like: + * + * if ( something_happens ) + * YY_FATAL_ERROR( "oops, the something happened" ); + * else + * everything_okay(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the YY_FATAL_ERROR() call. + */ + +#define YY_FATAL_ERROR(msg) \ + do \ + { \ + (void) fputs( msg, stderr ); \ + (void) putc( '\n', stderr ); \ + exit( 1 ); \ + } \ + while ( 0 ) + +/* default yywrap function - always treat EOF as an EOF */ +#define yywrap() 1 + +/* enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN + */ +#define BEGIN yy_start = 1 + 2 * + +/* action number for EOF rule of a given start state */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* special action meaning "start processing a new file" */ +#define YY_NEW_FILE \ + do \ + { \ + yyinbffr( yy_current_buffer, yyin ); \ + yyldbfst(); \ + } \ + while ( 0 ) + +/* default declaration of generated scanner - a define so the user can + * easily add parameters + */ +#define YY_DECL int yylex YY_PROTO(( void )) + +/* code executed at the end of each rule */ +#define YY_BREAK break; + +#define YY_END_OF_BUFFER_CHAR 0 + +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */ +#endif + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +#define YY_CHAR unsigned char +# line 1 "" +#define INITIAL 0 +/* scan.l - scanner for flex input */ +# line 5 "" +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char rcsid[] = + "@(#) $Header$ (LBL)"; +#endif + +#undef yywrap + +#include +#include + +#define ACTION_ECHO fprintf( tmpactfl, "%s", yytext ) +#define MARK_END_OF_PROLOG fprintf( tmpactfl, "%%%% end of prolog\n" ); + +#undef YY_DECL +#define YY_DECL \ + int flexscan() + +#define RETURNCHAR \ + yylval = yytext[0]; \ + return ( CHAR ); + +#define RETURNNAME \ + (void) strcpy( nmstr, (char *) yytext ); \ + return ( NAME ); + +#define PUT_BACK_STRING(str, start) \ + for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \ + unput((str)[i]) + +#define CHECK_REJECT(str) \ + if ( allupper( str ) ) \ + reject = true; + +#define CHECK_YYMORE(str) \ + if ( alllower( str ) ) \ + yymrused = true; +#define SECT2 1 +#define SECT2PROLOG 2 +#define SECT3 3 +#define CODEBLOCK 4 +#define PICKUPDEF 5 +#define SC 6 +#define CARETISBOL 7 +#define NUM 8 +#define QUOTE 9 +#define FIRSTCCL 10 +#define CCL 11 +#define ACTION 12 +#define RECOVER 13 +#define BRACEERROR 14 +#define C_COMMENT 15 +#define ACTION_COMMENT 16 +#define ACTION_STRING 17 +#define PERCENT_BRACE_ACTION 18 +#define USED_LIST 19 +#define CODEBLOCK_2 20 +#define XLATION 21 +# line 84 "" + +/* done after the current pattern has been matched and before the + * corresponding action - sets up yytext + */ +#define YY_DO_BEFORE_ACTION \ + yytext = yy_bp; \ + yyleng = yy_cp - yy_bp; \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* return all but the first 'n' matched characters back to the input stream */ +#define yyless(n) \ + do \ + { \ + /* undo effects of setting up yytext */ \ + *yy_cp = yy_hold_char; \ + yy_c_buf_p = yy_cp = yy_bp + n; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext ) + + +struct yy_buffer_state + { + FILE *yy_input_file; + + YY_CHAR *yy_ch_buf; /* input buffer */ + YY_CHAR *yy_buf_pos; /* current position in input buffer */ + + /* size of input buffer in bytes, not including room for EOB characters*/ + int yy_buf_size; + + /* number of characters read into yy_ch_buf, not including EOB characters */ + int yy_n_chars; + + int yy_eof_status; /* whether we've seen an EOF on this buffer */ +#define EOF_NOT_SEEN 0 + /* "pending" happens when the EOF has been seen but there's still + * some text process + */ +#define EOF_PENDING 1 +#define EOF_DONE 2 + }; + +static YY_BUFFER_STATE yy_current_buffer; + +/* we provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state" + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed */ +static YY_CHAR yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + + +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +#ifndef YY_USER_INIT +#define YY_USER_INIT +#endif + +extern YY_CHAR *yytext; +extern int yyleng; +extern FILE *yyin, *yyout; + +YY_CHAR *yytext; +int yyleng; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +#define YY_END_OF_BUFFER 121 +typedef int yy_ste_type; +static const short int yy_accept[341] = + { 0, + 0, 0, 0, 0, 0, 0, 119, 119, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 121, 19, 7, 18, 19, 16, + 1, 17, 19, 19, 15, 19, 67, 59, 60, 66, + 51, 67, 53, 67, 67, 67, 50, 49, 52, 67, + 120, 47, 119, 119, 28, 29, 28, 28, 28, 28, + 31, 30, 32, 73, 120, 69, 72, 70, 74, 88, + 89, 86, 87, 85, 75, 77, 76, 75, 81, 81, + + 80, 81, 83, 83, 84, 83, 99, 104, 105, 100, + 105, 103, 100, 100, 97, 98, 120, 33, 91, 90, + 22, 24, 23, 107, 109, 108, 111, 113, 114, 115, + 95, 95, 96, 95, 95, 95, 95, 38, 35, 34, + 38, 38, 44, 42, 45, 44, 44, 41, 41, 41, + 41, 40, 7, 18, 0, 16, 1, 17, 3, 14, + 8, 0, 12, 4, 0, 0, 5, 0, 15, 0, + 2, 59, 60, 0, 0, 0, 56, 0, 0, 55, + 55, 54, 117, 117, 117, 50, 49, 63, 50, 0, + 47, 46, 119, 119, 28, 28, 28, 28, 28, 31, + + 30, 72, 71, 85, 78, 79, 118, 118, 118, 82, + 99, 101, 100, 0, 102, 0, 100, 100, 0, 33, + 22, 20, 107, 106, 111, 112, 95, 95, 95, 92, + 95, 95, 95, 38, 35, 38, 38, 42, 0, 43, + 43, 43, 42, 40, 0, 13, 14, 8, 8, 0, + 12, 4, 0, 0, 0, 5, 0, 6, 0, 58, + 57, 0, 64, 0, 0, 55, 55, 65, 117, 117, + 63, 28, 28, 28, 25, 0, 118, 118, 100, 100, + 0, 21, 92, 92, 95, 95, 38, 38, 0, 39, + 43, 43, 0, 11, 4, 0, 11, 0, 0, 5, + + 0, 0, 0, 117, 28, 28, 118, 100, 100, 95, + 95, 38, 38, 43, 0, 9, 0, 0, 0, 28, + 28, 100, 100, 95, 95, 38, 38, 0, 0, 26, + 27, 93, 94, 93, 94, 36, 37, 10, 62, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 6, 7, 6, 6, 8, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 9, 10, 6, 1, 11, 12, 13, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 14, 15, 16, 17, + 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 18, 1, 19, 1, 20, 1, 21, 22, + 23, 24, 25, 26, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 27, 28, 16, 29, 30, 31, + 28, 16, 32, 16, 16, 16, 16, 16, 16, 16, + 16, 33, 34, 35, 16, 16, 36, 37, 16, 1, + 1, 1, 38, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 39, 1, + 1, 40, 21, 22, 23, 24, 25, 26, 16, 16, + + 16, 1, 1, 1, 1, 1, 1, 41, 27, 28, + 16, 29, 30, 31, 28, 16, 32, 1, 1, 1, + 1, 1, 1, 42, 1, 33, 34, 35, 16, 16, + 36, 37, 16, 1, 1, 1, 1, 1, 1, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 1, + 1, 1, 1, 1, 1 + } ; + +static const short int yy_base[404] = + { 0, + 0, 43, 85, 126, 1573, 1572, 1571, 1570, 168, 1558, + 97, 104, 211, 0, 1544, 1543, 99, 106, 118, 251, + 252, 254, 112, 114, 296, 0, 1549, 1548, 107, 111, + 140, 151, 153, 155, 253, 336, 378, 0, 339, 420, + 0, 0, 424, 465, 1550, 3243, 257, 3243, 1515, 0, + 265, 3243, 1538, 494, 0, 1540, 3243, 272, 3243, 3243, + 1495, 277, 3243, 1459, 534, 61, 343, 3243, 3243, 81, + 1496, 0, 1495, 3243, 0, 3243, 0, 1473, 1443, 1438, + 0, 281, 3243, 3243, 3243, 3243, 0, 1467, 3243, 3243, + 3243, 3243, 3243, 1434, 3243, 3243, 3243, 76, 3243, 1463, + + 3243, 242, 3243, 0, 3243, 314, 0, 3243, 1464, 0, + 330, 3243, 1448, 745, 3243, 3243, 777, 3243, 3243, 3243, + 0, 3243, 767, 0, 3243, 766, 0, 3243, 3243, 0, + 0, 350, 3243, 737, 0, 752, 739, 0, 286, 3243, + 750, 737, 3243, 357, 3243, 739, 318, 3243, 428, 738, + 327, 728, 364, 3243, 432, 0, 438, 3243, 3243, 372, + 442, 765, 446, 0, 451, 84, 0, 765, 0, 764, + 3243, 457, 3243, 763, 718, 732, 3243, 434, 438, 0, + 566, 3243, 3243, 0, 712, 480, 3243, 0, 3243, 750, + 0, 3243, 749, 3243, 0, 0, 725, 722, 609, 0, + + 484, 0, 3243, 707, 3243, 3243, 3243, 0, 706, 3243, + 0, 3243, 0, 456, 3243, 0, 721, 718, 742, 3243, + 0, 741, 0, 3243, 0, 3243, 0, 488, 703, 652, + 0, 709, 706, 0, 494, 707, 704, 499, 508, 3243, + 0, 689, 694, 688, 581, 3243, 518, 0, 603, 725, + 698, 0, 702, 693, 697, 0, 706, 3243, 705, 3243, + 3243, 671, 3243, 717, 669, 0, 0, 3243, 0, 655, + 0, 631, 573, 0, 3243, 577, 0, 537, 554, 507, + 529, 3243, 0, 0, 507, 500, 493, 485, 711, 3243, + 0, 471, 502, 3243, 0, 715, 3243, 472, 476, 0, + + 468, 740, 682, 3243, 469, 447, 3243, 455, 432, 440, + 426, 427, 414, 3243, 413, 3243, 415, 684, 688, 339, + 339, 258, 265, 238, 142, 128, 133, 121, 126, 0, + 0, 0, 0, 0, 0, 0, 0, 3243, 3243, 3243, + 783, 826, 869, 912, 955, 998, 1041, 1084, 1127, 1170, + 1213, 1256, 1299, 1342, 1385, 1428, 1460, 1503, 1535, 1578, + 1621, 1664, 1707, 1750, 1793, 1836, 1868, 1911, 1943, 1986, + 2029, 2072, 2115, 2147, 2190, 2233, 2276, 2319, 2362, 2405, + 2448, 2480, 2523, 2566, 2609, 2637, 2659, 2696, 2739, 2782, + 2805, 2848, 2871, 2914, 2937, 2980, 3012, 3044, 3067, 3110, + + 3133, 3176, 3199 + } ; + +static const short int yy_def[404] = + { 0, + 340, 340, 341, 341, 342, 342, 343, 343, 340, 9, + 344, 344, 340, 13, 345, 345, 346, 346, 347, 347, + 348, 348, 349, 349, 340, 25, 350, 350, 345, 345, + 351, 351, 352, 352, 353, 353, 340, 37, 354, 354, + 37, 37, 355, 356, 340, 340, 340, 340, 340, 357, + 340, 340, 340, 358, 359, 360, 340, 340, 340, 340, + 340, 340, 340, 361, 340, 362, 340, 340, 340, 340, + 363, 364, 365, 340, 366, 340, 367, 367, 367, 366, + 368, 340, 340, 340, 340, 340, 369, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 362, 340, 370, + + 340, 371, 340, 372, 340, 362, 373, 340, 340, 374, + 375, 340, 374, 374, 340, 340, 376, 340, 340, 340, + 377, 340, 340, 378, 340, 340, 379, 340, 340, 380, + 381, 381, 340, 381, 382, 382, 382, 383, 340, 340, + 383, 383, 340, 340, 340, 340, 384, 340, 340, 340, + 384, 340, 340, 340, 340, 357, 340, 340, 340, 340, + 385, 340, 340, 386, 340, 340, 387, 388, 359, 360, + 340, 340, 340, 389, 340, 340, 340, 361, 361, 390, + 390, 340, 340, 391, 340, 340, 340, 392, 340, 363, + 364, 340, 365, 340, 366, 367, 367, 367, 340, 368, + + 340, 369, 340, 340, 340, 340, 340, 393, 340, 340, + 373, 340, 374, 375, 340, 375, 374, 374, 376, 340, + 377, 394, 378, 340, 379, 340, 381, 381, 381, 340, + 382, 382, 382, 383, 340, 383, 383, 340, 340, 340, + 395, 340, 340, 340, 340, 340, 340, 385, 385, 396, + 340, 397, 396, 340, 340, 398, 388, 340, 389, 340, + 340, 340, 340, 361, 361, 390, 181, 340, 399, 340, + 392, 367, 367, 199, 340, 400, 401, 340, 374, 374, + 394, 340, 230, 402, 382, 382, 383, 383, 340, 340, + 403, 340, 396, 340, 397, 396, 340, 340, 340, 398, + + 340, 264, 361, 340, 367, 367, 340, 374, 374, 382, + 382, 383, 383, 340, 340, 340, 340, 361, 361, 367, + 367, 374, 374, 382, 382, 383, 383, 340, 340, 367, + 367, 374, 374, 382, 382, 383, 383, 340, 340, 0, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + + 340, 340, 340 + } ; + +static const short int yy_nxt[3287] = + { 0, + 46, 47, 47, 48, 47, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 49, 50, 46, 46, 46, 46, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 46, 46, 46, + 46, 46, 46, 46, 51, 51, 52, 51, 46, 46, + 46, 46, 46, 46, 46, 53, 46, 54, 55, 46, + 56, 46, 46, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 46, 46, 46, 46, 46, 46, 58, 58, 59, 58, + 60, 61, 60, 62, 60, 188, 184, 60, 82, 82, + + 83, 82, 91, 185, 63, 82, 82, 83, 82, 91, + 119, 184, 92, 254, 119, 85, 255, 85, 185, 92, + 189, 96, 64, 104, 65, 104, 66, 67, 67, 68, + 67, 60, 61, 60, 62, 60, 69, 97, 60, 93, + 70, 94, 339, 122, 338, 63, 93, 120, 94, 123, + 105, 120, 105, 106, 122, 106, 125, 337, 125, 98, + 123, 336, 126, 64, 126, 65, 335, 66, 75, 75, + 75, 76, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 77, 75, 75, 75, 75, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, + + 77, 77, 77, 77, 79, 75, 75, 75, 75, 75, + 75, 84, 84, 84, 85, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 86, 84, 87, 88, 84, 84, + 84, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, + 84, 84, 84, 84, 96, 85, 128, 85, 153, 153, + 154, 153, 100, 101, 100, 101, 157, 157, 158, 157, + 97, 334, 129, 172, 172, 173, 172, 208, 177, 174, + 177, 177, 201, 201, 209, 201, 175, 235, 235, 333, + 235, 332, 98, 102, 130, 102, 107, 107, 107, 108, + + 107, 107, 107, 107, 107, 107, 107, 107, 109, 107, + 107, 110, 107, 107, 111, 112, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 113, 110, 110, + 110, 110, 114, 107, 107, 115, 116, 107, 107, 128, + 139, 139, 140, 139, 186, 186, 187, 186, 215, 184, + 174, 228, 228, 241, 228, 129, 185, 175, 238, 238, + 242, 238, 241, 331, 229, 153, 153, 154, 153, 242, + 141, 216, 330, 247, 247, 142, 247, 130, 131, 132, + 132, 133, 132, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 134, 135, 131, 131, 131, 131, 135, 135, + + 135, 135, 135, 135, 135, 135, 135, 135, 135, 136, + 135, 135, 135, 135, 137, 131, 131, 131, 131, 131, + 131, 139, 139, 140, 139, 144, 144, 145, 144, 243, + 243, 329, 243, 245, 245, 246, 245, 328, 146, 157, + 157, 158, 157, 249, 249, 327, 249, 251, 251, 326, + 251, 141, 245, 245, 246, 253, 142, 325, 172, 172, + 173, 172, 324, 323, 174, 147, 149, 149, 145, 149, + 244, 175, 263, 264, 215, 179, 178, 322, 321, 150, + 265, 186, 186, 187, 186, 201, 201, 174, 201, 228, + 228, 320, 228, 317, 175, 235, 235, 216, 235, 316, + + 238, 238, 229, 238, 315, 294, 151, 152, 161, 289, + 289, 290, 289, 240, 162, 313, 163, 312, 162, 247, + 247, 162, 247, 162, 162, 163, 164, 165, 166, 167, + 311, 310, 282, 168, 180, 180, 180, 309, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, + 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 180, 180, 180, 180, 180, 182, 267, 308, 207, + 275, 267, 245, 245, 246, 245, 267, 267, 267, 267, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + + 267, 267, 267, 306, 249, 249, 268, 249, 267, 274, + 274, 274, 275, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 276, 274, 274, 274, 274, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 274, 274, 274, 274, + 274, 274, 283, 283, 283, 305, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 284, 283, 283, + 283, 283, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 283, + 283, 283, 283, 283, 283, 243, 243, 183, 243, 251, + + 251, 301, 251, 296, 296, 297, 296, 263, 260, 258, + 179, 303, 289, 289, 290, 289, 296, 296, 297, 296, + 263, 299, 263, 179, 319, 179, 263, 298, 294, 179, + 244, 292, 288, 287, 286, 285, 244, 302, 302, 302, + 302, 302, 302, 230, 282, 220, 280, 279, 278, 204, + 273, 272, 194, 191, 270, 263, 262, 261, 179, 302, + 318, 318, 318, 318, 318, 318, 260, 171, 258, 250, + 244, 239, 239, 237, 236, 233, 232, 230, 224, 222, + 220, 218, 318, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 127, + + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 156, 217, 212, 206, 156, 204, 203, 199, 198, + 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 156, 156, 156, 156, 197, 194, 191, + + 179, 176, 156, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 171, 160, 160, 169, 159, 155, 340, + 169, 118, 118, 89, 89, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 80, 74, 74, 72, 72, 169, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 178, 178, 178, 340, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 340, + 178, 178, 178, 178, 183, 183, 183, 340, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + + 183, 183, 183, 183, 183, 183, 183, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 192, 340, 340, 340, 340, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 193, 193, 193, 193, 193, 193, 193, + + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 195, 195, 195, 340, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 340, 195, 195, 195, 195, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 195, 195, 195, 195, 195, 195, 196, + 340, 340, 340, 196, 340, 340, 340, 340, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + + 196, 196, 196, 196, 196, 340, 340, 340, 340, 340, + 196, 200, 200, 200, 340, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 202, 340, 340, 340, 202, 340, + 340, 340, 340, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 340, 340, 340, 340, 340, 202, 205, 205, 205, 340, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 207, + 207, 207, 340, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 210, 210, 210, 340, 210, 210, 210, 210, + 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, + 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, + + 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, + 340, 210, 210, 210, 210, 211, 211, 211, 340, 211, + 211, 211, 211, 211, 211, 211, 211, 340, 211, 211, + 340, 211, 211, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 211, 211, 340, 340, 211, 211, 213, 340, + 340, 340, 213, 340, 340, 340, 340, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 340, 340, 340, 340, 340, 213, + 214, 214, 214, 340, 214, 214, 214, 214, 214, 214, + + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 221, 221, 221, 340, + 221, 221, 221, 221, 221, 340, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 223, + 223, 223, 340, 223, 223, 223, 223, 223, 340, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 225, 225, 225, 340, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 340, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + + 225, 225, 225, 340, 225, 226, 226, 226, 340, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 227, 227, + 227, 340, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 340, 227, 227, 227, 227, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 227, 227, 227, 227, 227, + 227, 231, 340, 340, 340, 231, 340, 340, 340, 340, + + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 340, 340, 340, + 340, 340, 231, 234, 340, 340, 340, 340, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 240, 240, 240, 340, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + + 240, 240, 240, 240, 240, 240, 240, 240, 240, 248, + 248, 248, 340, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 252, 340, 340, 340, 340, 252, 252, 252, + 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, + 252, 252, 252, 252, 256, 340, 340, 340, 340, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 257, 257, 257, 257, + + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 259, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 266, 266, 266, 340, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 340, 266, 266, 269, 269, 269, 269, 269, + 269, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 269, 271, 271, + 271, 340, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 277, 277, 277, 277, 277, 277, 340, 340, 340, + + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 277, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 291, 291, 291, + 291, 291, 291, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 291, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 295, 340, 340, 340, 295, 340, 340, + 340, 340, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 295, 340, + 340, 340, 340, 340, 295, 300, 340, 340, 340, 300, + 340, 340, 340, 340, 300, 300, 300, 300, 300, 300, + 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 300, 340, 340, 340, 340, 340, 300, 304, 304, 304, + 304, 304, 304, 340, 340, 340, 340, 340, 340, 340, + + 340, 340, 340, 340, 340, 340, 340, 340, 340, 304, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 307, 307, 307, 307, 307, 307, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 307, 284, 284, 284, 340, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 314, + 314, 314, 314, 314, 314, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 314, 45, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340 + } ; + +static const short int yy_chk[3287] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 70, 66, 3, 11, 11, + + 11, 11, 17, 66, 3, 12, 12, 12, 12, 18, + 29, 98, 17, 166, 30, 23, 166, 24, 98, 18, + 70, 19, 3, 23, 3, 24, 3, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 19, 4, 17, + 4, 17, 329, 31, 328, 4, 18, 29, 18, 31, + 23, 30, 24, 23, 32, 24, 33, 327, 34, 19, + 32, 326, 33, 4, 34, 4, 325, 4, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 20, 21, 35, 22, 47, 47, + 47, 47, 21, 21, 22, 22, 51, 51, 51, 51, + 20, 324, 35, 58, 58, 58, 58, 102, 62, 58, + 62, 62, 82, 82, 102, 82, 58, 139, 139, 323, + 139, 322, 20, 21, 35, 22, 25, 25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 36, + 39, 39, 39, 39, 67, 67, 67, 67, 111, 106, + 67, 132, 132, 147, 132, 36, 106, 67, 144, 144, + 147, 144, 151, 321, 132, 153, 153, 153, 153, 151, + 39, 111, 320, 160, 160, 39, 160, 36, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 40, 40, 40, 40, 43, 43, 43, 43, 149, + 149, 317, 149, 155, 155, 155, 155, 315, 43, 157, + 157, 157, 157, 161, 161, 313, 161, 163, 163, 312, + 163, 40, 165, 165, 165, 165, 40, 311, 172, 172, + 172, 172, 310, 309, 172, 43, 44, 44, 44, 44, + 149, 172, 178, 179, 214, 178, 179, 308, 306, 44, + 179, 186, 186, 186, 186, 201, 201, 186, 201, 228, + 228, 305, 228, 301, 186, 235, 235, 214, 235, 299, + + 238, 238, 228, 238, 298, 293, 44, 44, 54, 239, + 239, 239, 239, 292, 54, 288, 54, 287, 54, 247, + 247, 54, 247, 54, 54, 54, 54, 54, 54, 54, + 286, 285, 281, 54, 65, 65, 65, 280, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 181, 279, 278, + 276, 181, 245, 245, 245, 245, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + + 181, 181, 181, 273, 249, 249, 181, 249, 181, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 230, 230, 230, 272, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 243, 243, 270, 243, 251, + + 251, 262, 251, 253, 253, 253, 253, 265, 259, 257, + 265, 265, 289, 289, 289, 289, 296, 296, 296, 296, + 303, 255, 318, 303, 303, 318, 319, 254, 250, 319, + 244, 242, 237, 236, 233, 232, 243, 264, 264, 264, + 264, 264, 264, 229, 222, 219, 218, 217, 209, 204, + 198, 197, 193, 190, 185, 264, 176, 175, 264, 264, + 302, 302, 302, 302, 302, 302, 174, 170, 168, 162, + 152, 150, 146, 142, 141, 137, 136, 134, 126, 123, + 117, 114, 302, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, + + 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 343, + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, + + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, 346, 346, + + 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, + 346, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 347, 348, 348, 348, 348, 348, 348, + 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, + + 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, + 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, + 348, 348, 348, 348, 348, 348, 348, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, + 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, + 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, + 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, + + 350, 350, 350, 350, 350, 350, 350, 350, 350, 350, + 350, 350, 350, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, + + 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, 355, 355, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, + 356, 357, 113, 109, 100, 357, 94, 88, 80, 79, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 78, 73, 71, + + 64, 61, 357, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 56, 358, 358, 359, 53, 49, 45, + 359, 28, 27, 16, 15, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 10, 8, 7, 6, 5, 359, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 361, 361, 361, 0, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, 361, 0, + 361, 361, 361, 361, 362, 362, 362, 0, 362, 362, + 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, + 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, + 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, + + 362, 362, 362, 362, 362, 362, 362, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 364, 0, 0, 0, 0, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 365, 365, 365, 365, 365, 365, 365, + + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 366, 366, 366, 0, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 0, 366, 366, 366, 366, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 366, 366, 366, 366, 366, 366, 367, + 0, 0, 0, 367, 0, 0, 0, 0, 367, 367, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, + + 367, 367, 367, 367, 367, 0, 0, 0, 0, 0, + 367, 368, 368, 368, 0, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 369, 0, 0, 0, 369, 0, + 0, 0, 0, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 0, 0, 0, 0, 0, 369, 370, 370, 370, 0, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 371, + 371, 371, 0, 371, 371, 371, 371, 371, 371, 371, + 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 371, 371, 372, 372, 372, 0, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 0, 372, 372, 372, 372, 373, 373, 373, 0, 373, + 373, 373, 373, 373, 373, 373, 373, 0, 373, 373, + 0, 373, 373, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 373, 373, 0, 0, 373, 373, 374, 0, + 0, 0, 374, 0, 0, 0, 0, 374, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 0, 0, 0, 0, 0, 374, + 375, 375, 375, 0, 375, 375, 375, 375, 375, 375, + + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 376, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 377, 377, 377, 0, + 377, 377, 377, 377, 377, 0, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, + + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 377, 377, 377, 377, 377, 377, 377, 377, 377, 378, + 378, 378, 0, 378, 378, 378, 378, 378, 0, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 379, 379, 379, 0, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 0, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + + 379, 379, 379, 0, 379, 380, 380, 380, 0, 380, + 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, + 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, + 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, + 380, 380, 380, 380, 380, 380, 380, 380, 381, 381, + 381, 0, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 0, 381, 381, 381, 381, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 381, 381, 381, 381, 381, + 381, 382, 0, 0, 0, 382, 0, 0, 0, 0, + + 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 382, 0, 0, 0, + 0, 0, 382, 383, 0, 0, 0, 0, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 384, 384, 384, 0, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, + + 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, + 385, 385, 0, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 386, 0, 0, 0, 0, 386, 386, 386, + 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 386, 387, 0, 0, 0, 0, 387, + 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, + 387, 387, 387, 387, 387, 387, 388, 388, 388, 388, + + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 389, + 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, + 389, 389, 390, 390, 390, 0, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 390, 390, 0, 390, 390, 391, 391, 391, 391, 391, + 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 391, 392, 392, + 392, 0, 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, + 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, + 392, 393, 393, 393, 393, 393, 393, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 393, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 395, 395, 395, + 395, 395, 395, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 397, 0, 0, 0, 397, 0, 0, + 0, 0, 397, 397, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 397, 397, 0, + 0, 0, 0, 0, 397, 398, 0, 0, 0, 398, + 0, 0, 0, 0, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 0, 0, 0, 0, 0, 398, 399, 399, 399, + 399, 399, 399, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 401, 401, 401, 401, 401, 401, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 401, 402, 402, 402, 0, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + + 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, + 402, 402, 402, 402, 402, 402, 402, 402, 402, 403, + 403, 403, 403, 403, 403, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 403, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340 + } ; + +static yy_ste_type yy_last_accepting_state; +static YY_CHAR *yy_last_accepting_cpos; + +/* the intent behind this definition is that it'll catch + * any uses of REJECT which flex missed + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymrused_but_not_detected +#define YY_MORE_ADJ 0 + +/* these variables are all declared out here so that section 3 code can + * manipulate them + */ +/* points to current character in buffer */ +static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +static yy_ste_type yy_get_previous_state YY_PROTO(( void )); +static yy_ste_type yy_try_NUL_trans YY_PROTO(( yy_ste_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yyunput YY_PROTO(( YY_CHAR c, YY_CHAR *buf_ptr )); +void yyrestrt YY_PROTO(( FILE *input_file )); +void yyswtobf YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yyldbfst YY_PROTO(( void )); +YY_BUFFER_STATE yycrbffr YY_PROTO(( FILE *file, int size )); +void yydlbffr YY_PROTO(( YY_BUFFER_STATE b )); +void yyinbffr YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); + +#define yy_new_buffer yycrbffr + +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif + +YY_DECL + { + register yy_ste_type yy_current_state; + register YY_CHAR *yy_cp, *yy_bp; + register int yy_act; + + + static int bracelevel, didadef; + int i, indented_code, checking_used, new_xlation; + int doing_codeblock = false; + Char nmdef[MAXLINE], myesc(); + + + if ( yy_init ) + { + YY_USER_INIT; + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( yy_current_buffer ) + yyinbffr( yy_current_buffer, yyin ); + else + yy_current_buffer = yycrbffr( yyin, YY_BUF_SIZE ); + + yyldbfst(); + + yy_init = 0; + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* support of yytext */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of the + * current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + if ( yy_bp[-1] == '\n' ) + ++yy_current_state; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[*yy_cp]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while(yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) + { + yy_current_state = yy_def[yy_current_state]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_current_state != 340 ); + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + YY_USER_ACTION; + +do_action: /* this label is used only to access EOF actions */ + + + switch ( yy_act ) + { + case 0: /* must backtrack */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +# line 90 "" +indented_code = true; BEGIN(CODEBLOCK); + YY_BREAK +case 2: +# line 91 "" +++linenum; /* treat as a comment */ + YY_BREAK +case 3: +# line 92 "" +ECHO; BEGIN(C_COMMENT); + YY_BREAK +case 4: +# line 93 "" +return ( SCDECL ); + YY_BREAK +case 5: +# line 94 "" +return ( XSCDECL ); + YY_BREAK +case 6: +# line 95 "" +{ + ++linenum; + lndirout( stdout ); + indented_code = false; + BEGIN(CODEBLOCK); + } + YY_BREAK +case 7: +# line 102 "" +return ( WHITESPACE ); + YY_BREAK +case 8: +# line 104 "" +{ + sectnum = 2; + lndirout( stdout ); + BEGIN(SECT2PROLOG); + return ( SECTEND ); + } + YY_BREAK +case 9: +# line 111 "" +{ + pptmsg( "warning - %%used/%%unused have been deprecated" ); + checking_used = REALLY_USED; BEGIN(USED_LIST); + } + YY_BREAK +case 10: +# line 115 "" +{ + checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); + pptmsg( "warning - %%used/%%unused have been deprecated" ); + checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); + } + YY_BREAK +case 11: +# line 122 "" +{ +#ifdef NOTDEF + fprintf( stderr, + "old-style lex command at line %d ignored:\n\t%s", + linenum, yytext ); +#endif + ++linenum; + } + YY_BREAK +case 12: +# line 131 "" +/* ignore old lex directive */ + YY_BREAK +case 13: +# line 133 "" +{ + ++linenum; + xlation = + (int *) malloc( sizeof( int ) * (unsigned) csize ); + + if ( ! xlation ) + flxfatal( + "dynamic memory failure building %t table" ); + + for ( i = 0; i < csize; ++i ) + xlation[i] = 0; + + nuxlatns = 0; + + BEGIN(XLATION); + } + YY_BREAK +case 14: +# line 150 "" +synerr( "unrecognized '%' directive" ); + YY_BREAK +case 15: +# line 152 "" +{ + (void) strcpy( nmstr, (char *) yytext ); + didadef = false; + BEGIN(PICKUPDEF); + } + YY_BREAK +case 16: +# line 158 "" +RETURNNAME; + YY_BREAK +case 17: +# line 159 "" +++linenum; /* allows blank lines in section 1 */ + YY_BREAK +case 18: +# line 160 "" +++linenum; return ( '\n' ); + YY_BREAK +case 19: +# line 161 "" +synerr( "illegal character" ); BEGIN(RECOVER); + YY_BREAK +case 20: +# line 164 "" +ECHO; BEGIN(INITIAL); + YY_BREAK +case 21: +# line 165 "" +++linenum; ECHO; BEGIN(INITIAL); + YY_BREAK +case 22: +# line 166 "" +ECHO; + YY_BREAK +case 23: +# line 167 "" +ECHO; + YY_BREAK +case 24: +# line 168 "" +++linenum; ECHO; + YY_BREAK +case 25: +# line 171 "" +++linenum; BEGIN(INITIAL); + YY_BREAK +case 26: +# line 172 "" +ECHO; CHECK_REJECT(yytext); + YY_BREAK +case 27: +# line 173 "" +ECHO; CHECK_YYMORE(yytext); + YY_BREAK +case 28: +# line 174 "" +ECHO; + YY_BREAK +case 29: +# line 175 "" +{ + ++linenum; + ECHO; + if ( indented_code ) + BEGIN(INITIAL); + } + YY_BREAK +case 30: +# line 183 "" +/* separates name and definition */ + YY_BREAK +case 31: +# line 185 "" +{ + (void) strcpy( (char *) nmdef, (char *) yytext ); + + for ( i = strlen( (char *) nmdef ) - 1; + i >= 0 && + nmdef[i] == ' ' || nmdef[i] == '\t'; + --i ) + ; + + nmdef[i + 1] = '\0'; + + ndinstal( nmstr, nmdef ); + didadef = true; + } + YY_BREAK +case 32: +# line 200 "" +{ + if ( ! didadef ) + synerr( "incomplete name definition" ); + BEGIN(INITIAL); + ++linenum; + } + YY_BREAK +case 33: +# line 207 "" +++linenum; BEGIN(INITIAL); RETURNNAME; + YY_BREAK +case 34: +# line 210 "" +++linenum; BEGIN(INITIAL); + YY_BREAK +case 35: +# line 211 "" + + YY_BREAK +case 36: +# line 212 "" +{ + if ( allupper( yytext ) ) + rjctused = checking_used; + else + synerr( "unrecognized %used/%unused construct" ); + } + YY_BREAK +case 37: +# line 218 "" +{ + if ( alllower( yytext ) ) + yymrreus = checking_used; + else + synerr( "unrecognized %used/%unused construct" ); + } + YY_BREAK +case 38: +# line 224 "" +synerr( "unrecognized %used/%unused construct" ); + YY_BREAK +case 39: +# line 227 "" +++linenum; BEGIN(INITIAL); + YY_BREAK +case 40: +# line 228 "" +++nuxlatns; new_xlation = true; + YY_BREAK +case 41: +# line 229 "" +synerr( "bad row in translation table" ); + YY_BREAK +case 42: +# line 230 "" +/* ignore whitespace */ + YY_BREAK +case 43: +# line 232 "" +{ + xlation[myesc( yytext )] = + (new_xlation ? nuxlatns : -nuxlatns); + new_xlation = false; + } + YY_BREAK +case 44: +# line 237 "" +{ + xlation[yytext[0]] = + (new_xlation ? nuxlatns : -nuxlatns); + new_xlation = false; + } + YY_BREAK +case 45: +# line 243 "" +++linenum; + YY_BREAK +case 46: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 246 "" +{ + ++linenum; + ACTION_ECHO; + MARK_END_OF_PROLOG; + BEGIN(SECT2); + } + YY_BREAK +case 47: +# line 253 "" +++linenum; ACTION_ECHO; + YY_BREAK +case YY_STATE_EOF(SECT2PROLOG): +# line 255 "" +MARK_END_OF_PROLOG; yyterminate(); + YY_BREAK +case 49: +# line 257 "" +++linenum; /* allow blank lines in section 2 */ + YY_BREAK +case 50: +# line 259 "" +{ + indented_code = (yytext[0] != '%'); + doing_codeblock = true; + bracelevel = 1; + + if ( indented_code ) + ACTION_ECHO; + + BEGIN(CODEBLOCK_2); + } + YY_BREAK +case 51: +# line 270 "" +BEGIN(SC); return ( '<' ); + YY_BREAK +case 52: +# line 271 "" +return ( '^' ); + YY_BREAK +case 53: +# line 272 "" +BEGIN(QUOTE); return ( '"' ); + YY_BREAK +case 54: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 273 "" +BEGIN(NUM); return ( '{' ); + YY_BREAK +case 55: +# line 274 "" +BEGIN(BRACEERROR); + YY_BREAK +case 56: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 275 "" +return ( '$' ); + YY_BREAK +case 57: +# line 277 "" +{ + bracelevel = 1; + BEGIN(PERCENT_BRACE_ACTION); + return ( '\n' ); + } + YY_BREAK +case 58: +# line 282 "" +cntdactn = true; ++linenum; return ( '\n' ); + YY_BREAK +case 59: +# line 284 "" +{ + /* this rule is separate from the one below because + * otherwise we get variable trailing context, so + * we can't build the scanner using -{f,F} + */ + bracelevel = 0; + cntdactn = false; + BEGIN(ACTION); + return ( '\n' ); + } + YY_BREAK +case 60: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 295 "" +{ + bracelevel = 0; + cntdactn = false; + BEGIN(ACTION); + return ( '\n' ); + } + YY_BREAK +case 61: +# line 302 "" +++linenum; return ( '\n' ); + YY_BREAK +case 62: +# line 304 "" +return ( EOF_OP ); + YY_BREAK +case 63: +# line 306 "" +{ + sectnum = 3; + BEGIN(SECT3); + return ( EOF ); /* to stop the parser */ + } + YY_BREAK +case 64: +# line 312 "" +{ + int cclval; + + (void) strcpy( nmstr, (char *) yytext ); + + /* check to see if we've already encountered this ccl */ + if ( (cclval = ccllookp( (Char *) nmstr )) ) + { + yylval = cclval; + ++cclreuse; + return ( PREVCCL ); + } + else + { + /* we fudge a bit. We know that this ccl will + * soon be numbered as lastccl + 1 by cclinit + */ + cclnstal( (Char *) nmstr, lastccl + 1 ); + + /* push back everything but the leading bracket + * so the ccl can be rescanned + */ + PUT_BACK_STRING((Char *) nmstr, 1); + + BEGIN(FIRSTCCL); + return ( '[' ); + } + } + YY_BREAK +case 65: +# line 341 "" +{ + register Char *nmdefptr; + Char *ndlookup(); + + (void) strcpy( nmstr, (char *) yytext ); + nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ + + /* lookup from "nmstr + 1" to chop leading brace */ + if ( ! (nmdefptr = ndlookup( nmstr + 1 )) ) + synerr( "undefined {name}" ); + + else + { /* push back name surrounded by ()'s */ + unput(')'); + PUT_BACK_STRING(nmdefptr, 0); + unput('('); + } + } + YY_BREAK +case 66: +# line 360 "" +return ( yytext[0] ); + YY_BREAK +case 67: +# line 361 "" +RETURNCHAR; + YY_BREAK +case 68: +# line 362 "" +++linenum; return ( '\n' ); + YY_BREAK +case 69: +# line 365 "" +return ( ',' ); + YY_BREAK +case 70: +# line 366 "" +BEGIN(SECT2); return ( '>' ); + YY_BREAK +case 71: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 367 "" +BEGIN(CARETISBOL); return ( '>' ); + YY_BREAK +case 72: +# line 368 "" +RETURNNAME; + YY_BREAK +case 73: +# line 369 "" +synerr( "bad start condition name" ); + YY_BREAK +case 74: +# line 371 "" +BEGIN(SECT2); return ( '^' ); + YY_BREAK +case 75: +# line 374 "" +RETURNCHAR; + YY_BREAK +case 76: +# line 375 "" +BEGIN(SECT2); return ( '"' ); + YY_BREAK +case 77: +# line 377 "" +{ + synerr( "missing quote" ); + BEGIN(SECT2); + ++linenum; + return ( '"' ); + } + YY_BREAK +case 78: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 385 "" +BEGIN(CCL); return ( '^' ); + YY_BREAK +case 79: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 386 "" +return ( '^' ); + YY_BREAK +case 80: +# line 387 "" +BEGIN(CCL); yylval = '-'; return ( CHAR ); + YY_BREAK +case 81: +# line 388 "" +BEGIN(CCL); RETURNCHAR; + YY_BREAK +case 82: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +# line 390 "" +return ( '-' ); + YY_BREAK +case 83: +# line 391 "" +RETURNCHAR; + YY_BREAK +case 84: +# line 392 "" +BEGIN(SECT2); return ( ']' ); + YY_BREAK +case 85: +# line 395 "" +{ + yylval = myctoi( yytext ); + return ( NUMBER ); + } + YY_BREAK +case 86: +# line 400 "" +return ( ',' ); + YY_BREAK +case 87: +# line 401 "" +BEGIN(SECT2); return ( '}' ); + YY_BREAK +case 88: +# line 403 "" +{ + synerr( "bad character inside {}'s" ); + BEGIN(SECT2); + return ( '}' ); + } + YY_BREAK +case 89: +# line 409 "" +{ + synerr( "missing }" ); + BEGIN(SECT2); + ++linenum; + return ( '}' ); + } + YY_BREAK +case 90: +# line 417 "" +synerr( "bad name in {}'s" ); BEGIN(SECT2); + YY_BREAK +case 91: +# line 418 "" +synerr( "missing }" ); ++linenum; BEGIN(SECT2); + YY_BREAK +case 92: +# line 421 "" +bracelevel = 0; + YY_BREAK +case 93: +# line 422 "" +{ + ACTION_ECHO; + CHECK_REJECT(yytext); + } + YY_BREAK +case 94: +# line 426 "" +{ + ACTION_ECHO; + CHECK_YYMORE(yytext); + } + YY_BREAK +case 95: +# line 430 "" +ACTION_ECHO; + YY_BREAK +case 96: +# line 431 "" +{ + ++linenum; + ACTION_ECHO; + if ( bracelevel == 0 || + (doing_codeblock && indented_code) ) + { + if ( ! doing_codeblock ) + fputs( "\tYY_BREAK\n", tmpactfl ); + + doing_codeblock = false; + BEGIN(SECT2); + } + } + YY_BREAK + /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ +case 97: +# line 447 "" +ACTION_ECHO; ++bracelevel; + YY_BREAK +case 98: +# line 448 "" +ACTION_ECHO; --bracelevel; + YY_BREAK +case 99: +# line 449 "" +ACTION_ECHO; + YY_BREAK +case 100: +# line 450 "" +ACTION_ECHO; + YY_BREAK +case 101: +# line 451 "" +ACTION_ECHO; BEGIN(ACTION_COMMENT); + YY_BREAK +case 102: +# line 452 "" +ACTION_ECHO; /* character constant */ + YY_BREAK +case 103: +# line 453 "" +ACTION_ECHO; BEGIN(ACTION_STRING); + YY_BREAK +case 104: +# line 454 "" +{ + ++linenum; + ACTION_ECHO; + if ( bracelevel == 0 ) + { + fputs( "\tYY_BREAK\n", tmpactfl ); + BEGIN(SECT2); + } + } + YY_BREAK +case 105: +# line 463 "" +ACTION_ECHO; + YY_BREAK +case 106: +# line 465 "" +ACTION_ECHO; BEGIN(ACTION); + YY_BREAK +case 107: +# line 466 "" +ACTION_ECHO; + YY_BREAK +case 108: +# line 467 "" +ACTION_ECHO; + YY_BREAK +case 109: +# line 468 "" +++linenum; ACTION_ECHO; + YY_BREAK +case 110: +# line 469 "" +ACTION_ECHO; + YY_BREAK +case 111: +# line 471 "" +ACTION_ECHO; + YY_BREAK +case 112: +# line 472 "" +ACTION_ECHO; + YY_BREAK +case 113: +# line 473 "" +++linenum; ACTION_ECHO; + YY_BREAK +case 114: +# line 474 "" +ACTION_ECHO; BEGIN(ACTION); + YY_BREAK +case 115: +# line 475 "" +ACTION_ECHO; + YY_BREAK +case YY_STATE_EOF(ACTION): +case YY_STATE_EOF(ACTION_COMMENT): +case YY_STATE_EOF(ACTION_STRING): +# line 477 "" +{ + synerr( "EOF encountered inside an action" ); + yyterminate(); + } + YY_BREAK +case 117: +# line 483 "" +{ + yylval = myesc( yytext ); + return ( CHAR ); + } + YY_BREAK +case 118: +# line 488 "" +{ + yylval = myesc( yytext ); + BEGIN(CCL); + return ( CHAR ); + } + YY_BREAK +case 119: +# line 495 "" +ECHO; + YY_BREAK +case 120: +# line 496 "" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(SECT2): +case YY_STATE_EOF(SECT3): +case YY_STATE_EOF(CODEBLOCK): +case YY_STATE_EOF(PICKUPDEF): +case YY_STATE_EOF(SC): +case YY_STATE_EOF(CARETISBOL): +case YY_STATE_EOF(NUM): +case YY_STATE_EOF(QUOTE): +case YY_STATE_EOF(FIRSTCCL): +case YY_STATE_EOF(CCL): +case YY_STATE_EOF(RECOVER): +case YY_STATE_EOF(BRACEERROR): +case YY_STATE_EOF(C_COMMENT): +case YY_STATE_EOF(PERCENT_BRACE_ACTION): +case YY_STATE_EOF(USED_LIST): +case YY_STATE_EOF(CODEBLOCK_2): +case YY_STATE_EOF(XLATION): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* amount of text matched not including the EOB char */ + int yy_amount_of_matched_text = yy_cp - yytext - 1; + + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + + /* note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the end- + * of-buffer state). Contrast this with the test in yyinput(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* this was really a NUL */ + { + yy_ste_type yy_next_state; + + yy_c_buf_p = yytext + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* okay, we're now positioned to make the + * NUL transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we + * don't want to build jamming into it because + * then it will run more slowly) + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* consume the NUL */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* note: because we've taken care in + * yy_get_next_buffer() to have set up yytext, + * we can now set up yy_c_buf_p so that if some + * total hoser (like flex itself) wants + * to call the scanner after we return the + * YY_NULL, it'll still work - another YY_NULL + * will get returned. + */ + yy_c_buf_p = yytext + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF((yy_start - 1) / 2); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + } + break; + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: +#ifdef FLEX_DEBUG + printf( "action # %d\n", yy_act ); +#endif + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } + } + } + + +/* yy_get_next_buffer - try to read in a new buffer + * + * synopsis + * int yy_get_next_buffer(); + * + * returns a code representing an action + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + + { + register YY_CHAR *dest = yy_current_buffer->yy_ch_buf; + register YY_CHAR *source = yytext - 1; /* copy prev. char, too */ + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + /* try to read more data */ + + /* first move last chars to start of buffer */ + number_to_move = yy_c_buf_p - yytext; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_n_chars = 0; + + else + { + int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + else if ( num_to_read <= 0 ) + YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); + + /* read in more data */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == 1 ) + { + ret_val = EOB_ACT_END_OF_FILE; + yy_current_buffer->yy_eof_status = EOF_DONE; + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_eof_status = EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + /* yytext begins at the second character in yy_ch_buf; the first + * character is the one which preceded it before reading in the latest + * buffer; it needs to be kept around in case it's a newline, so + * yy_get_previous_state() will have with '^' rules active + */ + + yytext = &yy_current_buffer->yy_ch_buf[1]; + + return ( ret_val ); + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached + * + * synopsis + * yy_ste_type yy_get_previous_state(); + */ + +static yy_ste_type yy_get_previous_state() + + { + register yy_ste_type yy_current_state; + register YY_CHAR *yy_cp; + + register YY_CHAR *yy_bp = yytext; + + yy_current_state = yy_start; + if ( yy_bp[-1] == '\n' ) + ++yy_current_state; + + for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[*yy_cp] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = yy_def[yy_current_state]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return ( yy_current_state ); + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_ste_type yy_try_NUL_trans( register yy_ste_type yy_current_state ) +#else +static yy_ste_type yy_try_NUL_trans( yy_current_state ) +register yy_ste_type yy_current_state; +#endif + + { + register int yy_is_jam; + register YY_CHAR *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = yy_def[yy_current_state]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 340); + + return ( yy_is_jam ? 0 : yy_current_state ); + } + + +#ifdef YY_USE_PROTOS +static void yyunput( YY_CHAR c, register YY_CHAR *yy_bp ) +#else +static void yyunput( c, yy_bp ) +YY_CHAR c; +register YY_CHAR *yy_bp; +#endif + + { + register YY_CHAR *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */ + register YY_CHAR *dest = + &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2]; + register YY_CHAR *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += dest - source; + yy_bp += dest - source; + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + if ( yy_cp > yy_bp && yy_cp[-1] == '\n' ) + yy_cp[-2] = '\n'; + + *--yy_cp = c; + + /* note: the formal parameter *must* be called "yy_bp" for this + * macro to now work correctly + */ + YY_DO_BEFORE_ACTION; /* set up yytext again */ + } + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + + { + int c; + YY_CHAR *yy_cp = yy_c_buf_p; + + *yy_cp = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* this was really a NUL */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + yytext = yy_c_buf_p; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + { + yy_c_buf_p = yytext + YY_MORE_ADJ; + return ( EOF ); + } + + YY_NEW_FILE; + +#ifdef __cplusplus + return ( yyinput() ); +#else + return ( input() ); +#endif + } + break; + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext + YY_MORE_ADJ; + break; + + case EOB_ACT_LAST_MATCH: +#ifdef __cplusplus + YY_FATAL_ERROR( "unexpected last match in yyinput()" ); +#else + YY_FATAL_ERROR( "unexpected last match in input()" ); +#endif + } + } + } + + c = *yy_c_buf_p; + yy_hold_char = *++yy_c_buf_p; + + return ( c ); + } + + +#ifdef YY_USE_PROTOS +void yyrestrt( FILE *input_file ) +#else +void yyrestrt( input_file ) +FILE *input_file; +#endif + + { + yyinbffr( yy_current_buffer, input_file ); + yyldbfst(); + } + + +#ifdef YY_USE_PROTOS +void yyswtobf( YY_BUFFER_STATE new_buffer ) +#else +void yyswtobf( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* flush out information for old buffer */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yyldbfst(); + + /* we don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yyldbfst( void ) +#else +void yyldbfst() +#endif + + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yycrbffr( FILE *file, int size ) +#else +YY_BUFFER_STATE yycrbffr( file, size ) +FILE *file; +int size; +#endif + + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) ); + + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yycrbffr()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) ); + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yycrbffr()" ); + + yyinbffr( b, file ); + + return ( b ); + } + + +#ifdef YY_USE_PROTOS +void yydlbffr( YY_BUFFER_STATE b ) +#else +void yydlbffr( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + free( (char *) b->yy_ch_buf ); + free( (char *) b ); + } + + +#ifdef YY_USE_PROTOS +void yyinbffr( YY_BUFFER_STATE b, FILE *file ) +#else +void yyinbffr( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + { + b->yy_input_file = file; + + /* we put in the '\n' and start reading from [1] so that an + * initial match-at-newline will be true. + */ + + b->yy_ch_buf[0] = '\n'; + b->yy_n_chars = 1; + + /* we always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[1]; + + b->yy_eof_status = EOF_NOT_SEEN; + } +# line 496 "" + + + +int yywrap() + + { + if ( --ninfiles > 0 ) + { + stinpfle( *++inp_fles ); + return ( 0 ); + } + + else + return ( 1 ); + } + + +/* stinpfle - open the given file (if NULL, stdin) for scanning */ + +void stinpfle( file ) +char *file; + + { + if ( file ) + { + infilnam = file; + yyin = fopen( infilnam, "r" ); + + if ( yyin == NULL ) + lerrsf( "can't open %s", file ); + } + + else + { + yyin = stdin; + infilnam = ""; + } + } diff --git a/commands/flex-2.5.4/MISC/MVS/unfixit.l b/commands/flex-2.5.4/MISC/MVS/unfixit.l new file mode 100644 index 000000000..3f8dddc68 --- /dev/null +++ b/commands/flex-2.5.4/MISC/MVS/unfixit.l @@ -0,0 +1,141 @@ +%{ +/* unfixit.l - convert shortened external names to names back to their + * original names. (See fixit.l) + */ + +/* + * This program is included to satisfy "dumb" compilers/linkers which + * do not know about externals of names longer than 8 bytes. + * + * Steven W. Layten + * Chemical Abstracts Service + * PO BOX 3012 + * Columbus, OH 43210 + */ +%} +%% +"actfilnm" printf("action_file_name"); +"actnout" printf("action_out"); +"addacpt" printf("add_accept"); +"alllower" printf("all_lower"); +"allupper" printf("all_upper"); +"allocarr" printf("allocate_array"); +"asscrule" printf("assoc_rule"); +"bktrkfil" printf("backtrack_file"); +"bktrkrep" printf("backtrack_report"); +"bol_nded" printf("bol_needed"); +"bldeofac" printf("build_eof_action"); +"cclnstal" printf("cclinstal"); +"ccllookp" printf("ccllookup"); +"cclnegat" printf("cclnegate"); +"cclsrted" printf("cclsorted"); +"ck4bktrk" printf("check_for_backtracking"); +"cktrlcnt" printf("check_trailing_context"); +"cntdactn" printf("continued_action"); +"copystrn" printf("copy_string"); +"cpunsstr" printf("copy_unsigned_string"); +"cpyrght" printf("copyright"); +"copysngl" printf("copysingl"); +"c_mx_ccl" printf("current_max_ccl_tbl_size"); +"c_mx_dfa" printf("current_max_dfa_size"); +"c_mxdfas" printf("current_max_dfas"); +"curmxrls" printf("current_max_rules"); +"c_mx_scs" printf("current_max_scs"); +"c_mx_tmp" printf("current_max_template_xpairs"); +"c_mx_xpr" printf("current_max_xpairs"); +"c_mxccls" printf("current_maxccls"); +"curr_mns" printf("current_mns"); +"cursttyp" printf("current_state_type"); +"datflush" printf("dataflush"); +"dfacunin" printf("dfaacc_union"); +"do_indnt" printf("do_indent"); +"dmpasrl" printf("dump_associated_rules"); +"dmptrns" printf("dump_transitions"); +"dupmach" printf("dupmachine"); +"ecsfrmxt" printf("ecs_from_xlation"); +"eobstate" printf("end_of_buffer_state"); +"epsclos" printf("epsclosure"); +"expnxtck" printf("expand_nxt_chk"); +"fndtblsp" printf("find_table_space"); +"fnshrule" printf("finish_rule"); +"firstfre" printf("firstfree"); +"firstprt" printf("firstprot"); +"flxgettm" printf("flex_gettime"); +"flxerror" printf("flexerror"); +"flxfatal" printf("flexfatal"); +"fmtptmsg" printf("format_pinpoint_message"); +"gnNULtrn" printf("gen_NUL_trans"); +"gnbktrkg" printf("gen_backtracking"); +"gnbtactn" printf("gen_bt_action"); +"gnfndact" printf("gen_find_action"); +"gnlindir" printf("gen_line_dirs"); +"gnnxcste" printf("gen_next_compressed_state"); +"gnnxmtch" printf("gen_next_match"); +"gnnxtst" printf("gen_next_state"); +"gnstrtst" printf("gen_start_state"); +"hshentry" printf("hash_entry"); +"hshfct" printf("hashfunct"); +"incmxdfa" printf("increase_max_dfas"); +"indput2s" printf("indent_put2s"); +"indputs" printf("indent_puts"); +"infilnam" printf("infilename"); +"inp_fles" printf("input_files"); +"intractv" printf("interactive"); +"lndirout" printf("line_directive_out"); +"lnkmchns" printf("link_machines"); +"lst_cset" printf("list_character_set"); +"maketbls" printf("make_tables"); +"mkbgnorm" printf("mark_beginning_as_normal"); +"mktmplat" printf("mktemplate"); +"nbktrckg" printf("num_backtracking"); +"ninfiles" printf("num_input_files"); +"numraloc" printf("num_reallocs"); +"numrules" printf("num_rules"); +"nuxlatns" printf("num_xlations"); +"numnpair" printf("numsnpairs"); +"outfilnm" printf("output_file_name"); +"peakpair" printf("peakpairs"); +"perf_rep" printf("performance_report"); +"pptmsg" printf("pinpoint_message"); +"plcstate" printf("place_state"); +"prvctdan" printf("previous_continued_action"); +"prtstats" printf("printstats"); +"pgm_name" printf("program_name"); +"prtcomst" printf("protcomst"); +"rdblefrm" printf("readable_form"); +"realrjct" printf("real_reject"); +"rallocar" printf("reallocate_array"); +"rjctused" printf("reject_really_used"); +"rulelnno" printf("rule_linenum"); +"ruletype" printf("rule_type"); +"stinpfle" printf("set_input_file"); +"setupia" printf("set_up_initial_allocations"); +"startime" printf("starttime"); +"ste_type" printf("state_type"); +"symfollo" printf("symfollowset"); +"sympartn" printf("sympartition"); +"syntxerr" printf("syntaxerror"); +"tmpactfl" printf("temp_action_file"); +"todohead" printf("todo_head"); +"todonext" printf("todo_next"); +"trnschar" printf("transchar"); +"trnstout" printf("transition_struct_out"); +"trlcntxt" printf("trlcontxt"); +"vtrailrl" printf("variable_trail_rule"); +"vtrlctrl" printf("variable_trailing_context_rules"); +"varlngth" printf("varlength"); +"yycrbffr" printf("yy_create_buffer"); +"yydlbffr" printf("yy_delete_buffer"); +"yyinbffr" printf("yy_init_buffer"); +"yyldbfst" printf("yy_load_buffer_state"); +"yyswtobf" printf("yy_switch_to_buffer"); +"yyerrflg" printf("yyerrflag"); +"yymrreus" printf("yymore_really_used"); +"yymrused" printf("yymore_used"); +"yyrestrt" printf("yyrestart"); +. ECHO; +%% +main() +{ + yylex(); +} diff --git a/commands/flex-2.5.4/MISC/Macintosh/THINK_C_notes b/commands/flex-2.5.4/MISC/Macintosh/THINK_C_notes new file mode 100644 index 000000000..e99c97227 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Macintosh/THINK_C_notes @@ -0,0 +1,100 @@ +Notes on the THINK C version of Flex 2.4.6 +Scott Hofmann 23-JUL-94 +Internet: scotth@visix.com + +The only changes needed to compile Flex 2.4.6 under Symantec C++ 6.0 was +to #include in main.c and call ccommand() just before flexinit() +in main(). The notes below are mostly of historical significance only; most +of the workarounds below were to get around restrictions/problems in earlier +versions of THINK C. The only section which still applies is Russell Finn's +description of how to make Flex generate output of type 'KAHL'. Also, 4-byte +ints must be used by any project which uses Flex output. + +If you want to recreate the project, you'll need to add the files +alloca.c and xmalloc.c in this directory. Both files are copylefted; see +the GNU General Public License for details. You will also need to recompile +both the ANSI and unix libraries to use 4 byte ints, and if you want the +files that flex creates to have 'KAHL' as the creator you'll need to apply +Russell Finn's patch. + +Notes on the THINK C version of Flex 2.3.7 +Jonas Barklund, 25-JAN-92 +Internet: jonas@csd.uu.se + +I have merged the sources for Flex version 2.3.7 with the older version +which was hacked for THINK C version 4. I have conditionalized the code +so that I think it should work with both THINK C version 4 and 5 (for +those of you who don't know: the THINK_C symbol is defined as 1 in version +4 and as 5 in version 5). I have put in some missing prototypes, so it +compiles also with "require prototypes" on. + +Most of the notes below still apply, in particular that about the MakeRes +program. + + +Notes on the THINK C version of Flex +Russell S. Finn, 19-FEB-90 +Internet: rsfinn@athena.mit.edu, rsfinn@neutron.lcs.mit.edu +CompuServe: 76377,1107 +GEnie: RSFINN + +Flex appears to be covered by a copyright notice from the University of +California, similar to the one covering Berkeley Unix; the Free Software +Foundation is not part of the picture here. So here is a version +created with THINK C 4.0, along with the source code; as with the +Bison distribution, I am including *all* of the source code I received +with the package. + +The current version (modification date January 25, 1990) has only the +bare-bones interface provided by the THINK C library routine "ccommand", +which allows the user to type a command line and to redirect the output. +Perhaps someday I may try to implement a "real" user interface; perhaps +not. + +The only modifications made to the source file are surrounded by "#ifdef +THINK_C"..."#endif"; in theory, then, these sources could be recompiled +on another system if necessary. These are the actual files modified: +alloca.c, dfa.c, flexdef.h, main.c, misc.c, scan.c, sym.c. Most of these +changes were minor, and many of them would have been unnecessary if the +original Flex source code had been written for an ANSI-compliant C compiler. +In addition, the file "macutils.c" is completely new; see the discussion +of "MakeRes" below. + +THINK C users may find it convenient to have the output text files written +by Flex be THINK C documents. To do this, create a copy of the "ANSI" +project called "ANSI-KAHL", and a copy of the file "fopen.c" called +"fopen-KAHL.c". In the copy, find the routine "setfiletype", and replace +the lines: + if (!(oflag & F_BINARY)) + pb.ioFlFndrInfo.fdType = 'TEXT'; +with the lines: + if (!(oflag & F_BINARY)) { + pb.ioFlFndrInfo.fdType = 'TEXT'; + pb.ioFlFndrInfo.fdCreator = 'KAHL'; + } +Replace "fopen.c" with the new "fopen-KAHL.c", rebuild the new project +"ANSI-KAHL", and use this project in the project file "Flex.¹" +instead of the "ANSI" project. + +** The "MakeRes" program + +The output files created by Flex contain large amounts of preinitialized +static data; the file "scan.c" contained in the Flex.¹ project is one +such file. However, the Macintosh architecture limits normal applications +to 32K of global data. In many cases (including Flex), this limit can +be surpassed by the static data generated by Flex. + +The solution I have implemented for the THINK C version of Flex is to +extract the data tables from the Flex output file, and paste them into +the file "MakeRes.c". Then, by recompiling and running the program in +the "MakeRes.¹" project (it is not necessary to create an application), +a resource file called "Flex.¹.rsrc" is created in the current directory. +The Flex output file "scan.c" has been modified to load the static data +from the resource fork of the Flex application. This is done by calling +the "load_table" function, which is defined in the file "macutils.c". + +In the application for which I needed Flex, the data tables were small +enough that I didn't need to do this. However, if your application +requires you to do this, simply follow the model of "scan.c"; the MakeRes +project and source code has been included for your use. + diff --git a/commands/flex-2.5.4/MISC/Macintosh/alloca.c b/commands/flex-2.5.4/MISC/Macintosh/alloca.c new file mode 100644 index 000000000..9cb6fa036 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Macintosh/alloca.c @@ -0,0 +1,195 @@ +/* + alloca -- (mostly) portable public-domain implementation -- D A Gwyn + + last edit: 86/05/30 rms + include config.h, since on VMS it renames some symbols. + Use xmalloc instead of malloc. + + This implementation of the PWB library alloca() function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + + It should work under any C implementation that uses an + actual procedure stack (as opposed to a linked list of + frames). There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca()-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. +*/ +#ifndef lint +static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ +#endif + +#ifdef emacs +#include "config.h" +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs */ + +#ifndef alloca /* If compiling with GCC, this file's not needed. */ + +#ifdef __STDC__ +typedef void *pointer; /* generic pointer type */ +#else +typedef char *pointer; /* generic pointer type */ +#endif + +#define NULL 0 /* null pointer constant */ + +extern void free(); +extern pointer xmalloc(); + +/* + Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown +*/ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* direction unknown */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* known at compile-time */ + +#else /* STACK_DIRECTION == 0; need run-time code */ + +static int stack_dir; /* 1 or -1 once known */ +#define STACK_DIR stack_dir + +static void +find_stack_direction (/* void */) +{ + static char *addr = NULL; /* address of first + `dummy', once known */ + auto char dummy; /* to get stack address */ + + if (addr == NULL) + { /* initial entry */ + addr = &dummy; + + find_stack_direction (); /* recurse once */ + } + else /* second entry */ + if (&dummy > addr) + stack_dir = 1; /* stack grew upward */ + else + stack_dir = -1; /* stack grew downward */ +} + +#endif /* STACK_DIRECTION == 0 */ + +/* + An "alloca header" is used to: + (a) chain together all alloca()ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc() + alignment chunk size. The following default should work okay. +*/ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* to force sizeof(header) */ + struct + { + union hdr *next; /* for chaining headers */ + char *deep; /* for stack depth measure */ + } h; +} header; + +/* + alloca( size ) returns a pointer to at least `size' bytes of + storage which will be automatically reclaimed upon exit from + the procedure that called alloca(). Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. +*/ + +static header *last_alloca_header = NULL; /* -> last alloca header */ + +pointer +alloca (size) /* returns pointer to storage */ + unsigned size; /* # bytes to allocate */ +{ + auto char probe; /* probes stack depth: */ + register char *depth = &probe; + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* unknown growth direction */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca()ed storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* traverses linked list */ + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* collect garbage */ + + hp = np; /* -> next header */ + } + else + break; /* rest are not deeper */ + + last_alloca_header = hp; /* -> last valid storage */ + } + + if (size == 0) + return NULL; /* no allocation required */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = xmalloc (sizeof (header) + size); + + /* address of header */ + + ((header *)new)->h.next = last_alloca_header; + ((header *)new)->h.deep = depth; + + last_alloca_header = (header *)new; + + /* User storage begins just after header. */ + + return (pointer)((char *)new + sizeof(header)); + } +} + +#endif /* no alloca */ diff --git a/commands/flex-2.5.4/MISC/Macintosh/alloca.h b/commands/flex-2.5.4/MISC/Macintosh/alloca.h new file mode 100644 index 000000000..f48eaf2f7 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Macintosh/alloca.h @@ -0,0 +1,10 @@ +/**************** +** alloca.h +** +** header for alloca() +*****************/ + +typedef void *pointer; + +pointer alloca(unsigned size); + diff --git a/commands/flex-2.5.4/MISC/Macintosh/xmalloc.c b/commands/flex-2.5.4/MISC/Macintosh/xmalloc.c new file mode 100644 index 000000000..5bef83197 --- /dev/null +++ b/commands/flex-2.5.4/MISC/Macintosh/xmalloc.c @@ -0,0 +1,69 @@ +/* xmalloc.c -- malloc with out of memory checking + Copyright (C) 1990, 1991 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#if STDC_HEADERS || THINK_C +#include +#else +char *malloc (); +char *realloc (); +void free (); +#endif + +#ifdef THINK_C +#define error(x, y, z) perror(z) /* Throw out meaningless arguments */ +#else +void error (); +#endif + +/* Allocate N bytes of memory dynamically, with error checking. */ + +char * +xmalloc (n) + unsigned n; +{ + char *p; + + p = malloc (n); + if (p == 0) + /* Must exit with 2 for `cmp'. */ + error (2, 0, "virtual memory exhausted"); + return p; +} + +/* Change the size of an allocated block of memory P to N bytes, + with error checking. + If P is NULL, run xmalloc. + If N is 0, run free and return NULL. */ + +char * +xrealloc (p, n) + char *p; + unsigned n; +{ + if (p == 0) + return xmalloc (n); + if (n == 0) + { + free (p); + return 0; + } + p = realloc (p, n); + if (p == 0) + /* Must exit with 2 for `cmp'. */ + error (2, 0, "virtual memory exhausted"); + return p; +} diff --git a/commands/flex-2.5.4/MISC/NT/Makefile b/commands/flex-2.5.4/MISC/NT/Makefile new file mode 100644 index 000000000..581d49778 --- /dev/null +++ b/commands/flex-2.5.4/MISC/NT/Makefile @@ -0,0 +1,103 @@ +# +# make file for "flex" tool +# @(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/Makefile,v 2.9 +# 90/05/26 17:28:44 vern Exp $ (LBL) +# +# the first time around use "nmake f_flex" +# +# This makefile is specific for Microsoft's Visual C 2.0, & nmake +# +# - Stan Adermann +# + + +SKELFLAGS = -DDEFAULT_SKELETON_FILE=\"c:/src/flex/flex.skl\" +CFLAGS = -nologo -W2 -F 8000 -Ox -DUSG +LDFLAGS = /nologo /BATCH /STACK:8000 +FLEX_FLAGS = -ist8 -Sflex.skl + +FLEX = .\flex.exe +CC = cl +YACC = c:\lib\byacc +MAKE = nmake /nologo + +FLEXOBJS = \ + ccl.obj \ + dfa.obj \ + ecs.obj \ + gen.obj \ + main.obj \ + misc.obj \ + nfa.obj \ + parse.obj \ + scan.obj \ + skel.obj \ + sym.obj \ + tblcmp.obj \ + yylex.obj + +FLEX_C_SOURCES = \ + ccl.c \ + dfa.c \ + ecs.c \ + gen.c \ + main.c \ + misc.c \ + nfa.c \ + parse.c \ + scan.c \ + skel.c \ + sym.c \ + tblcmp.c \ + yylex.c + +all : flex.exe + +flex.exe : $(FLEXOBJS) + link $(LDFLAGS) $(FLEXOBJS) -out:$*.exe + +f_flex: + copy initscan.c scan.c + touch scan.c + @echo compiling first flex + $(MAKE) flex.exe + del scan.c + @echo using first flex to generate final version... + $(MAKE) flex.exe + +# +# general inference rule +# +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +parse.h parse.c : parse.y + $(YACC) -d parse.y + @move y_tab.c parse.c + @move y_tab.h parse.h + +scan.c : scan.l + $(FLEX) $(FLEX_FLAGS) $(COMPRESSION) scan.l >scan.c + + +scan.obj : scan.c parse.h flexdef.h + +main.obj : main.c flexdef.h + $(CC) $(CFLAGS) -c $(SKELFLAGS) main.c + +ccl.obj : ccl.c flexdef.h +dfa.obj : dfa.c flexdef.h +ecs.obj : ecs.c flexdef.h +gen.obj : gen.c flexdef.h +misc.obj : misc.c flexdef.h +nfa.obj : nfa.c flexdef.h +parse.obj : parse.c flexdef.h +sym.obj : sym.c flexdef.h +tblcmp.obj : tblcmp.c flexdef.h +yylex.obj : yylex.c flexdef.h +skel.obj : skel.c flexdef.h + + +clean : + del *.obj + del *.map diff --git a/commands/flex-2.5.4/MISC/NT/config.h b/commands/flex-2.5.4/MISC/NT/config.h new file mode 100644 index 000000000..17e831a95 --- /dev/null +++ b/commands/flex-2.5.4/MISC/NT/config.h @@ -0,0 +1,32 @@ +/* config.h. Generated automatically by configure. */ +/* $Header: /home/daffy/u0/vern/flex/RCS/conf.in,v 1.2 95/01/09 +12:11:51 vern Exp $ */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have and it should be used (not on +Ultrix). */ +#define HAVE_ALLOCA_H 0 + +/* Define if platform-specific command line handling is necessary. */ +/* #undef NEED_ARGV_FIXUP */ + +/* Define if you use FAT file system, leave undefined for NTFS */ +#undef SHORT_FILE_NAMES +/* #define SHORT_FILE_NAMES 1 */ diff --git a/commands/flex-2.5.4/MISC/NeXT b/commands/flex-2.5.4/MISC/NeXT new file mode 100644 index 000000000..f862a1f43 --- /dev/null +++ b/commands/flex-2.5.4/MISC/NeXT @@ -0,0 +1,34 @@ +this API is not documented/supported by NeXT and may go away at any time, + so test again when you upgrade (works fine for me on NEXTSTEP_Dev_3.2) +------------------------------------------------------------------------- +See KBNS.32.2.029 from the successor of: +ftp://ftp.cs.orst.edu/software/NeXT/documents/KBNS.32.1.rtf +Otherwise (that successor not yet having been published), ask me for a copy +of the item on RfSchtkt@maze.ruca.ua.ac.be. Bison's messages are not as +disciplined as flex' ones, so it should get more discipline first. + +Specifically (in addition to what's described in the KBNS item): +makeUser.o and make_support.o should be added to OBJECTS in Makefile.in +In parse.y, line_pinpoint() (assumption all messages ultimately go there), add: + make_support( + // don't worry about declaring: cc's source doesn't either, + // it seems + syntaxerror?0:1, + NULL, + infilename, + line, + str, + 0,0,0 + ); + +FMyIO: in cc, these files contain the word make_support: + ChangeLog-NeXT + Makefile.in + config/next.h: defines REPORT_EVENT in terms of make_support + make_support.c + +FMyIO: in cc, these files contain the word REPORT_EVENT: + cccp.c + config/next.h + gcc.c + toplev.c diff --git a/commands/flex-2.5.4/MISC/OS2/Makefile.os2 b/commands/flex-2.5.4/MISC/OS2/Makefile.os2 new file mode 100644 index 000000000..e984f6de2 --- /dev/null +++ b/commands/flex-2.5.4/MISC/OS2/Makefile.os2 @@ -0,0 +1,72 @@ +# make file for "flex" tool, emx+gcc + +release: + $(MAKE) -f Makefile.os2 flex.exe \ + CC="gcc -Zomf -O" O=".obj" A=".lib" AR="emxomfar" \ + LDFLAGS="-s -Zcrtdll -Zstack 512" +debug: + $(MAKE) -f Makefile.os2 flex.exe \ + CC="gcc -g" O=".o" A=".a" AR="ar" + +CFLAGS = -DOS2 -DSHORT_FILE_NAMES + +YACC = bison +FLEX = flex +FLEX_FLAGS = -ist + +.SUFFIXES: .c $O + +.c$O: + $(CC) $(CFLAGS) -c $< + +FLEXLIB = fl$A +FLEXOBJS = ccl$O dfa$O ecs$O gen$O main$O misc$O nfa$O parse$O \ + scan$O skel$O sym$O tblcmp$O yylex$O +LIBOBJS = libmain$O libyywrap$O + +flex.exe : $(FLEXOBJS) $(FLEXLIB) + $(CC) $(LDFLAGS) -o $@ $(FLEXOBJS) $(FLEXLIB) + +first_flex: + cp initscan.c scan.c + $(MAKE) $(MFLAGS) flex + +$(FLEXLIB): $(LIBOBJS) + $(AR) cru $(FLEXLIB) $(LIBOBJS) + $(AR) s $(FLEXLIB) + +parse.h parse.c: parse.y + $(YACC) -d -o parse.c parse.y + +scan.c : scan.l + $(FLEX) $(FLEX_FLAGS) $(COMPRESSION) scan.l >scan.c + +scan$O : scan.c parse.h flexdef.h + +main$O : main.c flexdef.h +ccl$O : ccl.c flexdef.h +dfa$O : dfa.c flexdef.h +ecs$O : ecs.c flexdef.h +gen$O : gen.c flexdef.h +misc$O : misc.c flexdef.h +nfa$O : nfa.c flexdef.h +parse$O : parse.c flexdef.h +sym$O : sym.c flexdef.h +tblcmp$O : tblcmp.c flexdef.h +yylex$O : yylex.c flexdef.h + +skel.c: flex.skl mkskel.sh + $(SHELL) mkskel.sh flex.skl >skel.c + +test : flex + flex $(FLEX_FLAGS) $(COMPRESSION) scan.l | diff scan.c - + +bigtest : + rm -f scan.c ; $(MAKE) COMPRESSION="-C" test + rm -f scan.c ; $(MAKE) COMPRESSION="-Ce" test + rm -f scan.c ; $(MAKE) COMPRESSION="-Cm" test + rm -f scan.c ; $(MAKE) COMPRESSION="-Cfe" test + rm -f scan.c ; $(MAKE) COMPRESSION="-CFe" test + rm -f scan.c ; $(MAKE) COMPRESSION="-Cf" test + rm -f scan.c ; $(MAKE) COMPRESSION="-CF" test + rm -f scan.c ; $(MAKE) diff --git a/commands/flex-2.5.4/MISC/OS2/config.h b/commands/flex-2.5.4/MISC/OS2/config.h new file mode 100644 index 000000000..acf7b8637 --- /dev/null +++ b/commands/flex-2.5.4/MISC/OS2/config.h @@ -0,0 +1,28 @@ +/* ------------------------------------------------ */ +/* version of config.h for OS/2 */ +/* ------------------------------------------------ */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H + +/* Define if platform-specific command line handling is necessary. */ +#define NEED_ARGV_FIXUP +#define argv_fixup(ac,av) { _response(ac,av); _wildcard(ac,av);} diff --git a/commands/flex-2.5.4/MISC/README b/commands/flex-2.5.4/MISC/README new file mode 100644 index 000000000..dc16b0233 --- /dev/null +++ b/commands/flex-2.5.4/MISC/README @@ -0,0 +1,76 @@ +Miscellaneous flex stuff. The items which have been tested with flex 2.5 are: + + - texinfo/, a subdirectory containing a "texinfo" version of flex(1) + and the corresponding "info" files (contributed by Francois Pinard). + + - VMS/, a subdirectory containing makefiles, configuration files, + run-time support, and installation notes for building flex 2.5 + on VMS (contributed by Pat Rankin). + + - Borland/ - makefile and config.h for Borland 4.02 compiler + (contributed by Terrence O Kane, who notes that no source + code changes were necessary). + + - NT/ - Makefile and config.h for NT, contributed by Stan Adermann. + + - OS2/ - Makefile and config.h for building flex under OS/2, + contributed by Kai Uwe Rommel. + + - Amiga/: notes on building flex for the Amiga, contributed + by Andreas Scherer. + + - parse.c, parse.h - output of running yacc (byacc, actually) + on parse.y. If your system doesn't have a flavor of yacc available, + copy these into the main flex source directory instead. + + - flex.man - preformatted version of flex man page + + +The following have been tested using flex 2.4: + + - debflex.awk, an awk script for anotating flex debug output. + It presently only works with gawk and mawk, not with "old" + or "new" awk. + + - NeXT: ProjectBuilder.app support for use in the NeXT world. + + - Notes on building flex for the Macintosh using Think-C, + in the Macintosh/ subdirectory. + + - testxxLexer.l, a sample C++ program that uses flex's scanner + class option ("-+"). + + - fastwc/, a subdirectory containing examples of how to use flex + to write progressively higher-performance versions of the Unix + "wc" utility. This certainly should work with 2.5, but hasn't + been tested. + + - Borland.old/: notes on building flex 2.4 for Borland C++ 3.1 + on MS-DOS. These shouldn't be needed for flex 2.5. Included + only in case you encounter unanticipated difficulties. + + - EBCDIC: contact information for building flex for EBCDIC. + + +The following are all out-of-date with respect to flex release 2.4 (and +in general up-to-date for flex 2.3): + + - Atari/Atari.patches, patches for porting flex to the Atari and + to Minix. + + - A number of notes and Makefiles for compiling flex under MS-DOS, + in the MSDOS/ subdirectory. + + - Notes on building flex for MVS, in the MVS/ subdirectory. + +If any of this is out-of-date and can be deleted, please let me know. + +And the following is included for compatibility with some broken versions +of bison: + + - alloca.c, a public-domain, mostly-portable version of the + alloca() routine (used by bison's parsers) written by D. A. Gwyn. + + +Many thanks to those who contributed these files. Updated versions will +be appreciated! diff --git a/commands/flex-2.5.4/MISC/VMS/README.VMS b/commands/flex-2.5.4/MISC/VMS/README.VMS new file mode 100644 index 000000000..e4a49660c --- /dev/null +++ b/commands/flex-2.5.4/MISC/VMS/README.VMS @@ -0,0 +1,83 @@ +Brief instructions for building flex 2.5.x for VMS: + + 0) if you have either MMS (from Digital) or MMK (freeware) for use +as a `make' utility, follow the directions in steps #1 through #5 below. +If not, execute + @BUILD.COM xxxC +where "xxxC" is either "VAXC" or "DECC" or "GNUC", and then skip to +step #5. + + 1) set default to the source directory (not the [.MISC.VMS] subdirectory +where this file is located). + + 2) COPY [.MISC.VMS]DESCRIP.MMS []*.* +(Recursive invocations of `make' for the `bigcheck' test assume that the +makefile will be found as descrip.mms in the current directory.) + +To build with VAX C for VAX/VMS: + 3) MMS /MACRO=("VAXC=1") FLEX.EXE +(The /macro qualifier is optional in this case.) + +To build with GNU C for VAX/VMS: + 2.5) possibly edit descrip.mms to uncomment `SET COMMAND' for GCCINIT, + depending on local site configuration + 3) MMS /MACRO=("GNUC=1") FLEX.EXE + +To build with DEC C for either VAX/VMS or Alpha/VMS: + 3) MMS /MACRO=("DECC=1") FLEX.EXE +(Expect one or two informational messages from the compiler about +implicitly declared functions.) + +Minimal testing of the resulting program: + 4) MMS CHECK +(If `diff' reports no warnings, the test has succeeded.) + +More thorough testing: + 4.5) MMS /MACRO=("xxxC=1") BIGCHECK ! "xxxC=1" as in step #3 above +(If using an older version of MMK rather than MMS, this might fail when +`make' is invoked recursively due to excessive BYTLM usage by MMK.) + +Installation (the VMS makefile does not support an `install' target; +you'll need to do this part manually): + 5) copy flex.exe, flex.doc, flex.skl, flexlib.olb, and FlexLexer.h to +location(s) appropriate for your site. To use flex, define a "foreign" +command by making a DCL symbol whose value begins with a dollar sign +immediately followed by the filename for flex.exe, as in + $ flex :== $local_tools:flex.exe +where `local_tools:' is the logical name pointing to flex.exe's location. +This symbol will ordinarily be a candidate for your login.com. When +invoking flex, upper- or mixed-case command line options must be enclosed +in quotes. For example, + $ flex "-Pxyz" "-L" -t mylexer.l > mylexer.c +(use prefix "xyz" instead of "yy", suppress `#line' compiler directives +in the output, write the output to `stdout', process file mylexer.l, +and capture `stdout' in file mylexer.c). As illustrated here, this VMS +version of flex supports emulation of command line I/O redirection used +by Unix shells. + + flex.exe -- the executable image for the flex program; + flex.doc -- documentation, the "man page" describing flex (flex.1 + processed with `nroff -man' followed by `col -b'); + flex.skl -- a text file containing flex's default skeleton; + with this version of flex, it is for reference only; + flex.exe does not need to know where to find it; + flexlib.olb -- an object library containing some support routines; + you might need to link your generated lexer against + it, depending on how your program is designed; + flex.exe does not access it; it corresponds to + `libfl.a' under Unix; + FlexLexer.h -- header file used for C++ class-based lexers; not + needed for ordinary C lexers. + +Notes: + This VMS port of flex supports only the original Unix command line +interface, not the native DCL interface which was available for flex 2.3. + + build.com -- DCL command procedure as alternative to descrip.mms; + descrip.mms -- 2.5.x makefile for use with MMS or MMK (see step #1); + mkskel.tpu -- TPU program used to make skel.c from flex.skl for full + build from scratch; performs same function as mkskel.sh; + vms-conf.h -- pre-configured `conf.in', copied to [-.-]config.h; + vms-code.c -- VMS-specific support code, copied to [-.-]vms-code.c; + README.VMS -- this file + diff --git a/commands/flex-2.5.4/MISC/VMS/build.com b/commands/flex-2.5.4/MISC/VMS/build.com new file mode 100644 index 000000000..dbde55ab0 --- /dev/null +++ b/commands/flex-2.5.4/MISC/VMS/build.com @@ -0,0 +1,155 @@ +$! VMS build procedure for flex 2.5.x; +$ v = 'f$verify(0)' +$! +$! usage: +$! $ @[.MISC.VMS]BUILD.COM compiler parser [test] +$! where `compiler' is either "GNUC" or "DECC" or "VAXC" or empty +$! and `parser' is either "BISON" or "BYACC" or "YACC" or empty +$! and `[test]' is either "CHECK-ONLY" or "NO-CHECK" or empty +$! empty compiler defaults to VAX C (even under Alpha/VMS); +$! special "LINK" compiler value does link without compilation; +$! empty parser defaults to using supplied parse code in [.MISC]; +$! optional test is performed by default. +$! +$ +$! we start from [.MISC.VMS], then move to the main source directory +$ where = f$parse("_._;",f$environ("PROCEDURE")) - "_._;" +$ set default 'where' +$ brkt = f$extract(f$length(where)-1,1,where) +$ if f$locate(".MISC.VMS"+brkt,where).lt.f$length(where) then - + set default 'f$string(f$extract(0,1,f$dir()) + "-.-" + brkt)' +$ +$ p1 := 'p1' +$ p2 := 'p2' +$ p3 := 'p3' +$ if p1.eqs."LINK" then goto link +$ if p3.eqs."CHECK-ONLY" then goto check +$ p2 = p2 - "_PARSER" +$! +$ CDEFS = "/Define=(""VMS"")" ! =(""VMS"",""DEFAULT_CSIZE=256"") +$! +$ if p1.eqs."GNUC" +$ then CC = "gcc" +$ CFLAGS = "/noList/Opt=2/Debug/noVerbose" +$ LIBS = "gnu_cc:[000000]gcclib.olb/Library, sys$library:vaxcrtl.olb/Library" +$ else CC = "cc" +$ if p1.eqs."DECC" +$ then CFLAGS = "/noList/Prefix=All" +$ LIBS = "" +$ if f$trnlnm("DECC$CC_DEFAULT").nes."" then CC = CC + "/DECC" +$ else CFLAGS = "/noList/Optimize=noInline" +$ LIBS = "sys$share:vaxcrtl.exe/Shareable" +$ if f$trnlnm("DECC$CC_DEFAULT").nes."" then CC = CC + "/VAXC" +$ if p1.nes."" .and. p1.nes."VAXC" then exit %x002C +$ endif +$ endif +$! +$ no_parser = 0 +$ if p2.eqs."BISON" +$ then YACC = "bison" +$ YACCFLAGS = "/Defines/Fixed_Outfiles" +$ ALLOCA = ",[]alloca.obj" +$ else +$ YACCFLAGS = "-d" +$ ALLOCA = "" +$ if p2.eqs."BYACC" .or. p2.eqs."YACC" +$ then YACC = f$edit(p2,"LOWERCASE") +$ else YACC = "! yacc" +$ if p2.nes."" .and. p2.nes."NO" .and. p2.nes."NONE" then exit %x002C +$ no_parser = 1 +$ endif +$ endif +$! +$ ECHO = "write sys$output" +$ COPY = "copy_" +$ MOVE = "rename_/New_Vers" +$ MUNG = "search_/Exact/Match=NOR" +$ PURGE = "purge_/noConfirm/noLog" +$ REMOVE = "delete_/noConfirm/noLog" +$ TPU = "edit_/TPU/noJournal/noDisplay/noSection" +$! +$ if v then set verify +$! +$ 'COPY' [.misc.vms]vms-conf.h config.h +$ 'COPY' [.misc.vms]vms-code.c vms-code.c +$ 'COPY' [.misc]flex.man flex.doc +$ if ALLOCA.nes."" then 'COPY' [.MISC]alloca.c alloca.c +$ 'COPY' initscan.c scan.c !make.bootstrap +$! +$ if f$search("skel.c").nes."" then - + if f$cvtime(f$file_attr("skel.c","RDT")).gts. - + f$cvtime(f$file_attr("flex.skl","RDT")) then goto skip_mkskel +$ 'TPU' /Command=[.misc.vms]mkskel.tpu flex.skl /Output=skel.c +$skip_mkskel: +$! +$ if f$search("parse.c").nes."" .and. f$search("parse.h").nes."" then - + if f$cvtime(f$file_attr("parse.c","RDT")).gts. - + f$cvtime(f$file_attr("parse.y","RDT")) then goto skip_yacc +$ if f$search("y_tab.%").nes."" then 'REMOVE' y_tab.%;* +$ if no_parser +$ then 'COPY' [.misc]parse.% sys$disk:[]y_tab.* +$ else 'YACC' 'YACCFLAGS' parse.y +$ endif +$ 'MUNG' y_tab.c "#module","#line" /Output=parse.c +$ 'REMOVE' y_tab.c;* +$ 'MOVE' y_tab.h parse.h +$skip_yacc: +$! +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] ccl.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] dfa.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] ecs.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] gen.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] main.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] misc.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] nfa.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] parse.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] scan.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] skel.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] sym.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] tblcmp.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] yylex.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] vms-code.c +$ if ALLOCA.nes."" then - !bison + 'CC' 'CFLAGS' /Define=("STACK_DIRECTION=-1","xmalloc=yy_flex_xmalloc") alloca.c +$! +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] libmain.c +$ 'CC' 'CFLAGS' 'CDEFS' /Include=[] libyywrap.c +$ library/Obj flexlib.olb/Create libmain.obj,libyywrap.obj/Insert +$ if f$search("flexlib.olb;-1").nes."" then 'PURGE' flexlib.olb +$! +$ open/Write optfile sys$disk:[]crtl.opt +$ write optfile LIBS +$ close optfile +$ if f$search("crtl.opt;-1").nes."" then 'PURGE' crtl.opt +$! +$ version = "# flex ""2.5""" !default, overridden by version.h +$ open/Read/Error=v_h_2 hfile version.h +$ read/End=v_h_1 hfile version +$v_h_1: close/noLog hfile +$v_h_2: version = f$element(1,"""",version) +$ open/Write optfile sys$disk:[]ident.opt +$ write optfile "identification=""flex ''version'""" +$ close optfile +$ if f$search("ident.opt;-1").nes."" then 'PURGE' ident.opt +$! +$link: +$ link/noMap/Exe=flex.exe ccl.obj,dfa.obj,ecs.obj,gen.obj,main.obj,misc.obj,- + nfa.obj,parse.obj,scan.obj,skel.obj,sym.obj,tblcmp.obj,yylex.obj,- + vms-code.obj 'ALLOCA' ,flexlib.olb/Lib,- + sys$disk:[]crtl.opt/Opt,sys$disk:[]ident.opt/Opt +$! +$ if p3.eqs."NO-CHECK" .or. p3.eqs."NOCHECK" then goto done +$ +$check: +$ 'ECHO' "" +$ 'ECHO' " Checking with COMPRESSION=""""" +$ mcr sys$disk:[]flex.exe -t -p scan.l > scan.chk +$ diff_/Output=_NL:/Maximum_Diff=1 scan.c scan.chk +$ if $status +$ then 'ECHO' " Test passed." +$ 'REMOVE' scan.chk;* +$ else 'ECHO' "? Test failed!" +$ endif +$ +$done: +$ exit diff --git a/commands/flex-2.5.4/MISC/VMS/descrip.mms b/commands/flex-2.5.4/MISC/VMS/descrip.mms new file mode 100644 index 000000000..5b2859d34 --- /dev/null +++ b/commands/flex-2.5.4/MISC/VMS/descrip.mms @@ -0,0 +1,311 @@ +# descrip.mms -- makefile for building `flex' using MMS or MMK on VMS; +# created manually from Makefile.in +# flex 2.5.0 Jan'95 + +MAKEFILE = descrip.mms # from [.MISC.VMS] +MAKE = $(MMS) /Descr=$(MAKEFILE) +MAKEFLAGS = $(MMSQUALIFIERS) + +# Possible values for DEFS: +# "VMS" -- used just to make sure parentheses aren't empty; +# For flex to always generate 8-bit scanners, append +# ,"DEFAULT_CSIZE=256" inside /Define=() of DEFS. + +DEFS = /Define=("VMS") +LDFLAGS = /noMap + +# compiler handling +.ifdef GNUC +CC = gcc +GCCINIT = ! SET COMMAND GNU_CC:[000000]GCC +CFLAGS = /noList/Opt=2/Debug/noVerbose +LIBS = gnu_cc:[000000]gcclib.olb/Library, sys$library:vaxcrtl.olb/Library +C_CHOICE = "GNUC=1" +.else ! not GNU C +CC = cc +GCCINIT = +.ifdef DECC +CFLAGS = /noList/Prefix=All +LIBS = +C_CHOICE = "DECC=1" +.else ! not DEC C; assume VAX C +CFLAGS = /noList/Optimize=noInline +LIBS = sys$share:vaxcrtl.exe/Shareable +C_CHOICE = "VAXC=1" +.endif +.endif + +# parser handling +# mms/macro=("xxxC=1","zzz_parser=1"), where "zzz_parser" is +# either "bison_parser" or "byacc_parser" or "yacc_parser", +# otherwise assumed to be "no_parser"; and where "xxxC=1" is +# either "VAXC=1", "GNUC=1", or "DECC=1" as above +.ifdef bison_parser +YACC = bison +YACCFLAGS = /Defines/Fixed_Outfiles +YACCINIT = set command gnu_bison:[000000]bison +ALLOCA = ,[]alloca.obj # note leading comma +.else +YACCFLAGS = -d +YACCINIT = +ALLOCA = +.ifdef byacc_parser +YACC = byacc +.else +.ifdef yacc_parser +YACC = yacc +.else +# none of bison, byacc, or yacc specified +.ifdef no_parser +.else +no_parser=1 +.endif # +.endif #yacc +.endif #byacc +.endif #bison + +# VMS-specific hackery +ECHO = write sys$output # requires single quoted arg +COPY = copy_ # +MOVE = rename_/New_Vers # within same device only +MUNG = search_/Exact/Match=NOR # to strip unwanted `#module' directive +NOOP = continue # non-empty command that does nothing +PURGE = purge_/noConfirm/noLog # relatively quiet file removal +REMOVE = delete_/noConfirm/noLog # ditto +TOUCH = append_/New _NL: # requires single file arg +TPU = edit_/TPU/noJournal/noDisplay/noSection + +# You can define this to be "lex.exe" if you want to replace lex at your site. +FLEX =flex.exe +# note: there should be no whitespace between `=' and the name, +# or else $(FLEX_EXEC) below will not function properly. +FLEXLIB = flexlib.olb + +# You normally do not need to modify anything below this point. +# ------------------------------------------------------------ + +VMSDIR = [.MISC.VMS] +MISCDIR = [.MISC] +CURDIR = sys$disk:[] + +CPPFLAGS = $(DEFS)/Include=[] +LIBOPT = $(CURDIR)crtl.opt # run-time library(s) +ID_OPT = $(CURDIR)ident.opt # version identification + +.SUFFIXES : # avoid overhead of umpteen built-in rules +.SUFFIXES : .obj .c + +.c.obj : + $(CC)$(CFLAGS)$(CPPFLAGS) $< + +VMSHDRS = $(VMSDIR)vms-conf.h # copied to []config.h +VMSSRCS = $(VMSDIR)vms-code.c # copied to []vms-code.c +VMSOBJS = ,vms-code.obj # note leading comma + +HEADERS = flexdef.h version.h + +SOURCES = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.y \ + scan.l skel.c sym.c tblcmp.c yylex.c +OBJECTS = ccl.obj,dfa.obj,ecs.obj,gen.obj,main.obj,misc.obj,nfa.obj,parse.obj,\ + scan.obj,skel.obj,sym.obj,tblcmp.obj,yylex.obj $(VMSOBJS) $(ALLOCA) + +LIBSRCS = libmain.c libyywrap.c +LIBOBJS = libmain.obj,libyywrap.obj + +LINTSRCS = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.c \ + scan.c skel.c sym.c tblcmp.c yylex.c + +DISTFILES = README NEWS COPYING INSTALL FlexLexer.h \ + configure.in conf.in Makefile.in mkskel.sh flex.skl \ + $(HEADERS) $(SOURCES) $(LIBSRCS) MISC \ + flex.1 scan.c install.sh mkinstalldirs configure + +DIST_NAME = flex + +# flex options to use when generating scan.c from scan.l +COMPRESSION = +PERF_REPORT = -p +# which "flex" to use to generate scan.c from scan.l +FLEX_EXEC = mcr $(CURDIR)$(FLEX) +FLEX_FLAGS = -t $(PERF_REPORT) #$(COMPRESSION) + +MARKER = make.bootstrap + +##### targets start here ##### + +all : $(FLEX) flex.doc + @ $(NOOP) + +install : $(FLEX) flex.doc flex.skl $(FLEXLIB) FlexLexer.h + @ $(ECHO) "-- Installation must be done manually." + @ $(ECHO) " $+" + +.ifdef GCCINIT +.FIRST + $(GCCINIT) + +.endif #GCCINIT + +flex : $(FLEX) + @ $(NOOP) + +$(FLEX) : $(MARKER) $(OBJECTS) $(FLEXLIB) $(LIBOPT) $(ID_OPT) + $(LINK)/Exe=$(FLEX) $(LDFLAGS)\ + $(OBJECTS),$(FLEXLIB)/Lib,$(LIBOPT)/Opt,$(ID_OPT)/Opt + +$(MARKER) : initscan.c + @- if f$search("scan.c").nes."" then $(REMOVE) scan.c;* + $(COPY) initscan.c scan.c + @ $(TOUCH) $(MARKER) + +parse.c : parse.y + @- if f$search("y_tab.%").nes."" then $(REMOVE) y_tab.%;* +.ifdef no_parser + $(COPY) $(MISCDIR)parse.% $(CURDIR)y_tab.* +.else + $(YACCINIT) + $(YACC) $(YACCFLAGS) parse.y +.endif + $(MUNG) y_tab.c "#module","#line" /Output=parse.c + @- $(REMOVE) y_tab.c;* + $(MOVE) y_tab.h parse.h + +parse.h : parse.c + @ $(TOUCH) parse.h + +scan.c : scan.l + $(FLEX_EXEC) $(FLEX_FLAGS) $(COMPRESSION) scan.l > scan.c + +scan.obj : scan.c parse.h flexdef.h config.h +yylex.obj : yylex.c parse.h flexdef.h config.h + +skel.c : flex.skl $(VMSDIR)mkskel.tpu + $(TPU) /Command=$(VMSDIR)mkskel.tpu flex.skl /Output=skel.c + +main.obj : main.c flexdef.h config.h version.h +ccl.obj : ccl.c flexdef.h config.h +dfa.obj : dfa.c flexdef.h config.h +ecs.obj : ecs.c flexdef.h config.h +gen.obj : gen.c flexdef.h config.h +misc.obj : misc.c flexdef.h config.h +nfa.obj : nfa.c flexdef.h config.h +parse.obj : parse.c flexdef.h config.h +skel.obj : skel.c flexdef.h config.h +sym.obj : sym.c flexdef.h config.h +tblcmp.obj : tblcmp.c flexdef.h config.h +vms-code.obj : vms-code.c flexdef.h config.h + +[]alloca.obj : alloca.c + $(CC)$(CFLAGS)/Define=("STACK_DIRECTION=-1","xmalloc=yy_flex_xmalloc") alloca.c + +alloca.c : $(MISCDIR)alloca.c + $(COPY) $(MISCDIR)alloca.c alloca.c + +config.h : $(VMSDIR)vms-conf.h + $(COPY) $(VMSDIR)vms-conf.h config.h + +vms-code.c : $(VMSDIR)vms-code.c + $(COPY) $(VMSDIR)vms-code.c vms-code.c + +test : check + @ $(NOOP) +check : $(FLEX) + @ $(ECHO) "" + @ $(ECHO) " Checking with COMPRESSION="$(COMPRESSION)"" + $(FLEX_EXEC) $(FLEX_FLAGS) $(COMPRESSION) scan.l > scan.chk + diff_/Output=_NL:/Maximum_Diff=1 scan.c scan.chk + +bigcheck : + @- if f$search("scan.c").nes."" then $(REMOVE) scan.c;* + $(MAKE)$(MAKEFLAGS) /Macro=($(C_CHOICE),"COMPRESSION=""-C""") check + @- $(REMOVE) scan.c;* + $(MAKE)$(MAKEFLAGS) /Macro=($(C_CHOICE),"COMPRESSION=""-Ce""") check + @- $(REMOVE) scan.c;* + $(MAKE)$(MAKEFLAGS) /Macro=($(C_CHOICE),"COMPRESSION=""-Cm""") check + @- $(REMOVE) scan.c;* + $(MAKE)$(MAKEFLAGS) /Macro=($(C_CHOICE),"COMPRESSION=""-f""") check + @- $(REMOVE) scan.c;* + $(MAKE)$(MAKEFLAGS) /Macro=($(C_CHOICE),"COMPRESSION=""-Cfea""") check + @- $(REMOVE) scan.c;* + $(MAKE)$(MAKEFLAGS) /Macro=($(C_CHOICE),"COMPRESSION=""-CFer""") check + @- $(REMOVE) scan.c;* + $(MAKE)$(MAKEFLAGS) /Macro=($(C_CHOICE),"COMPRESSION=""-l""","PERF_REPORT=") check + @- $(REMOVE) scan.c;*,scan.chk;* + $(MAKE)$(MAKEFLAGS) $(FLEX) + @- $(PURGE) scan.obj + @ $(ECHO) "All checks successful" + +$(FLEXLIB) : $(LIBOBJS) + library/Obj $(FLEXLIB)/Create $(LIBOBJS)/Insert + @ if f$search("$(FLEXLIB);-1").nes."" then $(PURGE) $(FLEXLIB) + +# We call it .doc instead of .man, to lessen culture shock. :-} +# If MISC/flex.man is out of date relative to flex.1, there's +# not much we can do about it with the tools readily available. +flex.doc : flex.1 + @ if f$search("$(MISCDIR)flex.man").eqs."" then \ + $(COPY) flex.1 $(MISCDIR)flex.man + $(COPY) $(MISCDIR)flex.man flex.doc + +# +# This is completely VMS-specific... +# + +# Linker options file specifying run-time library(s) to link against; +# choice depends on which C compiler is used, and might be empty. +$(LIBOPT) : $(MAKEFILE) + @ open/Write optfile $(LIBOPT) + @ write optfile "$(LIBS)" + @ close optfile + +# Linker options file putting the version number where the ANALYZE/IMAGE +# command will be able to find and report it; assumes that the first line +# of version.h has the version number enclosed within the first and second +# double quotes on it [as in ``#define FLEX_VERSION "2.5.0"'']. +$(ID_OPT) : version.h + @ version = "# flex ""2.5""" !default, overridden by version.h + @- open/Read hfile version.h + @- read hfile version + @- close/noLog hfile + @ version = f$element(1,"""",version) + @ open/Write optfile $(ID_OPT) + @ write optfile "identification=""flex ''version'""" + @ close optfile + + +# +# This is the only stuff moderately useful from the remainder +# of Makefile.in... +# + +mostlyclean : + @- if f$search("scan.chk").nes."" then $(REMOVE) scan.chk;* + @- if f$search("*.obj;-1").nes."" then $(PURGE) *.obj + @- if f$search("*.exe;-1").nes."" then $(PURGE) *.exe + @- if f$search("*.opt;-1").nes."" then $(PURGE) *.opt + +clean : mostlyclean + @- if f$search("*.obj").nes."" then $(REMOVE) *.obj;* + @- if f$search("parse.h").nes."" then $(REMOVE) parse.h;* + @- if f$search("parse.c").nes."" then $(REMOVE) parse.c;* + @- if f$search("alloca.c").nes."" .and.- + f$search("$(MISCDIR)alloca.c").nes."" then $(REMOVE) alloca.c;* + @- if f$search("$(LIBOPT)").nes."" then $(REMOVE) $(LIBOPT);* + @- if f$search("$(ID_OPT)").nes."" then $(REMOVE) $(ID_OPT);* + +distclean : clean + @- if f$search("$(MARKER)").nes."" then $(REMOVE) $(MARKER);* + @- if f$search("$(FLEX)").nes."" then $(REMOVE) $(FLEX);* + @- if f$search("$(FLEXLIB)").nes."" then $(REMOVE) $(FLEXLIB);* + @- if f$search("flex.doc").nes."" then $(REMOVE) flex.doc;* + @- if f$search("scan.c").nes."" then $(REMOVE) scan.c;* + @- if f$search("vms-code.c").nes."" .and.- + f$search("$(VMSDIR)vms-code.c").nes."" then $(REMOVE) vms-code.c;* + @- if f$search("config.h").nes."" .and.- + f$search("$(VMSDIR)vms-conf.h").nes."" then $(REMOVE) config.h;* +# @- if f$search("descrip.mms").nes."" .and.- +# f$search("$(VMSDIR)descrip.mms").nes."" then $(REMOVE) descrip.mms;* + +realclean : distclean + @- if f$search("skel.c").nes."" then $(REMOVE) skel.c;* + diff --git a/commands/flex-2.5.4/MISC/VMS/mkskel.tpu b/commands/flex-2.5.4/MISC/VMS/mkskel.tpu new file mode 100644 index 000000000..e20a0eb30 --- /dev/null +++ b/commands/flex-2.5.4/MISC/VMS/mkskel.tpu @@ -0,0 +1,45 @@ +! mkskel.tpu +! usage: +! edit/TPU/noDisplay/noSection/Command=mkskel.tpu flex.skl /Output=skel.c +! +! Create a C source file from the flex skeleton data. Copy the file, +! changing backslash (\) to doubled backslash (\\) and quote (") +! to backslash quote (\"). For each line, insert space+space+quote +! at the beginning and quote+comma at the end. Bracket the updated +! text with several lines of prologue and epilogue. +! + skelfile := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name")); + SET(NO_WRITE, skelfile); + target := '"' | '\'; !do this once, outside loops + POSITION(BEGINNING_OF(skelfile)); !start here + rest_of_line := CREATE_RANGE(MARK(NONE), MARK(NONE)); !also outside loops + LOOP + EXITIF MARK(NONE) = END_OF(skelfile); !are we done yet? + COPY_TEXT(' "'); start_pos := MARK(NONE); + POSITION(LINE_END); end_pos := MARK(NONE); + MODIFY_RANGE(rest_of_line, start_pos, end_pos); + LOOP + next_match := SEARCH_QUIETLY(target, FORWARD, EXACT, rest_of_line); + EXITIF next_match = 0; + POSITION(BEGINNING_OF(next_match)); + COPY_TEXT('\'); MOVE_HORIZONTAL(1); !past the matched character + MODIFY_RANGE(rest_of_line, MARK(NONE), end_pos); + ENDLOOP; + POSITION(LINE_END); COPY_TEXT('",'); + MOVE_VERTICAL(1); POSITION(LINE_BEGIN); !go to next line + ENDLOOP; + + POSITION(BEGINNING_OF(skelfile)); !insert five line prologue + COPY_TEXT('/* File created from flex.skl via mkskel.tpu */'); SPLIT_LINE; + SPLIT_LINE; + COPY_TEXT('#include "flexdef.h"'); SPLIT_LINE; + SPLIT_LINE; + COPY_TEXT('const char *skel[] = {'); SPLIT_LINE; + + POSITION(END_OF(skelfile)); !append two line epilogue + COPY_TEXT(' 0'); SPLIT_LINE; + COPY_TEXT('};'); !! SPLIT_LINE; + + WRITE_FILE(skelfile, GET_INFO(COMMAND_LINE, "output_file")); + QUIT +!---- diff --git a/commands/flex-2.5.4/MISC/VMS/vms-code.c b/commands/flex-2.5.4/MISC/VMS/vms-code.c new file mode 100644 index 000000000..825a6b3bb --- /dev/null +++ b/commands/flex-2.5.4/MISC/VMS/vms-code.c @@ -0,0 +1,152 @@ +/* vms-code.c -- additional VMS-specific support code for flex + */ + +#include "flexdef.h" + +static const char *original_arg0; +static const char default_arg0[] = "flex.exe"; + +#define IN_FD 0 +#define OUT_FD 1 +#define ERR_FD 2 + +static char *fix_arg0 PROTO((const char *)); + +/* Command line arguments fixup -- simplify argv[0], and handle `>' + output redirection request; called first thing from main(). */ + +void argv_fixup( iargc, iargv ) +int *iargc; +char ***iargv; +{ + const char *mode[3], *rfm[3], *name[3]; + char *p; + int i, oargc, punct, which, append, alt_rfm; + + /* + * Get original argv[0] supplied by run-time library startup code, + * then replace it with a stripped down one. + */ + original_arg0 = (*iargv)[0]; + (*iargv)[0] = fix_arg0(original_arg0); + + /* + * Check command line arguments for redirection request(s). + * For simplicity, if multiple attempts are made, the last one wins. + */ + name[0] = name[1] = name[2] = 0; + oargc = 1; /* number of args caller will see; count includes argv[0] */ + for (i = 1; i < *iargc; i++) { + p = (*iargv)[i]; + switch (*p) { + case '<': + /* might be "file"; then again, perhaps "<file" */ + punct = (strchr(p, '>') != 0); + if (p[1] == '<') { + if (!punct || p[2] == '<') + flexerror("<<'sentinel' input not supported."); + punct = 0; + } + if (punct) /* the '<' seems to be directory punctuation */ + goto arg; /*GOTO*/ + mode[IN_FD] = "r"; + rfm[IN_FD] = 0; + name[IN_FD] = ++p; + if (!*p && (i + 1) < *iargc) + name[IN_FD] = (*iargv)[++i]; + break; + case '>': + append = (p[1] == '>'); + if (append) ++p; + alt_rfm = (p[1] == '$'); + if (alt_rfm) ++p; + which = (p[1] == '&' ? ERR_FD : OUT_FD); + if (which == ERR_FD) ++p; + mode[which] = append ? "a" : "w"; + rfm[which] = alt_rfm ? "rfm=var" : "rfm=stmlf"; + name[which] = ++p; + if (!*p && (i + 1) < *iargc) + name[which] = (*iargv)[++i]; + break; + case '|': + flexerror("pipe output not supported."); + /*NOTREACHED*/ + break; + default: + arg: /* ordinary option or argument */ + (*iargv)[oargc++] = p; + break; + } + } + /* perform any requested redirection; don't bother with SYS$xxx logicals */ + if (name[IN_FD]) + if (!freopen(name[IN_FD], mode[IN_FD], stdin)) + lerrsf("failed to redirect `stdin' from \"%s\"", name[IN_FD]); + if (name[OUT_FD]) + if (!freopen(name[OUT_FD], mode[OUT_FD], stdout, + rfm[OUT_FD], "rat=cr", "mbc=32", "shr=nil")) + lerrsf("failed to redirect `stdout' to \"%s\"", name[OUT_FD]); + if (name[ERR_FD]) /* likely won't see message if this fails; oh well... */ + if (!freopen(name[ERR_FD], mode[ERR_FD], stderr, + rfm[ERR_FD], "rat=cr")) + lerrsf("failed to redirect `stderr' to \"%s\"", name[ERR_FD]); + /* remove any excess arguments (used up from redirection) */ + while (*iargc > oargc) + (*iargv)[--*iargc] = 0; + /* all done */ + return; +} + +/* Pick out the basename of a full filename, and return a pointer + to a modifiable copy of it. */ + +static char *fix_arg0( arg0 ) +const char *arg0; +{ + char *p, *new_arg0; + + if (arg0) { + /* strip off the path */ + if ((p = strrchr(arg0, ':')) != 0) /* device punctuation */ + arg0 = p + 1; + if ((p = strrchr(arg0, ']')) != 0) /* directory punctuation */ + arg0 = p + 1; + if ((p = strrchr(arg0, '>')) != 0) /* alternate dir punct */ + arg0 = p + 1; + } + if (!arg0 || !*arg0) + arg0 = default_arg0; + /* should now have "something.exe;#"; make a modifiable copy */ + new_arg0 = copy_string(arg0); + + /* strip off ".exe" and/or ";#" (version number), + unless it ended up as the whole name */ + if ((p = strchr(new_arg0, '.')) != 0 && (p > new_arg0) + && (p[1] == 'e' || p[1] == 'E') + && (p[2] == 'x' || p[2] == 'X') + && (p[3] == 'e' || p[3] == 'E') + && (p[4] == ';' || p[4] == '.' || p[4] == '\0')) + *p = '\0'; + else if ((p = strchr(new_arg0, ';')) != 0 && (p > new_arg0)) + *p = '\0'; + + return new_arg0; +} + + +#include +#include + +#ifdef exit +#undef exit +extern void exit PROTO((int)); /* ended up prototyping vms_exit */ +#endif + +/* Convert zero to VMS success and non-zero to VMS failure. The latter + does not bother trying to distinguish between various failure reasons. */ + +void vms_exit( status ) +int status; +{ + exit( status == 0 ? SS$_NORMAL : (SS$_ABORT | STS$M_INHIB_MSG) ); +} diff --git a/commands/flex-2.5.4/MISC/VMS/vms-conf.h b/commands/flex-2.5.4/MISC/VMS/vms-conf.h new file mode 100644 index 000000000..65aa477ec --- /dev/null +++ b/commands/flex-2.5.4/MISC/VMS/vms-conf.h @@ -0,0 +1,32 @@ +/* config.h manually constructed for VMS */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#define HAVE_STRING_H + +/* Define if you have the header file. */ +#ifndef __GNUC__ +#undef HAVE_SYS_TYPES_H +#else +#define HAVE_SYS_TYPES_H +#endif + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Extra platform-specific command line handling. */ +#define NEED_ARGV_FIXUP + +/* Override default exit behavior. */ +#define exit vms_exit diff --git a/commands/flex-2.5.4/MISC/alloca.c b/commands/flex-2.5.4/MISC/alloca.c new file mode 100644 index 000000000..bd4932aa4 --- /dev/null +++ b/commands/flex-2.5.4/MISC/alloca.c @@ -0,0 +1,484 @@ +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#ifdef HAVE_CONFIG_H +#if defined (emacs) || defined (CONFIG_BROKETS) +#include +#else +#include "config.h" +#endif +#endif + +/* If compiling with GCC 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 + +/* If someone has defined alloca as a macro, + there must be some other way alloca is supposed to work. */ +#ifndef alloca + +#ifdef emacs +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +#else +#define ADDRESS_FUNCTION(arg) &(arg) +#endif + +#if __STDC__ +typedef void *pointer; +#else +typedef char *pointer; +#endif + +#define NULL 0 + +/* Different portions of Emacs need to call different versions of + malloc. The Emacs executable needs alloca to call xmalloc, because + ordinary malloc isn't protected from input signals. On the other + hand, the utilities in lib-src need alloca to call malloc; some of + them are very simple, and don't have an xmalloc routine. + + Non-Emacs programs expect this to call use xmalloc. + + Callers below should use malloc. */ + +#ifndef emacs +#define malloc xmalloc +#endif +extern pointer malloc (); + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* Direction unknown. */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +#else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +#define STACK_DIR stack_dir + +static void +find_stack_direction () +{ + static char *addr = NULL; /* Address of first `dummy', once known. */ + auto char dummy; /* To get stack address. */ + + if (addr == NULL) + { /* Initial entry. */ + addr = ADDRESS_FUNCTION (dummy); + + find_stack_direction (); /* Recurse once. */ + } + else + { + /* Second entry. */ + if (ADDRESS_FUNCTION (dummy) > addr) + stack_dir = 1; /* Stack grew upward. */ + else + stack_dir = -1; /* Stack grew downward. */ + } +} + +#endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +pointer +alloca (size) + unsigned size; +{ + auto char probe; /* Probes stack depth: */ + register char *depth = ADDRESS_FUNCTION (probe); + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = malloc (sizeof (header) + size); + /* Address of header. */ + + ((header *) new)->h.next = last_alloca_header; + ((header *) new)->h.deep = depth; + + last_alloca_header = (header *) new; + + /* User storage begins just after header. */ + + return (pointer) ((char *) new + sizeof (header)); + } +} + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) + +#ifdef DEBUG_I00AFUNC +#include +#endif + +#ifndef CRAY_STACK +#define CRAY_STACK +#ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +#else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +#endif /* CRAY2 */ +#endif /* not CRAY_STACK */ + +#ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +#else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +#endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +#endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +#endif /* not CRAY2 */ +#endif /* CRAY */ + +#endif /* no alloca */ +#endif /* not GCC version 2 */ diff --git a/commands/flex-2.5.4/MISC/debflex.awk b/commands/flex-2.5.4/MISC/debflex.awk new file mode 100644 index 000000000..b1eda49c4 --- /dev/null +++ b/commands/flex-2.5.4/MISC/debflex.awk @@ -0,0 +1,119 @@ +# Clarify the flex debug trace by substituting first line of each rule. +# Francois Pinard , July 1990. +# +# Rewritten to process correctly \n's in scanner input. +# BEGIN section modified to correct a collection of rules. +# Michal Jaegermann , December 1993 +# +# Sample usage: +# flex -d PROGRAM.l +# gcc -o PROGRAM PROGRAM.c -lfl +# PROGRAM 2>&1 | gawk -f debflex.awk PROGRAM.l +# +# (VP's note: this script presently does not work with either "old" or +# "new" awk; fixes so it does will be welcome) + +BEGIN { + # Insure proper usage. + + if (ARGC != 2) { + print "usage: gawk -f debflex.awk FLEX_SOURCE +#include + +main() +{ + register int c, cc = 0, wc = 0, lc = 0; + FILE *f = stdin; + + while ((c = getc(f)) != EOF) { + ++cc; + if (isgraph(c)) { + ++wc; + do { + c = getc(f); + if (c == EOF) + goto done; + ++cc; + } while (isgraph(c)); + } + if (c == '\n') + ++lc; + } +done: printf( "%8d%8d%8d\n", lc, wc, cc ); +} diff --git a/commands/flex-2.5.4/MISC/fastwc/wc1.l b/commands/flex-2.5.4/MISC/fastwc/wc1.l new file mode 100644 index 000000000..d6696bcde --- /dev/null +++ b/commands/flex-2.5.4/MISC/fastwc/wc1.l @@ -0,0 +1,18 @@ +/* First cut at a flex-based "wc" tool. */ + +ws [ \t] +nonws [^ \t\n] + +%% + int cc = 0, wc = 0, lc = 0; + +{nonws}+ cc += yyleng; ++wc; + +{ws}+ cc += yyleng; + +\n ++lc; ++cc; + +<> { + printf( "%8d %8d %8d\n", lc, wc, cc ); + yyterminate(); + } diff --git a/commands/flex-2.5.4/MISC/fastwc/wc2.l b/commands/flex-2.5.4/MISC/fastwc/wc2.l new file mode 100644 index 000000000..bd63cd490 --- /dev/null +++ b/commands/flex-2.5.4/MISC/fastwc/wc2.l @@ -0,0 +1,20 @@ +/* Somewhat faster "wc" tool: match more text with each rule */ + +ws [ \t] +nonws [^ \t\n] +word {ws}*{nonws}+ + +%% + int cc = 0, wc = 0, lc = 0; + +{word}{ws}* cc += yyleng; ++wc; +{word}{ws}*\n cc += yyleng; ++wc; ++lc; + +{ws}+ cc += yyleng; + +\n+ cc += yyleng; lc += yyleng; + +<> { + printf( "%8d %8d %8d\n", lc, wc, cc ); + yyterminate(); + } diff --git a/commands/flex-2.5.4/MISC/fastwc/wc3.l b/commands/flex-2.5.4/MISC/fastwc/wc3.l new file mode 100644 index 000000000..7c5f2e271 --- /dev/null +++ b/commands/flex-2.5.4/MISC/fastwc/wc3.l @@ -0,0 +1,24 @@ +/* Somewhat faster still: potentially match a lot of text with each rule */ + +ws [ \t] +nonws [^ \t\n] +word {ws}*{nonws}+ +words {word}{ws}+ + +%% + int cc = 0, wc = 0, lc = 0; + +{word}{ws}* cc += yyleng; ++wc; +{word}{ws}*\n cc += yyleng; ++wc; ++lc; +{words}{word}{ws}* cc += yyleng; wc += 2; +{words}{2}{word}{ws}* cc += yyleng; wc += 3; +{words}{3}{word}{ws}* cc += yyleng; wc += 4; + +{ws}+ cc += yyleng; + +\n+ cc += yyleng; lc += yyleng; + +<> { + printf( "%8d %8d %8d\n", lc, wc, cc ); + yyterminate(); + } diff --git a/commands/flex-2.5.4/MISC/fastwc/wc4.l b/commands/flex-2.5.4/MISC/fastwc/wc4.l new file mode 100644 index 000000000..cbe56f6e1 --- /dev/null +++ b/commands/flex-2.5.4/MISC/fastwc/wc4.l @@ -0,0 +1,27 @@ +/* Fastest version of wc: add rules to pick up newlines, too */ + +ws [ \t] +nonws [^ \t\n] +word {ws}*{nonws}+ +words {word}{ws}+ + +%% + int cc = 0, wc = 0, lc = 0; + +{word}{ws}* ++wc; cc += yyleng; +{word}{ws}*\n ++wc; cc += yyleng; ++lc; +{words}{word}{ws}* wc += 2; cc += yyleng; +{words}{word}{ws}*\n wc += 2; cc += yyleng; ++lc; +{words}{2}{word}{ws}* wc += 3; cc += yyleng; +{words}{2}{word}{ws}*\n wc += 3; cc += yyleng; ++lc; +{words}{3}{word}{ws}* wc += 4; cc += yyleng; +{words}{3}{word}{ws}*\n wc += 4; cc += yyleng; ++lc; + +{ws}+ cc += yyleng; + +\n+ cc += yyleng; lc += yyleng; + +<> { + printf( "%8d %8d %8d\n", lc, wc, cc ); + yyterminate(); + } diff --git a/commands/flex-2.5.4/MISC/fastwc/wc5.l b/commands/flex-2.5.4/MISC/fastwc/wc5.l new file mode 100644 index 000000000..8fe17b622 --- /dev/null +++ b/commands/flex-2.5.4/MISC/fastwc/wc5.l @@ -0,0 +1,24 @@ +/* Oops; slight change from wc3.l introduces backtracking */ + +ws [ \t] +nonws [^ \t\n] +word {ws}*{nonws}+ +words {word}{ws}+ + +%% + int cc = 0, wc = 0, lc = 0; + +{word}{ws}* cc += yyleng; ++wc; +{word}{ws}*\n cc += yyleng; ++wc; ++lc; +{words}{word} cc += yyleng; wc += 2; /* oops */ +{words}{2}{word}{ws}* cc += yyleng; wc += 3; +{words}{3}{word}{ws}* cc += yyleng; wc += 4; + +{ws}+ cc += yyleng; + +\n+ cc += yyleng; lc += yyleng; + +<> { + printf( "%8d %8d %8d\n", lc, wc, cc ); + yyterminate(); + } diff --git a/commands/flex-2.5.4/MISC/flex.man b/commands/flex-2.5.4/MISC/flex.man new file mode 100644 index 000000000..d41f5ba5b --- /dev/null +++ b/commands/flex-2.5.4/MISC/flex.man @@ -0,0 +1,3696 @@ + + + +FLEX(1) USER COMMANDS FLEX(1) + + + +NAME + flex - fast lexical analyzer generator + +SYNOPSIS + flex [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix + -Sskeleton] [--help --version] [filename ...] + +OVERVIEW + This manual describes flex, a tool for generating programs + that perform pattern-matching on text. The manual includes + both tutorial and reference sections: + + Description + a brief overview of the tool + + Some Simple Examples + + Format Of The Input File + + Patterns + the extended regular expressions used by flex + + How The Input Is Matched + the rules for determining what has been matched + + Actions + how to specify what to do when a pattern is matched + + The Generated Scanner + details regarding the scanner that flex produces; + how to control the input source + + Start Conditions + introducing context into your scanners, and + managing "mini-scanners" + + Multiple Input Buffers + how to manipulate multiple input sources; how to + scan from strings instead of files + + End-of-file Rules + special rules for matching the end of the input + + Miscellaneous Macros + a summary of macros available to the actions + + Values Available To The User + a summary of values available to the actions + + Interfacing With Yacc + connecting flex scanners together with yacc parsers + + + + +Version 2.5 Last change: April 1995 1 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + Options + flex command-line options, and the "%option" + directive + + Performance Considerations + how to make your scanner go as fast as possible + + Generating C++ Scanners + the (experimental) facility for generating C++ + scanner classes + + Incompatibilities With Lex And POSIX + how flex differs from AT&T lex and the POSIX lex + standard + + Diagnostics + those error messages produced by flex (or scanners + it generates) whose meanings might not be apparent + + Files + files used by flex + + Deficiencies / Bugs + known problems with flex + + See Also + other documentation, related tools + + Author + includes contact information + + +DESCRIPTION + flex is a tool for generating scanners: programs which + recognized lexical patterns in text. flex reads the given + input files, or its standard input if no file names are + given, for a description of a scanner to generate. The + description is in the form of pairs of regular expressions + and C code, called rules. flex generates as output a C + source file, lex.yy.c, which defines a routine yylex(). This + file is compiled and linked with the -lfl library to produce + an executable. When the executable is run, it analyzes its + input for occurrences of the regular expressions. Whenever + it finds one, it executes the corresponding C code. + +SOME SIMPLE EXAMPLES + First some simple examples to get the flavor of how one uses + flex. The following flex input specifies a scanner which + whenever it encounters the string "username" will replace it + with the user's login name: + + %% + + + +Version 2.5 Last change: April 1995 2 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + username printf( "%s", getlogin() ); + + By default, any text not matched by a flex scanner is copied + to the output, so the net effect of this scanner is to copy + its input file to its output with each occurrence of "user- + name" expanded. In this input, there is just one rule. + "username" is the pattern and the "printf" is the action. + The "%%" marks the beginning of the rules. + + Here's another simple example: + + int num_lines = 0, num_chars = 0; + + %% + \n ++num_lines; ++num_chars; + . ++num_chars; + + %% + main() + { + yylex(); + printf( "# of lines = %d, # of chars = %d\n", + num_lines, num_chars ); + } + + This scanner counts the number of characters and the number + of lines in its input (it produces no output other than the + final report on the counts). The first line declares two + globals, "num_lines" and "num_chars", which are accessible + both inside yylex() and in the main() routine declared after + the second "%%". There are two rules, one which matches a + newline ("\n") and increments both the line count and the + character count, and one which matches any character other + than a newline (indicated by the "." regular expression). + + A somewhat more complicated example: + + /* scanner for a toy Pascal-like language */ + + %{ + /* need this for the call to atof() below */ + #include + %} + + DIGIT [0-9] + ID [a-z][a-z0-9]* + + %% + + {DIGIT}+ { + printf( "An integer: %s (%d)\n", yytext, + atoi( yytext ) ); + + + +Version 2.5 Last change: April 1995 3 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + } + + {DIGIT}+"."{DIGIT}* { + printf( "A float: %s (%g)\n", yytext, + atof( yytext ) ); + } + + if|then|begin|end|procedure|function { + printf( "A keyword: %s\n", yytext ); + } + + {ID} printf( "An identifier: %s\n", yytext ); + + "+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext ); + + "{"[^}\n]*"}" /* eat up one-line comments */ + + [ \t\n]+ /* eat up whitespace */ + + . printf( "Unrecognized character: %s\n", yytext ); + + %% + + main( argc, argv ) + int argc; + char **argv; + { + ++argv, --argc; /* skip over program name */ + if ( argc > 0 ) + yyin = fopen( argv[0], "r" ); + else + yyin = stdin; + + yylex(); + } + + This is the beginnings of a simple scanner for a language + like Pascal. It identifies different types of tokens and + reports on what it has seen. + + The details of this example will be explained in the follow- + ing sections. + +FORMAT OF THE INPUT FILE + The flex input file consists of three sections, separated by + a line with just %% in it: + + definitions + %% + rules + %% + user code + + + +Version 2.5 Last change: April 1995 4 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + The definitions section contains declarations of simple name + definitions to simplify the scanner specification, and + declarations of start conditions, which are explained in a + later section. + + Name definitions have the form: + + name definition + + The "name" is a word beginning with a letter or an under- + score ('_') followed by zero or more letters, digits, '_', + or '-' (dash). The definition is taken to begin at the + first non-white-space character following the name and con- + tinuing to the end of the line. The definition can subse- + quently be referred to using "{name}", which will expand to + "(definition)". For example, + + DIGIT [0-9] + ID [a-z][a-z0-9]* + + defines "DIGIT" to be a regular expression which matches a + single digit, and "ID" to be a regular expression which + matches a letter followed by zero-or-more letters-or-digits. + A subsequent reference to + + {DIGIT}+"."{DIGIT}* + + is identical to + + ([0-9])+"."([0-9])* + + and matches one-or-more digits followed by a '.' followed by + zero-or-more digits. + + The rules section of the flex input contains a series of + rules of the form: + + pattern action + + where the pattern must be unindented and the action must + begin on the same line. + + See below for a further description of patterns and actions. + + Finally, the user code section is simply copied to lex.yy.c + verbatim. It is used for companion routines which call or + are called by the scanner. The presence of this section is + optional; if it is missing, the second %% in the input file + may be skipped, too. + + In the definitions and rules sections, any indented text or + text enclosed in %{ and %} is copied verbatim to the output + + + +Version 2.5 Last change: April 1995 5 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + (with the %{}'s removed). The %{}'s must appear unindented + on lines by themselves. + + In the rules section, any indented or %{} text appearing + before the first rule may be used to declare variables which + are local to the scanning routine and (after the declara- + tions) code which is to be executed whenever the scanning + routine is entered. Other indented or %{} text in the rule + section is still copied to the output, but its meaning is + not well-defined and it may well cause compile-time errors + (this feature is present for POSIX compliance; see below for + other such features). + + In the definitions section (but not in the rules section), + an unindented comment (i.e., a line beginning with "/*") is + also copied verbatim to the output up to the next "*/". + +PATTERNS + The patterns in the input are written using an extended set + of regular expressions. These are: + + x match the character 'x' + . any character (byte) except newline + [xyz] a "character class"; in this case, the pattern + matches either an 'x', a 'y', or a 'z' + [abj-oZ] a "character class" with a range in it; matches + an 'a', a 'b', any letter from 'j' through 'o', + or a 'Z' + [^A-Z] a "negated character class", i.e., any character + but those in the class. In this case, any + character EXCEPT an uppercase letter. + [^A-Z\n] any character EXCEPT an uppercase letter or + a newline + r* zero or more r's, where r is any regular expression + r+ one or more r's + r? zero or one r's (that is, "an optional r") + r{2,5} anywhere from two to five r's + r{2,} two or more r's + r{4} exactly 4 r's + {name} the expansion of the "name" definition + (see above) + "[xyz]\"foo" + the literal string: [xyz]"foo + \X if X is an 'a', 'b', 'f', 'n', 'r', 't', or 'v', + then the ANSI-C interpretation of \x. + Otherwise, a literal 'X' (used to escape + operators such as '*') + \0 a NUL character (ASCII code 0) + \123 the character with octal value 123 + \x2a the character with hexadecimal value 2a + (r) match an r; parentheses are used to override + precedence (see below) + + + +Version 2.5 Last change: April 1995 6 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + rs the regular expression r followed by the + regular expression s; called "concatenation" + + + r|s either an r or an s + + + r/s an r but only if it is followed by an s. The + text matched by s is included when determining + whether this rule is the "longest match", + but is then returned to the input before + the action is executed. So the action only + sees the text matched by r. This type + of pattern is called trailing context". + (There are some combinations of r/s that flex + cannot match correctly; see notes in the + Deficiencies / Bugs section below regarding + "dangerous trailing context".) + ^r an r, but only at the beginning of a line (i.e., + which just starting to scan, or right after a + newline has been scanned). + r$ an r, but only at the end of a line (i.e., just + before a newline). Equivalent to "r/\n". + + Note that flex's notion of "newline" is exactly + whatever the C compiler used to compile flex + interprets '\n' as; in particular, on some DOS + systems you must either filter out \r's in the + input yourself, or explicitly use r/\r\n for "r$". + + + r an r, but only in start condition s (see + below for discussion of start conditions) + r + same, but in any of start conditions s1, + s2, or s3 + <*>r an r in any start condition, even an exclusive one. + + + <> an end-of-file + <> + an end-of-file when in start condition s1 or s2 + + Note that inside of a character class, all regular expres- + sion operators lose their special meaning except escape + ('\') and the character class operators, '-', ']', and, at + the beginning of the class, '^'. + + The regular expressions listed above are grouped according + to precedence, from highest precedence at the top to lowest + at the bottom. Those grouped together have equal pre- + cedence. For example, + + + +Version 2.5 Last change: April 1995 7 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + foo|bar* + + is the same as + + (foo)|(ba(r*)) + + since the '*' operator has higher precedence than concatena- + tion, and concatenation higher than alternation ('|'). This + pattern therefore matches either the string "foo" or the + string "ba" followed by zero-or-more r's. To match "foo" or + zero-or-more "bar"'s, use: + + foo|(bar)* + + and to match zero-or-more "foo"'s-or-"bar"'s: + + (foo|bar)* + + + In addition to characters and ranges of characters, charac- + ter classes can also contain character class expressions. + These are expressions enclosed inside [: and :] delimiters + (which themselves must appear between the '[' and ']' of the + character class; other elements may occur inside the charac- + ter class, too). The valid expressions are: + + [:alnum:] [:alpha:] [:blank:] + [:cntrl:] [:digit:] [:graph:] + [:lower:] [:print:] [:punct:] + [:space:] [:upper:] [:xdigit:] + + These expressions all designate a set of characters + equivalent to the corresponding standard C isXXX function. + For example, [:alnum:] designates those characters for which + isalnum() returns true - i.e., any alphabetic or numeric. + Some systems don't provide isblank(), so flex defines + [:blank:] as a blank or a tab. + + For example, the following character classes are all + equivalent: + + [[:alnum:]] + [[:alpha:][:digit:] + [[:alpha:]0-9] + [a-zA-Z0-9] + + If your scanner is case-insensitive (the -i flag), then + [:upper:] and [:lower:] are equivalent to [:alpha:]. + + Some notes on patterns: + + - A negated character class such as the example "[^A-Z]" + + + +Version 2.5 Last change: April 1995 8 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + above will match a newline unless "\n" (or an + equivalent escape sequence) is one of the characters + explicitly present in the negated character class + (e.g., "[^A-Z\n]"). This is unlike how many other reg- + ular expression tools treat negated character classes, + but unfortunately the inconsistency is historically + entrenched. Matching newlines means that a pattern + like [^"]* can match the entire input unless there's + another quote in the input. + + - A rule can have at most one instance of trailing con- + text (the '/' operator or the '$' operator). The start + condition, '^', and "<>" patterns can only occur + at the beginning of a pattern, and, as well as with '/' + and '$', cannot be grouped inside parentheses. A '^' + which does not occur at the beginning of a rule or a + '$' which does not occur at the end of a rule loses its + special properties and is treated as a normal charac- + ter. + + The following are illegal: + + foo/bar$ + foobar + + Note that the first of these, can be written + "foo/bar\n". + + The following will result in '$' or '^' being treated + as a normal character: + + foo|(bar$) + foo|^bar + + If what's wanted is a "foo" or a bar-followed-by-a- + newline, the following could be used (the special '|' + action is explained below): + + foo | + bar$ /* action goes here */ + + A similar trick will work for matching a foo or a bar- + at-the-beginning-of-a-line. + +HOW THE INPUT IS MATCHED + When the generated scanner is run, it analyzes its input + looking for strings which match any of its patterns. If it + finds more than one match, it takes the one matching the + most text (for trailing context rules, this includes the + length of the trailing part, even though it will then be + returned to the input). If it finds two or more matches of + the same length, the rule listed first in the flex input + + + +Version 2.5 Last change: April 1995 9 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + file is chosen. + + Once the match is determined, the text corresponding to the + match (called the token) is made available in the global + character pointer yytext, and its length in the global + integer yyleng. The action corresponding to the matched pat- + tern is then executed (a more detailed description of + actions follows), and then the remaining input is scanned + for another match. + + If no match is found, then the default rule is executed: the + next character in the input is considered matched and copied + to the standard output. Thus, the simplest legal flex input + is: + + %% + + which generates a scanner that simply copies its input (one + character at a time) to its output. + + Note that yytext can be defined in two different ways: + either as a character pointer or as a character array. You + can control which definition flex uses by including one of + the special directives %pointer or %array in the first + (definitions) section of your flex input. The default is + %pointer, unless you use the -l lex compatibility option, in + which case yytext will be an array. The advantage of using + %pointer is substantially faster scanning and no buffer + overflow when matching very large tokens (unless you run out + of dynamic memory). The disadvantage is that you are res- + tricted in how your actions can modify yytext (see the next + section), and calls to the unput() function destroys the + present contents of yytext, which can be a considerable + porting headache when moving between different lex versions. + + The advantage of %array is that you can then modify yytext + to your heart's content, and calls to unput() do not destroy + yytext (see below). Furthermore, existing lex programs + sometimes access yytext externally using declarations of the + form: + extern char yytext[]; + This definition is erroneous when used with %pointer, but + correct for %array. + + %array defines yytext to be an array of YYLMAX characters, + which defaults to a fairly large value. You can change the + size by simply #define'ing YYLMAX to a different value in + the first section of your flex input. As mentioned above, + with %pointer yytext grows dynamically to accommodate large + tokens. While this means your %pointer scanner can accommo- + date very large tokens (such as matching entire blocks of + comments), bear in mind that each time the scanner must + + + +Version 2.5 Last change: April 1995 10 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + resize yytext it also must rescan the entire token from the + beginning, so matching such tokens can prove slow. yytext + presently does not dynamically grow if a call to unput() + results in too much text being pushed back; instead, a run- + time error results. + + Also note that you cannot use %array with C++ scanner + classes (the c++ option; see below). + +ACTIONS + Each pattern in a rule has a corresponding action, which can + be any arbitrary C statement. The pattern ends at the first + non-escaped whitespace character; the remainder of the line + is its action. If the action is empty, then when the pat- + tern is matched the input token is simply discarded. For + example, here is the specification for a program which + deletes all occurrences of "zap me" from its input: + + %% + "zap me" + + (It will copy all other characters in the input to the out- + put since they will be matched by the default rule.) + + Here is a program which compresses multiple blanks and tabs + down to a single blank, and throws away whitespace found at + the end of a line: + + %% + [ \t]+ putchar( ' ' ); + [ \t]+$ /* ignore this token */ + + + If the action contains a '{', then the action spans till the + balancing '}' is found, and the action may cross multiple + lines. flex knows about C strings and comments and won't be + fooled by braces found within them, but also allows actions + to begin with %{ and will consider the action to be all the + text up to the next %} (regardless of ordinary braces inside + the action). + + An action consisting solely of a vertical bar ('|') means + "same as the action for the next rule." See below for an + illustration. + + Actions can include arbitrary C code, including return + statements to return a value to whatever routine called + yylex(). Each time yylex() is called it continues processing + tokens from where it last left off until it either reaches + the end of the file or executes a return. + + + + + +Version 2.5 Last change: April 1995 11 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + Actions are free to modify yytext except for lengthening it + (adding characters to its end--these will overwrite later + characters in the input stream). This however does not + apply when using %array (see above); in that case, yytext + may be freely modified in any way. + + Actions are free to modify yyleng except they should not do + so if the action also includes use of yymore() (see below). + + There are a number of special directives which can be + included within an action: + + - ECHO copies yytext to the scanner's output. + + - BEGIN followed by the name of a start condition places + the scanner in the corresponding start condition (see + below). + + - REJECT directs the scanner to proceed on to the "second + best" rule which matched the input (or a prefix of the + input). The rule is chosen as described above in "How + the Input is Matched", and yytext and yyleng set up + appropriately. It may either be one which matched as + much text as the originally chosen rule but came later + in the flex input file, or one which matched less text. + For example, the following will both count the words in + the input and call the routine special() whenever + "frob" is seen: + + int word_count = 0; + %% + + frob special(); REJECT; + [^ \t\n]+ ++word_count; + + Without the REJECT, any "frob"'s in the input would not + be counted as words, since the scanner normally exe- + cutes only one action per token. Multiple REJECT's are + allowed, each one finding the next best choice to the + currently active rule. For example, when the following + scanner scans the token "abcd", it will write "abcdab- + caba" to the output: + + %% + a | + ab | + abc | + abcd ECHO; REJECT; + .|\n /* eat up any unmatched character */ + + (The first three rules share the fourth's action since + they use the special '|' action.) REJECT is a + + + +Version 2.5 Last change: April 1995 12 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + particularly expensive feature in terms of scanner per- + formance; if it is used in any of the scanner's actions + it will slow down all of the scanner's matching. + Furthermore, REJECT cannot be used with the -Cf or -CF + options (see below). + + Note also that unlike the other special actions, REJECT + is a branch; code immediately following it in the + action will not be executed. + + - yymore() tells the scanner that the next time it + matches a rule, the corresponding token should be + appended onto the current value of yytext rather than + replacing it. For example, given the input "mega- + kludge" the following will write "mega-mega-kludge" to + the output: + + %% + mega- ECHO; yymore(); + kludge ECHO; + + First "mega-" is matched and echoed to the output. + Then "kludge" is matched, but the previous "mega-" is + still hanging around at the beginning of yytext so the + ECHO for the "kludge" rule will actually write "mega- + kludge". + + Two notes regarding use of yymore(). First, yymore() depends + on the value of yyleng correctly reflecting the size of the + current token, so you must not modify yyleng if you are + using yymore(). Second, the presence of yymore() in the + scanner's action entails a minor performance penalty in the + scanner's matching speed. + + - yyless(n) returns all but the first n characters of the + current token back to the input stream, where they will + be rescanned when the scanner looks for the next match. + yytext and yyleng are adjusted appropriately (e.g., + yyleng will now be equal to n ). For example, on the + input "foobar" the following will write out "foobar- + bar": + + %% + foobar ECHO; yyless(3); + [a-z]+ ECHO; + + An argument of 0 to yyless will cause the entire + current input string to be scanned again. Unless + you've changed how the scanner will subsequently pro- + cess its input (using BEGIN, for example), this will + result in an endless loop. + + + + +Version 2.5 Last change: April 1995 13 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + Note that yyless is a macro and can only be used in the flex + input file, not from other source files. + + - unput(c) puts the character c back onto the input + stream. It will be the next character scanned. The + following action will take the current token and cause + it to be rescanned enclosed in parentheses. + + { + int i; + /* Copy yytext because unput() trashes yytext */ + char *yycopy = strdup( yytext ); + unput( ')' ); + for ( i = yyleng - 1; i >= 0; --i ) + unput( yycopy[i] ); + unput( '(' ); + free( yycopy ); + } + + Note that since each unput() puts the given character + back at the beginning of the input stream, pushing back + strings must be done back-to-front. + + An important potential problem when using unput() is that if + you are using %pointer (the default), a call to unput() des- + troys the contents of yytext, starting with its rightmost + character and devouring one character to the left with each + call. If you need the value of yytext preserved after a + call to unput() (as in the above example), you must either + first copy it elsewhere, or build your scanner using %array + instead (see How The Input Is Matched). + + Finally, note that you cannot put back EOF to attempt to + mark the input stream with an end-of-file. + + - input() reads the next character from the input stream. + For example, the following is one way to eat up C com- + ments: + + %% + "/*" { + register int c; + + for ( ; ; ) + { + while ( (c = input()) != '*' && + c != EOF ) + ; /* eat up text of comment */ + + if ( c == '*' ) + { + while ( (c = input()) == '*' ) + + + +Version 2.5 Last change: April 1995 14 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + ; + if ( c == '/' ) + break; /* found the end */ + } + + if ( c == EOF ) + { + error( "EOF in comment" ); + break; + } + } + } + + (Note that if the scanner is compiled using C++, then + input() is instead referred to as yyinput(), in order + to avoid a name clash with the C++ stream by the name + of input.) + + - YY_FLUSH_BUFFER flushes the scanner's internal buffer + so that the next time the scanner attempts to match a + token, it will first refill the buffer using YY_INPUT + (see The Generated Scanner, below). This action is a + special case of the more general yy_flush_buffer() + function, described below in the section Multiple Input + Buffers. + + - yyterminate() can be used in lieu of a return statement + in an action. It terminates the scanner and returns a + 0 to the scanner's caller, indicating "all done". By + default, yyterminate() is also called when an end-of- + file is encountered. It is a macro and may be rede- + fined. + +THE GENERATED SCANNER + The output of flex is the file lex.yy.c, which contains the + scanning routine yylex(), a number of tables used by it for + matching tokens, and a number of auxiliary routines and mac- + ros. By default, yylex() is declared as follows: + + int yylex() + { + ... various definitions and the actions in here ... + } + + (If your environment supports function prototypes, then it + will be "int yylex( void )".) This definition may be + changed by defining the "YY_DECL" macro. For example, you + could use: + + #define YY_DECL float lexscan( a, b ) float a, b; + + to give the scanning routine the name lexscan, returning a + + + +Version 2.5 Last change: April 1995 15 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + float, and taking two floats as arguments. Note that if you + give arguments to the scanning routine using a K&R- + style/non-prototyped function declaration, you must ter- + minate the definition with a semi-colon (;). + + Whenever yylex() is called, it scans tokens from the global + input file yyin (which defaults to stdin). It continues + until it either reaches an end-of-file (at which point it + returns the value 0) or one of its actions executes a return + statement. + + If the scanner reaches an end-of-file, subsequent calls are + undefined unless either yyin is pointed at a new input file + (in which case scanning continues from that file), or yyres- + tart() is called. yyrestart() takes one argument, a FILE * + pointer (which can be nil, if you've set up YY_INPUT to scan + from a source other than yyin), and initializes yyin for + scanning from that file. Essentially there is no difference + between just assigning yyin to a new input file or using + yyrestart() to do so; the latter is available for compati- + bility with previous versions of flex, and because it can be + used to switch input files in the middle of scanning. It + can also be used to throw away the current input buffer, by + calling it with an argument of yyin; but better is to use + YY_FLUSH_BUFFER (see above). Note that yyrestart() does not + reset the start condition to INITIAL (see Start Conditions, + below). + + If yylex() stops scanning due to executing a return state- + ment in one of the actions, the scanner may then be called + again and it will resume scanning where it left off. + + By default (and for purposes of efficiency), the scanner + uses block-reads rather than simple getc() calls to read + characters from yyin. The nature of how it gets its input + can be controlled by defining the YY_INPUT macro. + YY_INPUT's calling sequence is + "YY_INPUT(buf,result,max_size)". Its action is to place up + to max_size characters in the character array buf and return + in the integer variable result either the number of charac- + ters read or the constant YY_NULL (0 on Unix systems) to + indicate EOF. The default YY_INPUT reads from the global + file-pointer "yyin". + + A sample definition of YY_INPUT (in the definitions section + of the input file): + + %{ + #define YY_INPUT(buf,result,max_size) \ + { \ + int c = getchar(); \ + result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ + + + +Version 2.5 Last change: April 1995 16 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + } + %} + + This definition will change the input processing to occur + one character at a time. + + When the scanner receives an end-of-file indication from + YY_INPUT, it then checks the yywrap() function. If yywrap() + returns false (zero), then it is assumed that the function + has gone ahead and set up yyin to point to another input + file, and scanning continues. If it returns true (non- + zero), then the scanner terminates, returning 0 to its + caller. Note that in either case, the start condition + remains unchanged; it does not revert to INITIAL. + + If you do not supply your own version of yywrap(), then you + must either use %option noyywrap (in which case the scanner + behaves as though yywrap() returned 1), or you must link + with -lfl to obtain the default version of the routine, + which always returns 1. + + Three routines are available for scanning from in-memory + buffers rather than files: yy_scan_string(), + yy_scan_bytes(), and yy_scan_buffer(). See the discussion of + them below in the section Multiple Input Buffers. + + The scanner writes its ECHO output to the yyout global + (default, stdout), which may be redefined by the user simply + by assigning it to some other FILE pointer. + +START CONDITIONS + flex provides a mechanism for conditionally activating + rules. Any rule whose pattern is prefixed with "" will + only be active when the scanner is in the start condition + named "sc". For example, + + [^"]* { /* eat up the string body ... */ + ... + } + + will be active only when the scanner is in the "STRING" + start condition, and + + \. { /* handle an escape ... */ + ... + } + + will be active only when the current start condition is + either "INITIAL", "STRING", or "QUOTE". + + Start conditions are declared in the definitions (first) + section of the input using unindented lines beginning with + + + +Version 2.5 Last change: April 1995 17 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + either %s or %x followed by a list of names. The former + declares inclusive start conditions, the latter exclusive + start conditions. A start condition is activated using the + BEGIN action. Until the next BEGIN action is executed, + rules with the given start condition will be active and + rules with other start conditions will be inactive. If the + start condition is inclusive, then rules with no start con- + ditions at all will also be active. If it is exclusive, + then only rules qualified with the start condition will be + active. A set of rules contingent on the same exclusive + start condition describe a scanner which is independent of + any of the other rules in the flex input. Because of this, + exclusive start conditions make it easy to specify "mini- + scanners" which scan portions of the input that are syntac- + tically different from the rest (e.g., comments). + + If the distinction between inclusive and exclusive start + conditions is still a little vague, here's a simple example + illustrating the connection between the two. The set of + rules: + + %s example + %% + + foo do_something(); + + bar something_else(); + + is equivalent to + + %x example + %% + + foo do_something(); + + bar something_else(); + + Without the qualifier, the bar pattern in + the second example wouldn't be active (i.e., couldn't match) + when in start condition example. If we just used + to qualify bar, though, then it would only be active in + example and not in INITIAL, while in the first example it's + active in both, because in the first example the example + startion condition is an inclusive (%s) start condition. + + Also note that the special start-condition specifier <*> + matches every start condition. Thus, the above example + could also have been written; + + %x example + %% + + + + +Version 2.5 Last change: April 1995 18 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + foo do_something(); + + <*>bar something_else(); + + + The default rule (to ECHO any unmatched character) remains + active in start conditions. It is equivalent to: + + <*>.|\n ECHO; + + + BEGIN(0) returns to the original state where only the rules + with no start conditions are active. This state can also be + referred to as the start-condition "INITIAL", so + BEGIN(INITIAL) is equivalent to BEGIN(0). (The parentheses + around the start condition name are not required but are + considered good style.) + + BEGIN actions can also be given as indented code at the + beginning of the rules section. For example, the following + will cause the scanner to enter the "SPECIAL" start condi- + tion whenever yylex() is called and the global variable + enter_special is true: + + int enter_special; + + %x SPECIAL + %% + if ( enter_special ) + BEGIN(SPECIAL); + + blahblahblah + ...more rules follow... + + + To illustrate the uses of start conditions, here is a + scanner which provides two different interpretations of a + string like "123.456". By default it will treat it as three + tokens, the integer "123", a dot ('.'), and the integer + "456". But if the string is preceded earlier in the line by + the string "expect-floats" it will treat it as a single + token, the floating-point number 123.456: + + %{ + #include + %} + %s expect + + %% + expect-floats BEGIN(expect); + + [0-9]+"."[0-9]+ { + + + +Version 2.5 Last change: April 1995 19 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + printf( "found a float, = %f\n", + atof( yytext ) ); + } + \n { + /* that's the end of the line, so + * we need another "expect-number" + * before we'll recognize any more + * numbers + */ + BEGIN(INITIAL); + } + + [0-9]+ { + printf( "found an integer, = %d\n", + atoi( yytext ) ); + } + + "." printf( "found a dot\n" ); + + Here is a scanner which recognizes (and discards) C comments + while maintaining a count of the current input line. + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* /* eat anything that's not a '*' */ + "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ + \n ++line_num; + "*"+"/" BEGIN(INITIAL); + + This scanner goes to a bit of trouble to match as much text + as possible with each rule. In general, when attempting to + write a high-speed scanner try to match as much possible in + each rule, as it's a big win. + + Note that start-conditions names are really integer values + and can be stored as such. Thus, the above could be + extended in the following fashion: + + %x comment foo + %% + int line_num = 1; + int comment_caller; + + "/*" { + comment_caller = INITIAL; + BEGIN(comment); + } + + + + +Version 2.5 Last change: April 1995 20 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + ... + + "/*" { + comment_caller = foo; + BEGIN(comment); + } + + [^*\n]* /* eat anything that's not a '*' */ + "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ + \n ++line_num; + "*"+"/" BEGIN(comment_caller); + + Furthermore, you can access the current start condition + using the integer-valued YY_START macro. For example, the + above assignments to comment_caller could instead be written + + comment_caller = YY_START; + + Flex provides YYSTATE as an alias for YY_START (since that + is what's used by AT&T lex). + + Note that start conditions do not have their own name-space; + %s's and %x's declare names in the same fashion as + #define's. + + Finally, here's an example of how to match C-style quoted + strings using exclusive start conditions, including expanded + escape sequences (but not including checking for a string + that's too long): + + %x str + + %% + char string_buf[MAX_STR_CONST]; + char *string_buf_ptr; + + + \" string_buf_ptr = string_buf; BEGIN(str); + + \" { /* saw closing quote - all done */ + BEGIN(INITIAL); + *string_buf_ptr = '\0'; + /* return string constant token type and + * value to parser + */ + } + + \n { + /* error - unterminated string constant */ + /* generate error message */ + } + + + + +Version 2.5 Last change: April 1995 21 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + \\[0-7]{1,3} { + /* octal escape sequence */ + int result; + + (void) sscanf( yytext + 1, "%o", &result ); + + if ( result > 0xff ) + /* error, constant is out-of-bounds */ + + *string_buf_ptr++ = result; + } + + \\[0-9]+ { + /* generate error - bad escape sequence; something + * like '\48' or '\0777777' + */ + } + + \\n *string_buf_ptr++ = '\n'; + \\t *string_buf_ptr++ = '\t'; + \\r *string_buf_ptr++ = '\r'; + \\b *string_buf_ptr++ = '\b'; + \\f *string_buf_ptr++ = '\f'; + + \\(.|\n) *string_buf_ptr++ = yytext[1]; + + [^\\\n\"]+ { + char *yptr = yytext; + + while ( *yptr ) + *string_buf_ptr++ = *yptr++; + } + + + Often, such as in some of the examples above, you wind up + writing a whole bunch of rules all preceded by the same + start condition(s). Flex makes this a little easier and + cleaner by introducing a notion of start condition scope. A + start condition scope is begun with: + + { + + where SCs is a list of one or more start conditions. Inside + the start condition scope, every rule automatically has the + prefix applied to it, until a '}' which matches the + initial '{'. So, for example, + + { + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + + + +Version 2.5 Last change: April 1995 22 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + } + + is equivalent to: + + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + + Start condition scopes may be nested. + + Three routines are available for manipulating stacks of + start conditions: + + void yy_push_state(int new_state) + pushes the current start condition onto the top of the + start condition stack and switches to new_state as + though you had used BEGIN new_state (recall that start + condition names are also integers). + + void yy_pop_state() + pops the top of the stack and switches to it via BEGIN. + + int yy_top_state() + returns the top of the stack without altering the + stack's contents. + + The start condition stack grows dynamically and so has no + built-in size limitation. If memory is exhausted, program + execution aborts. + + To use start condition stacks, your scanner must include a + %option stack directive (see Options below). + +MULTIPLE INPUT BUFFERS + Some scanners (such as those which support "include" files) + require reading from several input streams. As flex + scanners do a large amount of buffering, one cannot control + where the next input will be read from by simply writing a + YY_INPUT which is sensitive to the scanning context. + YY_INPUT is only called when the scanner reaches the end of + its buffer, which may be a long time after scanning a state- + ment such as an "include" which requires switching the input + source. + + To negotiate these sorts of problems, flex provides a + mechanism for creating and switching between multiple input + buffers. An input buffer is created by using: + + YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) + + which takes a FILE pointer and a size and creates a buffer + + + +Version 2.5 Last change: April 1995 23 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + associated with the given file and large enough to hold size + characters (when in doubt, use YY_BUF_SIZE for the size). + It returns a YY_BUFFER_STATE handle, which may then be + passed to other routines (see below). The YY_BUFFER_STATE + type is a pointer to an opaque struct yy_buffer_state struc- + ture, so you may safely initialize YY_BUFFER_STATE variables + to ((YY_BUFFER_STATE) 0) if you wish, and also refer to the + opaque structure in order to correctly declare input buffers + in source files other than that of your scanner. Note that + the FILE pointer in the call to yy_create_buffer is only + used as the value of yyin seen by YY_INPUT; if you redefine + YY_INPUT so it no longer uses yyin, then you can safely pass + a nil FILE pointer to yy_create_buffer. You select a partic- + ular buffer to scan from using: + + void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) + + switches the scanner's input buffer so subsequent tokens + will come from new_buffer. Note that yy_switch_to_buffer() + may be used by yywrap() to set things up for continued scan- + ning, instead of opening a new file and pointing yyin at it. + Note also that switching input sources via either + yy_switch_to_buffer() or yywrap() does not change the start + condition. + + void yy_delete_buffer( YY_BUFFER_STATE buffer ) + + is used to reclaim the storage associated with a buffer. ( + buffer can be nil, in which case the routine does nothing.) + You can also clear the current contents of a buffer using: + + void yy_flush_buffer( YY_BUFFER_STATE buffer ) + + This function discards the buffer's contents, so the next + time the scanner attempts to match a token from the buffer, + it will first fill the buffer anew using YY_INPUT. + + yy_new_buffer() is an alias for yy_create_buffer(), provided + for compatibility with the C++ use of new and delete for + creating and destroying dynamic objects. + + Finally, the YY_CURRENT_BUFFER macro returns a + YY_BUFFER_STATE handle to the current buffer. + + Here is an example of using these features for writing a + scanner which expands include files (the <> feature is + discussed below): + + /* the "incl" state is used for picking up the name + * of an include file + */ + %x incl + + + +Version 2.5 Last change: April 1995 24 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + %{ + #define MAX_INCLUDE_DEPTH 10 + YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; + int include_stack_ptr = 0; + %} + + %% + include BEGIN(incl); + + [a-z]+ ECHO; + [^a-z\n]*\n? ECHO; + + [ \t]* /* eat the whitespace */ + [^ \t\n]+ { /* got the include file name */ + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) + { + fprintf( stderr, "Includes nested too deeply" ); + exit( 1 ); + } + + include_stack[include_stack_ptr++] = + YY_CURRENT_BUFFER; + + yyin = fopen( yytext, "r" ); + + if ( ! yyin ) + error( ... ); + + yy_switch_to_buffer( + yy_create_buffer( yyin, YY_BUF_SIZE ) ); + + BEGIN(INITIAL); + } + + <> { + if ( --include_stack_ptr < 0 ) + { + yyterminate(); + } + + else + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( + include_stack[include_stack_ptr] ); + } + } + + Three routines are available for setting up input buffers + for scanning in-memory strings instead of files. All of + them create a new input buffer for scanning the string, and + return a corresponding YY_BUFFER_STATE handle (which you + + + +Version 2.5 Last change: April 1995 25 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + should delete with yy_delete_buffer() when done with it). + They also switch to the new buffer using + yy_switch_to_buffer(), so the next call to yylex() will + start scanning the string. + + yy_scan_string(const char *str) + scans a NUL-terminated string. + + yy_scan_bytes(const char *bytes, int len) + scans len bytes (including possibly NUL's) starting at + location bytes. + + Note that both of these functions create and scan a copy of + the string or bytes. (This may be desirable, since yylex() + modifies the contents of the buffer it is scanning.) You + can avoid the copy by using: + + yy_scan_buffer(char *base, yy_size_t size) + which scans in place the buffer starting at base, con- + sisting of size bytes, the last two bytes of which must + be YY_END_OF_BUFFER_CHAR (ASCII NUL). These last two + bytes are not scanned; thus, scanning consists of + base[0] through base[size-2], inclusive. + + If you fail to set up base in this manner (i.e., forget + the final two YY_END_OF_BUFFER_CHAR bytes), then + yy_scan_buffer() returns a nil pointer instead of + creating a new input buffer. + + The type yy_size_t is an integral type to which you can + cast an integer expression reflecting the size of the + buffer. + +END-OF-FILE RULES + The special rule "<>" indicates actions which are to be + taken when an end-of-file is encountered and yywrap() + returns non-zero (i.e., indicates no further files to pro- + cess). The action must finish by doing one of four things: + + - assigning yyin to a new input file (in previous ver- + sions of flex, after doing the assignment you had to + call the special action YY_NEW_FILE; this is no longer + necessary); + + - executing a return statement; + + - executing the special yyterminate() action; + + - or, switching to a new buffer using + yy_switch_to_buffer() as shown in the example above. + + + + + +Version 2.5 Last change: April 1995 26 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + <> rules may not be used with other patterns; they may + only be qualified with a list of start conditions. If an + unqualified <> rule is given, it applies to all start + conditions which do not already have <> actions. To + specify an <> rule for only the initial start condi- + tion, use + + <> + + + These rules are useful for catching things like unclosed + comments. An example: + + %x quote + %% + + ...other rules for dealing with quotes... + + <> { + error( "unterminated quote" ); + yyterminate(); + } + <> { + if ( *++filelist ) + yyin = fopen( *filelist, "r" ); + else + yyterminate(); + } + + +MISCELLANEOUS MACROS + The macro YY_USER_ACTION can be defined to provide an action + which is always executed prior to the matched rule's action. + For example, it could be #define'd to call a routine to con- + vert yytext to lower-case. When YY_USER_ACTION is invoked, + the variable yy_act gives the number of the matched rule + (rules are numbered starting with 1). Suppose you want to + profile how often each of your rules is matched. The fol- + lowing would do the trick: + + #define YY_USER_ACTION ++ctr[yy_act] + + where ctr is an array to hold the counts for the different + rules. Note that the macro YY_NUM_RULES gives the total + number of rules (including the default rule, even if you use + -s), so a correct declaration for ctr is: + + int ctr[YY_NUM_RULES]; + + + The macro YY_USER_INIT may be defined to provide an action + which is always executed before the first scan (and before + + + +Version 2.5 Last change: April 1995 27 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + the scanner's internal initializations are done). For exam- + ple, it could be used to call a routine to read in a data + table or open a logging file. + + The macro yy_set_interactive(is_interactive) can be used to + control whether the current buffer is considered interac- + tive. An interactive buffer is processed more slowly, but + must be used when the scanner's input source is indeed + interactive to avoid problems due to waiting to fill buffers + (see the discussion of the -I flag below). A non-zero value + in the macro invocation marks the buffer as interactive, a + zero value as non-interactive. Note that use of this macro + overrides %option always-interactive or %option never- + interactive (see Options below). yy_set_interactive() must + be invoked prior to beginning to scan the buffer that is (or + is not) to be considered interactive. + + The macro yy_set_bol(at_bol) can be used to control whether + the current buffer's scanning context for the next token + match is done as though at the beginning of a line. A non- + zero macro argument makes rules anchored with + + The macro YY_AT_BOL() returns true if the next token scanned + from the current buffer will have '^' rules active, false + otherwise. + + In the generated scanner, the actions are all gathered in + one large switch statement and separated using YY_BREAK, + which may be redefined. By default, it is simply a "break", + to separate each rule's action from the following rule's. + Redefining YY_BREAK allows, for example, C++ users to + #define YY_BREAK to do nothing (while being very careful + that every rule ends with a "break" or a "return"!) to avoid + suffering from unreachable statement warnings where because + a rule's action ends with "return", the YY_BREAK is inacces- + sible. + +VALUES AVAILABLE TO THE USER + This section summarizes the various values available to the + user in the rule actions. + + - char *yytext holds the text of the current token. It + may be modified but not lengthened (you cannot append + characters to the end). + + If the special directive %array appears in the first + section of the scanner description, then yytext is + instead declared char yytext[YYLMAX], where YYLMAX is a + macro definition that you can redefine in the first + section if you don't like the default value (generally + 8KB). Using %array results in somewhat slower + scanners, but the value of yytext becomes immune to + + + +Version 2.5 Last change: April 1995 28 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + calls to input() and unput(), which potentially destroy + its value when yytext is a character pointer. The + opposite of %array is %pointer, which is the default. + + You cannot use %array when generating C++ scanner + classes (the -+ flag). + + - int yyleng holds the length of the current token. + + - FILE *yyin is the file which by default flex reads + from. It may be redefined but doing so only makes + sense before scanning begins or after an EOF has been + encountered. Changing it in the midst of scanning will + have unexpected results since flex buffers its input; + use yyrestart() instead. Once scanning terminates + because an end-of-file has been seen, you can assign + yyin at the new input file and then call the scanner + again to continue scanning. + + - void yyrestart( FILE *new_file ) may be called to point + yyin at the new input file. The switch-over to the new + file is immediate (any previously buffered-up input is + lost). Note that calling yyrestart() with yyin as an + argument thus throws away the current input buffer and + continues scanning the same input file. + + - FILE *yyout is the file to which ECHO actions are done. + It can be reassigned by the user. + + - YY_CURRENT_BUFFER returns a YY_BUFFER_STATE handle to + the current buffer. + + - YY_START returns an integer value corresponding to the + current start condition. You can subsequently use this + value with BEGIN to return to that start condition. + +INTERFACING WITH YACC + One of the main uses of flex is as a companion to the yacc + parser-generator. yacc parsers expect to call a routine + named yylex() to find the next input token. The routine is + supposed to return the type of the next token as well as + putting any associated value in the global yylval. To use + flex with yacc, one specifies the -d option to yacc to + instruct it to generate the file y.tab.h containing defini- + tions of all the %tokens appearing in the yacc input. This + file is then included in the flex scanner. For example, if + one of the tokens is "TOK_NUMBER", part of the scanner might + look like: + + %{ + #include "y.tab.h" + %} + + + +Version 2.5 Last change: April 1995 29 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + %% + + [0-9]+ yylval = atoi( yytext ); return TOK_NUMBER; + + +OPTIONS + flex has the following options: + + -b Generate backing-up information to lex.backup. This is + a list of scanner states which require backing up and + the input characters on which they do so. By adding + rules one can remove backing-up states. If all + backing-up states are eliminated and -Cf or -CF is + used, the generated scanner will run faster (see the -p + flag). Only users who wish to squeeze every last cycle + out of their scanners need worry about this option. + (See the section on Performance Considerations below.) + + -c is a do-nothing, deprecated option included for POSIX + compliance. + + -d makes the generated scanner run in debug mode. When- + ever a pattern is recognized and the global + yy_flex_debug is non-zero (which is the default), the + scanner will write to stderr a line of the form: + + --accepting rule at line 53 ("the matched text") + + The line number refers to the location of the rule in + the file defining the scanner (i.e., the file that was + fed to flex). Messages are also generated when the + scanner backs up, accepts the default rule, reaches the + end of its input buffer (or encounters a NUL; at this + point, the two look the same as far as the scanner's + concerned), or reaches an end-of-file. + + -f specifies fast scanner. No table compression is done + and stdio is bypassed. The result is large but fast. + This option is equivalent to -Cfr (see below). + + -h generates a "help" summary of flex's options to stdout + and then exits. -? and --help are synonyms for -h. + + -i instructs flex to generate a case-insensitive scanner. + The case of letters given in the flex input patterns + will be ignored, and tokens in the input will be + matched regardless of case. The matched text given in + yytext will have the preserved case (i.e., it will not + be folded). + + -l turns on maximum compatibility with the original AT&T + lex implementation. Note that this does not mean full + + + +Version 2.5 Last change: April 1995 30 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + compatibility. Use of this option costs a considerable + amount of performance, and it cannot be used with the + -+, -f, -F, -Cf, or -CF options. For details on the + compatibilities it provides, see the section "Incompa- + tibilities With Lex And POSIX" below. This option also + results in the name YY_FLEX_LEX_COMPAT being #define'd + in the generated scanner. + + -n is another do-nothing, deprecated option included only + for POSIX compliance. + + -p generates a performance report to stderr. The report + consists of comments regarding features of the flex + input file which will cause a serious loss of perfor- + mance in the resulting scanner. If you give the flag + twice, you will also get comments regarding features + that lead to minor performance losses. + + Note that the use of REJECT, %option yylineno, and + variable trailing context (see the Deficiencies / Bugs + section below) entails a substantial performance + penalty; use of yymore(), the ^ operator, and the -I + flag entail minor performance penalties. + + -s causes the default rule (that unmatched scanner input + is echoed to stdout) to be suppressed. If the scanner + encounters input that does not match any of its rules, + it aborts with an error. This option is useful for + finding holes in a scanner's rule set. + + -t instructs flex to write the scanner it generates to + standard output instead of lex.yy.c. + + -v specifies that flex should write to stderr a summary of + statistics regarding the scanner it generates. Most of + the statistics are meaningless to the casual flex user, + but the first line identifies the version of flex (same + as reported by -V), and the next line the flags used + when generating the scanner, including those that are + on by default. + + -w suppresses warning messages. + + -B instructs flex to generate a batch scanner, the oppo- + site of interactive scanners generated by -I (see + below). In general, you use -B when you are certain + that your scanner will never be used interactively, and + you want to squeeze a little more performance out of + it. If your goal is instead to squeeze out a lot more + performance, you should be using the -Cf or -CF + options (discussed below), which turn on -B automati- + cally anyway. + + + +Version 2.5 Last change: April 1995 31 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + -F specifies that the fast scanner table representation + should be used (and stdio bypassed). This representa- + tion is about as fast as the full table representation + (-f), and for some sets of patterns will be consider- + ably smaller (and for others, larger). In general, if + the pattern set contains both "keywords" and a catch- + all, "identifier" rule, such as in the set: + + "case" return TOK_CASE; + "switch" return TOK_SWITCH; + ... + "default" return TOK_DEFAULT; + [a-z]+ return TOK_ID; + + then you're better off using the full table representa- + tion. If only the "identifier" rule is present and you + then use a hash table or some such to detect the key- + words, you're better off using -F. + + This option is equivalent to -CFr (see below). It can- + not be used with -+. + + -I instructs flex to generate an interactive scanner. An + interactive scanner is one that only looks ahead to + decide what token has been matched if it absolutely + must. It turns out that always looking one extra char- + acter ahead, even if the scanner has already seen + enough text to disambiguate the current token, is a bit + faster than only looking ahead when necessary. But + scanners that always look ahead give dreadful interac- + tive performance; for example, when a user types a new- + line, it is not recognized as a newline token until + they enter another token, which often means typing in + another whole line. + + Flex scanners default to interactive unless you use the + -Cf or -CF table-compression options (see below). + That's because if you're looking for high-performance + you should be using one of these options, so if you + didn't, flex assumes you'd rather trade off a bit of + run-time performance for intuitive interactive + behavior. Note also that you cannot use -I in conjunc- + tion with -Cf or -CF. Thus, this option is not really + needed; it is on by default for all those cases in + which it is allowed. + + You can force a scanner to not be interactive by using + -B (see above). + + -L instructs flex not to generate #line directives. + Without this option, flex peppers the generated scanner + with #line directives so error messages in the actions + + + +Version 2.5 Last change: April 1995 32 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + will be correctly located with respect to either the + original flex input file (if the errors are due to code + in the input file), or lex.yy.c (if the errors are + flex's fault -- you should report these sorts of errors + to the email address given below). + + -T makes flex run in trace mode. It will generate a lot + of messages to stderr concerning the form of the input + and the resultant non-deterministic and deterministic + finite automata. This option is mostly for use in + maintaining flex. + + -V prints the version number to stdout and exits. --ver- + sion is a synonym for -V. + + -7 instructs flex to generate a 7-bit scanner, i.e., one + which can only recognized 7-bit characters in its + input. The advantage of using -7 is that the scanner's + tables can be up to half the size of those generated + using the -8 option (see below). The disadvantage is + that such scanners often hang or crash if their input + contains an 8-bit character. + + Note, however, that unless you generate your scanner + using the -Cf or -CF table compression options, use of + -7 will save only a small amount of table space, and + make your scanner considerably less portable. Flex's + default behavior is to generate an 8-bit scanner unless + you use the -Cf or -CF, in which case flex defaults to + generating 7-bit scanners unless your site was always + configured to generate 8-bit scanners (as will often be + the case with non-USA sites). You can tell whether + flex generated a 7-bit or an 8-bit scanner by inspect- + ing the flag summary in the -v output as described + above. + + Note that if you use -Cfe or -CFe (those table compres- + sion options, but also using equivalence classes as + discussed see below), flex still defaults to generating + an 8-bit scanner, since usually with these compression + options full 8-bit tables are not much more expensive + than 7-bit tables. + + -8 instructs flex to generate an 8-bit scanner, i.e., one + which can recognize 8-bit characters. This flag is + only needed for scanners generated using -Cf or -CF, as + otherwise flex defaults to generating an 8-bit scanner + anyway. + + See the discussion of -7 above for flex's default + behavior and the tradeoffs between 7-bit and 8-bit + scanners. + + + +Version 2.5 Last change: April 1995 33 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + -+ specifies that you want flex to generate a C++ scanner + class. See the section on Generating C++ Scanners + below for details. + + -C[aefFmr] + controls the degree of table compression and, more gen- + erally, trade-offs between small scanners and fast + scanners. + + -Ca ("align") instructs flex to trade off larger tables + in the generated scanner for faster performance because + the elements of the tables are better aligned for + memory access and computation. On some RISC architec- + tures, fetching and manipulating longwords is more + efficient than with smaller-sized units such as short- + words. This option can double the size of the tables + used by your scanner. + + -Ce directs flex to construct equivalence classes, + i.e., sets of characters which have identical lexical + properties (for example, if the only appearance of + digits in the flex input is in the character class + "[0-9]" then the digits '0', '1', ..., '9' will all be + put in the same equivalence class). Equivalence + classes usually give dramatic reductions in the final + table/object file sizes (typically a factor of 2-5) and + are pretty cheap performance-wise (one array look-up + per character scanned). + + -Cf specifies that the full scanner tables should be + generated - flex should not compress the tables by tak- + ing advantages of similar transition functions for dif- + ferent states. + + -CF specifies that the alternate fast scanner represen- + tation (described above under the -F flag) should be + used. This option cannot be used with -+. + + -Cm directs flex to construct meta-equivalence classes, + which are sets of equivalence classes (or characters, + if equivalence classes are not being used) that are + commonly used together. Meta-equivalence classes are + often a big win when using compressed tables, but they + have a moderate performance impact (one or two "if" + tests and one array look-up per character scanned). + + -Cr causes the generated scanner to bypass use of the + standard I/O library (stdio) for input. Instead of + calling fread() or getc(), the scanner will use the + read() system call, resulting in a performance gain + which varies from system to system, but in general is + probably negligible unless you are also using -Cf or + + + +Version 2.5 Last change: April 1995 34 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + -CF. Using -Cr can cause strange behavior if, for exam- + ple, you read from yyin using stdio prior to calling + the scanner (because the scanner will miss whatever + text your previous reads left in the stdio input + buffer). + + -Cr has no effect if you define YY_INPUT (see The Gen- + erated Scanner above). + + A lone -C specifies that the scanner tables should be + compressed but neither equivalence classes nor meta- + equivalence classes should be used. + + The options -Cf or -CF and -Cm do not make sense + together - there is no opportunity for meta-equivalence + classes if the table is not being compressed. Other- + wise the options may be freely mixed, and are cumula- + tive. + + The default setting is -Cem, which specifies that flex + should generate equivalence classes and meta- + equivalence classes. This setting provides the highest + degree of table compression. You can trade off + faster-executing scanners at the cost of larger tables + with the following generally being true: + + slowest & smallest + -Cem + -Cm + -Ce + -C + -C{f,F}e + -C{f,F} + -C{f,F}a + fastest & largest + + Note that scanners with the smallest tables are usually + generated and compiled the quickest, so during develop- + ment you will usually want to use the default, maximal + compression. + + -Cfe is often a good compromise between speed and size + for production scanners. + + -ooutput + directs flex to write the scanner to the file output + instead of lex.yy.c. If you combine -o with the -t + option, then the scanner is written to stdout but its + #line directives (see the -L option above) refer to the + file output. + + -Pprefix + + + +Version 2.5 Last change: April 1995 35 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + changes the default yy prefix used by flex for all + globally-visible variable and function names to instead + be prefix. For example, -Pfoo changes the name of + yytext to footext. It also changes the name of the + default output file from lex.yy.c to lex.foo.c. Here + are all of the names affected: + + yy_create_buffer + yy_delete_buffer + yy_flex_debug + yy_init_buffer + yy_flush_buffer + yy_load_buffer_state + yy_switch_to_buffer + yyin + yyleng + yylex + yylineno + yyout + yyrestart + yytext + yywrap + + (If you are using a C++ scanner, then only yywrap and + yyFlexLexer are affected.) Within your scanner itself, + you can still refer to the global variables and func- + tions using either version of their name; but exter- + nally, they have the modified name. + + This option lets you easily link together multiple flex + programs into the same executable. Note, though, that + using this option also renames yywrap(), so you now + must either provide your own (appropriately-named) ver- + sion of the routine for your scanner, or use %option + noyywrap, as linking with -lfl no longer provides one + for you by default. + + -Sskeleton_file + overrides the default skeleton file from which flex + constructs its scanners. You'll never need this option + unless you are doing flex maintenance or development. + + flex also provides a mechanism for controlling options + within the scanner specification itself, rather than from + the flex command-line. This is done by including %option + directives in the first section of the scanner specifica- + tion. You can specify multiple options with a single + %option directive, and multiple directives in the first sec- + tion of your flex input file. + + Most options are given simply as names, optionally preceded + by the word "no" (with no intervening whitespace) to negate + + + +Version 2.5 Last change: April 1995 36 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + their meaning. A number are equivalent to flex flags or + their negation: + + 7bit -7 option + 8bit -8 option + align -Ca option + backup -b option + batch -B option + c++ -+ option + + caseful or + case-sensitive opposite of -i (default) + + case-insensitive or + caseless -i option + + debug -d option + default opposite of -s option + ecs -Ce option + fast -F option + full -f option + interactive -I option + lex-compat -l option + meta-ecs -Cm option + perf-report -p option + read -Cr option + stdout -t option + verbose -v option + warn opposite of -w option + (use "%option nowarn" for -w) + + array equivalent to "%array" + pointer equivalent to "%pointer" (default) + + Some %option's provide features otherwise not available: + + always-interactive + instructs flex to generate a scanner which always con- + siders its input "interactive". Normally, on each new + input file the scanner calls isatty() in an attempt to + determine whether the scanner's input source is + interactive and thus should be read a character at a + time. When this option is used, however, then no such + call is made. + + main directs flex to provide a default main() program for + the scanner, which simply calls yylex(). This option + implies noyywrap (see below). + + never-interactive + instructs flex to generate a scanner which never con- + siders its input "interactive" (again, no call made to + + + +Version 2.5 Last change: April 1995 37 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + isatty()). This is the opposite of always-interactive. + + stack + enables the use of start condition stacks (see Start + Conditions above). + + stdinit + if set (i.e., %option stdinit) initializes yyin and + yyout to stdin and stdout, instead of the default of + nil. Some existing lex programs depend on this + behavior, even though it is not compliant with ANSI C, + which does not require stdin and stdout to be compile- + time constant. + + yylineno + directs flex to generate a scanner that maintains the + number of the current line read from its input in the + global variable yylineno. This option is implied by + %option lex-compat. + + yywrap + if unset (i.e., %option noyywrap), makes the scanner + not call yywrap() upon an end-of-file, but simply + assume that there are no more files to scan (until the + user points yyin at a new file and calls yylex() + again). + + flex scans your rule actions to determine whether you use + the REJECT or yymore() features. The reject and yymore + options are available to override its decision as to whether + you use the options, either by setting them (e.g., %option + reject) to indicate the feature is indeed used, or unsetting + them to indicate it actually is not used (e.g., %option + noyymore). + + Three options take string-delimited values, offset with '=': + + %option outfile="ABC" + + is equivalent to -oABC, and + + %option prefix="XYZ" + + is equivalent to -PXYZ. Finally, + + %option yyclass="foo" + + only applies when generating a C++ scanner ( -+ option). It + informs flex that you have derived foo as a subclass of + yyFlexLexer, so flex will place your actions in the member + function foo::yylex() instead of yyFlexLexer::yylex(). It + also generates a yyFlexLexer::yylex() member function that + + + +Version 2.5 Last change: April 1995 38 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + emits a run-time error (by invoking + yyFlexLexer::LexerError()) if called. See Generating C++ + Scanners, below, for additional information. + + A number of options are available for lint purists who want + to suppress the appearance of unneeded routines in the gen- + erated scanner. Each of the following, if unset (e.g., + %option nounput ), results in the corresponding routine not + appearing in the generated scanner: + + input, unput + yy_push_state, yy_pop_state, yy_top_state + yy_scan_buffer, yy_scan_bytes, yy_scan_string + + (though yy_push_state() and friends won't appear anyway + unless you use %option stack). + +PERFORMANCE CONSIDERATIONS + The main design goal of flex is that it generate high- + performance scanners. It has been optimized for dealing + well with large sets of rules. Aside from the effects on + scanner speed of the table compression -C options outlined + above, there are a number of options/actions which degrade + performance. These are, from most expensive to least: + + REJECT + %option yylineno + arbitrary trailing context + + pattern sets that require backing up + %array + %option interactive + %option always-interactive + + '^' beginning-of-line operator + yymore() + + with the first three all being quite expensive and the last + two being quite cheap. Note also that unput() is imple- + mented as a routine call that potentially does quite a bit + of work, while yyless() is a quite-cheap macro; so if just + putting back some excess text you scanned, use yyless(). + + REJECT should be avoided at all costs when performance is + important. It is a particularly expensive option. + + Getting rid of backing up is messy and often may be an enor- + mous amount of work for a complicated scanner. In princi- + pal, one begins by using the -b flag to generate a + lex.backup file. For example, on the input + + %% + + + +Version 2.5 Last change: April 1995 39 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + the file looks like: + + State #6 is non-accepting - + associated rule line numbers: + 2 3 + out-transitions: [ o ] + jam-transitions: EOF [ \001-n p-\177 ] + + State #8 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ a ] + jam-transitions: EOF [ \001-` b-\177 ] + + State #9 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ r ] + jam-transitions: EOF [ \001-q s-\177 ] + + Compressed tables always back up. + + The first few lines tell us that there's a scanner state in + which it can make a transition on an 'o' but not on any + other character, and that in that state the currently + scanned text does not match any rule. The state occurs when + trying to match the rules found at lines 2 and 3 in the + input file. If the scanner is in that state and then reads + something other than an 'o', it will have to back up to find + a rule which is matched. With a bit of headscratching one + can see that this must be the state it's in when it has seen + "fo". When this has happened, if anything other than + another 'o' is seen, the scanner will have to back up to + simply match the 'f' (by the default rule). + + The comment regarding State #8 indicates there's a problem + when "foob" has been scanned. Indeed, on any character + other than an 'a', the scanner will have to back up to + accept "foo". Similarly, the comment for State #9 concerns + when "fooba" has been scanned and an 'r' does not follow. + + The final comment reminds us that there's no point going to + all the trouble of removing backing up from the rules unless + we're using -Cf or -CF, since there's no performance gain + doing so with compressed scanners. + + The way to remove the backing up is to add "error" rules: + + %% + + + +Version 2.5 Last change: April 1995 40 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + fooba | + foob | + fo { + /* false alarm, not really a keyword */ + return TOK_ID; + } + + + Eliminating backing up among a list of keywords can also be + done using a "catch-all" rule: + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + [a-z]+ return TOK_ID; + + This is usually the best solution when appropriate. + + Backing up messages tend to cascade. With a complicated set + of rules it's not uncommon to get hundreds of messages. If + one can decipher them, though, it often only takes a dozen + or so rules to eliminate the backing up (though it's easy to + make a mistake and have an error rule accidentally match a + valid token. A possible future flex feature will be to + automatically add rules to eliminate backing up). + + It's important to keep in mind that you gain the benefits of + eliminating backing up only if you eliminate every instance + of backing up. Leaving just one means you gain nothing. + + Variable trailing context (where both the leading and trail- + ing parts do not have a fixed length) entails almost the + same performance loss as REJECT (i.e., substantial). So + when possible a rule like: + + %% + mouse|rat/(cat|dog) run(); + + is better written: + + %% + mouse/cat|dog run(); + rat/cat|dog run(); + + or as + + %% + mouse|rat/cat run(); + + + +Version 2.5 Last change: April 1995 41 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + mouse|rat/dog run(); + + Note that here the special '|' action does not provide any + savings, and can even make things worse (see Deficiencies / + Bugs below). + + Another area where the user can increase a scanner's perfor- + mance (and one that's easier to implement) arises from the + fact that the longer the tokens matched, the faster the + scanner will run. This is because with long tokens the pro- + cessing of most input characters takes place in the (short) + inner scanning loop, and does not often have to go through + the additional work of setting up the scanning environment + (e.g., yytext) for the action. Recall the scanner for C + comments: + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* + "*"+[^*/\n]* + \n ++line_num; + "*"+"/" BEGIN(INITIAL); + + This could be sped up by writing it as: + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* + [^*\n]*\n ++line_num; + "*"+[^*/\n]* + "*"+[^*/\n]*\n ++line_num; + "*"+"/" BEGIN(INITIAL); + + Now instead of each newline requiring the processing of + another action, recognizing the newlines is "distributed" + over the other rules to keep the matched text as long as + possible. Note that adding rules does not slow down the + scanner! The speed of the scanner is independent of the + number of rules or (modulo the considerations given at the + beginning of this section) how complicated the rules are + with regard to operators such as '*' and '|'. + + A final example in speeding up a scanner: suppose you want + to scan through a file containing identifiers and keywords, + + + +Version 2.5 Last change: April 1995 42 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + one per line and with no other extraneous characters, and + recognize all the keywords. A natural first approach is: + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + .|\n /* it's not a keyword */ + + To eliminate the back-tracking, introduce a catch-all rule: + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + [a-z]+ | + .|\n /* it's not a keyword */ + + Now, if it's guaranteed that there's exactly one word per + line, then we can reduce the total number of matches by a + half by merging in the recognition of newlines with that of + the other tokens: + + %% + asm\n | + auto\n | + break\n | + ... etc ... + volatile\n | + while\n /* it's a keyword */ + + [a-z]+\n | + .|\n /* it's not a keyword */ + + One has to be careful here, as we have now reintroduced + backing up into the scanner. In particular, while we know + that there will never be any characters in the input stream + other than letters or newlines, flex can't figure this out, + and it will plan for possibly needing to back up when it has + scanned a token like "auto" and then the next character is + something other than a newline or a letter. Previously it + would then just match the "auto" rule and be done, but now + it has no "auto" rule, only a "auto\n" rule. To eliminate + the possibility of backing up, we could either duplicate all + + + +Version 2.5 Last change: April 1995 43 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + rules but without final newlines, or, since we never expect + to encounter such an input and therefore don't how it's + classified, we can introduce one more catch-all rule, this + one which doesn't include a newline: + + %% + asm\n | + auto\n | + break\n | + ... etc ... + volatile\n | + while\n /* it's a keyword */ + + [a-z]+\n | + [a-z]+ | + .|\n /* it's not a keyword */ + + Compiled with -Cf, this is about as fast as one can get a + flex scanner to go for this particular problem. + + A final note: flex is slow when matching NUL's, particularly + when a token contains multiple NUL's. It's best to write + rules which match short amounts of text if it's anticipated + that the text will often include NUL's. + + Another final note regarding performance: as mentioned above + in the section How the Input is Matched, dynamically resiz- + ing yytext to accommodate huge tokens is a slow process + because it presently requires that the (huge) token be res- + canned from the beginning. Thus if performance is vital, + you should attempt to match "large" quantities of text but + not "huge" quantities, where the cutoff between the two is + at about 8K characters/token. + +GENERATING C++ SCANNERS + flex provides two different ways to generate scanners for + use with C++. The first way is to simply compile a scanner + generated by flex using a C++ compiler instead of a C com- + piler. You should not encounter any compilations errors + (please report any you find to the email address given in + the Author section below). You can then use C++ code in + your rule actions instead of C code. Note that the default + input source for your scanner remains yyin, and default + echoing is still done to yyout. Both of these remain FILE * + variables and not C++ streams. + + You can also use flex to generate a C++ scanner class, using + the -+ option (or, equivalently, %option c++), which is + automatically specified if the name of the flex executable + ends in a '+', such as flex++. When using this option, flex + defaults to generating the scanner to the file lex.yy.cc + instead of lex.yy.c. The generated scanner includes the + + + +Version 2.5 Last change: April 1995 44 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + header file FlexLexer.h, which defines the interface to two + C++ classes. + + The first class, FlexLexer, provides an abstract base class + defining the general scanner class interface. It provides + the following member functions: + + const char* YYText() + returns the text of the most recently matched token, + the equivalent of yytext. + + int YYLeng() + returns the length of the most recently matched token, + the equivalent of yyleng. + + int lineno() const + returns the current input line number (see %option + yylineno), or 1 if %option yylineno was not used. + + void set_debug( int flag ) + sets the debugging flag for the scanner, equivalent to + assigning to yy_flex_debug (see the Options section + above). Note that you must build the scanner using + %option debug to include debugging information in it. + + int debug() const + returns the current setting of the debugging flag. + + Also provided are member functions equivalent to + yy_switch_to_buffer(), yy_create_buffer() (though the first + argument is an istream* object pointer and not a FILE*), + yy_flush_buffer(), yy_delete_buffer(), and yyrestart() + (again, the first argument is a istream* object pointer). + + The second class defined in FlexLexer.h is yyFlexLexer, + which is derived from FlexLexer. It defines the following + additional member functions: + + yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 ) + constructs a yyFlexLexer object using the given streams + for input and output. If not specified, the streams + default to cin and cout, respectively. + + virtual int yylex() + performs the same role is yylex() does for ordinary + flex scanners: it scans the input stream, consuming + tokens, until a rule's action returns a value. If you + derive a subclass S from yyFlexLexer and want to access + the member functions and variables of S inside yylex(), + then you need to use %option yyclass="S" to inform flex + that you will be using that subclass instead of yyFlex- + Lexer. In this case, rather than generating + + + +Version 2.5 Last change: April 1995 45 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + yyFlexLexer::yylex(), flex generates S::yylex() (and + also generates a dummy yyFlexLexer::yylex() that calls + yyFlexLexer::LexerError() if called). + + virtual void switch_streams(istream* new_in = 0, + ostream* new_out = 0) reassigns yyin to new_in (if + non-nil) and yyout to new_out (ditto), deleting the + previous input buffer if yyin is reassigned. + + int yylex( istream* new_in, ostream* new_out = 0 ) + first switches the input streams via switch_streams( + new_in, new_out ) and then returns the value of + yylex(). + + In addition, yyFlexLexer defines the following protected + virtual functions which you can redefine in derived classes + to tailor the scanner: + + virtual int LexerInput( char* buf, int max_size ) + reads up to max_size characters into buf and returns + the number of characters read. To indicate end-of- + input, return 0 characters. Note that "interactive" + scanners (see the -B and -I flags) define the macro + YY_INTERACTIVE. If you redefine LexerInput() and need + to take different actions depending on whether or not + the scanner might be scanning an interactive input + source, you can test for the presence of this name via + #ifdef. + + virtual void LexerOutput( const char* buf, int size ) + writes out size characters from the buffer buf, which, + while NUL-terminated, may also contain "internal" NUL's + if the scanner's rules can match text with NUL's in + them. + + virtual void LexerError( const char* msg ) + reports a fatal error message. The default version of + this function writes the message to the stream cerr and + exits. + + Note that a yyFlexLexer object contains its entire scanning + state. Thus you can use such objects to create reentrant + scanners. You can instantiate multiple instances of the + same yyFlexLexer class, and you can also combine multiple + C++ scanner classes together in the same program using the + -P option discussed above. + + Finally, note that the %array feature is not available to + C++ scanner classes; you must use %pointer (the default). + + Here is an example of a simple C++ scanner: + + + + +Version 2.5 Last change: April 1995 46 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + // An example of using the flex C++ scanner class. + + %{ + int mylineno = 0; + %} + + string \"[^\n"]+\" + + ws [ \t]+ + + alpha [A-Za-z] + dig [0-9] + name ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])* + num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)? + num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)? + number {num1}|{num2} + + %% + + {ws} /* skip blanks and tabs */ + + "/*" { + int c; + + while((c = yyinput()) != 0) + { + if(c == '\n') + ++mylineno; + + else if(c == '*') + { + if((c = yyinput()) == '/') + break; + else + unput(c); + } + } + } + + {number} cout << "number " << YYText() << '\n'; + + \n mylineno++; + + {name} cout << "name " << YYText() << '\n'; + + {string} cout << "string " << YYText() << '\n'; + + %% + + int main( int /* argc */, char** /* argv */ ) + { + FlexLexer* lexer = new yyFlexLexer; + + + +Version 2.5 Last change: April 1995 47 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + while(lexer->yylex() != 0) + ; + return 0; + } + If you want to create multiple (different) lexer classes, + you use the -P flag (or the prefix= option) to rename each + yyFlexLexer to some other xxFlexLexer. You then can include + in your other sources once per lexer class, + first renaming yyFlexLexer as follows: + + #undef yyFlexLexer + #define yyFlexLexer xxFlexLexer + #include + + #undef yyFlexLexer + #define yyFlexLexer zzFlexLexer + #include + + if, for example, you used %option prefix="xx" for one of + your scanners and %option prefix="zz" for the other. + + IMPORTANT: the present form of the scanning class is experi- + mental and may change considerably between major releases. + +INCOMPATIBILITIES WITH LEX AND POSIX + flex is a rewrite of the AT&T Unix lex tool (the two imple- + mentations do not share any code, though), with some exten- + sions and incompatibilities, both of which are of concern to + those who wish to write scanners acceptable to either imple- + mentation. Flex is fully compliant with the POSIX lex + specification, except that when using %pointer (the + default), a call to unput() destroys the contents of yytext, + which is counter to the POSIX specification. + + In this section we discuss all of the known areas of incom- + patibility between flex, AT&T lex, and the POSIX specifica- + tion. + + flex's -l option turns on maximum compatibility with the + original AT&T lex implementation, at the cost of a major + loss in the generated scanner's performance. We note below + which incompatibilities can be overcome using the -l option. + + flex is fully compatible with lex with the following excep- + tions: + + - The undocumented lex scanner internal variable yylineno + is not supported unless -l or %option yylineno is used. + + yylineno should be maintained on a per-buffer basis, + rather than a per-scanner (single global variable) + basis. + + + +Version 2.5 Last change: April 1995 48 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + yylineno is not part of the POSIX specification. + + - The input() routine is not redefinable, though it may + be called to read characters following whatever has + been matched by a rule. If input() encounters an end- + of-file the normal yywrap() processing is done. A + ``real'' end-of-file is returned by input() as EOF. + + Input is instead controlled by defining the YY_INPUT + macro. + + The flex restriction that input() cannot be redefined + is in accordance with the POSIX specification, which + simply does not specify any way of controlling the + scanner's input other than by making an initial assign- + ment to yyin. + + - The unput() routine is not redefinable. This restric- + tion is in accordance with POSIX. + + - flex scanners are not as reentrant as lex scanners. In + particular, if you have an interactive scanner and an + interrupt handler which long-jumps out of the scanner, + and the scanner is subsequently called again, you may + get the following message: + + fatal flex scanner internal error--end of buffer missed + + To reenter the scanner, first use + + yyrestart( yyin ); + + Note that this call will throw away any buffered input; + usually this isn't a problem with an interactive + scanner. + + Also note that flex C++ scanner classes are reentrant, + so if using C++ is an option for you, you should use + them instead. See "Generating C++ Scanners" above for + details. + + - output() is not supported. Output from the ECHO macro + is done to the file-pointer yyout (default stdout). + + output() is not part of the POSIX specification. + + - lex does not support exclusive start conditions (%x), + though they are in the POSIX specification. + + - When definitions are expanded, flex encloses them in + parentheses. With lex, the following: + + + + +Version 2.5 Last change: April 1995 49 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + NAME [A-Z][A-Z0-9]* + %% + foo{NAME}? printf( "Found it\n" ); + %% + + will not match the string "foo" because when the macro + is expanded the rule is equivalent to "foo[A-Z][A-Z0- + 9]*?" and the precedence is such that the '?' is asso- + ciated with "[A-Z0-9]*". With flex, the rule will be + expanded to "foo([A-Z][A-Z0-9]*)?" and so the string + "foo" will match. + + Note that if the definition begins with ^ or ends with + $ then it is not expanded with parentheses, to allow + these operators to appear in definitions without losing + their special meanings. But the , /, and <> + operators cannot be used in a flex definition. + + Using -l results in the lex behavior of no parentheses + around the definition. + + The POSIX specification is that the definition be + enclosed in parentheses. + + - Some implementations of lex allow a rule's action to + begin on a separate line, if the rule's pattern has + trailing whitespace: + + %% + foo|bar + { foobar_action(); } + + flex does not support this feature. + + - The lex %r (generate a Ratfor scanner) option is not + supported. It is not part of the POSIX specification. + + - After a call to unput(), yytext is undefined until the + next token is matched, unless the scanner was built + using %array. This is not the case with lex or the + POSIX specification. The -l option does away with this + incompatibility. + + - The precedence of the {} (numeric range) operator is + different. lex interprets "abc{1,3}" as "match one, + two, or three occurrences of 'abc'", whereas flex + interprets it as "match 'ab' followed by one, two, or + three occurrences of 'c'". The latter is in agreement + with the POSIX specification. + + - The precedence of the ^ operator is different. lex + interprets "^foo|bar" as "match either 'foo' at the + + + +Version 2.5 Last change: April 1995 50 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + beginning of a line, or 'bar' anywhere", whereas flex + interprets it as "match either 'foo' or 'bar' if they + come at the beginning of a line". The latter is in + agreement with the POSIX specification. + + - The special table-size declarations such as %a sup- + ported by lex are not required by flex scanners; flex + ignores them. + + - The name FLEX_SCANNER is #define'd so scanners may be + written for use with either flex or lex. Scanners also + include YY_FLEX_MAJOR_VERSION and YY_FLEX_MINOR_VERSION + indicating which version of flex generated the scanner + (for example, for the 2.5 release, these defines would + be 2 and 5 respectively). + + The following flex features are not included in lex or the + POSIX specification: + + C++ scanners + %option + start condition scopes + start condition stacks + interactive/non-interactive scanners + yy_scan_string() and friends + yyterminate() + yy_set_interactive() + yy_set_bol() + YY_AT_BOL() + <> + <*> + YY_DECL + YY_START + YY_USER_ACTION + YY_USER_INIT + #line directives + %{}'s around actions + multiple actions on a line + + plus almost all of the flex flags. The last feature in the + list refers to the fact that with flex you can put multiple + actions on the same line, separated with semi-colons, while + with lex, the following + + foo handle_foo(); ++num_foos_seen; + + is (rather surprisingly) truncated to + + foo handle_foo(); + + flex does not truncate the action. Actions that are not + enclosed in braces are simply terminated at the end of the + + + +Version 2.5 Last change: April 1995 51 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + line. + +DIAGNOSTICS + warning, rule cannot be matched indicates that the given + rule cannot be matched because it follows other rules that + will always match the same text as it. For example, in the + following "foo" cannot be matched because it comes after an + identifier "catch-all" rule: + + [a-z]+ got_identifier(); + foo got_foo(); + + Using REJECT in a scanner suppresses this warning. + + warning, -s option given but default rule can be matched + means that it is possible (perhaps only in a particular + start condition) that the default rule (match any single + character) is the only one that will match a particular + input. Since -s was given, presumably this is not intended. + + reject_used_but_not_detected undefined or + yymore_used_but_not_detected undefined - These errors can + occur at compile time. They indicate that the scanner uses + REJECT or yymore() but that flex failed to notice the fact, + meaning that flex scanned the first two sections looking for + occurrences of these actions and failed to find any, but + somehow you snuck some in (via a #include file, for exam- + ple). Use %option reject or %option yymore to indicate to + flex that you really do use these features. + + flex scanner jammed - a scanner compiled with -s has encoun- + tered an input string which wasn't matched by any of its + rules. This error can also occur due to internal problems. + + token too large, exceeds YYLMAX - your scanner uses %array + and one of its rules matched a string longer than the YYLMAX + constant (8K bytes by default). You can increase the value + by #define'ing YYLMAX in the definitions section of your + flex input. + + scanner requires -8 flag to use the character 'x' - Your + scanner specification includes recognizing the 8-bit charac- + ter 'x' and you did not specify the -8 flag, and your + scanner defaulted to 7-bit because you used the -Cf or -CF + table compression options. See the discussion of the -7 + flag for details. + + flex scanner push-back overflow - you used unput() to push + back so much text that the scanner's buffer could not hold + both the pushed-back text and the current token in yytext. + Ideally the scanner should dynamically resize the buffer in + this case, but at present it does not. + + + +Version 2.5 Last change: April 1995 52 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + input buffer overflow, can't enlarge buffer because scanner + uses REJECT - the scanner was working on matching an + extremely large token and needed to expand the input buffer. + This doesn't work with scanners that use REJECT. + + fatal flex scanner internal error--end of buffer missed - + This can occur in an scanner which is reentered after a + long-jump has jumped out (or over) the scanner's activation + frame. Before reentering the scanner, use: + + yyrestart( yyin ); + + or, as noted above, switch to using the C++ scanner class. + + too many start conditions in <> you listed more start condi- + tions in a <> construct than exist (so you must have listed + at least one of them twice). + +FILES + -lfl library with which scanners must be linked. + + lex.yy.c + generated scanner (called lexyy.c on some systems). + + lex.yy.cc + generated C++ scanner class, when using -+. + + + header file defining the C++ scanner base class, Flex- + Lexer, and its derived class, yyFlexLexer. + + flex.skl + skeleton scanner. This file is only used when building + flex, not when flex executes. + + lex.backup + backing-up information for -b flag (called lex.bck on + some systems). + +DEFICIENCIES / BUGS + Some trailing context patterns cannot be properly matched + and generate warning messages ("dangerous trailing con- + text"). These are patterns where the ending of the first + part of the rule matches the beginning of the second part, + such as "zx*/xy*", where the 'x*' matches the 'x' at the + beginning of the trailing context. (Note that the POSIX + draft states that the text matched by such patterns is unde- + fined.) + + For some trailing context rules, parts which are actually + fixed-length are not recognized as such, leading to the + abovementioned performance loss. In particular, parts using + + + +Version 2.5 Last change: April 1995 53 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + '|' or {n} (such as "foo{3}") are always considered + variable-length. + + Combining trailing context with the special '|' action can + result in fixed trailing context being turned into the more + expensive variable trailing context. For example, in the + following: + + %% + abc | + xyz/def + + + Use of unput() invalidates yytext and yyleng, unless the + %array directive or the -l option has been used. + + Pattern-matching of NUL's is substantially slower than + matching other characters. + + Dynamic resizing of the input buffer is slow, as it entails + rescanning all the text matched so far by the current (gen- + erally huge) token. + + Due to both buffering of input and read-ahead, you cannot + intermix calls to routines, such as, for example, + getchar(), with flex rules and expect it to work. Call + input() instead. + + The total table entries listed by the -v flag excludes the + number of table entries needed to determine what rule has + been matched. The number of entries is equal to the number + of DFA states if the scanner does not use REJECT, and some- + what greater than the number of states if it does. + + REJECT cannot be used with the -f or -F options. + + The flex internal algorithms need documentation. + +SEE ALSO + lex(1), yacc(1), sed(1), awk(1). + + John Levine, Tony Mason, and Doug Brown, Lex & Yacc, + O'Reilly and Associates. Be sure to get the 2nd edition. + + M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator + + Alfred Aho, Ravi Sethi and Jeffrey Ullman, Compilers: Prin- + ciples, Techniques and Tools, Addison-Wesley (1986). + Describes the pattern-matching techniques used by flex + (deterministic finite automata). + + + + + +Version 2.5 Last change: April 1995 54 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + +AUTHOR + Vern Paxson, with the help of many ideas and much inspira- + tion from Van Jacobson. Original version by Jef Poskanzer. + The fast table representation is a partial implementation of + a design done by Van Jacobson. The implementation was done + by Kevin Gong and Vern Paxson. + + Thanks to the many flex beta-testers, feedbackers, and con- + tributors, especially Francois Pinard, Casey Leedom, Robert + Abramovitz, Stan Adermann, Terry Allen, David Barker- + Plummer, John Basrai, Neal Becker, Nelson H.F. Beebe, + benson@odi.com, Karl Berry, Peter A. Bigot, Simon Blanchard, + Keith Bostic, Frederic Brehm, Ian Brockbank, Kin Cho, Nick + Christopher, Brian Clapper, J.T. Conklin, Jason Coughlin, + Bill Cox, Nick Cropper, Dave Curtis, Scott David Daniels, + Chris G. Demetriou, Theo Deraadt, Mike Donahue, Chuck + Doucette, Tom Epperly, Leo Eskin, Chris Faylor, Chris + Flatters, Jon Forrest, Jeffrey Friedl, Joe Gayda, Kaveh R. + Ghazi, Wolfgang Glunz, Eric Goldman, Christopher M. Gould, + Ulrich Grepel, Peer Griebel, Jan Hajic, Charles Hemphill, + NORO Hideo, Jarkko Hietaniemi, Scott Hofmann, Jeff Honig, + Dana Hudes, Eric Hughes, John Interrante, Ceriel Jacobs, + Michal Jaegermann, Sakari Jalovaara, Jeffrey R. Jones, Henry + Juengst, Klaus Kaempf, Jonathan I. Kamens, Terrence O Kane, + Amir Katz, ken@ken.hilco.com, Kevin B. Kenny, Steve Kirsch, + Winfried Koenig, Marq Kole, Ronald Lamprecht, Greg Lee, + Rohan Lenard, Craig Leres, John Levine, Steve Liddle, David + Loffredo, Mike Long, Mohamed el Lozy, Brian Madsen, Malte, + Joe Marshall, Bengt Martensson, Chris Metcalf, Luke Mewburn, + Jim Meyering, R. Alexander Milowski, Erik Naggum, G.T. + Nicol, Landon Noll, James Nordby, Marc Nozell, Richard + Ohnemus, Karsten Pahnke, Sven Panne, Roland Pesch, Walter + Pelissero, Gaumond Pierre, Esmond Pitt, Jef Poskanzer, Joe + Rahmeh, Jarmo Raiha, Frederic Raimbault, Pat Rankin, Rick + Richardson, Kevin Rodgers, Kai Uwe Rommel, Jim Roskind, + Alberto Santini, Andreas Scherer, Darrell Schiebel, Raf + Schietekat, Doug Schmidt, Philippe Schnoebelen, Andreas + Schwab, Larry Schwimmer, Alex Siegel, Eckehard Stolz, Jan- + Erik Strvmquist, Mike Stump, Paul Stuart, Dave Tallman, Ian + Lance Taylor, Chris Thewalt, Richard M. Timoney, Jodi Tsai, + Paul Tuinenga, Gary Weik, Frank Whaley, Gerhard Wilhelms, + Kent Williams, Ken Yap, Ron Zellar, Nathan Zelle, David + Zuhn, and those whose names have slipped my marginal mail- + archiving skills but whose contributions are appreciated all + the same. + + Thanks to Keith Bostic, Jon Forrest, Noah Friedman, John + Gilmore, Craig Leres, John Levine, Bob Mulcahy, G.T. Nicol, + Francois Pinard, Rich Salz, and Richard Stallman for help + with various distribution headaches. + + + + + +Version 2.5 Last change: April 1995 55 + + + + + + +FLEX(1) USER COMMANDS FLEX(1) + + + + Thanks to Esmond Pitt and Earle Horton for 8-bit character + support; to Benson Margulies and Fred Burke for C++ support; + to Kent Williams and Tom Epperly for C++ class support; to + Ove Ewerlid for support of NUL's; and to Eric Hughes for + support of multiple buffers. + + This work was primarily done when I was with the Real Time + Systems Group at the Lawrence Berkeley Laboratory in Berke- + ley, CA. Many thanks to all there for the support I + received. + + Send comments to vern@ee.lbl.gov. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Version 2.5 Last change: April 1995 56 + + + diff --git a/commands/flex-2.5.4/MISC/parse.c b/commands/flex-2.5.4/MISC/parse.c new file mode 100644 index 000000000..f5f1d80f5 --- /dev/null +++ b/commands/flex-2.5.4/MISC/parse.c @@ -0,0 +1,1452 @@ +#ifndef lint +static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define yyclearin (yychar=(-1)) +#define yyerrok (yyerrflag=0) +#define YYRECOVERING (yyerrflag!=0) +#define YYPREFIX "yy" +#line 10 "./parse.y" +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + + +/* Some versions of bison are broken in that they use alloca() but don't + * declare it properly. The following is the patented (just kidding!) + * #ifdef chud to fix the problem, courtesy of Francois Pinard. + */ +#ifdef YYBISON +/* AIX requires this to be the first thing in the file. What a piece. */ +# ifdef _AIX + #pragma alloca +# endif +#endif + +#include "flexdef.h" + +/* The remainder of the alloca() cruft has to come after including flexdef.h, + * so HAVE_ALLOCA_H is (possibly) defined. + */ +#ifdef YYBISON +# ifdef __GNUC__ +# ifndef alloca +# define alloca __builtin_alloca +# endif +# else +# if HAVE_ALLOCA_H +# include +# else +# ifdef __hpux +void *alloca (); +# else +# ifdef __TURBOC__ +# include +# else +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +/* Bletch, ^^^^ that was ugly! */ + + +int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, rulelen; +int trlcontxt, xcluflg, currccl, cclsorted, varlength, variable_trail_rule; + +int *scon_stk; +int scon_stk_ptr; + +static int madeany = false; /* whether we've made the '.' character class */ +int previous_continued_action; /* whether the previous rule's action was '|' */ + +/* Expand a POSIX character class expression. */ +#define CCL_EXPR(func) \ + { \ + int c; \ + for ( c = 0; c < csize; ++c ) \ + if ( isascii(c) && func(c) ) \ + ccladd( currccl, c ); \ + } + +/* While POSIX defines isblank(), it's not ANSI C. */ +#define IS_BLANK(c) ((c) == ' ' || (c) == '\t') + +/* On some over-ambitious machines, such as DEC Alpha's, the default + * token type is "long" instead of "int"; this leads to problems with + * declaring yylval in flexdef.h. But so far, all the yacc's I've seen + * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the + * following should ensure that the default token type is "int". + */ +#define YYSTYPE int + +#line 112 "y.tab.c" +#define CHAR 257 +#define NUMBER 258 +#define SECTEND 259 +#define SCDECL 260 +#define XSCDECL 261 +#define NAME 262 +#define PREVCCL 263 +#define EOF_OP 264 +#define OPTION_OP 265 +#define OPT_OUTFILE 266 +#define OPT_PREFIX 267 +#define OPT_YYCLASS 268 +#define CCE_ALNUM 269 +#define CCE_ALPHA 270 +#define CCE_BLANK 271 +#define CCE_CNTRL 272 +#define CCE_DIGIT 273 +#define CCE_GRAPH 274 +#define CCE_LOWER 275 +#define CCE_PRINT 276 +#define CCE_PUNCT 277 +#define CCE_SPACE 278 +#define CCE_UPPER 279 +#define CCE_XDIGIT 280 +#define YYERRCODE 256 +short yylhs[] = { -1, + 0, 1, 2, 2, 2, 2, 3, 6, 6, 7, + 7, 7, 8, 9, 9, 10, 10, 10, 4, 4, + 4, 5, 12, 12, 12, 12, 14, 11, 11, 11, + 15, 15, 15, 16, 13, 13, 13, 13, 18, 18, + 17, 19, 19, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 21, 21, 23, 23, 23, + 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 22, 22, +}; +short yylen[] = { 2, + 5, 0, 3, 2, 0, 1, 1, 1, 1, 2, + 1, 1, 2, 2, 0, 3, 3, 3, 5, 5, + 0, 0, 2, 1, 1, 1, 0, 4, 3, 0, + 3, 1, 1, 1, 2, 3, 2, 1, 3, 1, + 2, 2, 1, 2, 2, 2, 6, 5, 4, 1, + 1, 1, 3, 3, 1, 3, 4, 4, 2, 2, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 0, +}; +short yydefred[] = { 2, + 0, 0, 6, 0, 7, 8, 9, 15, 21, 0, + 4, 0, 0, 12, 11, 0, 0, 0, 0, 14, + 0, 1, 0, 10, 0, 0, 0, 0, 0, 21, + 0, 16, 17, 18, 29, 33, 34, 0, 32, 0, + 26, 55, 52, 25, 0, 50, 75, 0, 0, 0, + 24, 0, 0, 0, 0, 51, 28, 0, 20, 23, + 0, 0, 61, 0, 19, 0, 37, 0, 41, 0, + 0, 44, 45, 46, 31, 74, 53, 54, 0, 0, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 56, 60, 36, 0, 0, 57, 0, 49, + 0, 58, 0, 48, 47, +}; +short yydgoto[] = { 1, + 2, 4, 9, 13, 22, 10, 16, 11, 12, 20, + 23, 50, 51, 29, 38, 39, 52, 53, 54, 55, + 56, 61, 64, 94, +}; +short yysindex[] = { 0, + 0, -235, 0, -191, 0, 0, 0, 0, 0, -207, + 0, -215, -18, 0, 0, -202, 4, 26, 32, 0, + 41, 0, -35, 0, -168, -166, -165, 38, -180, 0, + -30, 0, 0, 0, 0, 0, 0, -16, 0, -40, + 0, 0, 0, 0, -2, 0, 0, -2, 8, 93, + 0, -2, -25, -2, 15, 0, 0, -153, 0, 0, + -27, -26, 0, -88, 0, -23, 0, -2, 0, 15, + -150, 0, 0, 0, 0, 0, 0, 0, -3, 65, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -2, -21, 0, -145, 0, + -116, 0, -12, 0, 0, +}; +short yyrindex[] = { 0, + 0, -188, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -154, 1, 0, 0, -140, 0, 0, 0, 0, + -176, 0, -28, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -32, + 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, + 0, 0, 106, 7, -10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108, 0, 0, 0, -7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, +}; +short yygindex[] = { 0, + 0, 0, 0, 92, 100, 0, 0, 0, 0, 0, + 0, 0, 81, 0, 0, 69, 0, 27, 60, -29, + 0, 0, 66, 0, +}; +#define YYTABLESIZE 326 +short yytable[] = { 43, + 22, 30, 42, 47, 93, 22, 77, 30, 104, 48, + 67, 22, 95, 30, 78, 46, 40, 22, 39, 21, + 3, 69, 101, 43, 70, 43, 42, 58, 42, 43, + 43, 47, 42, 42, 30, 43, 43, 48, 42, 42, + 30, 21, 40, 46, 39, 57, 30, 40, 14, 39, + 17, 18, 19, 40, 15, 39, 72, 73, 30, 24, + 49, 30, 22, 45, 25, 22, 70, 5, 6, 7, + 5, 5, 5, 8, 62, 36, 5, 74, 66, 27, + 43, 37, 28, 42, 59, 27, 26, 30, 49, 98, + 30, 30, 27, 32, 30, 33, 34, 68, 68, 35, + 68, 63, 65, 100, 13, 13, 13, 97, 37, 99, + 13, 102, 105, 43, 61, 38, 42, 35, 3, 3, + 3, 40, 31, 30, 3, 60, 75, 96, 79, 0, + 40, 0, 39, 0, 0, 0, 0, 71, 59, 0, + 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 30, 30, 41, 42, 22, 22, 76, + 30, 30, 43, 44, 22, 22, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 43, 0, 0, 42, + 0, 0, 43, 80, 42, 42, 30, 30, 0, 0, + 43, 0, 0, 30, 30, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 0, 61, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 59, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, +}; +short yycheck[] = { 10, + 0, 34, 10, 34, 93, 34, 34, 40, 125, 40, + 36, 40, 36, 46, 41, 46, 10, 46, 10, 60, + 256, 47, 44, 34, 54, 36, 34, 44, 36, 40, + 41, 34, 40, 41, 34, 46, 47, 40, 46, 47, + 40, 60, 36, 46, 36, 62, 46, 41, 256, 41, + 266, 267, 268, 47, 262, 47, 42, 43, 91, 262, + 91, 94, 91, 94, 61, 94, 96, 259, 260, 261, + 259, 260, 261, 265, 48, 256, 265, 63, 52, 256, + 91, 262, 42, 91, 125, 262, 61, 123, 91, 93, + 123, 91, 61, 262, 94, 262, 262, 124, 124, 62, + 124, 94, 10, 125, 259, 260, 261, 258, 262, 45, + 265, 257, 125, 124, 93, 10, 124, 10, 259, 260, + 261, 30, 23, 123, 265, 45, 58, 68, 63, -1, + 124, -1, 124, -1, -1, -1, -1, 123, 93, -1, + -1, 258, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 257, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 256, 257, 256, 257, 256, 257, 257, + 263, 264, 263, 264, 263, 264, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 257, -1, -1, 257, + -1, -1, 263, 257, 257, 263, 256, 257, -1, -1, + 263, -1, -1, 263, 264, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, -1, 257, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 257, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 280 +#if YYDEBUG +char *yyname[] = { +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,"'\"'",0,"'$'",0,0,0,"'('","')'","'*'","'+'","','","'-'","'.'","'/'",0,0, +0,0,0,0,0,0,0,0,0,0,"'<'","'='","'>'","'?'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,"'['",0,"']'","'^'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,"'{'","'|'","'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"CHAR","NUMBER","SECTEND", +"SCDECL","XSCDECL","NAME","PREVCCL","EOF_OP","OPTION_OP","OPT_OUTFILE", +"OPT_PREFIX","OPT_YYCLASS","CCE_ALNUM","CCE_ALPHA","CCE_BLANK","CCE_CNTRL", +"CCE_DIGIT","CCE_GRAPH","CCE_LOWER","CCE_PRINT","CCE_PUNCT","CCE_SPACE", +"CCE_UPPER","CCE_XDIGIT", +}; +char *yyrule[] = { +"$accept : goal", +"goal : initlex sect1 sect1end sect2 initforrule", +"initlex :", +"sect1 : sect1 startconddecl namelist1", +"sect1 : sect1 options", +"sect1 :", +"sect1 : error", +"sect1end : SECTEND", +"startconddecl : SCDECL", +"startconddecl : XSCDECL", +"namelist1 : namelist1 NAME", +"namelist1 : NAME", +"namelist1 : error", +"options : OPTION_OP optionlist", +"optionlist : optionlist option", +"optionlist :", +"option : OPT_OUTFILE '=' NAME", +"option : OPT_PREFIX '=' NAME", +"option : OPT_YYCLASS '=' NAME", +"sect2 : sect2 scon initforrule flexrule '\\n'", +"sect2 : sect2 scon '{' sect2 '}'", +"sect2 :", +"initforrule :", +"flexrule : '^' rule", +"flexrule : rule", +"flexrule : EOF_OP", +"flexrule : error", +"scon_stk_ptr :", +"scon : '<' scon_stk_ptr namelist2 '>'", +"scon : '<' '*' '>'", +"scon :", +"namelist2 : namelist2 ',' sconname", +"namelist2 : sconname", +"namelist2 : error", +"sconname : NAME", +"rule : re2 re", +"rule : re2 re '$'", +"rule : re '$'", +"rule : re", +"re : re '|' series", +"re : series", +"re2 : re '/'", +"series : series singleton", +"series : singleton", +"singleton : singleton '*'", +"singleton : singleton '+'", +"singleton : singleton '?'", +"singleton : singleton '{' NUMBER ',' NUMBER '}'", +"singleton : singleton '{' NUMBER ',' '}'", +"singleton : singleton '{' NUMBER '}'", +"singleton : '.'", +"singleton : fullccl", +"singleton : PREVCCL", +"singleton : '\"' string '\"'", +"singleton : '(' re ')'", +"singleton : CHAR", +"fullccl : '[' ccl ']'", +"fullccl : '[' '^' ccl ']'", +"ccl : ccl CHAR '-' CHAR", +"ccl : ccl CHAR", +"ccl : ccl ccl_expr", +"ccl :", +"ccl_expr : CCE_ALNUM", +"ccl_expr : CCE_ALPHA", +"ccl_expr : CCE_BLANK", +"ccl_expr : CCE_CNTRL", +"ccl_expr : CCE_DIGIT", +"ccl_expr : CCE_GRAPH", +"ccl_expr : CCE_LOWER", +"ccl_expr : CCE_PRINT", +"ccl_expr : CCE_PUNCT", +"ccl_expr : CCE_SPACE", +"ccl_expr : CCE_UPPER", +"ccl_expr : CCE_XDIGIT", +"string : string CHAR", +"string :", +}; +#endif +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 500 +#define YYMAXDEPTH 500 +#endif +#endif +int yydebug; +int yynerrs; +int yyerrflag; +int yychar; +short *yyssp; +YYSTYPE *yyvsp; +YYSTYPE yyval; +YYSTYPE yylval; +short yyss[YYSTACKSIZE]; +YYSTYPE yyvs[YYSTACKSIZE]; +#define yystacksize YYSTACKSIZE +#line 776 "./parse.y" + + +/* build_eof_action - build the "<>" action for the active start + * conditions + */ + +void build_eof_action() + { + register int i; + char action_text[MAXLINE]; + + for ( i = 1; i <= scon_stk_ptr; ++i ) + { + if ( sceof[scon_stk[i]] ) + format_pinpoint_message( + "multiple <> rules for start condition %s", + scname[scon_stk[i]] ); + + else + { + sceof[scon_stk[i]] = true; + sprintf( action_text, "case YY_STATE_EOF(%s):\n", + scname[scon_stk[i]] ); + add_action( action_text ); + } + } + + line_directive_out( (FILE *) 0, 1 ); + + /* This isn't a normal rule after all - don't count it as + * such, so we don't have any holes in the rule numbering + * (which make generating "rule can never match" warnings + * more difficult. + */ + --num_rules; + ++num_eof_rules; + } + + +/* format_synerr - write out formatted syntax error */ + +void format_synerr( msg, arg ) +char msg[], arg[]; + { + char errmsg[MAXLINE]; + + (void) sprintf( errmsg, msg, arg ); + synerr( errmsg ); + } + + +/* synerr - report a syntax error */ + +void synerr( str ) +char str[]; + { + syntaxerror = true; + pinpoint_message( str ); + } + + +/* format_warn - write out formatted warning */ + +void format_warn( msg, arg ) +char msg[], arg[]; + { + char warn_msg[MAXLINE]; + + (void) sprintf( warn_msg, msg, arg ); + warn( warn_msg ); + } + + +/* warn - report a warning, unless -w was given */ + +void warn( str ) +char str[]; + { + line_warning( str, linenum ); + } + +/* format_pinpoint_message - write out a message formatted with one string, + * pinpointing its location + */ + +void format_pinpoint_message( msg, arg ) +char msg[], arg[]; + { + char errmsg[MAXLINE]; + + (void) sprintf( errmsg, msg, arg ); + pinpoint_message( errmsg ); + } + + +/* pinpoint_message - write out a message, pinpointing its location */ + +void pinpoint_message( str ) +char str[]; + { + line_pinpoint( str, linenum ); + } + + +/* line_warning - report a warning at a given line, unless -w was given */ + +void line_warning( str, line ) +char str[]; +int line; + { + char warning[MAXLINE]; + + if ( ! nowarn ) + { + sprintf( warning, "warning, %s", str ); + line_pinpoint( warning, line ); + } + } + + +/* line_pinpoint - write out a message, pinpointing it at the given line */ + +void line_pinpoint( str, line ) +char str[]; +int line; + { + fprintf( stderr, "\"%s\", line %d: %s\n", infilename, line, str ); + } + + +/* yyerror - eat up an error message from the parser; + * currently, messages are ignore + */ + +void yyerror( msg ) +char msg[]; + { + } +#line 541 "y.tab.c" +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab +int +yyparse() +{ + register int yym, yyn, yystate; +#if YYDEBUG + register char *yys; + extern char *getenv(); + + if (yys = getenv("YYDEBUG")) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = (-1); + + yyssp = yyss; + yyvsp = yyvs; + *yyssp = yystate = 0; + +yyloop: + if (yyn = yydefred[yystate]) goto yyreduce; + if (yychar < 0) + { + if ((yychar = yylex()) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yyssp >= yyss + yystacksize - 1) + { + goto yyoverflow; + } + *++yyssp = yystate = yytable[yyn]; + *++yyvsp = yylval; + yychar = (-1); + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; +#ifdef lint + goto yynewerror; +#endif +yynewerror: + yyerror("syntax error"); +#ifdef lint + goto yyerrlab; +#endif +yyerrlab: + ++yynerrs; +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); +#endif + if (yyssp >= yyss + yystacksize - 1) + { + goto yyoverflow; + } + *++yyssp = yystate = yytable[yyn]; + *++yyvsp = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yyssp); +#endif + if (yyssp <= yyss) goto yyabort; + --yyssp; + --yyvsp; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = (-1); + goto yyloop; + } +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + yyval = yyvsp[1-yym]; + switch (yyn) + { +case 1: +#line 113 "./parse.y" +{ /* add default rule */ + int def_rule; + + pat = cclinit(); + cclnegate( pat ); + + def_rule = mkstate( -pat ); + + /* Remember the number of the default rule so we + * don't generate "can't match" warnings for it. + */ + default_rule = num_rules; + + finish_rule( def_rule, false, 0, 0 ); + + for ( i = 1; i <= lastsc; ++i ) + scset[i] = mkbranch( scset[i], def_rule ); + + if ( spprdflt ) + add_action( + "YY_FATAL_ERROR( \"flex scanner jammed\" )" ); + else + add_action( "ECHO" ); + + add_action( ";\n\tYY_BREAK\n" ); + } +break; +case 2: +#line 142 "./parse.y" +{ /* initialize for processing rules */ + + /* Create default DFA start condition. */ + scinstal( "INITIAL", false ); + } +break; +case 6: +#line 153 "./parse.y" +{ synerr( "unknown error processing section 1" ); } +break; +case 7: +#line 157 "./parse.y" +{ + check_options(); + scon_stk = allocate_integer_array( lastsc + 1 ); + scon_stk_ptr = 0; + } +break; +case 8: +#line 165 "./parse.y" +{ xcluflg = false; } +break; +case 9: +#line 168 "./parse.y" +{ xcluflg = true; } +break; +case 10: +#line 172 "./parse.y" +{ scinstal( nmstr, xcluflg ); } +break; +case 11: +#line 175 "./parse.y" +{ scinstal( nmstr, xcluflg ); } +break; +case 12: +#line 178 "./parse.y" +{ synerr( "bad start condition list" ); } +break; +case 16: +#line 189 "./parse.y" +{ + outfilename = copy_string( nmstr ); + did_outfilename = 1; + } +break; +case 17: +#line 194 "./parse.y" +{ prefix = copy_string( nmstr ); } +break; +case 18: +#line 196 "./parse.y" +{ yyclass = copy_string( nmstr ); } +break; +case 19: +#line 200 "./parse.y" +{ scon_stk_ptr = yyvsp[-3]; } +break; +case 20: +#line 202 "./parse.y" +{ scon_stk_ptr = yyvsp[-3]; } +break; +case 22: +#line 207 "./parse.y" +{ + /* Initialize for a parse of one rule. */ + trlcontxt = variable_trail_rule = varlength = false; + trailcnt = headcnt = rulelen = 0; + current_state_type = STATE_NORMAL; + previous_continued_action = continued_action; + in_rule = true; + + new_rule(); + } +break; +case 23: +#line 220 "./parse.y" +{ + pat = yyvsp[0]; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt ); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scbol[scon_stk[i]] = + mkbranch( scbol[scon_stk[i]], + pat ); + } + + else + { + /* Add to all non-exclusive start conditions, + * including the default (0) start condition. + */ + + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scbol[i] = mkbranch( scbol[i], + pat ); + } + + if ( ! bol_needed ) + { + bol_needed = true; + + if ( performance_report > 1 ) + pinpoint_message( + "'^' operator results in sub-optimal performance" ); + } + } +break; +case 24: +#line 256 "./parse.y" +{ + pat = yyvsp[0]; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt ); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scset[scon_stk[i]] = + mkbranch( scset[scon_stk[i]], + pat ); + } + + else + { + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scset[i] = + mkbranch( scset[i], + pat ); + } + } +break; +case 25: +#line 280 "./parse.y" +{ + if ( scon_stk_ptr > 0 ) + build_eof_action(); + + else + { + /* This EOF applies to all start conditions + * which don't already have EOF actions. + */ + for ( i = 1; i <= lastsc; ++i ) + if ( ! sceof[i] ) + scon_stk[++scon_stk_ptr] = i; + + if ( scon_stk_ptr == 0 ) + warn( + "all start conditions already have <> rules" ); + + else + build_eof_action(); + } + } +break; +case 26: +#line 303 "./parse.y" +{ synerr( "unrecognized rule" ); } +break; +case 27: +#line 307 "./parse.y" +{ yyval = scon_stk_ptr; } +break; +case 28: +#line 311 "./parse.y" +{ yyval = yyvsp[-2]; } +break; +case 29: +#line 314 "./parse.y" +{ + yyval = scon_stk_ptr; + + for ( i = 1; i <= lastsc; ++i ) + { + int j; + + for ( j = 1; j <= scon_stk_ptr; ++j ) + if ( scon_stk[j] == i ) + break; + + if ( j > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = i; + } + } +break; +case 30: +#line 331 "./parse.y" +{ yyval = scon_stk_ptr; } +break; +case 33: +#line 339 "./parse.y" +{ synerr( "bad start condition list" ); } +break; +case 34: +#line 343 "./parse.y" +{ + if ( (scnum = sclookup( nmstr )) == 0 ) + format_pinpoint_message( + "undeclared start condition %s", + nmstr ); + else + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + if ( scon_stk[i] == scnum ) + { + format_warn( + "<%s> specified twice", + scname[scnum] ); + break; + } + + if ( i > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = scnum; + } + } +break; +case 35: +#line 366 "./parse.y" +{ + if ( transchar[lastst[yyvsp[0]]] != SYM_EPSILON ) + /* Provide final transition \now/ so it + * will be marked as a trailing context + * state. + */ + yyvsp[0] = link_machines( yyvsp[0], + mkstate( SYM_EPSILON ) ); + + mark_beginning_as_normal( yyvsp[0] ); + current_state_type = STATE_NORMAL; + + if ( previous_continued_action ) + { + /* We need to treat this as variable trailing + * context so that the backup does not happen + * in the action but before the action switch + * statement. If the backup happens in the + * action, then the rules "falling into" this + * one's action will *also* do the backup, + * erroneously. + */ + if ( ! varlength || headcnt != 0 ) + warn( + "trailing context made variable due to preceding '|' action" ); + + /* Mark as variable. */ + varlength = true; + headcnt = 0; + } + + if ( lex_compat || (varlength && headcnt == 0) ) + { /* variable trailing context rule */ + /* Mark the first part of the rule as the + * accepting "head" part of a trailing + * context rule. + * + * By the way, we didn't do this at the + * beginning of this production because back + * then current_state_type was set up for a + * trail rule, and add_accept() can create + * a new state ... + */ + add_accept( yyvsp[-1], + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + else + trailcnt = rulelen; + + yyval = link_machines( yyvsp[-1], yyvsp[0] ); + } +break; +case 36: +#line 421 "./parse.y" +{ synerr( "trailing context used twice" ); } +break; +case 37: +#line 424 "./parse.y" +{ + headcnt = 0; + trailcnt = 1; + rulelen = 1; + varlength = false; + + current_state_type = STATE_TRAILING_CONTEXT; + + if ( trlcontxt ) + { + synerr( "trailing context used twice" ); + yyval = mkstate( SYM_EPSILON ); + } + + else if ( previous_continued_action ) + { + /* See the comment in the rule for "re2 re" + * above. + */ + warn( + "trailing context made variable due to preceding '|' action" ); + + varlength = true; + } + + if ( lex_compat || varlength ) + { + /* Again, see the comment in the rule for + * "re2 re" above. + */ + add_accept( yyvsp[-1], + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + trlcontxt = true; + + eps = mkstate( SYM_EPSILON ); + yyval = link_machines( yyvsp[-1], + link_machines( eps, mkstate( '\n' ) ) ); + } +break; +case 38: +#line 467 "./parse.y" +{ + yyval = yyvsp[0]; + + if ( trlcontxt ) + { + if ( lex_compat || (varlength && headcnt == 0) ) + /* Both head and trail are + * variable-length. + */ + variable_trail_rule = true; + else + trailcnt = rulelen; + } + } +break; +case 39: +#line 485 "./parse.y" +{ + varlength = true; + yyval = mkor( yyvsp[-2], yyvsp[0] ); + } +break; +case 40: +#line 491 "./parse.y" +{ yyval = yyvsp[0]; } +break; +case 41: +#line 496 "./parse.y" +{ + /* This rule is written separately so the + * reduction will occur before the trailing + * series is parsed. + */ + + if ( trlcontxt ) + synerr( "trailing context used twice" ); + else + trlcontxt = true; + + if ( varlength ) + /* We hope the trailing context is + * fixed-length. + */ + varlength = false; + else + headcnt = rulelen; + + rulelen = 0; + + current_state_type = STATE_TRAILING_CONTEXT; + yyval = yyvsp[-1]; + } +break; +case 42: +#line 523 "./parse.y" +{ + /* This is where concatenation of adjacent patterns + * gets done. + */ + yyval = link_machines( yyvsp[-1], yyvsp[0] ); + } +break; +case 43: +#line 531 "./parse.y" +{ yyval = yyvsp[0]; } +break; +case 44: +#line 535 "./parse.y" +{ + varlength = true; + + yyval = mkclos( yyvsp[-1] ); + } +break; +case 45: +#line 542 "./parse.y" +{ + varlength = true; + yyval = mkposcl( yyvsp[-1] ); + } +break; +case 46: +#line 548 "./parse.y" +{ + varlength = true; + yyval = mkopt( yyvsp[-1] ); + } +break; +case 47: +#line 554 "./parse.y" +{ + varlength = true; + + if ( yyvsp[-3] > yyvsp[-1] || yyvsp[-3] < 0 ) + { + synerr( "bad iteration values" ); + yyval = yyvsp[-5]; + } + else + { + if ( yyvsp[-3] == 0 ) + { + if ( yyvsp[-1] <= 0 ) + { + synerr( + "bad iteration values" ); + yyval = yyvsp[-5]; + } + else + yyval = mkopt( + mkrep( yyvsp[-5], 1, yyvsp[-1] ) ); + } + else + yyval = mkrep( yyvsp[-5], yyvsp[-3], yyvsp[-1] ); + } + } +break; +case 48: +#line 582 "./parse.y" +{ + varlength = true; + + if ( yyvsp[-2] <= 0 ) + { + synerr( "iteration value must be positive" ); + yyval = yyvsp[-4]; + } + + else + yyval = mkrep( yyvsp[-4], yyvsp[-2], INFINITY ); + } +break; +case 49: +#line 596 "./parse.y" +{ + /* The singleton could be something like "(foo)", + * in which case we have no idea what its length + * is, so we punt here. + */ + varlength = true; + + if ( yyvsp[-1] <= 0 ) + { + synerr( "iteration value must be positive" ); + yyval = yyvsp[-3]; + } + + else + yyval = link_machines( yyvsp[-3], + copysingl( yyvsp[-3], yyvsp[-1] - 1 ) ); + } +break; +case 50: +#line 615 "./parse.y" +{ + if ( ! madeany ) + { + /* Create the '.' character class. */ + anyccl = cclinit(); + ccladd( anyccl, '\n' ); + cclnegate( anyccl ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[anyccl], + ccllen[anyccl], nextecm, + ecgroup, csize, csize ); + + madeany = true; + } + + ++rulelen; + + yyval = mkstate( -anyccl ); + } +break; +case 51: +#line 637 "./parse.y" +{ + if ( ! cclsorted ) + /* Sort characters for fast searching. We + * use a shell sort since this list could + * be large. + */ + cshell( ccltbl + cclmap[yyvsp[0]], ccllen[yyvsp[0]], true ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[yyvsp[0]], ccllen[yyvsp[0]], + nextecm, ecgroup, csize, csize ); + + ++rulelen; + + yyval = mkstate( -yyvsp[0] ); + } +break; +case 52: +#line 655 "./parse.y" +{ + ++rulelen; + + yyval = mkstate( -yyvsp[0] ); + } +break; +case 53: +#line 662 "./parse.y" +{ yyval = yyvsp[-1]; } +break; +case 54: +#line 665 "./parse.y" +{ yyval = yyvsp[-1]; } +break; +case 55: +#line 668 "./parse.y" +{ + ++rulelen; + + if ( caseins && yyvsp[0] >= 'A' && yyvsp[0] <= 'Z' ) + yyvsp[0] = clower( yyvsp[0] ); + + yyval = mkstate( yyvsp[0] ); + } +break; +case 56: +#line 679 "./parse.y" +{ yyval = yyvsp[-1]; } +break; +case 57: +#line 682 "./parse.y" +{ + cclnegate( yyvsp[-1] ); + yyval = yyvsp[-1]; + } +break; +case 58: +#line 689 "./parse.y" +{ + if ( caseins ) + { + if ( yyvsp[-2] >= 'A' && yyvsp[-2] <= 'Z' ) + yyvsp[-2] = clower( yyvsp[-2] ); + if ( yyvsp[0] >= 'A' && yyvsp[0] <= 'Z' ) + yyvsp[0] = clower( yyvsp[0] ); + } + + if ( yyvsp[-2] > yyvsp[0] ) + synerr( "negative range in character class" ); + + else + { + for ( i = yyvsp[-2]; i <= yyvsp[0]; ++i ) + ccladd( yyvsp[-3], i ); + + /* Keep track if this ccl is staying in + * alphabetical order. + */ + cclsorted = cclsorted && (yyvsp[-2] > lastchar); + lastchar = yyvsp[0]; + } + + yyval = yyvsp[-3]; + } +break; +case 59: +#line 717 "./parse.y" +{ + if ( caseins && yyvsp[0] >= 'A' && yyvsp[0] <= 'Z' ) + yyvsp[0] = clower( yyvsp[0] ); + + ccladd( yyvsp[-1], yyvsp[0] ); + cclsorted = cclsorted && (yyvsp[0] > lastchar); + lastchar = yyvsp[0]; + yyval = yyvsp[-1]; + } +break; +case 60: +#line 728 "./parse.y" +{ + /* Too hard to properly maintain cclsorted. */ + cclsorted = false; + yyval = yyvsp[-1]; + } +break; +case 61: +#line 735 "./parse.y" +{ + cclsorted = true; + lastchar = 0; + currccl = yyval = cclinit(); + } +break; +case 62: +#line 742 "./parse.y" +{ CCL_EXPR(isalnum) } +break; +case 63: +#line 743 "./parse.y" +{ CCL_EXPR(isalpha) } +break; +case 64: +#line 744 "./parse.y" +{ CCL_EXPR(IS_BLANK) } +break; +case 65: +#line 745 "./parse.y" +{ CCL_EXPR(iscntrl) } +break; +case 66: +#line 746 "./parse.y" +{ CCL_EXPR(isdigit) } +break; +case 67: +#line 747 "./parse.y" +{ CCL_EXPR(isgraph) } +break; +case 68: +#line 748 "./parse.y" +{ CCL_EXPR(islower) } +break; +case 69: +#line 749 "./parse.y" +{ CCL_EXPR(isprint) } +break; +case 70: +#line 750 "./parse.y" +{ CCL_EXPR(ispunct) } +break; +case 71: +#line 751 "./parse.y" +{ CCL_EXPR(isspace) } +break; +case 72: +#line 752 "./parse.y" +{ + if ( caseins ) + CCL_EXPR(islower) + else + CCL_EXPR(isupper) + } +break; +case 73: +#line 758 "./parse.y" +{ CCL_EXPR(isxdigit) } +break; +case 74: +#line 762 "./parse.y" +{ + if ( caseins && yyvsp[0] >= 'A' && yyvsp[0] <= 'Z' ) + yyvsp[0] = clower( yyvsp[0] ); + + ++rulelen; + + yyval = link_machines( yyvsp[-1], mkstate( yyvsp[0] ) ); + } +break; +case 75: +#line 772 "./parse.y" +{ yyval = mkstate( SYM_EPSILON ); } +break; +#line 1397 "y.tab.c" + } + yyssp -= yym; + yystate = *yyssp; + yyvsp -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yyssp = YYFINAL; + *++yyvsp = yyval; + if (yychar < 0) + { + if ((yychar = yylex()) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yyssp, yystate); +#endif + if (yyssp >= yyss + yystacksize - 1) + { + goto yyoverflow; + } + *++yyssp = yystate; + *++yyvsp = yyval; + goto yyloop; +yyoverflow: + yyerror("yacc stack overflow"); +yyabort: + return (1); +yyaccept: + return (0); +} diff --git a/commands/flex-2.5.4/MISC/parse.h b/commands/flex-2.5.4/MISC/parse.h new file mode 100644 index 000000000..10febed9d --- /dev/null +++ b/commands/flex-2.5.4/MISC/parse.h @@ -0,0 +1,24 @@ +#define CHAR 257 +#define NUMBER 258 +#define SECTEND 259 +#define SCDECL 260 +#define XSCDECL 261 +#define NAME 262 +#define PREVCCL 263 +#define EOF_OP 264 +#define OPTION_OP 265 +#define OPT_OUTFILE 266 +#define OPT_PREFIX 267 +#define OPT_YYCLASS 268 +#define CCE_ALNUM 269 +#define CCE_ALPHA 270 +#define CCE_BLANK 271 +#define CCE_CNTRL 272 +#define CCE_DIGIT 273 +#define CCE_GRAPH 274 +#define CCE_LOWER 275 +#define CCE_PRINT 276 +#define CCE_PUNCT 277 +#define CCE_SPACE 278 +#define CCE_UPPER 279 +#define CCE_XDIGIT 280 diff --git a/commands/flex-2.5.4/MISC/testxxLexer.l b/commands/flex-2.5.4/MISC/testxxLexer.l new file mode 100644 index 000000000..94215411d --- /dev/null +++ b/commands/flex-2.5.4/MISC/testxxLexer.l @@ -0,0 +1,58 @@ + // An example of using the flex C++ scanner class. + +%option C++ noyywrap + +%{ +int mylineno = 0; +%} + +string \"[^\n"]+\" + +ws [ \t]+ + +alpha [A-Za-z] +dig [0-9] +name ({alpha}|{dig}|\$)({alpha}|{dig}|\_|\.|\-|\/|\$)* +num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)? +num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)? +number {num1}|{num2} + +%% + +{ws} /* skip blanks and tabs */ + +"/*" { + int c; + + while((c = yyinput()) != 0) + { + if(c == '\n') + ++mylineno; + + else if(c == '*') + { + if((c = yyinput()) == '/') + break; + else + unput(c); + } + } + } + +{number} cout << "number " << YYText() << '\n'; + +\n mylineno++; + +{name} cout << "name " << YYText() << '\n'; + +{string} cout << "string " << YYText() << '\n'; + +%% + +int main( int /* argc */, char** /* argv */ ) + { + FlexLexer* lexer = new yyFlexLexer; + while(lexer->yylex() != 0) + ; + return 0; + } diff --git a/commands/flex-2.5.4/MISC/texinfo/flex.info b/commands/flex-2.5.4/MISC/texinfo/flex.info new file mode 100644 index 000000000..926941857 --- /dev/null +++ b/commands/flex-2.5.4/MISC/texinfo/flex.info @@ -0,0 +1,2951 @@ +This is Info file flex.info, produced by Makeinfo-1.55 from the input +file flex.texi. + +START-INFO-DIR-ENTRY +* Flex: (flex). A fast scanner generator. +END-INFO-DIR-ENTRY + + This file documents Flex. + + Copyright (c) 1990 The Regents of the University of California. All +rights reserved. + + This code is derived from software contributed to Berkeley by Vern +Paxson. + + The United States Government has rights in this work pursuant to +contract no. DE-AC03-76SF00098 between the United States Department of +Energy and the University of California. + + Redistribution and use in source and binary forms with or without +modification are permitted provided that: (1) source distributions +retain this entire copyright notice and comment, and (2) distributions +including binaries display the following acknowledgement: "This +product includes software developed by the University of California, +Berkeley and its contributors" in the documentation or other materials +provided with the distribution and in all advertising materials +mentioning features or use of this software. Neither the name of the +University nor the names of its contributors may be used to endorse or +promote products derived from this software without specific prior +written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + +File: flex.info, Node: Top, Next: Name, Prev: (dir), Up: (dir) + +flex +**** + + This manual documents `flex'. It covers release 2.5. + +* Menu: + +* Name:: Name +* Synopsis:: Synopsis +* Overview:: Overview +* Description:: Description +* Examples:: Some simple examples +* Format:: Format of the input file +* Patterns:: Patterns +* Matching:: How the input is matched +* Actions:: Actions +* Generated scanner:: The generated scanner +* Start conditions:: Start conditions +* Multiple buffers:: Multiple input buffers +* End-of-file rules:: End-of-file rules +* Miscellaneous:: Miscellaneous macros +* User variables:: Values available to the user +* YACC interface:: Interfacing with `yacc' +* Options:: Options +* Performance:: Performance considerations +* C++:: Generating C++ scanners +* Incompatibilities:: Incompatibilities with `lex' and POSIX +* Diagnostics:: Diagnostics +* Files:: Files +* Deficiencies:: Deficiencies / Bugs +* See also:: See also +* Author:: Author + + +File: flex.info, Node: Name, Next: Synopsis, Prev: Top, Up: Top + +Name +==== + + flex - fast lexical analyzer generator + + +File: flex.info, Node: Synopsis, Next: Overview, Prev: Name, Up: Top + +Synopsis +======== + + flex [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton] + [--help --version] [FILENAME ...] + + +File: flex.info, Node: Overview, Next: Description, Prev: Synopsis, Up: Top + +Overview +======== + + This manual describes `flex', a tool for generating programs that +perform pattern-matching on text. The manual includes both tutorial +and reference sections: + +Description + a brief overview of the tool + +Some Simple Examples +Format Of The Input File +Patterns + the extended regular expressions used by flex + +How The Input Is Matched + the rules for determining what has been matched + +Actions + how to specify what to do when a pattern is matched + +The Generated Scanner + details regarding the scanner that flex produces; how to control + the input source + +Start Conditions + introducing context into your scanners, and managing + "mini-scanners" + +Multiple Input Buffers + how to manipulate multiple input sources; how to scan from strings + instead of files + +End-of-file Rules + special rules for matching the end of the input + +Miscellaneous Macros + a summary of macros available to the actions + +Values Available To The User + a summary of values available to the actions + +Interfacing With Yacc + connecting flex scanners together with yacc parsers + +Options + flex command-line options, and the "%option" directive + +Performance Considerations + how to make your scanner go as fast as possible + +Generating C++ Scanners + the (experimental) facility for generating C++ scanner classes + +Incompatibilities With Lex And POSIX + how flex differs from AT&T lex and the POSIX lex standard + +Diagnostics + those error messages produced by flex (or scanners it generates) + whose meanings might not be apparent + +Files + files used by flex + +Deficiencies / Bugs + known problems with flex + +See Also + other documentation, related tools + +Author + includes contact information + + +File: flex.info, Node: Description, Next: Examples, Prev: Overview, Up: Top + +Description +=========== + + `flex' is a tool for generating "scanners": programs which +recognized lexical patterns in text. `flex' reads the given input +files, or its standard input if no file names are given, for a +description of a scanner to generate. The description is in the form +of pairs of regular expressions and C code, called "rules". `flex' +generates as output a C source file, `lex.yy.c', which defines a +routine `yylex()'. This file is compiled and linked with the `-lfl' +library to produce an executable. When the executable is run, it +analyzes its input for occurrences of the regular expressions. +Whenever it finds one, it executes the corresponding C code. + + +File: flex.info, Node: Examples, Next: Format, Prev: Description, Up: Top + +Some simple examples +==================== + + First some simple examples to get the flavor of how one uses `flex'. +The following `flex' input specifies a scanner which whenever it +encounters the string "username" will replace it with the user's login +name: + + %% + username printf( "%s", getlogin() ); + + By default, any text not matched by a `flex' scanner is copied to +the output, so the net effect of this scanner is to copy its input file +to its output with each occurrence of "username" expanded. In this +input, there is just one rule. "username" is the PATTERN and the +"printf" is the ACTION. The "%%" marks the beginning of the rules. + + Here's another simple example: + + int num_lines = 0, num_chars = 0; + + %% + \n ++num_lines; ++num_chars; + . ++num_chars; + + %% + main() + { + yylex(); + printf( "# of lines = %d, # of chars = %d\n", + num_lines, num_chars ); + } + + This scanner counts the number of characters and the number of lines +in its input (it produces no output other than the final report on the +counts). The first line declares two globals, "num_lines" and +"num_chars", which are accessible both inside `yylex()' and in the +`main()' routine declared after the second "%%". There are two rules, +one which matches a newline ("\n") and increments both the line count +and the character count, and one which matches any character other than +a newline (indicated by the "." regular expression). + + A somewhat more complicated example: + + /* scanner for a toy Pascal-like language */ + + %{ + /* need this for the call to atof() below */ + #include + %} + + DIGIT [0-9] + ID [a-z][a-z0-9]* + + %% + + {DIGIT}+ { + printf( "An integer: %s (%d)\n", yytext, + atoi( yytext ) ); + } + + {DIGIT}+"."{DIGIT}* { + printf( "A float: %s (%g)\n", yytext, + atof( yytext ) ); + } + + if|then|begin|end|procedure|function { + printf( "A keyword: %s\n", yytext ); + } + + {ID} printf( "An identifier: %s\n", yytext ); + + "+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext ); + + "{"[^}\n]*"}" /* eat up one-line comments */ + + [ \t\n]+ /* eat up whitespace */ + + . printf( "Unrecognized character: %s\n", yytext ); + + %% + + main( argc, argv ) + int argc; + char **argv; + { + ++argv, --argc; /* skip over program name */ + if ( argc > 0 ) + yyin = fopen( argv[0], "r" ); + else + yyin = stdin; + + yylex(); + } + + This is the beginnings of a simple scanner for a language like +Pascal. It identifies different types of TOKENS and reports on what it +has seen. + + The details of this example will be explained in the following +sections. + + +File: flex.info, Node: Format, Next: Patterns, Prev: Examples, Up: Top + +Format of the input file +======================== + + The `flex' input file consists of three sections, separated by a +line with just `%%' in it: + + definitions + %% + rules + %% + user code + + The "definitions" section contains declarations of simple "name" +definitions to simplify the scanner specification, and declarations of +"start conditions", which are explained in a later section. Name +definitions have the form: + + name definition + + The "name" is a word beginning with a letter or an underscore ('_') +followed by zero or more letters, digits, '_', or '-' (dash). The +definition is taken to begin at the first non-white-space character +following the name and continuing to the end of the line. The +definition can subsequently be referred to using "{name}", which will +expand to "(definition)". For example, + + DIGIT [0-9] + ID [a-z][a-z0-9]* + +defines "DIGIT" to be a regular expression which matches a single +digit, and "ID" to be a regular expression which matches a letter +followed by zero-or-more letters-or-digits. A subsequent reference to + + {DIGIT}+"."{DIGIT}* + +is identical to + + ([0-9])+"."([0-9])* + +and matches one-or-more digits followed by a '.' followed by +zero-or-more digits. + + The RULES section of the `flex' input contains a series of rules of +the form: + + pattern action + +where the pattern must be unindented and the action must begin on the +same line. + + See below for a further description of patterns and actions. + + Finally, the user code section is simply copied to `lex.yy.c' +verbatim. It is used for companion routines which call or are called +by the scanner. The presence of this section is optional; if it is +missing, the second `%%' in the input file may be skipped, too. + + In the definitions and rules sections, any *indented* text or text +enclosed in `%{' and `%}' is copied verbatim to the output (with the +`%{}''s removed). The `%{}''s must appear unindented on lines by +themselves. + + In the rules section, any indented or %{} text appearing before the +first rule may be used to declare variables which are local to the +scanning routine and (after the declarations) code which is to be +executed whenever the scanning routine is entered. Other indented or +%{} text in the rule section is still copied to the output, but its +meaning is not well-defined and it may well cause compile-time errors +(this feature is present for `POSIX' compliance; see below for other +such features). + + In the definitions section (but not in the rules section), an +unindented comment (i.e., a line beginning with "/*") is also copied +verbatim to the output up to the next "*/". + + +File: flex.info, Node: Patterns, Next: Matching, Prev: Format, Up: Top + +Patterns +======== + + The patterns in the input are written using an extended set of +regular expressions. These are: + +`x' + match the character `x' + +`.' + any character (byte) except newline + +`[xyz]' + a "character class"; in this case, the pattern matches either an + `x', a `y', or a `z' + +`[abj-oZ]' + a "character class" with a range in it; matches an `a', a `b', any + letter from `j' through `o', or a `Z' + +`[^A-Z]' + a "negated character class", i.e., any character but those in the + class. In this case, any character EXCEPT an uppercase letter. + +`[^A-Z\n]' + any character EXCEPT an uppercase letter or a newline + +`R*' + zero or more R's, where R is any regular expression + +`R+' + one or more R's + +`R?' + zero or one R's (that is, "an optional R") + +`R{2,5}' + anywhere from two to five R's + +`R{2,}' + two or more R's + +`R{4}' + exactly 4 R's + +`{NAME}' + the expansion of the "NAME" definition (see above) + +`"[xyz]\"foo"' + the literal string: `[xyz]"foo' + +`\X' + if X is an `a', `b', `f', `n', `r', `t', or `v', then the ANSI-C + interpretation of \X. Otherwise, a literal `X' (used to escape + operators such as `*') + +`\0' + a NUL character (ASCII code 0) + +`\123' + the character with octal value 123 + +`\x2a' + the character with hexadecimal value `2a' + +`(R)' + match an R; parentheses are used to override precedence (see below) + +`RS' + the regular expression R followed by the regular expression S; + called "concatenation" + +`R|S' + either an R or an S + +`R/S' + an R but only if it is followed by an S. The text matched by S is + included when determining whether this rule is the "longest + match", but is then returned to the input before the action is + executed. So the action only sees the text matched by R. This + type of pattern is called "trailing context". (There are some + combinations of `R/S' that `flex' cannot match correctly; see + notes in the Deficiencies / Bugs section below regarding + "dangerous trailing context".) + +`^R' + an R, but only at the beginning of a line (i.e., which just + starting to scan, or right after a newline has been scanned). + +`R$' + an R, but only at the end of a line (i.e., just before a newline). + Equivalent to "R/\n". + + Note that flex's notion of "newline" is exactly whatever the C + compiler used to compile flex interprets '\n' as; in particular, + on some DOS systems you must either filter out \r's in the input + yourself, or explicitly use R/\r\n for "r$". + +`R' + an R, but only in start condition S (see below for discussion of + start conditions) R same, but in any of start conditions + S1, S2, or S3 + +`<*>R' + an R in any start condition, even an exclusive one. + +`<>' + an end-of-file <> an end-of-file when in start + condition S1 or S2 + + Note that inside of a character class, all regular expression +operators lose their special meaning except escape ('\') and the +character class operators, '-', ']', and, at the beginning of the +class, '^'. + + The regular expressions listed above are grouped according to +precedence, from highest precedence at the top to lowest at the bottom. +Those grouped together have equal precedence. For example, + + foo|bar* + +is the same as + + (foo)|(ba(r*)) + +since the '*' operator has higher precedence than concatenation, and +concatenation higher than alternation ('|'). This pattern therefore +matches *either* the string "foo" *or* the string "ba" followed by +zero-or-more r's. To match "foo" or zero-or-more "bar"'s, use: + + foo|(bar)* + +and to match zero-or-more "foo"'s-or-"bar"'s: + + (foo|bar)* + + In addition to characters and ranges of characters, character +classes can also contain character class "expressions". These are +expressions enclosed inside `[': and `:'] delimiters (which themselves +must appear between the '[' and ']' of the character class; other +elements may occur inside the character class, too). The valid +expressions are: + + [:alnum:] [:alpha:] [:blank:] + [:cntrl:] [:digit:] [:graph:] + [:lower:] [:print:] [:punct:] + [:space:] [:upper:] [:xdigit:] + + These expressions all designate a set of characters equivalent to +the corresponding standard C `isXXX' function. For example, +`[:alnum:]' designates those characters for which `isalnum()' returns +true - i.e., any alphabetic or numeric. Some systems don't provide +`isblank()', so flex defines `[:blank:]' as a blank or a tab. + + For example, the following character classes are all equivalent: + + [[:alnum:]] + [[:alpha:][:digit:] + [[:alpha:]0-9] + [a-zA-Z0-9] + + If your scanner is case-insensitive (the `-i' flag), then +`[:upper:]' and `[:lower:]' are equivalent to `[:alpha:]'. + + Some notes on patterns: + + - A negated character class such as the example "[^A-Z]" above *will + match a newline* unless "\n" (or an equivalent escape sequence) is + one of the characters explicitly present in the negated character + class (e.g., "[^A-Z\n]"). This is unlike how many other regular + expression tools treat negated character classes, but + unfortunately the inconsistency is historically entrenched. + Matching newlines means that a pattern like [^"]* can match the + entire input unless there's another quote in the input. + + - A rule can have at most one instance of trailing context (the '/' + operator or the '$' operator). The start condition, '^', and + "<>" patterns can only occur at the beginning of a pattern, + and, as well as with '/' and '$', cannot be grouped inside + parentheses. A '^' which does not occur at the beginning of a + rule or a '$' which does not occur at the end of a rule loses its + special properties and is treated as a normal character. + + The following are illegal: + + foo/bar$ + foobar + + Note that the first of these, can be written "foo/bar\n". + + The following will result in '$' or '^' being treated as a normal + character: + + foo|(bar$) + foo|^bar + + If what's wanted is a "foo" or a bar-followed-by-a-newline, the + following could be used (the special '|' action is explained + below): + + foo | + bar$ /* action goes here */ + + A similar trick will work for matching a foo or a + bar-at-the-beginning-of-a-line. + + +File: flex.info, Node: Matching, Next: Actions, Prev: Patterns, Up: Top + +How the input is matched +======================== + + When the generated scanner is run, it analyzes its input looking for +strings which match any of its patterns. If it finds more than one +match, it takes the one matching the most text (for trailing context +rules, this includes the length of the trailing part, even though it +will then be returned to the input). If it finds two or more matches +of the same length, the rule listed first in the `flex' input file is +chosen. + + Once the match is determined, the text corresponding to the match +(called the TOKEN) is made available in the global character pointer +`yytext', and its length in the global integer `yyleng'. The ACTION +corresponding to the matched pattern is then executed (a more detailed +description of actions follows), and then the remaining input is +scanned for another match. + + If no match is found, then the "default rule" is executed: the next +character in the input is considered matched and copied to the standard +output. Thus, the simplest legal `flex' input is: + + %% + + which generates a scanner that simply copies its input (one +character at a time) to its output. + + Note that `yytext' can be defined in two different ways: either as a +character *pointer* or as a character *array*. You can control which +definition `flex' uses by including one of the special directives +`%pointer' or `%array' in the first (definitions) section of your flex +input. The default is `%pointer', unless you use the `-l' lex +compatibility option, in which case `yytext' will be an array. The +advantage of using `%pointer' is substantially faster scanning and no +buffer overflow when matching very large tokens (unless you run out of +dynamic memory). The disadvantage is that you are restricted in how +your actions can modify `yytext' (see the next section), and calls to +the `unput()' function destroys the present contents of `yytext', which +can be a considerable porting headache when moving between different +`lex' versions. + + The advantage of `%array' is that you can then modify `yytext' to +your heart's content, and calls to `unput()' do not destroy `yytext' +(see below). Furthermore, existing `lex' programs sometimes access +`yytext' externally using declarations of the form: + extern char yytext[]; + This definition is erroneous when used with `%pointer', but correct +for `%array'. + + `%array' defines `yytext' to be an array of `YYLMAX' characters, +which defaults to a fairly large value. You can change the size by +simply #define'ing `YYLMAX' to a different value in the first section +of your `flex' input. As mentioned above, with `%pointer' yytext grows +dynamically to accommodate large tokens. While this means your +`%pointer' scanner can accommodate very large tokens (such as matching +entire blocks of comments), bear in mind that each time the scanner +must resize `yytext' it also must rescan the entire token from the +beginning, so matching such tokens can prove slow. `yytext' presently +does *not* dynamically grow if a call to `unput()' results in too much +text being pushed back; instead, a run-time error results. + + Also note that you cannot use `%array' with C++ scanner classes (the +`c++' option; see below). + + +File: flex.info, Node: Actions, Next: Generated scanner, Prev: Matching, Up: Top + +Actions +======= + + Each pattern in a rule has a corresponding action, which can be any +arbitrary C statement. The pattern ends at the first non-escaped +whitespace character; the remainder of the line is its action. If the +action is empty, then when the pattern is matched the input token is +simply discarded. For example, here is the specification for a program +which deletes all occurrences of "zap me" from its input: + + %% + "zap me" + + (It will copy all other characters in the input to the output since +they will be matched by the default rule.) + + Here is a program which compresses multiple blanks and tabs down to +a single blank, and throws away whitespace found at the end of a line: + + %% + [ \t]+ putchar( ' ' ); + [ \t]+$ /* ignore this token */ + + If the action contains a '{', then the action spans till the +balancing '}' is found, and the action may cross multiple lines. +`flex' knows about C strings and comments and won't be fooled by braces +found within them, but also allows actions to begin with `%{' and will +consider the action to be all the text up to the next `%}' (regardless +of ordinary braces inside the action). + + An action consisting solely of a vertical bar ('|') means "same as +the action for the next rule." See below for an illustration. + + Actions can include arbitrary C code, including `return' statements +to return a value to whatever routine called `yylex()'. Each time +`yylex()' is called it continues processing tokens from where it last +left off until it either reaches the end of the file or executes a +return. + + Actions are free to modify `yytext' except for lengthening it +(adding characters to its end-these will overwrite later characters in +the input stream). This however does not apply when using `%array' +(see above); in that case, `yytext' may be freely modified in any way. + + Actions are free to modify `yyleng' except they should not do so if +the action also includes use of `yymore()' (see below). + + There are a number of special directives which can be included +within an action: + + - `ECHO' copies yytext to the scanner's output. + + - `BEGIN' followed by the name of a start condition places the + scanner in the corresponding start condition (see below). + + - `REJECT' directs the scanner to proceed on to the "second best" + rule which matched the input (or a prefix of the input). The rule + is chosen as described above in "How the Input is Matched", and + `yytext' and `yyleng' set up appropriately. It may either be one + which matched as much text as the originally chosen rule but came + later in the `flex' input file, or one which matched less text. + For example, the following will both count the words in the input + and call the routine special() whenever "frob" is seen: + + int word_count = 0; + %% + + frob special(); REJECT; + [^ \t\n]+ ++word_count; + + Without the `REJECT', any "frob"'s in the input would not be + counted as words, since the scanner normally executes only one + action per token. Multiple `REJECT's' are allowed, each one + finding the next best choice to the currently active rule. For + example, when the following scanner scans the token "abcd", it + will write "abcdabcaba" to the output: + + %% + a | + ab | + abc | + abcd ECHO; REJECT; + .|\n /* eat up any unmatched character */ + + (The first three rules share the fourth's action since they use + the special '|' action.) `REJECT' is a particularly expensive + feature in terms of scanner performance; if it is used in *any* of + the scanner's actions it will slow down *all* of the scanner's + matching. Furthermore, `REJECT' cannot be used with the `-Cf' or + `-CF' options (see below). + + Note also that unlike the other special actions, `REJECT' is a + *branch*; code immediately following it in the action will *not* + be executed. + + - `yymore()' tells the scanner that the next time it matches a rule, + the corresponding token should be *appended* onto the current + value of `yytext' rather than replacing it. For example, given + the input "mega-kludge" the following will write + "mega-mega-kludge" to the output: + + %% + mega- ECHO; yymore(); + kludge ECHO; + + First "mega-" is matched and echoed to the output. Then "kludge" + is matched, but the previous "mega-" is still hanging around at + the beginning of `yytext' so the `ECHO' for the "kludge" rule will + actually write "mega-kludge". + + Two notes regarding use of `yymore()'. First, `yymore()' depends on +the value of `yyleng' correctly reflecting the size of the current +token, so you must not modify `yyleng' if you are using `yymore()'. +Second, the presence of `yymore()' in the scanner's action entails a +minor performance penalty in the scanner's matching speed. + + - `yyless(n)' returns all but the first N characters of the current + token back to the input stream, where they will be rescanned when + the scanner looks for the next match. `yytext' and `yyleng' are + adjusted appropriately (e.g., `yyleng' will now be equal to N ). + For example, on the input "foobar" the following will write out + "foobarbar": + + %% + foobar ECHO; yyless(3); + [a-z]+ ECHO; + + An argument of 0 to `yyless' will cause the entire current input + string to be scanned again. Unless you've changed how the scanner + will subsequently process its input (using `BEGIN', for example), + this will result in an endless loop. + + Note that `yyless' is a macro and can only be used in the flex + input file, not from other source files. + + - `unput(c)' puts the character `c' back onto the input stream. It + will be the next character scanned. The following action will + take the current token and cause it to be rescanned enclosed in + parentheses. + + { + int i; + /* Copy yytext because unput() trashes yytext */ + char *yycopy = strdup( yytext ); + unput( ')' ); + for ( i = yyleng - 1; i >= 0; --i ) + unput( yycopy[i] ); + unput( '(' ); + free( yycopy ); + } + + Note that since each `unput()' puts the given character back at + the *beginning* of the input stream, pushing back strings must be + done back-to-front. An important potential problem when using + `unput()' is that if you are using `%pointer' (the default), a + call to `unput()' *destroys* the contents of `yytext', starting + with its rightmost character and devouring one character to the + left with each call. If you need the value of yytext preserved + after a call to `unput()' (as in the above example), you must + either first copy it elsewhere, or build your scanner using + `%array' instead (see How The Input Is Matched). + + Finally, note that you cannot put back `EOF' to attempt to mark + the input stream with an end-of-file. + + - `input()' reads the next character from the input stream. For + example, the following is one way to eat up C comments: + + %% + "/*" { + register int c; + + for ( ; ; ) + { + while ( (c = input()) != '*' && + c != EOF ) + ; /* eat up text of comment */ + + if ( c == '*' ) + { + while ( (c = input()) == '*' ) + ; + if ( c == '/' ) + break; /* found the end */ + } + + if ( c == EOF ) + { + error( "EOF in comment" ); + break; + } + } + } + + (Note that if the scanner is compiled using `C++', then `input()' + is instead referred to as `yyinput()', in order to avoid a name + clash with the `C++' stream by the name of `input'.) + + - YY_FLUSH_BUFFER flushes the scanner's internal buffer so that the + next time the scanner attempts to match a token, it will first + refill the buffer using `YY_INPUT' (see The Generated Scanner, + below). This action is a special case of the more general + `yy_flush_buffer()' function, described below in the section + Multiple Input Buffers. + + - `yyterminate()' can be used in lieu of a return statement in an + action. It terminates the scanner and returns a 0 to the + scanner's caller, indicating "all done". By default, + `yyterminate()' is also called when an end-of-file is encountered. + It is a macro and may be redefined. + + +File: flex.info, Node: Generated scanner, Next: Start conditions, Prev: Actions, Up: Top + +The generated scanner +===================== + + The output of `flex' is the file `lex.yy.c', which contains the +scanning routine `yylex()', a number of tables used by it for matching +tokens, and a number of auxiliary routines and macros. By default, +`yylex()' is declared as follows: + + int yylex() + { + ... various definitions and the actions in here ... + } + + (If your environment supports function prototypes, then it will be +"int yylex( void )".) This definition may be changed by defining +the "YY_DECL" macro. For example, you could use: + + #define YY_DECL float lexscan( a, b ) float a, b; + + to give the scanning routine the name `lexscan', returning a float, +and taking two floats as arguments. Note that if you give arguments to +the scanning routine using a K&R-style/non-prototyped function +declaration, you must terminate the definition with a semi-colon (`;'). + + Whenever `yylex()' is called, it scans tokens from the global input +file `yyin' (which defaults to stdin). It continues until it either +reaches an end-of-file (at which point it returns the value 0) or one +of its actions executes a `return' statement. + + If the scanner reaches an end-of-file, subsequent calls are undefined +unless either `yyin' is pointed at a new input file (in which case +scanning continues from that file), or `yyrestart()' is called. +`yyrestart()' takes one argument, a `FILE *' pointer (which can be nil, +if you've set up `YY_INPUT' to scan from a source other than `yyin'), +and initializes `yyin' for scanning from that file. Essentially there +is no difference between just assigning `yyin' to a new input file or +using `yyrestart()' to do so; the latter is available for compatibility +with previous versions of `flex', and because it can be used to switch +input files in the middle of scanning. It can also be used to throw +away the current input buffer, by calling it with an argument of +`yyin'; but better is to use `YY_FLUSH_BUFFER' (see above). Note that +`yyrestart()' does *not* reset the start condition to `INITIAL' (see +Start Conditions, below). + + If `yylex()' stops scanning due to executing a `return' statement in +one of the actions, the scanner may then be called again and it will +resume scanning where it left off. + + By default (and for purposes of efficiency), the scanner uses +block-reads rather than simple `getc()' calls to read characters from +`yyin'. The nature of how it gets its input can be controlled by +defining the `YY_INPUT' macro. YY_INPUT's calling sequence is +"YY_INPUT(buf,result,max_size)". Its action is to place up to MAX_SIZE +characters in the character array BUF and return in the integer +variable RESULT either the number of characters read or the constant +YY_NULL (0 on Unix systems) to indicate EOF. The default YY_INPUT +reads from the global file-pointer "yyin". + + A sample definition of YY_INPUT (in the definitions section of the +input file): + + %{ + #define YY_INPUT(buf,result,max_size) \ + { \ + int c = getchar(); \ + result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ + } + %} + + This definition will change the input processing to occur one +character at a time. + + When the scanner receives an end-of-file indication from YY_INPUT, +it then checks the `yywrap()' function. If `yywrap()' returns false +(zero), then it is assumed that the function has gone ahead and set up +`yyin' to point to another input file, and scanning continues. If it +returns true (non-zero), then the scanner terminates, returning 0 to +its caller. Note that in either case, the start condition remains +unchanged; it does *not* revert to `INITIAL'. + + If you do not supply your own version of `yywrap()', then you must +either use `%option noyywrap' (in which case the scanner behaves as +though `yywrap()' returned 1), or you must link with `-lfl' to obtain +the default version of the routine, which always returns 1. + + Three routines are available for scanning from in-memory buffers +rather than files: `yy_scan_string()', `yy_scan_bytes()', and +`yy_scan_buffer()'. See the discussion of them below in the section +Multiple Input Buffers. + + The scanner writes its `ECHO' output to the `yyout' global (default, +stdout), which may be redefined by the user simply by assigning it to +some other `FILE' pointer. + + +File: flex.info, Node: Start conditions, Next: Multiple buffers, Prev: Generated scanner, Up: Top + +Start conditions +================ + + `flex' provides a mechanism for conditionally activating rules. Any +rule whose pattern is prefixed with "" will only be active when the +scanner is in the start condition named "sc". For example, + + [^"]* { /* eat up the string body ... */ + ... + } + +will be active only when the scanner is in the "STRING" start +condition, and + + \. { /* handle an escape ... */ + ... + } + +will be active only when the current start condition is either +"INITIAL", "STRING", or "QUOTE". + + Start conditions are declared in the definitions (first) section of +the input using unindented lines beginning with either `%s' or `%x' +followed by a list of names. The former declares *inclusive* start +conditions, the latter *exclusive* start conditions. A start condition +is activated using the `BEGIN' action. Until the next `BEGIN' action is +executed, rules with the given start condition will be active and rules +with other start conditions will be inactive. If the start condition +is *inclusive*, then rules with no start conditions at all will also be +active. If it is *exclusive*, then *only* rules qualified with the +start condition will be active. A set of rules contingent on the same +exclusive start condition describe a scanner which is independent of +any of the other rules in the `flex' input. Because of this, exclusive +start conditions make it easy to specify "mini-scanners" which scan +portions of the input that are syntactically different from the rest +(e.g., comments). + + If the distinction between inclusive and exclusive start conditions +is still a little vague, here's a simple example illustrating the +connection between the two. The set of rules: + + %s example + %% + + foo do_something(); + + bar something_else(); + +is equivalent to + + %x example + %% + + foo do_something(); + + bar something_else(); + + Without the `' qualifier, the `bar' pattern in the +second example wouldn't be active (i.e., couldn't match) when in start +condition `example'. If we just used `' to qualify `bar', +though, then it would only be active in `example' and not in `INITIAL', +while in the first example it's active in both, because in the first +example the `example' starting condition is an *inclusive* (`%s') start +condition. + + Also note that the special start-condition specifier `<*>' matches +every start condition. Thus, the above example could also have been +written; + + %x example + %% + + foo do_something(); + + <*>bar something_else(); + + The default rule (to `ECHO' any unmatched character) remains active +in start conditions. It is equivalent to: + + <*>.|\\n ECHO; + + `BEGIN(0)' returns to the original state where only the rules with +no start conditions are active. This state can also be referred to as +the start-condition "INITIAL", so `BEGIN(INITIAL)' is equivalent to +`BEGIN(0)'. (The parentheses around the start condition name are not +required but are considered good style.) + + `BEGIN' actions can also be given as indented code at the beginning +of the rules section. For example, the following will cause the +scanner to enter the "SPECIAL" start condition whenever `yylex()' is +called and the global variable `enter_special' is true: + + int enter_special; + + %x SPECIAL + %% + if ( enter_special ) + BEGIN(SPECIAL); + + blahblahblah + ...more rules follow... + + To illustrate the uses of start conditions, here is a scanner which +provides two different interpretations of a string like "123.456". By +default it will treat it as as three tokens, the integer "123", a dot +('.'), and the integer "456". But if the string is preceded earlier in +the line by the string "expect-floats" it will treat it as a single +token, the floating-point number 123.456: + + %{ + #include + %} + %s expect + + %% + expect-floats BEGIN(expect); + + [0-9]+"."[0-9]+ { + printf( "found a float, = %f\n", + atof( yytext ) ); + } + \n { + /* that's the end of the line, so + * we need another "expect-number" + * before we'll recognize any more + * numbers + */ + BEGIN(INITIAL); + } + + [0-9]+ { + + Version 2.5 December 1994 18 + + printf( "found an integer, = %d\n", + atoi( yytext ) ); + } + + "." printf( "found a dot\n" ); + + Here is a scanner which recognizes (and discards) C comments while +maintaining a count of the current input line. + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* /* eat anything that's not a '*' */ + "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ + \n ++line_num; + "*"+"/" BEGIN(INITIAL); + + This scanner goes to a bit of trouble to match as much text as +possible with each rule. In general, when attempting to write a +high-speed scanner try to match as much possible in each rule, as it's +a big win. + + Note that start-conditions names are really integer values and can +be stored as such. Thus, the above could be extended in the following +fashion: + + %x comment foo + %% + int line_num = 1; + int comment_caller; + + "/*" { + comment_caller = INITIAL; + BEGIN(comment); + } + + ... + + "/*" { + comment_caller = foo; + BEGIN(comment); + } + + [^*\n]* /* eat anything that's not a '*' */ + "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ + \n ++line_num; + "*"+"/" BEGIN(comment_caller); + + Furthermore, you can access the current start condition using the +integer-valued `YY_START' macro. For example, the above assignments to +`comment_caller' could instead be written + + comment_caller = YY_START; + + Flex provides `YYSTATE' as an alias for `YY_START' (since that is +what's used by AT&T `lex'). + + Note that start conditions do not have their own name-space; %s's +and %x's declare names in the same fashion as #define's. + + Finally, here's an example of how to match C-style quoted strings +using exclusive start conditions, including expanded escape sequences +(but not including checking for a string that's too long): + + %x str + + %% + char string_buf[MAX_STR_CONST]; + char *string_buf_ptr; + + \" string_buf_ptr = string_buf; BEGIN(str); + + \" { /* saw closing quote - all done */ + BEGIN(INITIAL); + *string_buf_ptr = '\0'; + /* return string constant token type and + * value to parser + */ + } + + \n { + /* error - unterminated string constant */ + /* generate error message */ + } + + \\[0-7]{1,3} { + /* octal escape sequence */ + int result; + + (void) sscanf( yytext + 1, "%o", &result ); + + if ( result > 0xff ) + /* error, constant is out-of-bounds */ + + *string_buf_ptr++ = result; + } + + \\[0-9]+ { + /* generate error - bad escape sequence; something + * like '\48' or '\0777777' + */ + } + + \\n *string_buf_ptr++ = '\n'; + \\t *string_buf_ptr++ = '\t'; + \\r *string_buf_ptr++ = '\r'; + \\b *string_buf_ptr++ = '\b'; + \\f *string_buf_ptr++ = '\f'; + + \\(.|\n) *string_buf_ptr++ = yytext[1]; + + [^\\\n\"]+ { + char *yptr = yytext; + + while ( *yptr ) + *string_buf_ptr++ = *yptr++; + } + + Often, such as in some of the examples above, you wind up writing a +whole bunch of rules all preceded by the same start condition(s). Flex +makes this a little easier and cleaner by introducing a notion of start +condition "scope". A start condition scope is begun with: + + { + +where SCs is a list of one or more start conditions. Inside the start +condition scope, every rule automatically has the prefix `' +applied to it, until a `}' which matches the initial `{'. So, for +example, + + { + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + } + +is equivalent to: + + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + + Start condition scopes may be nested. + + Three routines are available for manipulating stacks of start +conditions: + +`void yy_push_state(int new_state)' + pushes the current start condition onto the top of the start + condition stack and switches to NEW_STATE as though you had used + `BEGIN new_state' (recall that start condition names are also + integers). + +`void yy_pop_state()' + pops the top of the stack and switches to it via `BEGIN'. + +`int yy_top_state()' + returns the top of the stack without altering the stack's contents. + + The start condition stack grows dynamically and so has no built-in +size limitation. If memory is exhausted, program execution aborts. + + To use start condition stacks, your scanner must include a `%option +stack' directive (see Options below). + + +File: flex.info, Node: Multiple buffers, Next: End-of-file rules, Prev: Start conditions, Up: Top + +Multiple input buffers +====================== + + Some scanners (such as those which support "include" files) require +reading from several input streams. As `flex' scanners do a large +amount of buffering, one cannot control where the next input will be +read from by simply writing a `YY_INPUT' which is sensitive to the +scanning context. `YY_INPUT' is only called when the scanner reaches +the end of its buffer, which may be a long time after scanning a +statement such as an "include" which requires switching the input +source. + + To negotiate these sorts of problems, `flex' provides a mechanism +for creating and switching between multiple input buffers. An input +buffer is created by using: + + YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) + +which takes a `FILE' pointer and a size and creates a buffer associated +with the given file and large enough to hold SIZE characters (when in +doubt, use `YY_BUF_SIZE' for the size). It returns a `YY_BUFFER_STATE' +handle, which may then be passed to other routines (see below). The +`YY_BUFFER_STATE' type is a pointer to an opaque `struct' +`yy_buffer_state' structure, so you may safely initialize +YY_BUFFER_STATE variables to `((YY_BUFFER_STATE) 0)' if you wish, and +also refer to the opaque structure in order to correctly declare input +buffers in source files other than that of your scanner. Note that the +`FILE' pointer in the call to `yy_create_buffer' is only used as the +value of `yyin' seen by `YY_INPUT'; if you redefine `YY_INPUT' so it no +longer uses `yyin', then you can safely pass a nil `FILE' pointer to +`yy_create_buffer'. You select a particular buffer to scan from using: + + void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) + + switches the scanner's input buffer so subsequent tokens will come +from NEW_BUFFER. Note that `yy_switch_to_buffer()' may be used by +`yywrap()' to set things up for continued scanning, instead of opening +a new file and pointing `yyin' at it. Note also that switching input +sources via either `yy_switch_to_buffer()' or `yywrap()' does *not* +change the start condition. + + void yy_delete_buffer( YY_BUFFER_STATE buffer ) + +is used to reclaim the storage associated with a buffer. You can also +clear the current contents of a buffer using: + + void yy_flush_buffer( YY_BUFFER_STATE buffer ) + + This function discards the buffer's contents, so the next time the +scanner attempts to match a token from the buffer, it will first fill +the buffer anew using `YY_INPUT'. + + `yy_new_buffer()' is an alias for `yy_create_buffer()', provided for +compatibility with the C++ use of `new' and `delete' for creating and +destroying dynamic objects. + + Finally, the `YY_CURRENT_BUFFER' macro returns a `YY_BUFFER_STATE' +handle to the current buffer. + + Here is an example of using these features for writing a scanner +which expands include files (the `<>' feature is discussed below): + + /* the "incl" state is used for picking up the name + * of an include file + */ + %x incl + + %{ + #define MAX_INCLUDE_DEPTH 10 + YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; + int include_stack_ptr = 0; + %} + + %% + include BEGIN(incl); + + [a-z]+ ECHO; + [^a-z\n]*\n? ECHO; + + [ \t]* /* eat the whitespace */ + [^ \t\n]+ { /* got the include file name */ + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) + { + fprintf( stderr, "Includes nested too deeply" ); + exit( 1 ); + } + + include_stack[include_stack_ptr++] = + YY_CURRENT_BUFFER; + + yyin = fopen( yytext, "r" ); + + if ( ! yyin ) + error( ... ); + + yy_switch_to_buffer( + yy_create_buffer( yyin, YY_BUF_SIZE ) ); + + BEGIN(INITIAL); + } + + <> { + if ( --include_stack_ptr < 0 ) + { + yyterminate(); + } + + else + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( + include_stack[include_stack_ptr] ); + } + } + + Three routines are available for setting up input buffers for +scanning in-memory strings instead of files. All of them create a new +input buffer for scanning the string, and return a corresponding +`YY_BUFFER_STATE' handle (which you should delete with +`yy_delete_buffer()' when done with it). They also switch to the new +buffer using `yy_switch_to_buffer()', so the next call to `yylex()' will +start scanning the string. + +`yy_scan_string(const char *str)' + scans a NUL-terminated string. + +`yy_scan_bytes(const char *bytes, int len)' + scans `len' bytes (including possibly NUL's) starting at location + BYTES. + + Note that both of these functions create and scan a *copy* of the +string or bytes. (This may be desirable, since `yylex()' modifies the +contents of the buffer it is scanning.) You can avoid the copy by using: + +`yy_scan_buffer(char *base, yy_size_t size)' + which scans in place the buffer starting at BASE, consisting of + SIZE bytes, the last two bytes of which *must* be + `YY_END_OF_BUFFER_CHAR' (ASCII NUL). These last two bytes are not + scanned; thus, scanning consists of `base[0]' through + `base[size-2]', inclusive. + + If you fail to set up BASE in this manner (i.e., forget the final + two `YY_END_OF_BUFFER_CHAR' bytes), then `yy_scan_buffer()' + returns a nil pointer instead of creating a new input buffer. + + The type `yy_size_t' is an integral type to which you can cast an + integer expression reflecting the size of the buffer. + + +File: flex.info, Node: End-of-file rules, Next: Miscellaneous, Prev: Multiple buffers, Up: Top + +End-of-file rules +================= + + The special rule "<>" indicates actions which are to be taken +when an end-of-file is encountered and yywrap() returns non-zero (i.e., +indicates no further files to process). The action must finish by +doing one of four things: + + - assigning `yyin' to a new input file (in previous versions of + flex, after doing the assignment you had to call the special + action `YY_NEW_FILE'; this is no longer necessary); + + - executing a `return' statement; + + - executing the special `yyterminate()' action; + + - or, switching to a new buffer using `yy_switch_to_buffer()' as + shown in the example above. + + <> rules may not be used with other patterns; they may only be +qualified with a list of start conditions. If an unqualified <> +rule is given, it applies to *all* start conditions which do not +already have <> actions. To specify an <> rule for only the +initial start condition, use + + <> + + These rules are useful for catching things like unclosed comments. +An example: + + %x quote + %% + + ...other rules for dealing with quotes... + + <> { + error( "unterminated quote" ); + yyterminate(); + } + <> { + if ( *++filelist ) + yyin = fopen( *filelist, "r" ); + else + yyterminate(); + } + + +File: flex.info, Node: Miscellaneous, Next: User variables, Prev: End-of-file rules, Up: Top + +Miscellaneous macros +==================== + + The macro `YY_USER_ACTION' can be defined to provide an action which +is always executed prior to the matched rule's action. For example, it +could be #define'd to call a routine to convert yytext to lower-case. +When `YY_USER_ACTION' is invoked, the variable `yy_act' gives the +number of the matched rule (rules are numbered starting with 1). +Suppose you want to profile how often each of your rules is matched. +The following would do the trick: + + #define YY_USER_ACTION ++ctr[yy_act] + + where `ctr' is an array to hold the counts for the different rules. +Note that the macro `YY_NUM_RULES' gives the total number of rules +(including the default rule, even if you use `-s', so a correct +declaration for `ctr' is: + + int ctr[YY_NUM_RULES]; + + The macro `YY_USER_INIT' may be defined to provide an action which +is always executed before the first scan (and before the scanner's +internal initializations are done). For example, it could be used to +call a routine to read in a data table or open a logging file. + + The macro `yy_set_interactive(is_interactive)' can be used to +control whether the current buffer is considered *interactive*. An +interactive buffer is processed more slowly, but must be used when the +scanner's input source is indeed interactive to avoid problems due to +waiting to fill buffers (see the discussion of the `-I' flag below). A +non-zero value in the macro invocation marks the buffer as interactive, +a zero value as non-interactive. Note that use of this macro overrides +`%option always-interactive' or `%option never-interactive' (see +Options below). `yy_set_interactive()' must be invoked prior to +beginning to scan the buffer that is (or is not) to be considered +interactive. + + The macro `yy_set_bol(at_bol)' can be used to control whether the +current buffer's scanning context for the next token match is done as +though at the beginning of a line. A non-zero macro argument makes +rules anchored with + + The macro `YY_AT_BOL()' returns true if the next token scanned from +the current buffer will have '^' rules active, false otherwise. + + In the generated scanner, the actions are all gathered in one large +switch statement and separated using `YY_BREAK', which may be +redefined. By default, it is simply a "break", to separate each rule's +action from the following rule's. Redefining `YY_BREAK' allows, for +example, C++ users to #define YY_BREAK to do nothing (while being very +careful that every rule ends with a "break" or a "return"!) to avoid +suffering from unreachable statement warnings where because a rule's +action ends with "return", the `YY_BREAK' is inaccessible. + + +File: flex.info, Node: User variables, Next: YACC interface, Prev: Miscellaneous, Up: Top + +Values available to the user +============================ + + This section summarizes the various values available to the user in +the rule actions. + + - `char *yytext' holds the text of the current token. It may be + modified but not lengthened (you cannot append characters to the + end). + + If the special directive `%array' appears in the first section of + the scanner description, then `yytext' is instead declared `char + yytext[YYLMAX]', where `YYLMAX' is a macro definition that you can + redefine in the first section if you don't like the default value + (generally 8KB). Using `%array' results in somewhat slower + scanners, but the value of `yytext' becomes immune to calls to + `input()' and `unput()', which potentially destroy its value when + `yytext' is a character pointer. The opposite of `%array' is + `%pointer', which is the default. + + You cannot use `%array' when generating C++ scanner classes (the + `-+' flag). + + - `int yyleng' holds the length of the current token. + + - `FILE *yyin' is the file which by default `flex' reads from. It + may be redefined but doing so only makes sense before scanning + begins or after an EOF has been encountered. Changing it in the + midst of scanning will have unexpected results since `flex' + buffers its input; use `yyrestart()' instead. Once scanning + terminates because an end-of-file has been seen, you can assign + `yyin' at the new input file and then call the scanner again to + continue scanning. + + - `void yyrestart( FILE *new_file )' may be called to point `yyin' + at the new input file. The switch-over to the new file is + immediate (any previously buffered-up input is lost). Note that + calling `yyrestart()' with `yyin' as an argument thus throws away + the current input buffer and continues scanning the same input + file. + + - `FILE *yyout' is the file to which `ECHO' actions are done. It + can be reassigned by the user. + + - `YY_CURRENT_BUFFER' returns a `YY_BUFFER_STATE' handle to the + current buffer. + + - `YY_START' returns an integer value corresponding to the current + start condition. You can subsequently use this value with `BEGIN' + to return to that start condition. + + +File: flex.info, Node: YACC interface, Next: Options, Prev: User variables, Up: Top + +Interfacing with `yacc' +======================= + + One of the main uses of `flex' is as a companion to the `yacc' +parser-generator. `yacc' parsers expect to call a routine named +`yylex()' to find the next input token. The routine is supposed to +return the type of the next token as well as putting any associated +value in the global `yylval'. To use `flex' with `yacc', one specifies +the `-d' option to `yacc' to instruct it to generate the file `y.tab.h' +containing definitions of all the `%tokens' appearing in the `yacc' +input. This file is then included in the `flex' scanner. For example, +if one of the tokens is "TOK_NUMBER", part of the scanner might look +like: + + %{ + #include "y.tab.h" + %} + + %% + + [0-9]+ yylval = atoi( yytext ); return TOK_NUMBER; + + +File: flex.info, Node: Options, Next: Performance, Prev: YACC interface, Up: Top + +Options +======= + + `flex' has the following options: + +`-b' + Generate backing-up information to `lex.backup'. This is a list + of scanner states which require backing up and the input + characters on which they do so. By adding rules one can remove + backing-up states. If *all* backing-up states are eliminated and + `-Cf' or `-CF' is used, the generated scanner will run faster (see + the `-p' flag). Only users who wish to squeeze every last cycle + out of their scanners need worry about this option. (See the + section on Performance Considerations below.) + +`-c' + is a do-nothing, deprecated option included for POSIX compliance. + +`-d' + makes the generated scanner run in "debug" mode. Whenever a + pattern is recognized and the global `yy_flex_debug' is non-zero + (which is the default), the scanner will write to `stderr' a line + of the form: + + --accepting rule at line 53 ("the matched text") + + The line number refers to the location of the rule in the file + defining the scanner (i.e., the file that was fed to flex). + Messages are also generated when the scanner backs up, accepts the + default rule, reaches the end of its input buffer (or encounters a + NUL; at this point, the two look the same as far as the scanner's + concerned), or reaches an end-of-file. + +`-f' + specifies "fast scanner". No table compression is done and stdio + is bypassed. The result is large but fast. This option is + equivalent to `-Cfr' (see below). + +`-h' + generates a "help" summary of `flex's' options to `stdout' and + then exits. `-?' and `--help' are synonyms for `-h'. + +`-i' + instructs `flex' to generate a *case-insensitive* scanner. The + case of letters given in the `flex' input patterns will be + ignored, and tokens in the input will be matched regardless of + case. The matched text given in `yytext' will have the preserved + case (i.e., it will not be folded). + +`-l' + turns on maximum compatibility with the original AT&T `lex' + implementation. Note that this does not mean *full* + compatibility. Use of this option costs a considerable amount of + performance, and it cannot be used with the `-+, -f, -F, -Cf', or + `-CF' options. For details on the compatibilities it provides, see + the section "Incompatibilities With Lex And POSIX" below. This + option also results in the name `YY_FLEX_LEX_COMPAT' being + #define'd in the generated scanner. + +`-n' + is another do-nothing, deprecated option included only for POSIX + compliance. + +`-p' + generates a performance report to stderr. The report consists of + comments regarding features of the `flex' input file which will + cause a serious loss of performance in the resulting scanner. If + you give the flag twice, you will also get comments regarding + features that lead to minor performance losses. + + Note that the use of `REJECT', `%option yylineno' and variable + trailing context (see the Deficiencies / Bugs section below) + entails a substantial performance penalty; use of `yymore()', the + `^' operator, and the `-I' flag entail minor performance penalties. + +`-s' + causes the "default rule" (that unmatched scanner input is echoed + to `stdout') to be suppressed. If the scanner encounters input + that does not match any of its rules, it aborts with an error. + This option is useful for finding holes in a scanner's rule set. + +`-t' + instructs `flex' to write the scanner it generates to standard + output instead of `lex.yy.c'. + +`-v' + specifies that `flex' should write to `stderr' a summary of + statistics regarding the scanner it generates. Most of the + statistics are meaningless to the casual `flex' user, but the + first line identifies the version of `flex' (same as reported by + `-V'), and the next line the flags used when generating the + scanner, including those that are on by default. + +`-w' + suppresses warning messages. + +`-B' + instructs `flex' to generate a *batch* scanner, the opposite of + *interactive* scanners generated by `-I' (see below). In general, + you use `-B' when you are *certain* that your scanner will never + be used interactively, and you want to squeeze a *little* more + performance out of it. If your goal is instead to squeeze out a + *lot* more performance, you should be using the `-Cf' or `-CF' + options (discussed below), which turn on `-B' automatically anyway. + +`-F' + specifies that the "fast" scanner table representation should be + used (and stdio bypassed). This representation is about as fast + as the full table representation `(-f)', and for some sets of + patterns will be considerably smaller (and for others, larger). + In general, if the pattern set contains both "keywords" and a + catch-all, "identifier" rule, such as in the set: + + "case" return TOK_CASE; + "switch" return TOK_SWITCH; + ... + "default" return TOK_DEFAULT; + [a-z]+ return TOK_ID; + + then you're better off using the full table representation. If + only the "identifier" rule is present and you then use a hash + table or some such to detect the keywords, you're better off using + `-F'. + + This option is equivalent to `-CFr' (see below). It cannot be + used with `-+'. + +`-I' + instructs `flex' to generate an *interactive* scanner. An + interactive scanner is one that only looks ahead to decide what + token has been matched if it absolutely must. It turns out that + always looking one extra character ahead, even if the scanner has + already seen enough text to disambiguate the current token, is a + bit faster than only looking ahead when necessary. But scanners + that always look ahead give dreadful interactive performance; for + example, when a user types a newline, it is not recognized as a + newline token until they enter *another* token, which often means + typing in another whole line. + + `Flex' scanners default to *interactive* unless you use the `-Cf' + or `-CF' table-compression options (see below). That's because if + you're looking for high-performance you should be using one of + these options, so if you didn't, `flex' assumes you'd rather trade + off a bit of run-time performance for intuitive interactive + behavior. Note also that you *cannot* use `-I' in conjunction + with `-Cf' or `-CF'. Thus, this option is not really needed; it + is on by default for all those cases in which it is allowed. + + You can force a scanner to *not* be interactive by using `-B' (see + above). + +`-L' + instructs `flex' not to generate `#line' directives. Without this + option, `flex' peppers the generated scanner with #line directives + so error messages in the actions will be correctly located with + respect to either the original `flex' input file (if the errors + are due to code in the input file), or `lex.yy.c' (if the errors + are `flex's' fault - you should report these sorts of errors to + the email address given below). + +`-T' + makes `flex' run in `trace' mode. It will generate a lot of + messages to `stderr' concerning the form of the input and the + resultant non-deterministic and deterministic finite automata. + This option is mostly for use in maintaining `flex'. + +`-V' + prints the version number to `stdout' and exits. `--version' is a + synonym for `-V'. + +`-7' + instructs `flex' to generate a 7-bit scanner, i.e., one which can + only recognized 7-bit characters in its input. The advantage of + using `-7' is that the scanner's tables can be up to half the size + of those generated using the `-8' option (see below). The + disadvantage is that such scanners often hang or crash if their + input contains an 8-bit character. + + Note, however, that unless you generate your scanner using the + `-Cf' or `-CF' table compression options, use of `-7' will save + only a small amount of table space, and make your scanner + considerably less portable. `Flex's' default behavior is to + generate an 8-bit scanner unless you use the `-Cf' or `-CF', in + which case `flex' defaults to generating 7-bit scanners unless + your site was always configured to generate 8-bit scanners (as + will often be the case with non-USA sites). You can tell whether + flex generated a 7-bit or an 8-bit scanner by inspecting the flag + summary in the `-v' output as described above. + + Note that if you use `-Cfe' or `-CFe' (those table compression + options, but also using equivalence classes as discussed see + below), flex still defaults to generating an 8-bit scanner, since + usually with these compression options full 8-bit tables are not + much more expensive than 7-bit tables. + +`-8' + instructs `flex' to generate an 8-bit scanner, i.e., one which can + recognize 8-bit characters. This flag is only needed for scanners + generated using `-Cf' or `-CF', as otherwise flex defaults to + generating an 8-bit scanner anyway. + + See the discussion of `-7' above for flex's default behavior and + the tradeoffs between 7-bit and 8-bit scanners. + +`-+' + specifies that you want flex to generate a C++ scanner class. See + the section on Generating C++ Scanners below for details. + +`-C[aefFmr]' + controls the degree of table compression and, more generally, + trade-offs between small scanners and fast scanners. + + `-Ca' ("align") instructs flex to trade off larger tables in the + generated scanner for faster performance because the elements of + the tables are better aligned for memory access and computation. + On some RISC architectures, fetching and manipulating long-words + is more efficient than with smaller-sized units such as + shortwords. This option can double the size of the tables used by + your scanner. + + `-Ce' directs `flex' to construct "equivalence classes", i.e., + sets of characters which have identical lexical properties (for + example, if the only appearance of digits in the `flex' input is + in the character class "[0-9]" then the digits '0', '1', ..., '9' + will all be put in the same equivalence class). Equivalence + classes usually give dramatic reductions in the final table/object + file sizes (typically a factor of 2-5) and are pretty cheap + performance-wise (one array look-up per character scanned). + + `-Cf' specifies that the *full* scanner tables should be generated + - `flex' should not compress the tables by taking advantages of + similar transition functions for different states. + + `-CF' specifies that the alternate fast scanner representation + (described above under the `-F' flag) should be used. This option + cannot be used with `-+'. + + `-Cm' directs `flex' to construct "meta-equivalence classes", + which are sets of equivalence classes (or characters, if + equivalence classes are not being used) that are commonly used + together. Meta-equivalence classes are often a big win when using + compressed tables, but they have a moderate performance impact + (one or two "if" tests and one array look-up per character + scanned). + + `-Cr' causes the generated scanner to *bypass* use of the standard + I/O library (stdio) for input. Instead of calling `fread()' or + `getc()', the scanner will use the `read()' system call, resulting + in a performance gain which varies from system to system, but in + general is probably negligible unless you are also using `-Cf' or + `-CF'. Using `-Cr' can cause strange behavior if, for example, + you read from `yyin' using stdio prior to calling the scanner + (because the scanner will miss whatever text your previous reads + left in the stdio input buffer). + + `-Cr' has no effect if you define `YY_INPUT' (see The Generated + Scanner above). + + A lone `-C' specifies that the scanner tables should be compressed + but neither equivalence classes nor meta-equivalence classes + should be used. + + The options `-Cf' or `-CF' and `-Cm' do not make sense together - + there is no opportunity for meta-equivalence classes if the table + is not being compressed. Otherwise the options may be freely + mixed, and are cumulative. + + The default setting is `-Cem', which specifies that `flex' should + generate equivalence classes and meta-equivalence classes. This + setting provides the highest degree of table compression. You can + trade off faster-executing scanners at the cost of larger tables + with the following generally being true: + + slowest & smallest + -Cem + -Cm + -Ce + -C + -C{f,F}e + -C{f,F} + -C{f,F}a + fastest & largest + + Note that scanners with the smallest tables are usually generated + and compiled the quickest, so during development you will usually + want to use the default, maximal compression. + + `-Cfe' is often a good compromise between speed and size for + production scanners. + +`-ooutput' + directs flex to write the scanner to the file `out-' `put' instead + of `lex.yy.c'. If you combine `-o' with the `-t' option, then the + scanner is written to `stdout' but its `#line' directives (see the + `-L' option above) refer to the file `output'. + +`-Pprefix' + changes the default `yy' prefix used by `flex' for all + globally-visible variable and function names to instead be PREFIX. + For example, `-Pfoo' changes the name of `yytext' to `footext'. + It also changes the name of the default output file from + `lex.yy.c' to `lex.foo.c'. Here are all of the names affected: + + yy_create_buffer + yy_delete_buffer + yy_flex_debug + yy_init_buffer + yy_flush_buffer + yy_load_buffer_state + yy_switch_to_buffer + yyin + yyleng + yylex + yylineno + yyout + yyrestart + yytext + yywrap + + (If you are using a C++ scanner, then only `yywrap' and + `yyFlexLexer' are affected.) Within your scanner itself, you can + still refer to the global variables and functions using either + version of their name; but externally, they have the modified name. + + This option lets you easily link together multiple `flex' programs + into the same executable. Note, though, that using this option + also renames `yywrap()', so you now *must* either provide your own + (appropriately-named) version of the routine for your scanner, or + use `%option noyywrap', as linking with `-lfl' no longer provides + one for you by default. + +`-Sskeleton_file' + overrides the default skeleton file from which `flex' constructs + its scanners. You'll never need this option unless you are doing + `flex' maintenance or development. + + `flex' also provides a mechanism for controlling options within the +scanner specification itself, rather than from the flex command-line. +This is done by including `%option' directives in the first section of +the scanner specification. You can specify multiple options with a +single `%option' directive, and multiple directives in the first +section of your flex input file. Most options are given simply as +names, optionally preceded by the word "no" (with no intervening +whitespace) to negate their meaning. A number are equivalent to flex +flags or their negation: + + 7bit -7 option + 8bit -8 option + align -Ca option + backup -b option + batch -B option + c++ -+ option + + caseful or + case-sensitive opposite of -i (default) + + case-insensitive or + caseless -i option + + debug -d option + default opposite of -s option + ecs -Ce option + fast -F option + full -f option + interactive -I option + lex-compat -l option + meta-ecs -Cm option + perf-report -p option + read -Cr option + stdout -t option + verbose -v option + warn opposite of -w option + (use "%option nowarn" for -w) + + array equivalent to "%array" + pointer equivalent to "%pointer" (default) + + Some `%option's' provide features otherwise not available: + +`always-interactive' + instructs flex to generate a scanner which always considers its + input "interactive". Normally, on each new input file the scanner + calls `isatty()' in an attempt to determine whether the scanner's + input source is interactive and thus should be read a character at + a time. When this option is used, however, then no such call is + made. + +`main' + directs flex to provide a default `main()' program for the + scanner, which simply calls `yylex()'. This option implies + `noyywrap' (see below). + +`never-interactive' + instructs flex to generate a scanner which never considers its + input "interactive" (again, no call made to `isatty())'. This is + the opposite of `always-' *interactive*. + +`stack' + enables the use of start condition stacks (see Start Conditions + above). + +`stdinit' + if unset (i.e., `%option nostdinit') initializes `yyin' and + `yyout' to nil `FILE' pointers, instead of `stdin' and `stdout'. + +`yylineno' + directs `flex' to generate a scanner that maintains the number of + the current line read from its input in the global variable + `yylineno'. This option is implied by `%option lex-compat'. + +`yywrap' + if unset (i.e., `%option noyywrap'), makes the scanner not call + `yywrap()' upon an end-of-file, but simply assume that there are + no more files to scan (until the user points `yyin' at a new file + and calls `yylex()' again). + + `flex' scans your rule actions to determine whether you use the +`REJECT' or `yymore()' features. The `reject' and `yymore' options are +available to override its decision as to whether you use the options, +either by setting them (e.g., `%option reject') to indicate the feature +is indeed used, or unsetting them to indicate it actually is not used +(e.g., `%option noyymore'). + + Three options take string-delimited values, offset with '=': + + %option outfile="ABC" + +is equivalent to `-oABC', and + + %option prefix="XYZ" + +is equivalent to `-PXYZ'. + + Finally, + + %option yyclass="foo" + +only applies when generating a C++ scanner (`-+' option). It informs +`flex' that you have derived `foo' as a subclass of `yyFlexLexer' so +`flex' will place your actions in the member function `foo::yylex()' +instead of `yyFlexLexer::yylex()'. It also generates a +`yyFlexLexer::yylex()' member function that emits a run-time error (by +invoking `yyFlexLexer::LexerError()') if called. See Generating C++ +Scanners, below, for additional information. + + A number of options are available for lint purists who want to +suppress the appearance of unneeded routines in the generated scanner. +Each of the following, if unset, results in the corresponding routine +not appearing in the generated scanner: + + input, unput + yy_push_state, yy_pop_state, yy_top_state + yy_scan_buffer, yy_scan_bytes, yy_scan_string + +(though `yy_push_state()' and friends won't appear anyway unless you +use `%option stack'). + + +File: flex.info, Node: Performance, Next: C++, Prev: Options, Up: Top + +Performance considerations +========================== + + The main design goal of `flex' is that it generate high-performance +scanners. It has been optimized for dealing well with large sets of +rules. Aside from the effects on scanner speed of the table +compression `-C' options outlined above, there are a number of +options/actions which degrade performance. These are, from most +expensive to least: + + REJECT + %option yylineno + arbitrary trailing context + + pattern sets that require backing up + %array + %option interactive + %option always-interactive + + '^' beginning-of-line operator + yymore() + + with the first three all being quite expensive and the last two +being quite cheap. Note also that `unput()' is implemented as a +routine call that potentially does quite a bit of work, while +`yyless()' is a quite-cheap macro; so if just putting back some excess +text you scanned, use `yyless()'. + + `REJECT' should be avoided at all costs when performance is +important. It is a particularly expensive option. + + Getting rid of backing up is messy and often may be an enormous +amount of work for a complicated scanner. In principal, one begins by +using the `-b' flag to generate a `lex.backup' file. For example, on +the input + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + +the file looks like: + + State #6 is non-accepting - + associated rule line numbers: + 2 3 + out-transitions: [ o ] + jam-transitions: EOF [ \001-n p-\177 ] + + State #8 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ a ] + jam-transitions: EOF [ \001-` b-\177 ] + + State #9 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ r ] + jam-transitions: EOF [ \001-q s-\177 ] + + Compressed tables always back up. + + The first few lines tell us that there's a scanner state in which it +can make a transition on an 'o' but not on any other character, and +that in that state the currently scanned text does not match any rule. +The state occurs when trying to match the rules found at lines 2 and 3 +in the input file. If the scanner is in that state and then reads +something other than an 'o', it will have to back up to find a rule +which is matched. With a bit of head-scratching one can see that this +must be the state it's in when it has seen "fo". When this has +happened, if anything other than another 'o' is seen, the scanner will +have to back up to simply match the 'f' (by the default rule). + + The comment regarding State #8 indicates there's a problem when +"foob" has been scanned. Indeed, on any character other than an 'a', +the scanner will have to back up to accept "foo". Similarly, the +comment for State #9 concerns when "fooba" has been scanned and an 'r' +does not follow. + + The final comment reminds us that there's no point going to all the +trouble of removing backing up from the rules unless we're using `-Cf' +or `-CF', since there's no performance gain doing so with compressed +scanners. + + The way to remove the backing up is to add "error" rules: + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + fooba | + foob | + fo { + /* false alarm, not really a keyword */ + return TOK_ID; + } + + Eliminating backing up among a list of keywords can also be done +using a "catch-all" rule: + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + [a-z]+ return TOK_ID; + + This is usually the best solution when appropriate. + + Backing up messages tend to cascade. With a complicated set of +rules it's not uncommon to get hundreds of messages. If one can +decipher them, though, it often only takes a dozen or so rules to +eliminate the backing up (though it's easy to make a mistake and have +an error rule accidentally match a valid token. A possible future +`flex' feature will be to automatically add rules to eliminate backing +up). + + It's important to keep in mind that you gain the benefits of +eliminating backing up only if you eliminate *every* instance of +backing up. Leaving just one means you gain nothing. + + VARIABLE trailing context (where both the leading and trailing parts +do not have a fixed length) entails almost the same performance loss as +`REJECT' (i.e., substantial). So when possible a rule like: + + %% + mouse|rat/(cat|dog) run(); + +is better written: + + %% + mouse/cat|dog run(); + rat/cat|dog run(); + +or as + + %% + mouse|rat/cat run(); + mouse|rat/dog run(); + + Note that here the special '|' action does *not* provide any +savings, and can even make things worse (see Deficiencies / Bugs below). + + Another area where the user can increase a scanner's performance +(and one that's easier to implement) arises from the fact that the +longer the tokens matched, the faster the scanner will run. This is +because with long tokens the processing of most input characters takes +place in the (short) inner scanning loop, and does not often have to go +through the additional work of setting up the scanning environment +(e.g., `yytext') for the action. Recall the scanner for C comments: + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* + "*"+[^*/\n]* + \n ++line_num; + "*"+"/" BEGIN(INITIAL); + + This could be sped up by writing it as: + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\n]* + [^*\n]*\n ++line_num; + "*"+[^*/\n]* + "*"+[^*/\n]*\n ++line_num; + "*"+"/" BEGIN(INITIAL); + + Now instead of each newline requiring the processing of another +action, recognizing the newlines is "distributed" over the other rules +to keep the matched text as long as possible. Note that *adding* rules +does *not* slow down the scanner! The speed of the scanner is +independent of the number of rules or (modulo the considerations given +at the beginning of this section) how complicated the rules are with +regard to operators such as '*' and '|'. + + A final example in speeding up a scanner: suppose you want to scan +through a file containing identifiers and keywords, one per line and +with no other extraneous characters, and recognize all the keywords. A +natural first approach is: + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + .|\n /* it's not a keyword */ + + To eliminate the back-tracking, introduce a catch-all rule: + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + [a-z]+ | + .|\n /* it's not a keyword */ + + Now, if it's guaranteed that there's exactly one word per line, then +we can reduce the total number of matches by a half by merging in the +recognition of newlines with that of the other tokens: + + %% + asm\n | + auto\n | + break\n | + ... etc ... + volatile\n | + while\n /* it's a keyword */ + + [a-z]+\n | + .|\n /* it's not a keyword */ + + One has to be careful here, as we have now reintroduced backing up +into the scanner. In particular, while *we* know that there will never +be any characters in the input stream other than letters or newlines, +`flex' can't figure this out, and it will plan for possibly needing to +back up when it has scanned a token like "auto" and then the next +character is something other than a newline or a letter. Previously it +would then just match the "auto" rule and be done, but now it has no +"auto" rule, only a "auto\n" rule. To eliminate the possibility of +backing up, we could either duplicate all rules but without final +newlines, or, since we never expect to encounter such an input and +therefore don't how it's classified, we can introduce one more +catch-all rule, this one which doesn't include a newline: + + %% + asm\n | + auto\n | + break\n | + ... etc ... + volatile\n | + while\n /* it's a keyword */ + + [a-z]+\n | + [a-z]+ | + .|\n /* it's not a keyword */ + + Compiled with `-Cf', this is about as fast as one can get a `flex' +scanner to go for this particular problem. + + A final note: `flex' is slow when matching NUL's, particularly when +a token contains multiple NUL's. It's best to write rules which match +*short* amounts of text if it's anticipated that the text will often +include NUL's. + + Another final note regarding performance: as mentioned above in the +section How the Input is Matched, dynamically resizing `yytext' to +accommodate huge tokens is a slow process because it presently requires +that the (huge) token be rescanned from the beginning. Thus if +performance is vital, you should attempt to match "large" quantities of +text but not "huge" quantities, where the cutoff between the two is at +about 8K characters/token. + + +File: flex.info, Node: C++, Next: Incompatibilities, Prev: Performance, Up: Top + +Generating C++ scanners +======================= + + `flex' provides two different ways to generate scanners for use with +C++. The first way is to simply compile a scanner generated by `flex' +using a C++ compiler instead of a C compiler. You should not encounter +any compilations errors (please report any you find to the email address +given in the Author section below). You can then use C++ code in your +rule actions instead of C code. Note that the default input source for +your scanner remains `yyin', and default echoing is still done to +`yyout'. Both of these remain `FILE *' variables and not C++ `streams'. + + You can also use `flex' to generate a C++ scanner class, using the +`-+' option, (or, equivalently, `%option c++'), which is automatically +specified if the name of the flex executable ends in a `+', such as +`flex++'. When using this option, flex defaults to generating the +scanner to the file `lex.yy.cc' instead of `lex.yy.c'. The generated +scanner includes the header file `FlexLexer.h', which defines the +interface to two C++ classes. + + The first class, `FlexLexer', provides an abstract base class +defining the general scanner class interface. It provides the +following member functions: + +`const char* YYText()' + returns the text of the most recently matched token, the + equivalent of `yytext'. + +`int YYLeng()' + returns the length of the most recently matched token, the + equivalent of `yyleng'. + +`int lineno() const' + returns the current input line number (see `%option yylineno'), or + 1 if `%option yylineno' was not used. + +`void set_debug( int flag )' + sets the debugging flag for the scanner, equivalent to assigning to + `yy_flex_debug' (see the Options section above). Note that you + must build the scanner using `%option debug' to include debugging + information in it. + +`int debug() const' + returns the current setting of the debugging flag. + + Also provided are member functions equivalent to +`yy_switch_to_buffer(), yy_create_buffer()' (though the first argument +is an `istream*' object pointer and not a `FILE*', `yy_flush_buffer()', +`yy_delete_buffer()', and `yyrestart()' (again, the first argument is a +`istream*' object pointer). + + The second class defined in `FlexLexer.h' is `yyFlexLexer', which is +derived from `FlexLexer'. It defines the following additional member +functions: + +`yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 )' + constructs a `yyFlexLexer' object using the given streams for + input and output. If not specified, the streams default to `cin' + and `cout', respectively. + +`virtual int yylex()' + performs the same role is `yylex()' does for ordinary flex + scanners: it scans the input stream, consuming tokens, until a + rule's action returns a value. If you derive a subclass S from + `yyFlexLexer' and want to access the member functions and + variables of S inside `yylex()', then you need to use `%option + yyclass="S"' to inform `flex' that you will be using that subclass + instead of `yyFlexLexer'. In this case, rather than generating + `yyFlexLexer::yylex()', `flex' generates `S::yylex()' (and also + generates a dummy `yyFlexLexer::yylex()' that calls + `yyFlexLexer::LexerError()' if called). + +`virtual void switch_streams(istream* new_in = 0, ostream* new_out = 0)' + reassigns `yyin' to `new_in' (if non-nil) and `yyout' to `new_out' + (ditto), deleting the previous input buffer if `yyin' is + reassigned. + +`int yylex( istream* new_in = 0, ostream* new_out = 0 )' + first switches the input streams via `switch_streams( new_in, + new_out )' and then returns the value of `yylex()'. + + In addition, `yyFlexLexer' defines the following protected virtual +functions which you can redefine in derived classes to tailor the +scanner: + +`virtual int LexerInput( char* buf, int max_size )' + reads up to `max_size' characters into BUF and returns the number + of characters read. To indicate end-of-input, return 0 + characters. Note that "interactive" scanners (see the `-B' and + `-I' flags) define the macro `YY_INTERACTIVE'. If you redefine + `LexerInput()' and need to take different actions depending on + whether or not the scanner might be scanning an interactive input + source, you can test for the presence of this name via `#ifdef'. + +`virtual void LexerOutput( const char* buf, int size )' + writes out SIZE characters from the buffer BUF, which, while + NUL-terminated, may also contain "internal" NUL's if the scanner's + rules can match text with NUL's in them. + +`virtual void LexerError( const char* msg )' + reports a fatal error message. The default version of this + function writes the message to the stream `cerr' and exits. + + Note that a `yyFlexLexer' object contains its *entire* scanning +state. Thus you can use such objects to create reentrant scanners. +You can instantiate multiple instances of the same `yyFlexLexer' class, +and you can also combine multiple C++ scanner classes together in the +same program using the `-P' option discussed above. Finally, note that +the `%array' feature is not available to C++ scanner classes; you must +use `%pointer' (the default). + + Here is an example of a simple C++ scanner: + + // An example of using the flex C++ scanner class. + + %{ + int mylineno = 0; + %} + + string \"[^\n"]+\" + + ws [ \t]+ + + alpha [A-Za-z] + dig [0-9] + name ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])* + num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)? + num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)? + number {num1}|{num2} + + %% + + {ws} /* skip blanks and tabs */ + + "/*" { + int c; + + while((c = yyinput()) != 0) + { + if(c == '\n') + ++mylineno; + + else if(c == '*') + { + if((c = yyinput()) == '/') + break; + else + unput(c); + } + } + } + + {number} cout << "number " << YYText() << '\n'; + + \n mylineno++; + + {name} cout << "name " << YYText() << '\n'; + + {string} cout << "string " << YYText() << '\n'; + + %% + + Version 2.5 December 1994 44 + + int main( int /* argc */, char** /* argv */ ) + { + FlexLexer* lexer = new yyFlexLexer; + while(lexer->yylex() != 0) + ; + return 0; + } + + If you want to create multiple (different) lexer classes, you use +the `-P' flag (or the `prefix=' option) to rename each `yyFlexLexer' to +some other `xxFlexLexer'. You then can include `' in your +other sources once per lexer class, first renaming `yyFlexLexer' as +follows: + + #undef yyFlexLexer + #define yyFlexLexer xxFlexLexer + #include + + #undef yyFlexLexer + #define yyFlexLexer zzFlexLexer + #include + + if, for example, you used `%option prefix="xx"' for one of your +scanners and `%option prefix="zz"' for the other. + + IMPORTANT: the present form of the scanning class is *experimental* +and may change considerably between major releases. + + +File: flex.info, Node: Incompatibilities, Next: Diagnostics, Prev: C++, Up: Top + +Incompatibilities with `lex' and POSIX +====================================== + + `flex' is a rewrite of the AT&T Unix `lex' tool (the two +implementations do not share any code, though), with some extensions +and incompatibilities, both of which are of concern to those who wish +to write scanners acceptable to either implementation. Flex is fully +compliant with the POSIX `lex' specification, except that when using +`%pointer' (the default), a call to `unput()' destroys the contents of +`yytext', which is counter to the POSIX specification. + + In this section we discuss all of the known areas of incompatibility +between flex, AT&T lex, and the POSIX specification. + + `flex's' `-l' option turns on maximum compatibility with the +original AT&T `lex' implementation, at the cost of a major loss in the +generated scanner's performance. We note below which incompatibilities +can be overcome using the `-l' option. + + `flex' is fully compatible with `lex' with the following exceptions: + + - The undocumented `lex' scanner internal variable `yylineno' is not + supported unless `-l' or `%option yylineno' is used. `yylineno' + should be maintained on a per-buffer basis, rather than a + per-scanner (single global variable) basis. `yylineno' is not + part of the POSIX specification. + + - The `input()' routine is not redefinable, though it may be called + to read characters following whatever has been matched by a rule. + If `input()' encounters an end-of-file the normal `yywrap()' + processing is done. A "real" end-of-file is returned by `input()' + as `EOF'. + + Input is instead controlled by defining the `YY_INPUT' macro. + + The `flex' restriction that `input()' cannot be redefined is in + accordance with the POSIX specification, which simply does not + specify any way of controlling the scanner's input other than by + making an initial assignment to `yyin'. + + - The `unput()' routine is not redefinable. This restriction is in + accordance with POSIX. + + - `flex' scanners are not as reentrant as `lex' scanners. In + particular, if you have an interactive scanner and an interrupt + handler which long-jumps out of the scanner, and the scanner is + subsequently called again, you may get the following message: + + fatal flex scanner internal error--end of buffer missed + + To reenter the scanner, first use + + yyrestart( yyin ); + + Note that this call will throw away any buffered input; usually + this isn't a problem with an interactive scanner. + + Also note that flex C++ scanner classes *are* reentrant, so if + using C++ is an option for you, you should use them instead. See + "Generating C++ Scanners" above for details. + + - `output()' is not supported. Output from the `ECHO' macro is done + to the file-pointer `yyout' (default `stdout'). + + `output()' is not part of the POSIX specification. + + - `lex' does not support exclusive start conditions (%x), though + they are in the POSIX specification. + + - When definitions are expanded, `flex' encloses them in + parentheses. With lex, the following: + + NAME [A-Z][A-Z0-9]* + %% + foo{NAME}? printf( "Found it\n" ); + %% + + will not match the string "foo" because when the macro is expanded + the rule is equivalent to "foo[A-Z][A-Z0-9]*?" and the precedence + is such that the '?' is associated with "[A-Z0-9]*". With `flex', + the rule will be expanded to "foo([A-Z][A-Z0-9]*)?" and so the + string "foo" will match. + + Note that if the definition begins with `^' or ends with `$' then + it is *not* expanded with parentheses, to allow these operators to + appear in definitions without losing their special meanings. But + the `, /', and `<>' operators cannot be used in a `flex' + definition. + + Using `-l' results in the `lex' behavior of no parentheses around + the definition. + + The POSIX specification is that the definition be enclosed in + parentheses. + + - Some implementations of `lex' allow a rule's action to begin on a + separate line, if the rule's pattern has trailing whitespace: + + %% + foo|bar + { foobar_action(); } + + `flex' does not support this feature. + + - The `lex' `%r' (generate a Ratfor scanner) option is not + supported. It is not part of the POSIX specification. + + - After a call to `unput()', `yytext' is undefined until the next + token is matched, unless the scanner was built using `%array'. + This is not the case with `lex' or the POSIX specification. The + `-l' option does away with this incompatibility. + + - The precedence of the `{}' (numeric range) operator is different. + `lex' interprets "abc{1,3}" as "match one, two, or three + occurrences of 'abc'", whereas `flex' interprets it as "match 'ab' + followed by one, two, or three occurrences of 'c'". The latter is + in agreement with the POSIX specification. + + - The precedence of the `^' operator is different. `lex' interprets + "^foo|bar" as "match either 'foo' at the beginning of a line, or + 'bar' anywhere", whereas `flex' interprets it as "match either + 'foo' or 'bar' if they come at the beginning of a line". The + latter is in agreement with the POSIX specification. + + - The special table-size declarations such as `%a' supported by + `lex' are not required by `flex' scanners; `flex' ignores them. + + - The name FLEX_SCANNER is #define'd so scanners may be written for + use with either `flex' or `lex'. Scanners also include + `YY_FLEX_MAJOR_VERSION' and `YY_FLEX_MINOR_VERSION' indicating + which version of `flex' generated the scanner (for example, for the + 2.5 release, these defines would be 2 and 5 respectively). + + The following `flex' features are not included in `lex' or the POSIX +specification: + + C++ scanners + %option + start condition scopes + start condition stacks + interactive/non-interactive scanners + yy_scan_string() and friends + yyterminate() + yy_set_interactive() + yy_set_bol() + YY_AT_BOL() + <> + <*> + YY_DECL + YY_START + YY_USER_ACTION + YY_USER_INIT + #line directives + %{}'s around actions + multiple actions on a line + +plus almost all of the flex flags. The last feature in the list refers +to the fact that with `flex' you can put multiple actions on the same +line, separated with semicolons, while with `lex', the following + + foo handle_foo(); ++num_foos_seen; + +is (rather surprisingly) truncated to + + foo handle_foo(); + + `flex' does not truncate the action. Actions that are not enclosed +in braces are simply terminated at the end of the line. + + +File: flex.info, Node: Diagnostics, Next: Files, Prev: Incompatibilities, Up: Top + +Diagnostics +=========== + +`warning, rule cannot be matched' + indicates that the given rule cannot be matched because it follows + other rules that will always match the same text as it. For + example, in the following "foo" cannot be matched because it comes + after an identifier "catch-all" rule: + + [a-z]+ got_identifier(); + foo got_foo(); + + Using `REJECT' in a scanner suppresses this warning. + +`warning, -s option given but default rule can be matched' + means that it is possible (perhaps only in a particular start + condition) that the default rule (match any single character) is + the only one that will match a particular input. Since `-s' was + given, presumably this is not intended. + +`reject_used_but_not_detected undefined' +`yymore_used_but_not_detected undefined' + These errors can occur at compile time. They indicate that the + scanner uses `REJECT' or `yymore()' but that `flex' failed to + notice the fact, meaning that `flex' scanned the first two sections + looking for occurrences of these actions and failed to find any, + but somehow you snuck some in (via a #include file, for example). + Use `%option reject' or `%option yymore' to indicate to flex that + you really do use these features. + +`flex scanner jammed' + a scanner compiled with `-s' has encountered an input string which + wasn't matched by any of its rules. This error can also occur due + to internal problems. + +`token too large, exceeds YYLMAX' + your scanner uses `%array' and one of its rules matched a string + longer than the `YYL-' `MAX' constant (8K bytes by default). You + can increase the value by #define'ing `YYLMAX' in the definitions + section of your `flex' input. + +`scanner requires -8 flag to use the character 'X'' + Your scanner specification includes recognizing the 8-bit + character X and you did not specify the -8 flag, and your scanner + defaulted to 7-bit because you used the `-Cf' or `-CF' table + compression options. See the discussion of the `-7' flag for + details. + +`flex scanner push-back overflow' + you used `unput()' to push back so much text that the scanner's + buffer could not hold both the pushed-back text and the current + token in `yytext'. Ideally the scanner should dynamically resize + the buffer in this case, but at present it does not. + +`input buffer overflow, can't enlarge buffer because scanner uses REJECT' + the scanner was working on matching an extremely large token and + needed to expand the input buffer. This doesn't work with + scanners that use `REJECT'. + +`fatal flex scanner internal error--end of buffer missed' + This can occur in an scanner which is reentered after a long-jump + has jumped out (or over) the scanner's activation frame. Before + reentering the scanner, use: + + yyrestart( yyin ); + + or, as noted above, switch to using the C++ scanner class. + +`too many start conditions in <> construct!' + you listed more start conditions in a <> construct than exist (so + you must have listed at least one of them twice). + + +File: flex.info, Node: Files, Next: Deficiencies, Prev: Diagnostics, Up: Top + +Files +===== + +`-lfl' + library with which scanners must be linked. + +`lex.yy.c' + generated scanner (called `lexyy.c' on some systems). + +`lex.yy.cc' + generated C++ scanner class, when using `-+'. + +`' + header file defining the C++ scanner base class, `FlexLexer', and + its derived class, `yyFlexLexer'. + +`flex.skl' + skeleton scanner. This file is only used when building flex, not + when flex executes. + +`lex.backup' + backing-up information for `-b' flag (called `lex.bck' on some + systems). + + +File: flex.info, Node: Deficiencies, Next: See also, Prev: Files, Up: Top + +Deficiencies / Bugs +=================== + + Some trailing context patterns cannot be properly matched and +generate warning messages ("dangerous trailing context"). These are +patterns where the ending of the first part of the rule matches the +beginning of the second part, such as "zx*/xy*", where the 'x*' matches +the 'x' at the beginning of the trailing context. (Note that the POSIX +draft states that the text matched by such patterns is undefined.) + + For some trailing context rules, parts which are actually +fixed-length are not recognized as such, leading to the abovementioned +performance loss. In particular, parts using '|' or {n} (such as +"foo{3}") are always considered variable-length. + + Combining trailing context with the special '|' action can result in +*fixed* trailing context being turned into the more expensive VARIABLE +trailing context. For example, in the following: + + %% + abc | + xyz/def + + Use of `unput()' invalidates yytext and yyleng, unless the `%array' +directive or the `-l' option has been used. + + Pattern-matching of NUL's is substantially slower than matching +other characters. + + Dynamic resizing of the input buffer is slow, as it entails +rescanning all the text matched so far by the current (generally huge) +token. + + Due to both buffering of input and read-ahead, you cannot intermix +calls to routines, such as, for example, `getchar()', with +`flex' rules and expect it to work. Call `input()' instead. + + The total table entries listed by the `-v' flag excludes the number +of table entries needed to determine what rule has been matched. The +number of entries is equal to the number of DFA states if the scanner +does not use `REJECT', and somewhat greater than the number of states +if it does. + + `REJECT' cannot be used with the `-f' or `-F' options. + + The `flex' internal algorithms need documentation. + + +File: flex.info, Node: See also, Next: Author, Prev: Deficiencies, Up: Top + +See also +======== + + `lex'(1), `yacc'(1), `sed'(1), `awk'(1). + + John Levine, Tony Mason, and Doug Brown: Lex & Yacc; O'Reilly and +Associates. Be sure to get the 2nd edition. + + M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator. + + Alfred Aho, Ravi Sethi and Jeffrey Ullman: Compilers: Principles, +Techniques and Tools; Addison-Wesley (1986). Describes the +pattern-matching techniques used by `flex' (deterministic finite +automata). + + +File: flex.info, Node: Author, Prev: See also, Up: Top + +Author +====== + + Vern Paxson, with the help of many ideas and much inspiration from +Van Jacobson. Original version by Jef Poskanzer. The fast table +representation is a partial implementation of a design done by Van +Jacobson. The implementation was done by Kevin Gong and Vern Paxson. + + Thanks to the many `flex' beta-testers, feedbackers, and +contributors, especially Francois Pinard, Casey Leedom, Stan Adermann, +Terry Allen, David Barker-Plummer, John Basrai, Nelson H.F. Beebe, +`benson@odi.com', Karl Berry, Peter A. Bigot, Simon Blanchard, Keith +Bostic, Frederic Brehm, Ian Brockbank, Kin Cho, Nick Christopher, Brian +Clapper, J.T. Conklin, Jason Coughlin, Bill Cox, Nick Cropper, Dave +Curtis, Scott David Daniels, Chris G. Demetriou, Theo Deraadt, Mike +Donahue, Chuck Doucette, Tom Epperly, Leo Eskin, Chris Faylor, Chris +Flatters, Jon Forrest, Joe Gayda, Kaveh R. Ghazi, Eric Goldman, +Christopher M. Gould, Ulrich Grepel, Peer Griebel, Jan Hajic, Charles +Hemphill, NORO Hideo, Jarkko Hietaniemi, Scott Hofmann, Jeff Honig, +Dana Hudes, Eric Hughes, John Interrante, Ceriel Jacobs, Michal +Jaegermann, Sakari Jalovaara, Jeffrey R. Jones, Henry Juengst, Klaus +Kaempf, Jonathan I. Kamens, Terrence O Kane, Amir Katz, +`ken@ken.hilco.com', Kevin B. Kenny, Steve Kirsch, Winfried Koenig, +Marq Kole, Ronald Lamprecht, Greg Lee, Rohan Lenard, Craig Leres, John +Levine, Steve Liddle, Mike Long, Mohamed el Lozy, Brian Madsen, Malte, +Joe Marshall, Bengt Martensson, Chris Metcalf, Luke Mewburn, Jim +Meyering, R. Alexander Milowski, Erik Naggum, G.T. Nicol, Landon Noll, +James Nordby, Marc Nozell, Richard Ohnemus, Karsten Pahnke, Sven Panne, +Roland Pesch, Walter Pelissero, Gaumond Pierre, Esmond Pitt, Jef +Poskanzer, Joe Rahmeh, Jarmo Raiha, Frederic Raimbault, Pat Rankin, +Rick Richardson, Kevin Rodgers, Kai Uwe Rommel, Jim Roskind, Alberto +Santini, Andreas Scherer, Darrell Schiebel, Raf Schietekat, Doug +Schmidt, Philippe Schnoebelen, Andreas Schwab, Alex Siegel, Eckehard +Stolz, Jan-Erik Strvmquist, Mike Stump, Paul Stuart, Dave Tallman, Ian +Lance Taylor, Chris Thewalt, Richard M. Timoney, Jodi Tsai, Paul +Tuinenga, Gary Weik, Frank Whaley, Gerhard Wilhelms, Kent Williams, Ken +Yap, Ron Zellar, Nathan Zelle, David Zuhn, and those whose names have +slipped my marginal mail-archiving skills but whose contributions are +appreciated all the same. + + Thanks to Keith Bostic, Jon Forrest, Noah Friedman, John Gilmore, +Craig Leres, John Levine, Bob Mulcahy, G.T. Nicol, Francois Pinard, +Rich Salz, and Richard Stallman for help with various distribution +headaches. + + Thanks to Esmond Pitt and Earle Horton for 8-bit character support; +to Benson Margulies and Fred Burke for C++ support; to Kent Williams +and Tom Epperly for C++ class support; to Ove Ewerlid for support of +NUL's; and to Eric Hughes for support of multiple buffers. + + This work was primarily done when I was with the Real Time Systems +Group at the Lawrence Berkeley Laboratory in Berkeley, CA. Many thanks +to all there for the support I received. + + Send comments to `vern@ee.lbl.gov'. + + + +Tag Table: +Node: Top1430 +Node: Name2808 +Node: Synopsis2933 +Node: Overview3145 +Node: Description4986 +Node: Examples5748 +Node: Format8896 +Node: Patterns11637 +Node: Matching18138 +Node: Actions21438 +Node: Generated scanner30560 +Node: Start conditions34988 +Node: Multiple buffers45069 +Node: End-of-file rules50975 +Node: Miscellaneous52508 +Node: User variables55279 +Node: YACC interface57651 +Node: Options58542 +Node: Performance78234 +Node: C++87532 +Node: Incompatibilities94993 +Node: Diagnostics101853 +Node: Files105094 +Node: Deficiencies105715 +Node: See also107684 +Node: Author108216 + +End Tag Table diff --git a/commands/flex-2.5.4/MISC/texinfo/flex.texi b/commands/flex-2.5.4/MISC/texinfo/flex.texi new file mode 100644 index 000000000..23280b114 --- /dev/null +++ b/commands/flex-2.5.4/MISC/texinfo/flex.texi @@ -0,0 +1,3448 @@ +\input texinfo +@c %**start of header +@setfilename flex.info +@settitle Flex - a scanner generator +@c @finalout +@c @setchapternewpage odd +@c %**end of header + +@set EDITION 2.5 +@set UPDATED March 1995 +@set VERSION 2.5 + +@c FIXME - Reread a printed copy with a red pen and patience. +@c FIXME - Modify all "See ..." references and replace with @xref's. + +@ifinfo +@format +START-INFO-DIR-ENTRY +* Flex: (flex). A fast scanner generator. +END-INFO-DIR-ENTRY +@end format +@end ifinfo + +@c Define new indices for commands, filenames, and options. +@c @defcodeindex cm +@c @defcodeindex fl +@c @defcodeindex op + +@c Put everything in one index (arbitrarily chosen to be the concept index). +@c @syncodeindex cm cp +@c @syncodeindex fl cp +@syncodeindex fn cp +@syncodeindex ky cp +@c @syncodeindex op cp +@syncodeindex pg cp +@syncodeindex vr cp + +@ifinfo +This file documents Flex. + +Copyright (c) 1990 The Regents of the University of California. +All rights reserved. + +This code is derived from software contributed to Berkeley by +Vern Paxson. + +The United States Government has rights in this work pursuant +to contract no. DE-AC03-76SF00098 between the United States +Department of Energy and the University of California. + +Redistribution and use in source and binary forms with or without +modification are permitted provided that: (1) source distributions +retain this entire copyright notice and comment, and (2) +distributions including binaries display the following +acknowledgement: ``This product includes software developed by the +University of California, Berkeley and its contributors'' in the +documentation or other materials provided with the distribution and +in all advertising materials mentioning features or use of this +software. Neither the name of the University nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. + +@ignore +Permission is granted to process this file through TeX and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +@end ifinfo + +@titlepage +@title Flex, version @value{VERSION} +@subtitle A fast scanner generator +@subtitle Edition @value{EDITION}, @value{UPDATED} +@author Vern Paxson + +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1990 The Regents of the University of California. +All rights reserved. + +This code is derived from software contributed to Berkeley by +Vern Paxson. + +The United States Government has rights in this work pursuant +to contract no. DE-AC03-76SF00098 between the United States +Department of Energy and the University of California. + +Redistribution and use in source and binary forms with or without +modification are permitted provided that: (1) source distributions +retain this entire copyright notice and comment, and (2) +distributions including binaries display the following +acknowledgement: ``This product includes software developed by the +University of California, Berkeley and its contributors'' in the +documentation or other materials provided with the distribution and +in all advertising materials mentioning features or use of this +software. Neither the name of the University nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. +@end titlepage + +@ifinfo + +@node Top, Name, (dir), (dir) +@top flex + +@cindex scanner generator + +This manual documents @code{flex}. It covers release @value{VERSION}. + +@menu +* Name:: Name +* Synopsis:: Synopsis +* Overview:: Overview +* Description:: Description +* Examples:: Some simple examples +* Format:: Format of the input file +* Patterns:: Patterns +* Matching:: How the input is matched +* Actions:: Actions +* Generated scanner:: The generated scanner +* Start conditions:: Start conditions +* Multiple buffers:: Multiple input buffers +* End-of-file rules:: End-of-file rules +* Miscellaneous:: Miscellaneous macros +* User variables:: Values available to the user +* YACC interface:: Interfacing with @code{yacc} +* Options:: Options +* Performance:: Performance considerations +* C++:: Generating C++ scanners +* Incompatibilities:: Incompatibilities with @code{lex} and POSIX +* Diagnostics:: Diagnostics +* Files:: Files +* Deficiencies:: Deficiencies / Bugs +* See also:: See also +* Author:: Author +@c * Index:: Index +@end menu + +@end ifinfo + +@node Name, Synopsis, Top, Top +@section Name + +flex - fast lexical analyzer generator + +@node Synopsis, Overview, Name, Top +@section Synopsis + +@example +flex [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton] +[--help --version] [@var{filename} @dots{}] +@end example + +@node Overview, Description, Synopsis, Top +@section Overview + +This manual describes @code{flex}, a tool for generating programs +that perform pattern-matching on text. The manual +includes both tutorial and reference sections: + +@table @asis +@item Description +a brief overview of the tool + +@item Some Simple Examples + +@item Format Of The Input File + +@item Patterns +the extended regular expressions used by flex + +@item How The Input Is Matched +the rules for determining what has been matched + +@item Actions +how to specify what to do when a pattern is matched + +@item The Generated Scanner +details regarding the scanner that flex produces; +how to control the input source + +@item Start Conditions +introducing context into your scanners, and +managing "mini-scanners" + +@item Multiple Input Buffers +how to manipulate multiple input sources; how to +scan from strings instead of files + +@item End-of-file Rules +special rules for matching the end of the input + +@item Miscellaneous Macros +a summary of macros available to the actions + +@item Values Available To The User +a summary of values available to the actions + +@item Interfacing With Yacc +connecting flex scanners together with yacc parsers + +@item Options +flex command-line options, and the "%option" +directive + +@item Performance Considerations +how to make your scanner go as fast as possible + +@item Generating C++ Scanners +the (experimental) facility for generating C++ +scanner classes + +@item Incompatibilities With Lex And POSIX +how flex differs from AT&T lex and the POSIX lex +standard + +@item Diagnostics +those error messages produced by flex (or scanners +it generates) whose meanings might not be apparent + +@item Files +files used by flex + +@item Deficiencies / Bugs +known problems with flex + +@item See Also +other documentation, related tools + +@item Author +includes contact information +@end table + +@node Description, Examples, Overview, Top +@section Description + +@code{flex} is a tool for generating @dfn{scanners}: programs which +recognized lexical patterns in text. @code{flex} reads the given +input files, or its standard input if no file names are +given, for a description of a scanner to generate. The +description is in the form of pairs of regular expressions +and C code, called @dfn{rules}. @code{flex} generates as output a C +source file, @file{lex.yy.c}, which defines a routine @samp{yylex()}. +This file is compiled and linked with the @samp{-lfl} library to +produce an executable. When the executable is run, it +analyzes its input for occurrences of the regular +expressions. Whenever it finds one, it executes the +corresponding C code. + +@node Examples, Format, Description, Top +@section Some simple examples + +First some simple examples to get the flavor of how one +uses @code{flex}. The following @code{flex} input specifies a scanner +which whenever it encounters the string "username" will +replace it with the user's login name: + +@example +%% +username printf( "%s", getlogin() ); +@end example + +By default, any text not matched by a @code{flex} scanner is +copied to the output, so the net effect of this scanner is +to copy its input file to its output with each occurrence +of "username" expanded. In this input, there is just one +rule. "username" is the @var{pattern} and the "printf" is the +@var{action}. The "%%" marks the beginning of the rules. + +Here's another simple example: + +@example + int num_lines = 0, num_chars = 0; + +%% +\n ++num_lines; ++num_chars; +. ++num_chars; + +%% +main() + @{ + yylex(); + printf( "# of lines = %d, # of chars = %d\n", + num_lines, num_chars ); + @} +@end example + +This scanner counts the number of characters and the +number of lines in its input (it produces no output other +than the final report on the counts). The first line +declares two globals, "num_lines" and "num_chars", which +are accessible both inside @samp{yylex()} and in the @samp{main()} +routine declared after the second "%%". There are two rules, +one which matches a newline ("\n") and increments both the +line count and the character count, and one which matches +any character other than a newline (indicated by the "." +regular expression). + +A somewhat more complicated example: + +@example +/* scanner for a toy Pascal-like language */ + +%@{ +/* need this for the call to atof() below */ +#include +%@} + +DIGIT [0-9] +ID [a-z][a-z0-9]* + +%% + +@{DIGIT@}+ @{ + printf( "An integer: %s (%d)\n", yytext, + atoi( yytext ) ); + @} + +@{DIGIT@}+"."@{DIGIT@}* @{ + printf( "A float: %s (%g)\n", yytext, + atof( yytext ) ); + @} + +if|then|begin|end|procedure|function @{ + printf( "A keyword: %s\n", yytext ); + @} + +@{ID@} printf( "An identifier: %s\n", yytext ); + +"+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext ); + +"@{"[^@}\n]*"@}" /* eat up one-line comments */ + +[ \t\n]+ /* eat up whitespace */ + +. printf( "Unrecognized character: %s\n", yytext ); + +%% + +main( argc, argv ) +int argc; +char **argv; + @{ + ++argv, --argc; /* skip over program name */ + if ( argc > 0 ) + yyin = fopen( argv[0], "r" ); + else + yyin = stdin; + + yylex(); + @} +@end example + +This is the beginnings of a simple scanner for a language +like Pascal. It identifies different types of @var{tokens} and +reports on what it has seen. + +The details of this example will be explained in the +following sections. + +@node Format, Patterns, Examples, Top +@section Format of the input file + +The @code{flex} input file consists of three sections, separated +by a line with just @samp{%%} in it: + +@example +definitions +%% +rules +%% +user code +@end example + +The @dfn{definitions} section contains declarations of simple +@dfn{name} definitions to simplify the scanner specification, +and declarations of @dfn{start conditions}, which are explained +in a later section. +Name definitions have the form: + +@example +name definition +@end example + +The "name" is a word beginning with a letter or an +underscore ('_') followed by zero or more letters, digits, '_', +or '-' (dash). The definition is taken to begin at the +first non-white-space character following the name and +continuing to the end of the line. The definition can +subsequently be referred to using "@{name@}", which will +expand to "(definition)". For example, + +@example +DIGIT [0-9] +ID [a-z][a-z0-9]* +@end example + +@noindent +defines "DIGIT" to be a regular expression which matches a +single digit, and "ID" to be a regular expression which +matches a letter followed by zero-or-more +letters-or-digits. A subsequent reference to + +@example +@{DIGIT@}+"."@{DIGIT@}* +@end example + +@noindent +is identical to + +@example +([0-9])+"."([0-9])* +@end example + +@noindent +and matches one-or-more digits followed by a '.' followed +by zero-or-more digits. + +The @var{rules} section of the @code{flex} input contains a series of +rules of the form: + +@example +pattern action +@end example + +@noindent +where the pattern must be unindented and the action must +begin on the same line. + +See below for a further description of patterns and +actions. + +Finally, the user code section is simply copied to +@file{lex.yy.c} verbatim. It is used for companion routines +which call or are called by the scanner. The presence of +this section is optional; if it is missing, the second @samp{%%} +in the input file may be skipped, too. + +In the definitions and rules sections, any @emph{indented} text or +text enclosed in @samp{%@{} and @samp{%@}} is copied verbatim to the +output (with the @samp{%@{@}}'s removed). The @samp{%@{@}}'s must +appear unindented on lines by themselves. + +In the rules section, any indented or %@{@} text appearing +before the first rule may be used to declare variables +which are local to the scanning routine and (after the +declarations) code which is to be executed whenever the +scanning routine is entered. Other indented or %@{@} text +in the rule section is still copied to the output, but its +meaning is not well-defined and it may well cause +compile-time errors (this feature is present for @code{POSIX} compliance; +see below for other such features). + +In the definitions section (but not in the rules section), +an unindented comment (i.e., a line beginning with "/*") +is also copied verbatim to the output up to the next "*/". + +@node Patterns, Matching, Format, Top +@section Patterns + +The patterns in the input are written using an extended +set of regular expressions. These are: + +@table @samp +@item x +match the character @samp{x} +@item . +any character (byte) except newline +@item [xyz] +a "character class"; in this case, the pattern +matches either an @samp{x}, a @samp{y}, or a @samp{z} +@item [abj-oZ] +a "character class" with a range in it; matches +an @samp{a}, a @samp{b}, any letter from @samp{j} through @samp{o}, +or a @samp{Z} +@item [^A-Z] +a "negated character class", i.e., any character +but those in the class. In this case, any +character EXCEPT an uppercase letter. +@item [^A-Z\n] +any character EXCEPT an uppercase letter or +a newline +@item @var{r}* +zero or more @var{r}'s, where @var{r} is any regular expression +@item @var{r}+ +one or more @var{r}'s +@item @var{r}? +zero or one @var{r}'s (that is, "an optional @var{r}") +@item @var{r}@{2,5@} +anywhere from two to five @var{r}'s +@item @var{r}@{2,@} +two or more @var{r}'s +@item @var{r}@{4@} +exactly 4 @var{r}'s +@item @{@var{name}@} +the expansion of the "@var{name}" definition +(see above) +@item "[xyz]\"foo" +the literal string: @samp{[xyz]"foo} +@item \@var{x} +if @var{x} is an @samp{a}, @samp{b}, @samp{f}, @samp{n}, @samp{r}, @samp{t}, or @samp{v}, +then the ANSI-C interpretation of \@var{x}. +Otherwise, a literal @samp{@var{x}} (used to escape +operators such as @samp{*}) +@item \0 +a NUL character (ASCII code 0) +@item \123 +the character with octal value 123 +@item \x2a +the character with hexadecimal value @code{2a} +@item (@var{r}) +match an @var{r}; parentheses are used to override +precedence (see below) +@item @var{r}@var{s} +the regular expression @var{r} followed by the +regular expression @var{s}; called "concatenation" +@item @var{r}|@var{s} +either an @var{r} or an @var{s} +@item @var{r}/@var{s} +an @var{r} but only if it is followed by an @var{s}. The text +matched by @var{s} is included when determining whether this rule is +the @dfn{longest match}, but is then returned to the input before +the action is executed. So the action only sees the text matched +by @var{r}. This type of pattern is called @dfn{trailing context}. +(There are some combinations of @samp{@var{r}/@var{s}} that @code{flex} +cannot match correctly; see notes in the Deficiencies / Bugs section +below regarding "dangerous trailing context".) +@item ^@var{r} +an @var{r}, but only at the beginning of a line (i.e., +which just starting to scan, or right after a +newline has been scanned). +@item @var{r}$ +an @var{r}, but only at the end of a line (i.e., just +before a newline). Equivalent to "@var{r}/\n". + +Note that flex's notion of "newline" is exactly +whatever the C compiler used to compile flex +interprets '\n' as; in particular, on some DOS +systems you must either filter out \r's in the +input yourself, or explicitly use @var{r}/\r\n for "r$". +@item <@var{s}>@var{r} +an @var{r}, but only in start condition @var{s} (see +below for discussion of start conditions) +<@var{s1},@var{s2},@var{s3}>@var{r} +same, but in any of start conditions @var{s1}, +@var{s2}, or @var{s3} +@item <*>@var{r} +an @var{r} in any start condition, even an exclusive one. +@item <> +an end-of-file +<@var{s1},@var{s2}><> +an end-of-file when in start condition @var{s1} or @var{s2} +@end table + +Note that inside of a character class, all regular +expression operators lose their special meaning except escape +('\') and the character class operators, '-', ']', and, at +the beginning of the class, '^'. + +The regular expressions listed above are grouped according +to precedence, from highest precedence at the top to +lowest at the bottom. Those grouped together have equal +precedence. For example, + +@example +foo|bar* +@end example + +@noindent +is the same as + +@example +(foo)|(ba(r*)) +@end example + +@noindent +since the '*' operator has higher precedence than +concatenation, and concatenation higher than alternation ('|'). +This pattern therefore matches @emph{either} the string "foo" @emph{or} +the string "ba" followed by zero-or-more r's. To match +"foo" or zero-or-more "bar"'s, use: + +@example +foo|(bar)* +@end example + +@noindent +and to match zero-or-more "foo"'s-or-"bar"'s: + +@example +(foo|bar)* +@end example + +In addition to characters and ranges of characters, +character classes can also contain character class +@dfn{expressions}. These are expressions enclosed inside @samp{[}: and @samp{:}] +delimiters (which themselves must appear between the '[' +and ']' of the character class; other elements may occur +inside the character class, too). The valid expressions +are: + +@example +[:alnum:] [:alpha:] [:blank:] +[:cntrl:] [:digit:] [:graph:] +[:lower:] [:print:] [:punct:] +[:space:] [:upper:] [:xdigit:] +@end example + +These expressions all designate a set of characters +equivalent to the corresponding standard C @samp{isXXX} function. For +example, @samp{[:alnum:]} designates those characters for which +@samp{isalnum()} returns true - i.e., any alphabetic or numeric. +Some systems don't provide @samp{isblank()}, so flex defines +@samp{[:blank:]} as a blank or a tab. + +For example, the following character classes are all +equivalent: + +@example +[[:alnum:]] +[[:alpha:][:digit:] +[[:alpha:]0-9] +[a-zA-Z0-9] +@end example + +If your scanner is case-insensitive (the @samp{-i} flag), then +@samp{[:upper:]} and @samp{[:lower:]} are equivalent to @samp{[:alpha:]}. + +Some notes on patterns: + +@itemize - +@item +A negated character class such as the example +"[^A-Z]" above @emph{will match a newline} unless "\n" (or an +equivalent escape sequence) is one of the +characters explicitly present in the negated character +class (e.g., "[^A-Z\n]"). This is unlike how many +other regular expression tools treat negated +character classes, but unfortunately the inconsistency +is historically entrenched. Matching newlines +means that a pattern like [^"]* can match the +entire input unless there's another quote in the +input. + +@item +A rule can have at most one instance of trailing +context (the '/' operator or the '$' operator). +The start condition, '^', and "<>" patterns +can only occur at the beginning of a pattern, and, +as well as with '/' and '$', cannot be grouped +inside parentheses. A '^' which does not occur at +the beginning of a rule or a '$' which does not +occur at the end of a rule loses its special +properties and is treated as a normal character. + +The following are illegal: + +@example +foo/bar$ +foobar +@end example + +Note that the first of these, can be written +"foo/bar\n". + +The following will result in '$' or '^' being +treated as a normal character: + +@example +foo|(bar$) +foo|^bar +@end example + +If what's wanted is a "foo" or a +bar-followed-by-a-newline, the following could be used (the special +'|' action is explained below): + +@example +foo | +bar$ /* action goes here */ +@end example + +A similar trick will work for matching a foo or a +bar-at-the-beginning-of-a-line. +@end itemize + +@node Matching, Actions, Patterns, Top +@section How the input is matched + +When the generated scanner is run, it analyzes its input +looking for strings which match any of its patterns. If +it finds more than one match, it takes the one matching +the most text (for trailing context rules, this includes +the length of the trailing part, even though it will then +be returned to the input). If it finds two or more +matches of the same length, the rule listed first in the +@code{flex} input file is chosen. + +Once the match is determined, the text corresponding to +the match (called the @var{token}) is made available in the +global character pointer @code{yytext}, and its length in the +global integer @code{yyleng}. The @var{action} corresponding to the +matched pattern is then executed (a more detailed +description of actions follows), and then the remaining input is +scanned for another match. + +If no match is found, then the @dfn{default rule} is executed: +the next character in the input is considered matched and +copied to the standard output. Thus, the simplest legal +@code{flex} input is: + +@example +%% +@end example + +which generates a scanner that simply copies its input +(one character at a time) to its output. + +Note that @code{yytext} can be defined in two different ways: +either as a character @emph{pointer} or as a character @emph{array}. +You can control which definition @code{flex} uses by including +one of the special directives @samp{%pointer} or @samp{%array} in the +first (definitions) section of your flex input. The +default is @samp{%pointer}, unless you use the @samp{-l} lex +compatibility option, in which case @code{yytext} will be an array. The +advantage of using @samp{%pointer} is substantially faster +scanning and no buffer overflow when matching very large +tokens (unless you run out of dynamic memory). The +disadvantage is that you are restricted in how your actions can +modify @code{yytext} (see the next section), and calls to the +@samp{unput()} function destroys the present contents of @code{yytext}, +which can be a considerable porting headache when moving +between different @code{lex} versions. + +The advantage of @samp{%array} is that you can then modify @code{yytext} +to your heart's content, and calls to @samp{unput()} do not +destroy @code{yytext} (see below). Furthermore, existing @code{lex} +programs sometimes access @code{yytext} externally using +declarations of the form: +@example +extern char yytext[]; +@end example +This definition is erroneous when used with @samp{%pointer}, but +correct for @samp{%array}. + +@samp{%array} defines @code{yytext} to be an array of @code{YYLMAX} characters, +which defaults to a fairly large value. You can change +the size by simply #define'ing @code{YYLMAX} to a different value +in the first section of your @code{flex} input. As mentioned +above, with @samp{%pointer} yytext grows dynamically to +accommodate large tokens. While this means your @samp{%pointer} scanner +can accommodate very large tokens (such as matching entire +blocks of comments), bear in mind that each time the +scanner must resize @code{yytext} it also must rescan the entire +token from the beginning, so matching such tokens can +prove slow. @code{yytext} presently does @emph{not} dynamically grow if +a call to @samp{unput()} results in too much text being pushed +back; instead, a run-time error results. + +Also note that you cannot use @samp{%array} with C++ scanner +classes (the @code{c++} option; see below). + +@node Actions, Generated scanner, Matching, Top +@section Actions + +Each pattern in a rule has a corresponding action, which +can be any arbitrary C statement. The pattern ends at the +first non-escaped whitespace character; the remainder of +the line is its action. If the action is empty, then when +the pattern is matched the input token is simply +discarded. For example, here is the specification for a +program which deletes all occurrences of "zap me" from its +input: + +@example +%% +"zap me" +@end example + +(It will copy all other characters in the input to the +output since they will be matched by the default rule.) + +Here is a program which compresses multiple blanks and +tabs down to a single blank, and throws away whitespace +found at the end of a line: + +@example +%% +[ \t]+ putchar( ' ' ); +[ \t]+$ /* ignore this token */ +@end example + +If the action contains a '@{', then the action spans till +the balancing '@}' is found, and the action may cross +multiple lines. @code{flex} knows about C strings and comments and +won't be fooled by braces found within them, but also +allows actions to begin with @samp{%@{} and will consider the +action to be all the text up to the next @samp{%@}} (regardless of +ordinary braces inside the action). + +An action consisting solely of a vertical bar ('|') means +"same as the action for the next rule." See below for an +illustration. + +Actions can include arbitrary C code, including @code{return} +statements to return a value to whatever routine called +@samp{yylex()}. Each time @samp{yylex()} is called it continues +processing tokens from where it last left off until it either +reaches the end of the file or executes a return. + +Actions are free to modify @code{yytext} except for lengthening +it (adding characters to its end--these will overwrite +later characters in the input stream). This however does +not apply when using @samp{%array} (see above); in that case, +@code{yytext} may be freely modified in any way. + +Actions are free to modify @code{yyleng} except they should not +do so if the action also includes use of @samp{yymore()} (see +below). + +There are a number of special directives which can be +included within an action: + +@itemize - +@item +@samp{ECHO} copies yytext to the scanner's output. + +@item +@code{BEGIN} followed by the name of a start condition +places the scanner in the corresponding start +condition (see below). + +@item +@code{REJECT} directs the scanner to proceed on to the +"second best" rule which matched the input (or a +prefix of the input). The rule is chosen as +described above in "How the Input is Matched", and +@code{yytext} and @code{yyleng} set up appropriately. It may +either be one which matched as much text as the +originally chosen rule but came later in the @code{flex} +input file, or one which matched less text. For +example, the following will both count the words in +the input and call the routine special() whenever +"frob" is seen: + +@example + int word_count = 0; +%% + +frob special(); REJECT; +[^ \t\n]+ ++word_count; +@end example + +Without the @code{REJECT}, any "frob"'s in the input would +not be counted as words, since the scanner normally +executes only one action per token. Multiple +@code{REJECT's} are allowed, each one finding the next +best choice to the currently active rule. For +example, when the following scanner scans the token +"abcd", it will write "abcdabcaba" to the output: + +@example +%% +a | +ab | +abc | +abcd ECHO; REJECT; +.|\n /* eat up any unmatched character */ +@end example + +(The first three rules share the fourth's action +since they use the special '|' action.) @code{REJECT} is +a particularly expensive feature in terms of +scanner performance; if it is used in @emph{any} of the +scanner's actions it will slow down @emph{all} of the +scanner's matching. Furthermore, @code{REJECT} cannot be used +with the @samp{-Cf} or @samp{-CF} options (see below). + +Note also that unlike the other special actions, +@code{REJECT} is a @emph{branch}; code immediately following it +in the action will @emph{not} be executed. + +@item +@samp{yymore()} tells the scanner that the next time it +matches a rule, the corresponding token should be +@emph{appended} onto the current value of @code{yytext} rather +than replacing it. For example, given the input +"mega-kludge" the following will write +"mega-mega-kludge" to the output: + +@example +%% +mega- ECHO; yymore(); +kludge ECHO; +@end example + +First "mega-" is matched and echoed to the output. +Then "kludge" is matched, but the previous "mega-" +is still hanging around at the beginning of @code{yytext} +so the @samp{ECHO} for the "kludge" rule will actually +write "mega-kludge". +@end itemize + +Two notes regarding use of @samp{yymore()}. First, @samp{yymore()} +depends on the value of @code{yyleng} correctly reflecting the +size of the current token, so you must not modify @code{yyleng} +if you are using @samp{yymore()}. Second, the presence of +@samp{yymore()} in the scanner's action entails a minor +performance penalty in the scanner's matching speed. + +@itemize - +@item +@samp{yyless(n)} returns all but the first @var{n} characters of +the current token back to the input stream, where +they will be rescanned when the scanner looks for +the next match. @code{yytext} and @code{yyleng} are adjusted +appropriately (e.g., @code{yyleng} will now be equal to @var{n} +). For example, on the input "foobar" the +following will write out "foobarbar": + +@example +%% +foobar ECHO; yyless(3); +[a-z]+ ECHO; +@end example + +An argument of 0 to @code{yyless} will cause the entire +current input string to be scanned again. Unless +you've changed how the scanner will subsequently +process its input (using @code{BEGIN}, for example), this +will result in an endless loop. + +Note that @code{yyless} is a macro and can only be used in the +flex input file, not from other source files. + +@item +@samp{unput(c)} puts the character @code{c} back onto the input +stream. It will be the next character scanned. +The following action will take the current token +and cause it to be rescanned enclosed in +parentheses. + +@example +@{ +int i; +/* Copy yytext because unput() trashes yytext */ +char *yycopy = strdup( yytext ); +unput( ')' ); +for ( i = yyleng - 1; i >= 0; --i ) + unput( yycopy[i] ); +unput( '(' ); +free( yycopy ); +@} +@end example + +Note that since each @samp{unput()} puts the given +character back at the @emph{beginning} of the input stream, +pushing back strings must be done back-to-front. +An important potential problem when using @samp{unput()} is that +if you are using @samp{%pointer} (the default), a call to @samp{unput()} +@emph{destroys} the contents of @code{yytext}, starting with its +rightmost character and devouring one character to the left +with each call. If you need the value of yytext preserved +after a call to @samp{unput()} (as in the above example), you +must either first copy it elsewhere, or build your scanner +using @samp{%array} instead (see How The Input Is Matched). + +Finally, note that you cannot put back @code{EOF} to attempt to +mark the input stream with an end-of-file. + +@item +@samp{input()} reads the next character from the input +stream. For example, the following is one way to +eat up C comments: + +@example +%% +"/*" @{ + register int c; + + for ( ; ; ) + @{ + while ( (c = input()) != '*' && + c != EOF ) + ; /* eat up text of comment */ + + if ( c == '*' ) + @{ + while ( (c = input()) == '*' ) + ; + if ( c == '/' ) + break; /* found the end */ + @} + + if ( c == EOF ) + @{ + error( "EOF in comment" ); + break; + @} + @} + @} +@end example + +(Note that if the scanner is compiled using @samp{C++}, +then @samp{input()} is instead referred to as @samp{yyinput()}, +in order to avoid a name clash with the @samp{C++} stream +by the name of @code{input}.) + +@item YY_FLUSH_BUFFER +flushes the scanner's internal buffer so that the next time the scanner +attempts to match a token, it will first refill the buffer using +@code{YY_INPUT} (see The Generated Scanner, below). This action is +a special case of the more general @samp{yy_flush_buffer()} function, +described below in the section Multiple Input Buffers. + +@item +@samp{yyterminate()} can be used in lieu of a return +statement in an action. It terminates the scanner +and returns a 0 to the scanner's caller, indicating +"all done". By default, @samp{yyterminate()} is also +called when an end-of-file is encountered. It is a +macro and may be redefined. +@end itemize + +@node Generated scanner, Start conditions, Actions, Top +@section The generated scanner + +The output of @code{flex} is the file @file{lex.yy.c}, which contains +the scanning routine @samp{yylex()}, a number of tables used by +it for matching tokens, and a number of auxiliary routines +and macros. By default, @samp{yylex()} is declared as follows: + +@example +int yylex() + @{ + @dots{} various definitions and the actions in here @dots{} + @} +@end example + +(If your environment supports function prototypes, then it +will be "int yylex( void )".) This definition may be +changed by defining the "YY_DECL" macro. For example, you +could use: + +@example +#define YY_DECL float lexscan( a, b ) float a, b; +@end example + +to give the scanning routine the name @code{lexscan}, returning a +float, and taking two floats as arguments. Note that if +you give arguments to the scanning routine using a +K&R-style/non-prototyped function declaration, you must +terminate the definition with a semi-colon (@samp{;}). + +Whenever @samp{yylex()} is called, it scans tokens from the +global input file @code{yyin} (which defaults to stdin). It +continues until it either reaches an end-of-file (at which +point it returns the value 0) or one of its actions +executes a @code{return} statement. + +If the scanner reaches an end-of-file, subsequent calls are undefined +unless either @code{yyin} is pointed at a new input file (in which case +scanning continues from that file), or @samp{yyrestart()} is called. +@samp{yyrestart()} takes one argument, a @samp{FILE *} pointer (which +can be nil, if you've set up @code{YY_INPUT} to scan from a source +other than @code{yyin}), and initializes @code{yyin} for scanning from +that file. Essentially there is no difference between just assigning +@code{yyin} to a new input file or using @samp{yyrestart()} to do so; +the latter is available for compatibility with previous versions of +@code{flex}, and because it can be used to switch input files in the +middle of scanning. It can also be used to throw away the current +input buffer, by calling it with an argument of @code{yyin}; but +better is to use @code{YY_FLUSH_BUFFER} (see above). Note that +@samp{yyrestart()} does @emph{not} reset the start condition to +@code{INITIAL} (see Start Conditions, below). + + +If @samp{yylex()} stops scanning due to executing a @code{return} +statement in one of the actions, the scanner may then be called +again and it will resume scanning where it left off. + +By default (and for purposes of efficiency), the scanner +uses block-reads rather than simple @samp{getc()} calls to read +characters from @code{yyin}. The nature of how it gets its input +can be controlled by defining the @code{YY_INPUT} macro. +YY_INPUT's calling sequence is +"YY_INPUT(buf,result,max_size)". Its action is to place +up to @var{max_size} characters in the character array @var{buf} and +return in the integer variable @var{result} either the number of +characters read or the constant YY_NULL (0 on Unix +systems) to indicate EOF. The default YY_INPUT reads from +the global file-pointer "yyin". + +A sample definition of YY_INPUT (in the definitions +section of the input file): + +@example +%@{ +#define YY_INPUT(buf,result,max_size) \ + @{ \ + int c = getchar(); \ + result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ + @} +%@} +@end example + +This definition will change the input processing to occur +one character at a time. + +When the scanner receives an end-of-file indication from +YY_INPUT, it then checks the @samp{yywrap()} function. If +@samp{yywrap()} returns false (zero), then it is assumed that the +function has gone ahead and set up @code{yyin} to point to +another input file, and scanning continues. If it returns +true (non-zero), then the scanner terminates, returning 0 +to its caller. Note that in either case, the start +condition remains unchanged; it does @emph{not} revert to @code{INITIAL}. + +If you do not supply your own version of @samp{yywrap()}, then you +must either use @samp{%option noyywrap} (in which case the scanner +behaves as though @samp{yywrap()} returned 1), or you must link with +@samp{-lfl} to obtain the default version of the routine, which always +returns 1. + +Three routines are available for scanning from in-memory +buffers rather than files: @samp{yy_scan_string()}, +@samp{yy_scan_bytes()}, and @samp{yy_scan_buffer()}. See the discussion +of them below in the section Multiple Input Buffers. + +The scanner writes its @samp{ECHO} output to the @code{yyout} global +(default, stdout), which may be redefined by the user +simply by assigning it to some other @code{FILE} pointer. + +@node Start conditions, Multiple buffers, Generated scanner, Top +@section Start conditions + +@code{flex} provides a mechanism for conditionally activating +rules. Any rule whose pattern is prefixed with "" +will only be active when the scanner is in the start +condition named "sc". For example, + +@example +[^"]* @{ /* eat up the string body ... */ + @dots{} + @} +@end example + +@noindent +will be active only when the scanner is in the "STRING" +start condition, and + +@example +\. @{ /* handle an escape ... */ + @dots{} + @} +@end example + +@noindent +will be active only when the current start condition is +either "INITIAL", "STRING", or "QUOTE". + +Start conditions are declared in the definitions (first) +section of the input using unindented lines beginning with +either @samp{%s} or @samp{%x} followed by a list of names. The former +declares @emph{inclusive} start conditions, the latter @emph{exclusive} +start conditions. A start condition is activated using +the @code{BEGIN} action. Until the next @code{BEGIN} action is +executed, rules with the given start condition will be active +and rules with other start conditions will be inactive. +If the start condition is @emph{inclusive}, then rules with no +start conditions at all will also be active. If it is +@emph{exclusive}, then @emph{only} rules qualified with the start +condition will be active. A set of rules contingent on the +same exclusive start condition describe a scanner which is +independent of any of the other rules in the @code{flex} input. +Because of this, exclusive start conditions make it easy +to specify "mini-scanners" which scan portions of the +input that are syntactically different from the rest +(e.g., comments). + +If the distinction between inclusive and exclusive start +conditions is still a little vague, here's a simple +example illustrating the connection between the two. The set +of rules: + +@example +%s example +%% + +foo do_something(); + +bar something_else(); +@end example + +@noindent +is equivalent to + +@example +%x example +%% + +foo do_something(); + +bar something_else(); +@end example + +Without the @samp{} qualifier, the @samp{bar} pattern +in the second example wouldn't be active (i.e., couldn't match) when +in start condition @samp{example}. If we just used @samp{} +to qualify @samp{bar}, though, then it would only be active in +@samp{example} and not in @code{INITIAL}, while in the first example +it's active in both, because in the first example the @samp{example} +starting condition is an @emph{inclusive} (@samp{%s}) start condition. + +Also note that the special start-condition specifier @samp{<*>} +matches every start condition. Thus, the above example +could also have been written; + +@example +%x example +%% + +foo do_something(); + +<*>bar something_else(); +@end example + +The default rule (to @samp{ECHO} any unmatched character) remains +active in start conditions. It is equivalent to: + +@example +<*>.|\\n ECHO; +@end example + +@samp{BEGIN(0)} returns to the original state where only the +rules with no start conditions are active. This state can +also be referred to as the start-condition "INITIAL", so +@samp{BEGIN(INITIAL)} is equivalent to @samp{BEGIN(0)}. (The +parentheses around the start condition name are not required but +are considered good style.) + +@code{BEGIN} actions can also be given as indented code at the +beginning of the rules section. For example, the +following will cause the scanner to enter the "SPECIAL" start +condition whenever @samp{yylex()} is called and the global +variable @code{enter_special} is true: + +@example + int enter_special; + +%x SPECIAL +%% + if ( enter_special ) + BEGIN(SPECIAL); + +blahblahblah +@dots{}more rules follow@dots{} +@end example + +To illustrate the uses of start conditions, here is a +scanner which provides two different interpretations of a +string like "123.456". By default it will treat it as as +three tokens, the integer "123", a dot ('.'), and the +integer "456". But if the string is preceded earlier in +the line by the string "expect-floats" it will treat it as +a single token, the floating-point number 123.456: + +@example +%@{ +#include +%@} +%s expect + +%% +expect-floats BEGIN(expect); + +[0-9]+"."[0-9]+ @{ + printf( "found a float, = %f\n", + atof( yytext ) ); + @} +\n @{ + /* that's the end of the line, so + * we need another "expect-number" + * before we'll recognize any more + * numbers + */ + BEGIN(INITIAL); + @} + +[0-9]+ @{ + +Version 2.5 December 1994 18 + + printf( "found an integer, = %d\n", + atoi( yytext ) ); + @} + +"." printf( "found a dot\n" ); +@end example + +Here is a scanner which recognizes (and discards) C +comments while maintaining a count of the current input line. + +@example +%x comment +%% + int line_num = 1; + +"/*" BEGIN(comment); + +[^*\n]* /* eat anything that's not a '*' */ +"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ +\n ++line_num; +"*"+"/" BEGIN(INITIAL); +@end example + +This scanner goes to a bit of trouble to match as much +text as possible with each rule. In general, when +attempting to write a high-speed scanner try to match as +much possible in each rule, as it's a big win. + +Note that start-conditions names are really integer values +and can be stored as such. Thus, the above could be +extended in the following fashion: + +@example +%x comment foo +%% + int line_num = 1; + int comment_caller; + +"/*" @{ + comment_caller = INITIAL; + BEGIN(comment); + @} + +@dots{} + +"/*" @{ + comment_caller = foo; + BEGIN(comment); + @} + +[^*\n]* /* eat anything that's not a '*' */ +"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ +\n ++line_num; +"*"+"/" BEGIN(comment_caller); +@end example + +Furthermore, you can access the current start condition +using the integer-valued @code{YY_START} macro. For example, the +above assignments to @code{comment_caller} could instead be +written + +@example +comment_caller = YY_START; +@end example + +Flex provides @code{YYSTATE} as an alias for @code{YY_START} (since that +is what's used by AT&T @code{lex}). + +Note that start conditions do not have their own +name-space; %s's and %x's declare names in the same fashion as +#define's. + +Finally, here's an example of how to match C-style quoted +strings using exclusive start conditions, including +expanded escape sequences (but not including checking for +a string that's too long): + +@example +%x str + +%% + char string_buf[MAX_STR_CONST]; + char *string_buf_ptr; + +\" string_buf_ptr = string_buf; BEGIN(str); + +\" @{ /* saw closing quote - all done */ + BEGIN(INITIAL); + *string_buf_ptr = '\0'; + /* return string constant token type and + * value to parser + */ + @} + +\n @{ + /* error - unterminated string constant */ + /* generate error message */ + @} + +\\[0-7]@{1,3@} @{ + /* octal escape sequence */ + int result; + + (void) sscanf( yytext + 1, "%o", &result ); + + if ( result > 0xff ) + /* error, constant is out-of-bounds */ + + *string_buf_ptr++ = result; + @} + +\\[0-9]+ @{ + /* generate error - bad escape sequence; something + * like '\48' or '\0777777' + */ + @} + +\\n *string_buf_ptr++ = '\n'; +\\t *string_buf_ptr++ = '\t'; +\\r *string_buf_ptr++ = '\r'; +\\b *string_buf_ptr++ = '\b'; +\\f *string_buf_ptr++ = '\f'; + +\\(.|\n) *string_buf_ptr++ = yytext[1]; + +[^\\\n\"]+ @{ + char *yptr = yytext; + + while ( *yptr ) + *string_buf_ptr++ = *yptr++; + @} +@end example + +Often, such as in some of the examples above, you wind up +writing a whole bunch of rules all preceded by the same +start condition(s). Flex makes this a little easier and +cleaner by introducing a notion of start condition @dfn{scope}. +A start condition scope is begun with: + +@example +@{ +@end example + +@noindent +where SCs is a list of one or more start conditions. +Inside the start condition scope, every rule automatically +has the prefix @samp{} applied to it, until a @samp{@}} which +matches the initial @samp{@{}. So, for example, + +@example +@{ + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; +@} +@end example + +@noindent +is equivalent to: + +@example +"\\n" return '\n'; +"\\r" return '\r'; +"\\f" return '\f'; +"\\0" return '\0'; +@end example + +Start condition scopes may be nested. + +Three routines are available for manipulating stacks of +start conditions: + +@table @samp +@item void yy_push_state(int new_state) +pushes the current start condition onto the top of +the start condition stack and switches to @var{new_state} +as though you had used @samp{BEGIN new_state} (recall that +start condition names are also integers). + +@item void yy_pop_state() +pops the top of the stack and switches to it via +@code{BEGIN}. + +@item int yy_top_state() +returns the top of the stack without altering the +stack's contents. +@end table + +The start condition stack grows dynamically and so has no +built-in size limitation. If memory is exhausted, program +execution aborts. + +To use start condition stacks, your scanner must include a +@samp{%option stack} directive (see Options below). + +@node Multiple buffers, End-of-file rules, Start conditions, Top +@section Multiple input buffers + +Some scanners (such as those which support "include" +files) require reading from several input streams. As +@code{flex} scanners do a large amount of buffering, one cannot +control where the next input will be read from by simply +writing a @code{YY_INPUT} which is sensitive to the scanning +context. @code{YY_INPUT} is only called when the scanner reaches +the end of its buffer, which may be a long time after +scanning a statement such as an "include" which requires +switching the input source. + +To negotiate these sorts of problems, @code{flex} provides a +mechanism for creating and switching between multiple +input buffers. An input buffer is created by using: + +@example +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +@end example + +@noindent +which takes a @code{FILE} pointer and a size and creates a buffer +associated with the given file and large enough to hold +@var{size} characters (when in doubt, use @code{YY_BUF_SIZE} for the +size). It returns a @code{YY_BUFFER_STATE} handle, which may +then be passed to other routines (see below). The +@code{YY_BUFFER_STATE} type is a pointer to an opaque @code{struct} +@code{yy_buffer_state} structure, so you may safely initialize +YY_BUFFER_STATE variables to @samp{((YY_BUFFER_STATE) 0)} if you +wish, and also refer to the opaque structure in order to +correctly declare input buffers in source files other than +that of your scanner. Note that the @code{FILE} pointer in the +call to @code{yy_create_buffer} is only used as the value of @code{yyin} +seen by @code{YY_INPUT}; if you redefine @code{YY_INPUT} so it no longer +uses @code{yyin}, then you can safely pass a nil @code{FILE} pointer to +@code{yy_create_buffer}. You select a particular buffer to scan +from using: + +@example +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +@end example + +switches the scanner's input buffer so subsequent tokens +will come from @var{new_buffer}. Note that +@samp{yy_switch_to_buffer()} may be used by @samp{yywrap()} to set +things up for continued scanning, instead of opening a new +file and pointing @code{yyin} at it. Note also that switching +input sources via either @samp{yy_switch_to_buffer()} or @samp{yywrap()} +does @emph{not} change the start condition. + +@example +void yy_delete_buffer( YY_BUFFER_STATE buffer ) +@end example + +@noindent +is used to reclaim the storage associated with a buffer. +You can also clear the current contents of a buffer using: + +@example +void yy_flush_buffer( YY_BUFFER_STATE buffer ) +@end example + +This function discards the buffer's contents, so the next time the +scanner attempts to match a token from the buffer, it will first fill +the buffer anew using @code{YY_INPUT}. + +@samp{yy_new_buffer()} is an alias for @samp{yy_create_buffer()}, +provided for compatibility with the C++ use of @code{new} and @code{delete} +for creating and destroying dynamic objects. + +Finally, the @code{YY_CURRENT_BUFFER} macro returns a +@code{YY_BUFFER_STATE} handle to the current buffer. + +Here is an example of using these features for writing a +scanner which expands include files (the @samp{<>} feature +is discussed below): + +@example +/* the "incl" state is used for picking up the name + * of an include file + */ +%x incl + +%@{ +#define MAX_INCLUDE_DEPTH 10 +YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +int include_stack_ptr = 0; +%@} + +%% +include BEGIN(incl); + +[a-z]+ ECHO; +[^a-z\n]*\n? ECHO; + +[ \t]* /* eat the whitespace */ +[^ \t\n]+ @{ /* got the include file name */ + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) + @{ + fprintf( stderr, "Includes nested too deeply" ); + exit( 1 ); + @} + + include_stack[include_stack_ptr++] = + YY_CURRENT_BUFFER; + + yyin = fopen( yytext, "r" ); + + if ( ! yyin ) + error( @dots{} ); + + yy_switch_to_buffer( + yy_create_buffer( yyin, YY_BUF_SIZE ) ); + + BEGIN(INITIAL); + @} + +<> @{ + if ( --include_stack_ptr < 0 ) + @{ + yyterminate(); + @} + + else + @{ + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( + include_stack[include_stack_ptr] ); + @} + @} +@end example + +Three routines are available for setting up input buffers +for scanning in-memory strings instead of files. All of +them create a new input buffer for scanning the string, +and return a corresponding @code{YY_BUFFER_STATE} handle (which +you should delete with @samp{yy_delete_buffer()} when done with +it). They also switch to the new buffer using +@samp{yy_switch_to_buffer()}, so the next call to @samp{yylex()} will +start scanning the string. + +@table @samp +@item yy_scan_string(const char *str) +scans a NUL-terminated string. + +@item yy_scan_bytes(const char *bytes, int len) +scans @code{len} bytes (including possibly NUL's) starting +at location @var{bytes}. +@end table + +Note that both of these functions create and scan a @emph{copy} +of the string or bytes. (This may be desirable, since +@samp{yylex()} modifies the contents of the buffer it is +scanning.) You can avoid the copy by using: + +@table @samp +@item yy_scan_buffer(char *base, yy_size_t size) +which scans in place the buffer starting at @var{base}, +consisting of @var{size} bytes, the last two bytes of +which @emph{must} be @code{YY_END_OF_BUFFER_CHAR} (ASCII NUL). +These last two bytes are not scanned; thus, +scanning consists of @samp{base[0]} through @samp{base[size-2]}, +inclusive. + +If you fail to set up @var{base} in this manner (i.e., +forget the final two @code{YY_END_OF_BUFFER_CHAR} bytes), +then @samp{yy_scan_buffer()} returns a nil pointer instead +of creating a new input buffer. + +The type @code{yy_size_t} is an integral type to which you +can cast an integer expression reflecting the size +of the buffer. +@end table + +@node End-of-file rules, Miscellaneous, Multiple buffers, Top +@section End-of-file rules + +The special rule "<>" indicates actions which are to +be taken when an end-of-file is encountered and yywrap() +returns non-zero (i.e., indicates no further files to +process). The action must finish by doing one of four +things: + +@itemize - +@item +assigning @code{yyin} to a new input file (in previous +versions of flex, after doing the assignment you +had to call the special action @code{YY_NEW_FILE}; this is +no longer necessary); + +@item +executing a @code{return} statement; + +@item +executing the special @samp{yyterminate()} action; + +@item +or, switching to a new buffer using +@samp{yy_switch_to_buffer()} as shown in the example +above. +@end itemize + +<> rules may not be used with other patterns; they +may only be qualified with a list of start conditions. If +an unqualified <> rule is given, it applies to @emph{all} +start conditions which do not already have <> +actions. To specify an <> rule for only the initial +start condition, use + +@example +<> +@end example + +These rules are useful for catching things like unclosed +comments. An example: + +@example +%x quote +%% + +@dots{}other rules for dealing with quotes@dots{} + +<> @{ + error( "unterminated quote" ); + yyterminate(); + @} +<> @{ + if ( *++filelist ) + yyin = fopen( *filelist, "r" ); + else + yyterminate(); + @} +@end example + +@node Miscellaneous, User variables, End-of-file rules, Top +@section Miscellaneous macros + +The macro @code{YY_USER_ACTION} can be defined to provide an +action which is always executed prior to the matched +rule's action. For example, it could be #define'd to call +a routine to convert yytext to lower-case. When +@code{YY_USER_ACTION} is invoked, the variable @code{yy_act} gives the +number of the matched rule (rules are numbered starting +with 1). Suppose you want to profile how often each of +your rules is matched. The following would do the trick: + +@example +#define YY_USER_ACTION ++ctr[yy_act] +@end example + +where @code{ctr} is an array to hold the counts for the different +rules. Note that the macro @code{YY_NUM_RULES} gives the total number +of rules (including the default rule, even if you use @samp{-s}, so +a correct declaration for @code{ctr} is: + +@example +int ctr[YY_NUM_RULES]; +@end example + +The macro @code{YY_USER_INIT} may be defined to provide an action +which is always executed before the first scan (and before +the scanner's internal initializations are done). For +example, it could be used to call a routine to read in a +data table or open a logging file. + +The macro @samp{yy_set_interactive(is_interactive)} can be used +to control whether the current buffer is considered +@emph{interactive}. An interactive buffer is processed more slowly, +but must be used when the scanner's input source is indeed +interactive to avoid problems due to waiting to fill +buffers (see the discussion of the @samp{-I} flag below). A +non-zero value in the macro invocation marks the buffer as +interactive, a zero value as non-interactive. Note that +use of this macro overrides @samp{%option always-interactive} or +@samp{%option never-interactive} (see Options below). +@samp{yy_set_interactive()} must be invoked prior to beginning to +scan the buffer that is (or is not) to be considered +interactive. + +The macro @samp{yy_set_bol(at_bol)} can be used to control +whether the current buffer's scanning context for the next +token match is done as though at the beginning of a line. +A non-zero macro argument makes rules anchored with + +The macro @samp{YY_AT_BOL()} returns true if the next token +scanned from the current buffer will have '^' rules +active, false otherwise. + +In the generated scanner, the actions are all gathered in +one large switch statement and separated using @code{YY_BREAK}, +which may be redefined. By default, it is simply a +"break", to separate each rule's action from the following +rule's. Redefining @code{YY_BREAK} allows, for example, C++ +users to #define YY_BREAK to do nothing (while being very +careful that every rule ends with a "break" or a +"return"!) to avoid suffering from unreachable statement +warnings where because a rule's action ends with "return", +the @code{YY_BREAK} is inaccessible. + +@node User variables, YACC interface, Miscellaneous, Top +@section Values available to the user + +This section summarizes the various values available to +the user in the rule actions. + +@itemize - +@item +@samp{char *yytext} holds the text of the current token. +It may be modified but not lengthened (you cannot +append characters to the end). + +If the special directive @samp{%array} appears in the +first section of the scanner description, then +@code{yytext} is instead declared @samp{char yytext[YYLMAX]}, +where @code{YYLMAX} is a macro definition that you can +redefine in the first section if you don't like the +default value (generally 8KB). Using @samp{%array} +results in somewhat slower scanners, but the value +of @code{yytext} becomes immune to calls to @samp{input()} and +@samp{unput()}, which potentially destroy its value when +@code{yytext} is a character pointer. The opposite of +@samp{%array} is @samp{%pointer}, which is the default. + +You cannot use @samp{%array} when generating C++ scanner +classes (the @samp{-+} flag). + +@item +@samp{int yyleng} holds the length of the current token. + +@item +@samp{FILE *yyin} is the file which by default @code{flex} reads +from. It may be redefined but doing so only makes +sense before scanning begins or after an EOF has +been encountered. Changing it in the midst of +scanning will have unexpected results since @code{flex} +buffers its input; use @samp{yyrestart()} instead. Once +scanning terminates because an end-of-file has been +seen, you can assign @code{yyin} at the new input file and +then call the scanner again to continue scanning. + +@item +@samp{void yyrestart( FILE *new_file )} may be called to +point @code{yyin} at the new input file. The switch-over +to the new file is immediate (any previously +buffered-up input is lost). Note that calling +@samp{yyrestart()} with @code{yyin} as an argument thus throws +away the current input buffer and continues +scanning the same input file. + +@item +@samp{FILE *yyout} is the file to which @samp{ECHO} actions are +done. It can be reassigned by the user. + +@item +@code{YY_CURRENT_BUFFER} returns a @code{YY_BUFFER_STATE} handle +to the current buffer. + +@item +@code{YY_START} returns an integer value corresponding to +the current start condition. You can subsequently +use this value with @code{BEGIN} to return to that start +condition. +@end itemize + +@node YACC interface, Options, User variables, Top +@section Interfacing with @code{yacc} + +One of the main uses of @code{flex} is as a companion to the @code{yacc} +parser-generator. @code{yacc} parsers expect to call a routine +named @samp{yylex()} to find the next input token. The routine +is supposed to return the type of the next token as well +as putting any associated value in the global @code{yylval}. To +use @code{flex} with @code{yacc}, one specifies the @samp{-d} option to @code{yacc} to +instruct it to generate the file @file{y.tab.h} containing +definitions of all the @samp{%tokens} appearing in the @code{yacc} input. +This file is then included in the @code{flex} scanner. For +example, if one of the tokens is "TOK_NUMBER", part of the +scanner might look like: + +@example +%@{ +#include "y.tab.h" +%@} + +%% + +[0-9]+ yylval = atoi( yytext ); return TOK_NUMBER; +@end example + +@node Options, Performance, YACC interface, Top +@section Options +@code{flex} has the following options: + +@table @samp +@item -b +Generate backing-up information to @file{lex.backup}. +This is a list of scanner states which require +backing up and the input characters on which they +do so. By adding rules one can remove backing-up +states. If @emph{all} backing-up states are eliminated +and @samp{-Cf} or @samp{-CF} is used, the generated scanner will +run faster (see the @samp{-p} flag). Only users who wish +to squeeze every last cycle out of their scanners +need worry about this option. (See the section on +Performance Considerations below.) + +@item -c +is a do-nothing, deprecated option included for +POSIX compliance. + +@item -d +makes the generated scanner run in @dfn{debug} mode. +Whenever a pattern is recognized and the global +@code{yy_flex_debug} is non-zero (which is the default), +the scanner will write to @code{stderr} a line of the +form: + +@example +--accepting rule at line 53 ("the matched text") +@end example + +The line number refers to the location of the rule +in the file defining the scanner (i.e., the file +that was fed to flex). Messages are also generated +when the scanner backs up, accepts the default +rule, reaches the end of its input buffer (or +encounters a NUL; at this point, the two look the +same as far as the scanner's concerned), or reaches +an end-of-file. + +@item -f +specifies @dfn{fast scanner}. No table compression is +done and stdio is bypassed. The result is large +but fast. This option is equivalent to @samp{-Cfr} (see +below). + +@item -h +generates a "help" summary of @code{flex's} options to +@code{stdout} and then exits. @samp{-?} and @samp{--help} are synonyms +for @samp{-h}. + +@item -i +instructs @code{flex} to generate a @emph{case-insensitive} +scanner. The case of letters given in the @code{flex} input +patterns will be ignored, and tokens in the input +will be matched regardless of case. The matched +text given in @code{yytext} will have the preserved case +(i.e., it will not be folded). + +@item -l +turns on maximum compatibility with the original +AT&T @code{lex} implementation. Note that this does not +mean @emph{full} compatibility. Use of this option costs +a considerable amount of performance, and it cannot +be used with the @samp{-+, -f, -F, -Cf}, or @samp{-CF} options. +For details on the compatibilities it provides, see +the section "Incompatibilities With Lex And POSIX" +below. This option also results in the name +@code{YY_FLEX_LEX_COMPAT} being #define'd in the generated +scanner. + +@item -n +is another do-nothing, deprecated option included +only for POSIX compliance. + +@item -p +generates a performance report to stderr. The +report consists of comments regarding features of +the @code{flex} input file which will cause a serious loss +of performance in the resulting scanner. If you +give the flag twice, you will also get comments +regarding features that lead to minor performance +losses. + +Note that the use of @code{REJECT}, @samp{%option yylineno} and +variable trailing context (see the Deficiencies / Bugs section below) +entails a substantial performance penalty; use of @samp{yymore()}, +the @samp{^} operator, and the @samp{-I} flag entail minor performance +penalties. + +@item -s +causes the @dfn{default rule} (that unmatched scanner +input is echoed to @code{stdout}) to be suppressed. If +the scanner encounters input that does not match +any of its rules, it aborts with an error. This +option is useful for finding holes in a scanner's +rule set. + +@item -t +instructs @code{flex} to write the scanner it generates to +standard output instead of @file{lex.yy.c}. + +@item -v +specifies that @code{flex} should write to @code{stderr} a +summary of statistics regarding the scanner it +generates. Most of the statistics are meaningless to +the casual @code{flex} user, but the first line identifies +the version of @code{flex} (same as reported by @samp{-V}), and +the next line the flags used when generating the +scanner, including those that are on by default. + +@item -w +suppresses warning messages. + +@item -B +instructs @code{flex} to generate a @emph{batch} scanner, the +opposite of @emph{interactive} scanners generated by @samp{-I} +(see below). In general, you use @samp{-B} when you are +@emph{certain} that your scanner will never be used +interactively, and you want to squeeze a @emph{little} more +performance out of it. If your goal is instead to +squeeze out a @emph{lot} more performance, you should be +using the @samp{-Cf} or @samp{-CF} options (discussed below), +which turn on @samp{-B} automatically anyway. + +@item -F +specifies that the @dfn{fast} scanner table +representation should be used (and stdio bypassed). This +representation is about as fast as the full table +representation @samp{(-f)}, and for some sets of patterns +will be considerably smaller (and for others, +larger). In general, if the pattern set contains +both "keywords" and a catch-all, "identifier" rule, +such as in the set: + +@example +"case" return TOK_CASE; +"switch" return TOK_SWITCH; +... +"default" return TOK_DEFAULT; +[a-z]+ return TOK_ID; +@end example + +@noindent +then you're better off using the full table +representation. If only the "identifier" rule is +present and you then use a hash table or some such to +detect the keywords, you're better off using @samp{-F}. + +This option is equivalent to @samp{-CFr} (see below). It +cannot be used with @samp{-+}. + +@item -I +instructs @code{flex} to generate an @emph{interactive} scanner. +An interactive scanner is one that only looks ahead +to decide what token has been matched if it +absolutely must. It turns out that always looking one +extra character ahead, even if the scanner has +already seen enough text to disambiguate the +current token, is a bit faster than only looking ahead +when necessary. But scanners that always look +ahead give dreadful interactive performance; for +example, when a user types a newline, it is not +recognized as a newline token until they enter +@emph{another} token, which often means typing in another +whole line. + +@code{Flex} scanners default to @emph{interactive} unless you use +the @samp{-Cf} or @samp{-CF} table-compression options (see +below). That's because if you're looking for +high-performance you should be using one of these +options, so if you didn't, @code{flex} assumes you'd +rather trade off a bit of run-time performance for +intuitive interactive behavior. Note also that you +@emph{cannot} use @samp{-I} in conjunction with @samp{-Cf} or @samp{-CF}. +Thus, this option is not really needed; it is on by +default for all those cases in which it is allowed. + +You can force a scanner to @emph{not} be interactive by +using @samp{-B} (see above). + +@item -L +instructs @code{flex} not to generate @samp{#line} directives. +Without this option, @code{flex} peppers the generated +scanner with #line directives so error messages in +the actions will be correctly located with respect +to either the original @code{flex} input file (if the +errors are due to code in the input file), or +@file{lex.yy.c} (if the errors are @code{flex's} fault -- you +should report these sorts of errors to the email +address given below). + +@item -T +makes @code{flex} run in @code{trace} mode. It will generate a +lot of messages to @code{stderr} concerning the form of +the input and the resultant non-deterministic and +deterministic finite automata. This option is +mostly for use in maintaining @code{flex}. + +@item -V +prints the version number to @code{stdout} and exits. +@samp{--version} is a synonym for @samp{-V}. + +@item -7 +instructs @code{flex} to generate a 7-bit scanner, i.e., +one which can only recognized 7-bit characters in +its input. The advantage of using @samp{-7} is that the +scanner's tables can be up to half the size of +those generated using the @samp{-8} option (see below). +The disadvantage is that such scanners often hang +or crash if their input contains an 8-bit +character. + +Note, however, that unless you generate your +scanner using the @samp{-Cf} or @samp{-CF} table compression options, +use of @samp{-7} will save only a small amount of table +space, and make your scanner considerably less +portable. @code{Flex's} default behavior is to generate +an 8-bit scanner unless you use the @samp{-Cf} or @samp{-CF}, in +which case @code{flex} defaults to generating 7-bit +scanners unless your site was always configured to +generate 8-bit scanners (as will often be the case +with non-USA sites). You can tell whether flex +generated a 7-bit or an 8-bit scanner by inspecting +the flag summary in the @samp{-v} output as described +above. + +Note that if you use @samp{-Cfe} or @samp{-CFe} (those table +compression options, but also using equivalence +classes as discussed see below), flex still +defaults to generating an 8-bit scanner, since +usually with these compression options full 8-bit +tables are not much more expensive than 7-bit +tables. + +@item -8 +instructs @code{flex} to generate an 8-bit scanner, i.e., +one which can recognize 8-bit characters. This +flag is only needed for scanners generated using +@samp{-Cf} or @samp{-CF}, as otherwise flex defaults to +generating an 8-bit scanner anyway. + +See the discussion of @samp{-7} above for flex's default +behavior and the tradeoffs between 7-bit and 8-bit +scanners. + +@item -+ +specifies that you want flex to generate a C++ +scanner class. See the section on Generating C++ +Scanners below for details. + +@item -C[aefFmr] +controls the degree of table compression and, more +generally, trade-offs between small scanners and +fast scanners. + +@samp{-Ca} ("align") instructs flex to trade off larger +tables in the generated scanner for faster +performance because the elements of the tables are better +aligned for memory access and computation. On some +RISC architectures, fetching and manipulating +long-words is more efficient than with smaller-sized +units such as shortwords. This option can double +the size of the tables used by your scanner. + +@samp{-Ce} directs @code{flex} to construct @dfn{equivalence classes}, +i.e., sets of characters which have identical +lexical properties (for example, if the only appearance +of digits in the @code{flex} input is in the character +class "[0-9]" then the digits '0', '1', @dots{}, '9' +will all be put in the same equivalence class). +Equivalence classes usually give dramatic +reductions in the final table/object file sizes +(typically a factor of 2-5) and are pretty cheap +performance-wise (one array look-up per character +scanned). + +@samp{-Cf} specifies that the @emph{full} scanner tables should +be generated - @code{flex} should not compress the tables +by taking advantages of similar transition +functions for different states. + +@samp{-CF} specifies that the alternate fast scanner +representation (described above under the @samp{-F} flag) +should be used. This option cannot be used with +@samp{-+}. + +@samp{-Cm} directs @code{flex} to construct @dfn{meta-equivalence +classes}, which are sets of equivalence classes (or +characters, if equivalence classes are not being +used) that are commonly used together. +Meta-equivalence classes are often a big win when using +compressed tables, but they have a moderate +performance impact (one or two "if" tests and one array +look-up per character scanned). + +@samp{-Cr} causes the generated scanner to @emph{bypass} use of +the standard I/O library (stdio) for input. +Instead of calling @samp{fread()} or @samp{getc()}, the scanner +will use the @samp{read()} system call, resulting in a +performance gain which varies from system to +system, but in general is probably negligible unless +you are also using @samp{-Cf} or @samp{-CF}. Using @samp{-Cr} can cause +strange behavior if, for example, you read from +@code{yyin} using stdio prior to calling the scanner +(because the scanner will miss whatever text your +previous reads left in the stdio input buffer). + +@samp{-Cr} has no effect if you define @code{YY_INPUT} (see The +Generated Scanner above). + +A lone @samp{-C} specifies that the scanner tables should +be compressed but neither equivalence classes nor +meta-equivalence classes should be used. + +The options @samp{-Cf} or @samp{-CF} and @samp{-Cm} do not make sense +together - there is no opportunity for +meta-equivalence classes if the table is not being +compressed. Otherwise the options may be freely +mixed, and are cumulative. + +The default setting is @samp{-Cem}, which specifies that +@code{flex} should generate equivalence classes and +meta-equivalence classes. This setting provides the +highest degree of table compression. You can trade +off faster-executing scanners at the cost of larger +tables with the following generally being true: + +@example +slowest & smallest + -Cem + -Cm + -Ce + -C + -C@{f,F@}e + -C@{f,F@} + -C@{f,F@}a +fastest & largest +@end example + +Note that scanners with the smallest tables are +usually generated and compiled the quickest, so +during development you will usually want to use the +default, maximal compression. + +@samp{-Cfe} is often a good compromise between speed and +size for production scanners. + +@item -ooutput +directs flex to write the scanner to the file @samp{out-} +@code{put} instead of @file{lex.yy.c}. If you combine @samp{-o} with +the @samp{-t} option, then the scanner is written to +@code{stdout} but its @samp{#line} directives (see the @samp{-L} option +above) refer to the file @code{output}. + +@item -Pprefix +changes the default @samp{yy} prefix used by @code{flex} for all +globally-visible variable and function names to +instead be @var{prefix}. For example, @samp{-Pfoo} changes the +name of @code{yytext} to @file{footext}. It also changes the +name of the default output file from @file{lex.yy.c} to +@file{lex.foo.c}. Here are all of the names affected: + +@example +yy_create_buffer +yy_delete_buffer +yy_flex_debug +yy_init_buffer +yy_flush_buffer +yy_load_buffer_state +yy_switch_to_buffer +yyin +yyleng +yylex +yylineno +yyout +yyrestart +yytext +yywrap +@end example + +(If you are using a C++ scanner, then only @code{yywrap} +and @code{yyFlexLexer} are affected.) Within your scanner +itself, you can still refer to the global variables +and functions using either version of their name; +but externally, they have the modified name. + +This option lets you easily link together multiple +@code{flex} programs into the same executable. Note, +though, that using this option also renames +@samp{yywrap()}, so you now @emph{must} either provide your own +(appropriately-named) version of the routine for +your scanner, or use @samp{%option noyywrap}, as linking +with @samp{-lfl} no longer provides one for you by +default. + +@item -Sskeleton_file +overrides the default skeleton file from which @code{flex} +constructs its scanners. You'll never need this +option unless you are doing @code{flex} maintenance or +development. +@end table + +@code{flex} also provides a mechanism for controlling options +within the scanner specification itself, rather than from +the flex command-line. This is done by including @samp{%option} +directives in the first section of the scanner +specification. You can specify multiple options with a single +@samp{%option} directive, and multiple directives in the first +section of your flex input file. Most options are given +simply as names, optionally preceded by the word "no" +(with no intervening whitespace) to negate their meaning. +A number are equivalent to flex flags or their negation: + +@example +7bit -7 option +8bit -8 option +align -Ca option +backup -b option +batch -B option +c++ -+ option + +caseful or +case-sensitive opposite of -i (default) + +case-insensitive or +caseless -i option + +debug -d option +default opposite of -s option +ecs -Ce option +fast -F option +full -f option +interactive -I option +lex-compat -l option +meta-ecs -Cm option +perf-report -p option +read -Cr option +stdout -t option +verbose -v option +warn opposite of -w option + (use "%option nowarn" for -w) + +array equivalent to "%array" +pointer equivalent to "%pointer" (default) +@end example + +Some @samp{%option's} provide features otherwise not available: + +@table @samp +@item always-interactive +instructs flex to generate a scanner which always +considers its input "interactive". Normally, on +each new input file the scanner calls @samp{isatty()} in +an attempt to determine whether the scanner's input +source is interactive and thus should be read a +character at a time. When this option is used, +however, then no such call is made. + +@item main +directs flex to provide a default @samp{main()} program +for the scanner, which simply calls @samp{yylex()}. This +option implies @code{noyywrap} (see below). + +@item never-interactive +instructs flex to generate a scanner which never +considers its input "interactive" (again, no call +made to @samp{isatty())}. This is the opposite of @samp{always-} +@emph{interactive}. + +@item stack +enables the use of start condition stacks (see +Start Conditions above). + +@item stdinit +if unset (i.e., @samp{%option nostdinit}) initializes @code{yyin} +and @code{yyout} to nil @code{FILE} pointers, instead of @code{stdin} +and @code{stdout}. + +@item yylineno +directs @code{flex} to generate a scanner that maintains the number +of the current line read from its input in the global variable +@code{yylineno}. This option is implied by @samp{%option lex-compat}. + +@item yywrap +if unset (i.e., @samp{%option noyywrap}), makes the +scanner not call @samp{yywrap()} upon an end-of-file, but +simply assume that there are no more files to scan +(until the user points @code{yyin} at a new file and calls +@samp{yylex()} again). +@end table + +@code{flex} scans your rule actions to determine whether you use +the @code{REJECT} or @samp{yymore()} features. The @code{reject} and @code{yymore} +options are available to override its decision as to +whether you use the options, either by setting them (e.g., +@samp{%option reject}) to indicate the feature is indeed used, or +unsetting them to indicate it actually is not used (e.g., +@samp{%option noyymore}). + +Three options take string-delimited values, offset with '=': + +@example +%option outfile="ABC" +@end example + +@noindent +is equivalent to @samp{-oABC}, and + +@example +%option prefix="XYZ" +@end example + +@noindent +is equivalent to @samp{-PXYZ}. + +Finally, + +@example +%option yyclass="foo" +@end example + +@noindent +only applies when generating a C++ scanner (@samp{-+} option). It +informs @code{flex} that you have derived @samp{foo} as a subclass of +@code{yyFlexLexer} so @code{flex} will place your actions in the member +function @samp{foo::yylex()} instead of @samp{yyFlexLexer::yylex()}. +It also generates a @samp{yyFlexLexer::yylex()} member function that +emits a run-time error (by invoking @samp{yyFlexLexer::LexerError()}) +if called. See Generating C++ Scanners, below, for additional +information. + +A number of options are available for lint purists who +want to suppress the appearance of unneeded routines in +the generated scanner. Each of the following, if unset, +results in the corresponding routine not appearing in the +generated scanner: + +@example +input, unput +yy_push_state, yy_pop_state, yy_top_state +yy_scan_buffer, yy_scan_bytes, yy_scan_string +@end example + +@noindent +(though @samp{yy_push_state()} and friends won't appear anyway +unless you use @samp{%option stack}). + +@node Performance, C++, Options, Top +@section Performance considerations + +The main design goal of @code{flex} is that it generate +high-performance scanners. It has been optimized for dealing +well with large sets of rules. Aside from the effects on +scanner speed of the table compression @samp{-C} options outlined +above, there are a number of options/actions which degrade +performance. These are, from most expensive to least: + +@example +REJECT +%option yylineno +arbitrary trailing context + +pattern sets that require backing up +%array +%option interactive +%option always-interactive + +'^' beginning-of-line operator +yymore() +@end example + +with the first three all being quite expensive and the +last two being quite cheap. Note also that @samp{unput()} is +implemented as a routine call that potentially does quite +a bit of work, while @samp{yyless()} is a quite-cheap macro; so +if just putting back some excess text you scanned, use +@samp{yyless()}. + +@code{REJECT} should be avoided at all costs when performance is +important. It is a particularly expensive option. + +Getting rid of backing up is messy and often may be an +enormous amount of work for a complicated scanner. In +principal, one begins by using the @samp{-b} flag to generate a +@file{lex.backup} file. For example, on the input + +@example +%% +foo return TOK_KEYWORD; +foobar return TOK_KEYWORD; +@end example + +@noindent +the file looks like: + +@example +State #6 is non-accepting - + associated rule line numbers: + 2 3 + out-transitions: [ o ] + jam-transitions: EOF [ \001-n p-\177 ] + +State #8 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ a ] + jam-transitions: EOF [ \001-` b-\177 ] + +State #9 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ r ] + jam-transitions: EOF [ \001-q s-\177 ] + +Compressed tables always back up. +@end example + +The first few lines tell us that there's a scanner state +in which it can make a transition on an 'o' but not on any +other character, and that in that state the currently +scanned text does not match any rule. The state occurs +when trying to match the rules found at lines 2 and 3 in +the input file. If the scanner is in that state and then +reads something other than an 'o', it will have to back up +to find a rule which is matched. With a bit of +head-scratching one can see that this must be the state it's in +when it has seen "fo". When this has happened, if +anything other than another 'o' is seen, the scanner will +have to back up to simply match the 'f' (by the default +rule). + +The comment regarding State #8 indicates there's a problem +when "foob" has been scanned. Indeed, on any character +other than an 'a', the scanner will have to back up to +accept "foo". Similarly, the comment for State #9 +concerns when "fooba" has been scanned and an 'r' does not +follow. + +The final comment reminds us that there's no point going +to all the trouble of removing backing up from the rules +unless we're using @samp{-Cf} or @samp{-CF}, since there's no +performance gain doing so with compressed scanners. + +The way to remove the backing up is to add "error" rules: + +@example +%% +foo return TOK_KEYWORD; +foobar return TOK_KEYWORD; + +fooba | +foob | +fo @{ + /* false alarm, not really a keyword */ + return TOK_ID; + @} +@end example + +Eliminating backing up among a list of keywords can also +be done using a "catch-all" rule: + +@example +%% +foo return TOK_KEYWORD; +foobar return TOK_KEYWORD; + +[a-z]+ return TOK_ID; +@end example + +This is usually the best solution when appropriate. + +Backing up messages tend to cascade. With a complicated +set of rules it's not uncommon to get hundreds of +messages. If one can decipher them, though, it often only +takes a dozen or so rules to eliminate the backing up +(though it's easy to make a mistake and have an error rule +accidentally match a valid token. A possible future @code{flex} +feature will be to automatically add rules to eliminate +backing up). + +It's important to keep in mind that you gain the benefits +of eliminating backing up only if you eliminate @emph{every} +instance of backing up. Leaving just one means you gain +nothing. + +@var{Variable} trailing context (where both the leading and +trailing parts do not have a fixed length) entails almost +the same performance loss as @code{REJECT} (i.e., substantial). +So when possible a rule like: + +@example +%% +mouse|rat/(cat|dog) run(); +@end example + +@noindent +is better written: + +@example +%% +mouse/cat|dog run(); +rat/cat|dog run(); +@end example + +@noindent +or as + +@example +%% +mouse|rat/cat run(); +mouse|rat/dog run(); +@end example + +Note that here the special '|' action does @emph{not} provide any +savings, and can even make things worse (see Deficiencies +/ Bugs below). + +Another area where the user can increase a scanner's +performance (and one that's easier to implement) arises from +the fact that the longer the tokens matched, the faster +the scanner will run. This is because with long tokens +the processing of most input characters takes place in the +(short) inner scanning loop, and does not often have to go +through the additional work of setting up the scanning +environment (e.g., @code{yytext}) for the action. Recall the +scanner for C comments: + +@example +%x comment +%% + int line_num = 1; + +"/*" BEGIN(comment); + +[^*\n]* +"*"+[^*/\n]* +\n ++line_num; +"*"+"/" BEGIN(INITIAL); +@end example + +This could be sped up by writing it as: + +@example +%x comment +%% + int line_num = 1; + +"/*" BEGIN(comment); + +[^*\n]* +[^*\n]*\n ++line_num; +"*"+[^*/\n]* +"*"+[^*/\n]*\n ++line_num; +"*"+"/" BEGIN(INITIAL); +@end example + +Now instead of each newline requiring the processing of +another action, recognizing the newlines is "distributed" +over the other rules to keep the matched text as long as +possible. Note that @emph{adding} rules does @emph{not} slow down the +scanner! The speed of the scanner is independent of the +number of rules or (modulo the considerations given at the +beginning of this section) how complicated the rules are +with regard to operators such as '*' and '|'. + +A final example in speeding up a scanner: suppose you want +to scan through a file containing identifiers and +keywords, one per line and with no other extraneous +characters, and recognize all the keywords. A natural first +approach is: + +@example +%% +asm | +auto | +break | +@dots{} etc @dots{} +volatile | +while /* it's a keyword */ + +.|\n /* it's not a keyword */ +@end example + +To eliminate the back-tracking, introduce a catch-all +rule: + +@example +%% +asm | +auto | +break | +... etc ... +volatile | +while /* it's a keyword */ + +[a-z]+ | +.|\n /* it's not a keyword */ +@end example + +Now, if it's guaranteed that there's exactly one word per +line, then we can reduce the total number of matches by a +half by merging in the recognition of newlines with that +of the other tokens: + +@example +%% +asm\n | +auto\n | +break\n | +@dots{} etc @dots{} +volatile\n | +while\n /* it's a keyword */ + +[a-z]+\n | +.|\n /* it's not a keyword */ +@end example + +One has to be careful here, as we have now reintroduced +backing up into the scanner. In particular, while @emph{we} know +that there will never be any characters in the input +stream other than letters or newlines, @code{flex} can't figure +this out, and it will plan for possibly needing to back up +when it has scanned a token like "auto" and then the next +character is something other than a newline or a letter. +Previously it would then just match the "auto" rule and be +done, but now it has no "auto" rule, only a "auto\n" rule. +To eliminate the possibility of backing up, we could +either duplicate all rules but without final newlines, or, +since we never expect to encounter such an input and +therefore don't how it's classified, we can introduce one +more catch-all rule, this one which doesn't include a +newline: + +@example +%% +asm\n | +auto\n | +break\n | +@dots{} etc @dots{} +volatile\n | +while\n /* it's a keyword */ + +[a-z]+\n | +[a-z]+ | +.|\n /* it's not a keyword */ +@end example + +Compiled with @samp{-Cf}, this is about as fast as one can get a +@code{flex} scanner to go for this particular problem. + +A final note: @code{flex} is slow when matching NUL's, +particularly when a token contains multiple NUL's. It's best to +write rules which match @emph{short} amounts of text if it's +anticipated that the text will often include NUL's. + +Another final note regarding performance: as mentioned +above in the section How the Input is Matched, dynamically +resizing @code{yytext} to accommodate huge tokens is a slow +process because it presently requires that the (huge) token +be rescanned from the beginning. Thus if performance is +vital, you should attempt to match "large" quantities of +text but not "huge" quantities, where the cutoff between +the two is at about 8K characters/token. + +@node C++, Incompatibilities, Performance, Top +@section Generating C++ scanners + +@code{flex} provides two different ways to generate scanners for +use with C++. The first way is to simply compile a +scanner generated by @code{flex} using a C++ compiler instead of a C +compiler. You should not encounter any compilations +errors (please report any you find to the email address +given in the Author section below). You can then use C++ +code in your rule actions instead of C code. Note that +the default input source for your scanner remains @code{yyin}, +and default echoing is still done to @code{yyout}. Both of these +remain @samp{FILE *} variables and not C++ @code{streams}. + +You can also use @code{flex} to generate a C++ scanner class, using +the @samp{-+} option, (or, equivalently, @samp{%option c++}), which +is automatically specified if the name of the flex executable ends +in a @samp{+}, such as @code{flex++}. When using this option, flex +defaults to generating the scanner to the file @file{lex.yy.cc} instead +of @file{lex.yy.c}. The generated scanner includes the header file +@file{FlexLexer.h}, which defines the interface to two C++ classes. + +The first class, @code{FlexLexer}, provides an abstract base +class defining the general scanner class interface. It +provides the following member functions: + +@table @samp +@item const char* YYText() +returns the text of the most recently matched +token, the equivalent of @code{yytext}. + +@item int YYLeng() +returns the length of the most recently matched +token, the equivalent of @code{yyleng}. + +@item int lineno() const +returns the current input line number (see @samp{%option yylineno}), +or 1 if @samp{%option yylineno} was not used. + +@item void set_debug( int flag ) +sets the debugging flag for the scanner, equivalent to assigning to +@code{yy_flex_debug} (see the Options section above). Note that you +must build the scanner using @samp{%option debug} to include debugging +information in it. + +@item int debug() const +returns the current setting of the debugging flag. +@end table + +Also provided are member functions equivalent to +@samp{yy_switch_to_buffer(), yy_create_buffer()} (though the +first argument is an @samp{istream*} object pointer and not a +@samp{FILE*}, @samp{yy_flush_buffer()}, @samp{yy_delete_buffer()}, +and @samp{yyrestart()} (again, the first argument is a @samp{istream*} +object pointer). + +The second class defined in @file{FlexLexer.h} is @code{yyFlexLexer}, +which is derived from @code{FlexLexer}. It defines the following +additional member functions: + +@table @samp +@item yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 ) +constructs a @code{yyFlexLexer} object using the given +streams for input and output. If not specified, +the streams default to @code{cin} and @code{cout}, respectively. + +@item virtual int yylex() +performs the same role is @samp{yylex()} does for ordinary +flex scanners: it scans the input stream, consuming +tokens, until a rule's action returns a value. If you derive a subclass +@var{S} +from @code{yyFlexLexer} +and want to access the member functions and variables of +@var{S} +inside @samp{yylex()}, +then you need to use @samp{%option yyclass="@var{S}"} +to inform @code{flex} +that you will be using that subclass instead of @code{yyFlexLexer}. +In this case, rather than generating @samp{yyFlexLexer::yylex()}, +@code{flex} generates @samp{@var{S}::yylex()} +(and also generates a dummy @samp{yyFlexLexer::yylex()} +that calls @samp{yyFlexLexer::LexerError()} +if called). + +@item virtual void switch_streams(istream* new_in = 0, ostream* new_out = 0) +reassigns @code{yyin} to @code{new_in} +(if non-nil) +and @code{yyout} to @code{new_out} +(ditto), deleting the previous input buffer if @code{yyin} +is reassigned. + +@item int yylex( istream* new_in = 0, ostream* new_out = 0 ) +first switches the input streams via @samp{switch_streams( new_in, new_out )} +and then returns the value of @samp{yylex()}. +@end table + +In addition, @code{yyFlexLexer} defines the following protected +virtual functions which you can redefine in derived +classes to tailor the scanner: + +@table @samp +@item virtual int LexerInput( char* buf, int max_size ) +reads up to @samp{max_size} characters into @var{buf} and +returns the number of characters read. To indicate +end-of-input, return 0 characters. Note that +"interactive" scanners (see the @samp{-B} and @samp{-I} flags) +define the macro @code{YY_INTERACTIVE}. If you redefine +@code{LexerInput()} and need to take different actions +depending on whether or not the scanner might be +scanning an interactive input source, you can test +for the presence of this name via @samp{#ifdef}. + +@item virtual void LexerOutput( const char* buf, int size ) +writes out @var{size} characters from the buffer @var{buf}, +which, while NUL-terminated, may also contain +"internal" NUL's if the scanner's rules can match +text with NUL's in them. + +@item virtual void LexerError( const char* msg ) +reports a fatal error message. The default version +of this function writes the message to the stream +@code{cerr} and exits. +@end table + +Note that a @code{yyFlexLexer} object contains its @emph{entire} +scanning state. Thus you can use such objects to create +reentrant scanners. You can instantiate multiple instances of +the same @code{yyFlexLexer} class, and you can also combine +multiple C++ scanner classes together in the same program +using the @samp{-P} option discussed above. +Finally, note that the @samp{%array} feature is not available to +C++ scanner classes; you must use @samp{%pointer} (the default). + +Here is an example of a simple C++ scanner: + +@example + // An example of using the flex C++ scanner class. + +%@{ +int mylineno = 0; +%@} + +string \"[^\n"]+\" + +ws [ \t]+ + +alpha [A-Za-z] +dig [0-9] +name (@{alpha@}|@{dig@}|\$)(@{alpha@}|@{dig@}|[_.\-/$])* +num1 [-+]?@{dig@}+\.?([eE][-+]?@{dig@}+)? +num2 [-+]?@{dig@}*\.@{dig@}+([eE][-+]?@{dig@}+)? +number @{num1@}|@{num2@} + +%% + +@{ws@} /* skip blanks and tabs */ + +"/*" @{ + int c; + + while((c = yyinput()) != 0) + @{ + if(c == '\n') + ++mylineno; + + else if(c == '*') + @{ + if((c = yyinput()) == '/') + break; + else + unput(c); + @} + @} + @} + +@{number@} cout << "number " << YYText() << '\n'; + +\n mylineno++; + +@{name@} cout << "name " << YYText() << '\n'; + +@{string@} cout << "string " << YYText() << '\n'; + +%% + +Version 2.5 December 1994 44 + +int main( int /* argc */, char** /* argv */ ) + @{ + FlexLexer* lexer = new yyFlexLexer; + while(lexer->yylex() != 0) + ; + return 0; + @} +@end example + +If you want to create multiple (different) lexer classes, +you use the @samp{-P} flag (or the @samp{prefix=} option) to rename each +@code{yyFlexLexer} to some other @code{xxFlexLexer}. You then can +include @samp{} in your other sources once per lexer +class, first renaming @code{yyFlexLexer} as follows: + +@example +#undef yyFlexLexer +#define yyFlexLexer xxFlexLexer +#include + +#undef yyFlexLexer +#define yyFlexLexer zzFlexLexer +#include +@end example + +if, for example, you used @samp{%option prefix="xx"} for one of +your scanners and @samp{%option prefix="zz"} for the other. + +IMPORTANT: the present form of the scanning class is +@emph{experimental} and may change considerably between major +releases. + +@node Incompatibilities, Diagnostics, C++, Top +@section Incompatibilities with @code{lex} and POSIX + +@code{flex} is a rewrite of the AT&T Unix @code{lex} tool (the two +implementations do not share any code, though), with some +extensions and incompatibilities, both of which are of +concern to those who wish to write scanners acceptable to +either implementation. Flex is fully compliant with the +POSIX @code{lex} specification, except that when using @samp{%pointer} +(the default), a call to @samp{unput()} destroys the contents of +@code{yytext}, which is counter to the POSIX specification. + +In this section we discuss all of the known areas of +incompatibility between flex, AT&T lex, and the POSIX +specification. + +@code{flex's} @samp{-l} option turns on maximum compatibility with the +original AT&T @code{lex} implementation, at the cost of a major +loss in the generated scanner's performance. We note +below which incompatibilities can be overcome using the @samp{-l} +option. + +@code{flex} is fully compatible with @code{lex} with the following +exceptions: + +@itemize - +@item +The undocumented @code{lex} scanner internal variable @code{yylineno} +is not supported unless @samp{-l} or @samp{%option yylineno} is used. +@code{yylineno} should be maintained on a per-buffer basis, rather +than a per-scanner (single global variable) basis. @code{yylineno} is +not part of the POSIX specification. + +@item +The @samp{input()} routine is not redefinable, though it +may be called to read characters following whatever +has been matched by a rule. If @samp{input()} encounters +an end-of-file the normal @samp{yywrap()} processing is +done. A ``real'' end-of-file is returned by +@samp{input()} as @code{EOF}. + +Input is instead controlled by defining the +@code{YY_INPUT} macro. + +The @code{flex} restriction that @samp{input()} cannot be +redefined is in accordance with the POSIX +specification, which simply does not specify any way of +controlling the scanner's input other than by making +an initial assignment to @code{yyin}. + +@item +The @samp{unput()} routine is not redefinable. This +restriction is in accordance with POSIX. + +@item +@code{flex} scanners are not as reentrant as @code{lex} scanners. +In particular, if you have an interactive scanner +and an interrupt handler which long-jumps out of +the scanner, and the scanner is subsequently called +again, you may get the following message: + +@example +fatal flex scanner internal error--end of buffer missed +@end example + +To reenter the scanner, first use + +@example +yyrestart( yyin ); +@end example + +Note that this call will throw away any buffered +input; usually this isn't a problem with an +interactive scanner. + +Also note that flex C++ scanner classes @emph{are} +reentrant, so if using C++ is an option for you, you +should use them instead. See "Generating C++ +Scanners" above for details. + +@item +@samp{output()} is not supported. Output from the @samp{ECHO} +macro is done to the file-pointer @code{yyout} (default +@code{stdout}). + +@samp{output()} is not part of the POSIX specification. + +@item +@code{lex} does not support exclusive start conditions +(%x), though they are in the POSIX specification. + +@item +When definitions are expanded, @code{flex} encloses them +in parentheses. With lex, the following: + +@example +NAME [A-Z][A-Z0-9]* +%% +foo@{NAME@}? printf( "Found it\n" ); +%% +@end example + +will not match the string "foo" because when the +macro is expanded the rule is equivalent to +"foo[A-Z][A-Z0-9]*?" and the precedence is such that the +'?' is associated with "[A-Z0-9]*". With @code{flex}, the +rule will be expanded to "foo([A-Z][A-Z0-9]*)?" and +so the string "foo" will match. + +Note that if the definition begins with @samp{^} or ends +with @samp{$} then it is @emph{not} expanded with parentheses, to +allow these operators to appear in definitions +without losing their special meanings. But the +@samp{, /}, and @samp{<>} operators cannot be used in a +@code{flex} definition. + +Using @samp{-l} results in the @code{lex} behavior of no +parentheses around the definition. + +The POSIX specification is that the definition be enclosed in +parentheses. + +@item +Some implementations of @code{lex} allow a rule's action to begin on +a separate line, if the rule's pattern has trailing whitespace: + +@example +%% +foo|bar + @{ foobar_action(); @} +@end example + +@code{flex} does not support this feature. + +@item +The @code{lex} @samp{%r} (generate a Ratfor scanner) option is +not supported. It is not part of the POSIX +specification. + +@item +After a call to @samp{unput()}, @code{yytext} is undefined until +the next token is matched, unless the scanner was +built using @samp{%array}. This is not the case with @code{lex} +or the POSIX specification. The @samp{-l} option does +away with this incompatibility. + +@item +The precedence of the @samp{@{@}} (numeric range) operator +is different. @code{lex} interprets "abc@{1,3@}" as "match +one, two, or three occurrences of 'abc'", whereas +@code{flex} interprets it as "match 'ab' followed by one, +two, or three occurrences of 'c'". The latter is +in agreement with the POSIX specification. + +@item +The precedence of the @samp{^} operator is different. @code{lex} +interprets "^foo|bar" as "match either 'foo' at the +beginning of a line, or 'bar' anywhere", whereas +@code{flex} interprets it as "match either 'foo' or 'bar' +if they come at the beginning of a line". The +latter is in agreement with the POSIX specification. + +@item +The special table-size declarations such as @samp{%a} +supported by @code{lex} are not required by @code{flex} scanners; +@code{flex} ignores them. + +@item +The name FLEX_SCANNER is #define'd so scanners may +be written for use with either @code{flex} or @code{lex}. +Scanners also include @code{YY_FLEX_MAJOR_VERSION} and +@code{YY_FLEX_MINOR_VERSION} indicating which version of +@code{flex} generated the scanner (for example, for the +2.5 release, these defines would be 2 and 5 +respectively). +@end itemize + +The following @code{flex} features are not included in @code{lex} or the +POSIX specification: + +@example +C++ scanners +%option +start condition scopes +start condition stacks +interactive/non-interactive scanners +yy_scan_string() and friends +yyterminate() +yy_set_interactive() +yy_set_bol() +YY_AT_BOL() +<> +<*> +YY_DECL +YY_START +YY_USER_ACTION +YY_USER_INIT +#line directives +%@{@}'s around actions +multiple actions on a line +@end example + +@noindent +plus almost all of the flex flags. The last feature in +the list refers to the fact that with @code{flex} you can put +multiple actions on the same line, separated with +semicolons, while with @code{lex}, the following + +@example +foo handle_foo(); ++num_foos_seen; +@end example + +@noindent +is (rather surprisingly) truncated to + +@example +foo handle_foo(); +@end example + +@code{flex} does not truncate the action. Actions that are not +enclosed in braces are simply terminated at the end of the +line. + +@node Diagnostics, Files, Incompatibilities, Top +@section Diagnostics + +@table @samp +@item warning, rule cannot be matched +indicates that the given +rule cannot be matched because it follows other rules that +will always match the same text as it. For example, in +the following "foo" cannot be matched because it comes +after an identifier "catch-all" rule: + +@example +[a-z]+ got_identifier(); +foo got_foo(); +@end example + +Using @code{REJECT} in a scanner suppresses this warning. + +@item warning, -s option given but default rule can be matched +means that it is possible (perhaps only in a particular +start condition) that the default rule (match any single +character) is the only one that will match a particular +input. Since @samp{-s} was given, presumably this is not +intended. + +@item reject_used_but_not_detected undefined +@itemx yymore_used_but_not_detected undefined +These errors can +occur at compile time. They indicate that the scanner +uses @code{REJECT} or @samp{yymore()} but that @code{flex} failed to notice the +fact, meaning that @code{flex} scanned the first two sections +looking for occurrences of these actions and failed to +find any, but somehow you snuck some in (via a #include +file, for example). Use @samp{%option reject} or @samp{%option yymore} +to indicate to flex that you really do use these features. + +@item flex scanner jammed +a scanner compiled with @samp{-s} has +encountered an input string which wasn't matched by any of +its rules. This error can also occur due to internal +problems. + +@item token too large, exceeds YYLMAX +your scanner uses @samp{%array} +and one of its rules matched a string longer than the @samp{YYL-} +@code{MAX} constant (8K bytes by default). You can increase the +value by #define'ing @code{YYLMAX} in the definitions section of +your @code{flex} input. + +@item scanner requires -8 flag to use the character '@var{x}' +Your +scanner specification includes recognizing the 8-bit +character @var{x} and you did not specify the -8 flag, and your +scanner defaulted to 7-bit because you used the @samp{-Cf} or @samp{-CF} +table compression options. See the discussion of the @samp{-7} +flag for details. + +@item flex scanner push-back overflow +you used @samp{unput()} to push +back so much text that the scanner's buffer could not hold +both the pushed-back text and the current token in @code{yytext}. +Ideally the scanner should dynamically resize the buffer +in this case, but at present it does not. + +@item input buffer overflow, can't enlarge buffer because scanner uses REJECT +the scanner was working on matching an +extremely large token and needed to expand the input +buffer. This doesn't work with scanners that use @code{REJECT}. + +@item fatal flex scanner internal error--end of buffer missed +This can occur in an scanner which is reentered after a +long-jump has jumped out (or over) the scanner's +activation frame. Before reentering the scanner, use: + +@example +yyrestart( yyin ); +@end example + +@noindent +or, as noted above, switch to using the C++ scanner class. + +@item too many start conditions in <> construct! +you listed +more start conditions in a <> construct than exist (so you +must have listed at least one of them twice). +@end table + +@node Files, Deficiencies, Diagnostics, Top +@section Files + +@table @file +@item -lfl +library with which scanners must be linked. + +@item lex.yy.c +generated scanner (called @file{lexyy.c} on some systems). + +@item lex.yy.cc +generated C++ scanner class, when using @samp{-+}. + +@item +header file defining the C++ scanner base class, +@code{FlexLexer}, and its derived class, @code{yyFlexLexer}. + +@item flex.skl +skeleton scanner. This file is only used when +building flex, not when flex executes. + +@item lex.backup +backing-up information for @samp{-b} flag (called @file{lex.bck} +on some systems). +@end table + +@node Deficiencies, See also, Files, Top +@section Deficiencies / Bugs + +Some trailing context patterns cannot be properly matched +and generate warning messages ("dangerous trailing +context"). These are patterns where the ending of the first +part of the rule matches the beginning of the second part, +such as "zx*/xy*", where the 'x*' matches the 'x' at the +beginning of the trailing context. (Note that the POSIX +draft states that the text matched by such patterns is +undefined.) + +For some trailing context rules, parts which are actually +fixed-length are not recognized as such, leading to the +abovementioned performance loss. In particular, parts +using '|' or @{n@} (such as "foo@{3@}") are always considered +variable-length. + +Combining trailing context with the special '|' action can +result in @emph{fixed} trailing context being turned into the +more expensive @var{variable} trailing context. For example, in +the following: + +@example +%% +abc | +xyz/def +@end example + +Use of @samp{unput()} invalidates yytext and yyleng, unless the +@samp{%array} directive or the @samp{-l} option has been used. + +Pattern-matching of NUL's is substantially slower than +matching other characters. + +Dynamic resizing of the input buffer is slow, as it +entails rescanning all the text matched so far by the +current (generally huge) token. + +Due to both buffering of input and read-ahead, you cannot +intermix calls to routines, such as, for +example, @samp{getchar()}, with @code{flex} rules and expect it to work. +Call @samp{input()} instead. + +The total table entries listed by the @samp{-v} flag excludes the +number of table entries needed to determine what rule has +been matched. The number of entries is equal to the +number of DFA states if the scanner does not use @code{REJECT}, and +somewhat greater than the number of states if it does. + +@code{REJECT} cannot be used with the @samp{-f} or @samp{-F} options. + +The @code{flex} internal algorithms need documentation. + +@node See also, Author, Deficiencies, Top +@section See also + +@code{lex}(1), @code{yacc}(1), @code{sed}(1), @code{awk}(1). + +John Levine, Tony Mason, and Doug Brown: Lex & Yacc; +O'Reilly and Associates. Be sure to get the 2nd edition. + +M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator. + +Alfred Aho, Ravi Sethi and Jeffrey Ullman: Compilers: +Principles, Techniques and Tools; Addison-Wesley (1986). +Describes the pattern-matching techniques used by @code{flex} +(deterministic finite automata). + +@node Author, , See also, Top +@section Author + +Vern Paxson, with the help of many ideas and much inspiration from +Van Jacobson. Original version by Jef Poskanzer. The fast table +representation is a partial implementation of a design done by Van +Jacobson. The implementation was done by Kevin Gong and Vern Paxson. + +Thanks to the many @code{flex} beta-testers, feedbackers, and +contributors, especially Francois Pinard, Casey Leedom, Stan +Adermann, Terry Allen, David Barker-Plummer, John Basrai, Nelson +H.F. Beebe, @samp{benson@@odi.com}, Karl Berry, Peter A. Bigot, +Simon Blanchard, Keith Bostic, Frederic Brehm, Ian Brockbank, Kin +Cho, Nick Christopher, Brian Clapper, J.T. Conklin, Jason Coughlin, +Bill Cox, Nick Cropper, Dave Curtis, Scott David Daniels, Chris +G. Demetriou, Theo Deraadt, Mike Donahue, Chuck Doucette, Tom Epperly, +Leo Eskin, Chris Faylor, Chris Flatters, Jon Forrest, Joe Gayda, Kaveh +R. Ghazi, Eric Goldman, Christopher M. Gould, Ulrich Grepel, Peer +Griebel, Jan Hajic, Charles Hemphill, NORO Hideo, Jarkko Hietaniemi, +Scott Hofmann, Jeff Honig, Dana Hudes, Eric Hughes, John Interrante, +Ceriel Jacobs, Michal Jaegermann, Sakari Jalovaara, Jeffrey R. Jones, +Henry Juengst, Klaus Kaempf, Jonathan I. Kamens, Terrence O Kane, +Amir Katz, @samp{ken@@ken.hilco.com}, Kevin B. Kenny, Steve Kirsch, +Winfried Koenig, Marq Kole, Ronald Lamprecht, Greg Lee, Rohan Lenard, +Craig Leres, John Levine, Steve Liddle, Mike Long, Mohamed el Lozy, +Brian Madsen, Malte, Joe Marshall, Bengt Martensson, Chris Metcalf, +Luke Mewburn, Jim Meyering, R. Alexander Milowski, Erik Naggum, +G.T. Nicol, Landon Noll, James Nordby, Marc Nozell, Richard Ohnemus, +Karsten Pahnke, Sven Panne, Roland Pesch, Walter Pelissero, Gaumond +Pierre, Esmond Pitt, Jef Poskanzer, Joe Rahmeh, Jarmo Raiha, Frederic +Raimbault, Pat Rankin, Rick Richardson, Kevin Rodgers, Kai Uwe Rommel, +Jim Roskind, Alberto Santini, Andreas Scherer, Darrell Schiebel, Raf +Schietekat, Doug Schmidt, Philippe Schnoebelen, Andreas Schwab, Alex +Siegel, Eckehard Stolz, Jan-Erik Strvmquist, Mike Stump, Paul Stuart, +Dave Tallman, Ian Lance Taylor, Chris Thewalt, Richard M. Timoney, +Jodi Tsai, Paul Tuinenga, Gary Weik, Frank Whaley, Gerhard Wilhelms, +Kent Williams, Ken Yap, Ron Zellar, Nathan Zelle, David Zuhn, and +those whose names have slipped my marginal mail-archiving skills but +whose contributions are appreciated all the same. + +Thanks to Keith Bostic, Jon Forrest, Noah Friedman, John Gilmore, +Craig Leres, John Levine, Bob Mulcahy, G.T. Nicol, Francois Pinard, +Rich Salz, and Richard Stallman for help with various distribution +headaches. + +Thanks to Esmond Pitt and Earle Horton for 8-bit character support; +to Benson Margulies and Fred Burke for C++ support; to Kent Williams +and Tom Epperly for C++ class support; to Ove Ewerlid for support of +NUL's; and to Eric Hughes for support of multiple buffers. + +This work was primarily done when I was with the Real Time Systems +Group at the Lawrence Berkeley Laboratory in Berkeley, CA. Many thanks +to all there for the support I received. + +Send comments to @samp{vern@@ee.lbl.gov}. + +@c @node Index, , Top, Top +@c @unnumbered Index +@c +@c @printindex cp + +@contents +@bye + +@c Local variables: +@c texinfo-column-for-description: 32 +@c End: diff --git a/commands/flex-2.5.4/Makefile.in b/commands/flex-2.5.4/Makefile.in new file mode 100644 index 000000000..a7dd07b7b --- /dev/null +++ b/commands/flex-2.5.4/Makefile.in @@ -0,0 +1,262 @@ +# @(#) $Header$ (LBL) + +@SET_MAKE@ + +# Possible values for DEFS: +# +# By default, flex generates 8-bit scanners when using table compression, +# and 7-bit scanners when using uncompressed tables (-f or -F options). +# For flex to always generate 8-bit scanners, add "-DDEFAULT_CSIZE=256" +# to DEFS. +# +# For Vax/VMS, add "-DVMS" to DEFS. +# +# For MS-DOS, add "-DMS_DOS" to DEFS. See the directory MISC/MSDOS for +# additional info. + +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +DEFS = @DEFS@ +LDFLAGS = -stack 256k +LIBS = @LIBS@ + +# Installation targeting. Files will be installed under the tree +# rooted at prefix. flex will be installed in bindir, libfl.a in +# libdir, FlexLexer.h will be installed in includedir, and the manual +# pages will be installed in mandir with extension manext. +# +# Raw, unformatted troff source will be installed if INSTALLMAN=man, +# nroff preformatted versions will be installed if INSTALLMAN=cat. + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = $(exec_prefix)/bin +libdir = $(exec_prefix)/lib +includedir = $(prefix)/include +manext = 1 +mandir = $(prefix)/man/man$(manext) + +# You can define these to be "lex" and "libl.a" if you want to replace +# lex at your site. +FLEX = flex +FLEXLIB = libfl.a + +INSTALLMAN = man + +SHELL = /bin/sh +srcdir = @srcdir@ +VPATH = @srcdir@ + +LN_S = @LN_S@ +YACC = @YACC@ +CC = @CC@ +AR = ar +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ + +# You normally do not need to modify anything below this point. +# ------------------------------------------------------------ + +CPPFLAGS = -I. -I$(srcdir) + +.c.o: + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< + +HEADERS = flexdef.h version.h + +SOURCES = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.y \ + scan.l skel.c sym.c tblcmp.c yylex.c +OBJECTS = ccl.o dfa.o ecs.o gen.o main.o misc.o nfa.o parse.o \ + scan.o skel.o sym.o tblcmp.o yylex.o @ALLOCA@ + +LIBSRCS = libmain.c libyywrap.c +LIBOBJS = libmain.o libyywrap.o + +LINTSRCS = ccl.c dfa.c ecs.c gen.c main.c misc.c nfa.c parse.c \ + scan.c skel.c sym.c tblcmp.c yylex.c + +DISTFILES = README NEWS COPYING INSTALL FlexLexer.h \ + configure.in conf.in Makefile.in mkskel.sh flex.skl \ + $(HEADERS) $(SOURCES) $(LIBSRCS) MISC \ + flex.1 scan.c install.sh mkinstalldirs configure + +DIST_NAME = flex + +# which "flex" to use to generate scan.c from scan.l +FLEX_EXEC = ./$(FLEX) +FLEX_FLAGS = -t $(PERF_REPORT) +COMPRESSION = +PERF_REPORT = -p + + +all: $(FLEX) + +$(FLEX): .bootstrap $(OBJECTS) $(FLEXLIB) + $(CC) $(CFLAGS) -o $(FLEX) $(LDFLAGS) $(OBJECTS) $(FLEXLIB) $(LIBS) + +.bootstrap: initscan.c + @rm -f scan.c + cp $(srcdir)/initscan.c scan.c + touch .bootstrap + +parse.c: parse.y + $(YACC) -d $(srcdir)/parse.y + @sed '/extern char.*malloc/d' parse.tmp + @mv parse.tmp parse.c + @mv y.tab.h parse.h + @rm -f y.tab.c + +parse.h: parse.c + +scan.c: scan.l + $(FLEX_EXEC) $(FLEX_FLAGS) $(COMPRESSION) $(srcdir)/scan.l >scan.c + @sed s,\"$(srcdir)/scan.l\",\"scan.l\", scan.tmp + @mv scan.tmp scan.c + +scan.o: scan.c parse.h flexdef.h config.h +yylex.o: yylex.c parse.h flexdef.h config.h + +skel.c: flex.skl mkskel.sh + $(SHELL) $(srcdir)/mkskel.sh $(srcdir)/flex.skl >skel.c + +main.o: main.c flexdef.h config.h version.h +ccl.o: ccl.c flexdef.h config.h +dfa.o: dfa.c flexdef.h config.h +ecs.o: ecs.c flexdef.h config.h +gen.o: gen.c flexdef.h config.h +misc.o: misc.c flexdef.h config.h +nfa.o: nfa.c flexdef.h config.h +parse.o: parse.c flexdef.h config.h +skel.o: skel.c flexdef.h config.h +sym.o: sym.c flexdef.h config.h +tblcmp.o: tblcmp.c flexdef.h config.h + +alloca.o: alloca.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c -Dxmalloc=yy_flex_xmalloc alloca.c + +alloca.c: $(srcdir)/MISC/alloca.c + @rm -f alloca.c + cp $(srcdir)/MISC/alloca.c . + +test: check +check: $(FLEX) + $(FLEX_EXEC) $(FLEX_FLAGS) $(COMPRESSION) $(srcdir)/scan.l \ + | sed s,\"$(srcdir)/scan.l\",\"scan.l\", \ + | diff scan.c - + @echo "Check successful, using COMPRESSION=\"$(COMPRESSION)\"" + +bigcheck: + rm -f scan.c ; $(MAKE) COMPRESSION="-C" check + rm -f scan.c ; $(MAKE) COMPRESSION="-Ce" check + rm -f scan.c ; $(MAKE) COMPRESSION="-Cm" check + rm -f scan.c ; $(MAKE) COMPRESSION="-f" check + rm -f scan.c ; $(MAKE) COMPRESSION="-Cfea" check + rm -f scan.c ; $(MAKE) COMPRESSION="-CFer" check + rm -f scan.c ; $(MAKE) COMPRESSION="-l" PERF_REPORT="" check + rm -f scan.c ; $(MAKE) + @echo "All checks successful" + +$(FLEXLIB): $(LIBOBJS) + $(AR) cru $(FLEXLIB) $(LIBOBJS) + -$(RANLIB) $(FLEXLIB) + +$(FLEX).man: flex.1 + cd $(srcdir) && nroff -man flex.1 >$(FLEX).man + +install: $(FLEX) $(FLEXLIB) installdirs install.$(INSTALLMAN) + $(INSTALL_PROGRAM) $(FLEX) $(bindir)/$(FLEX) + @rm -f $(bindir)/$(FLEX)++ + cd $(bindir) && $(LN_S) $(FLEX) $(FLEX)++ + $(INSTALL_DATA) $(FLEXLIB) $(libdir)/$(FLEXLIB) + -cd $(libdir) && $(RANLIB) $(FLEXLIB) + $(INSTALL_DATA) $(srcdir)/FlexLexer.h $(includedir)/FlexLexer.h + +# Note, the following rules delete any vestigial flexdoc installed +# for a prior flex release. +install.man: flex.1 + rm -f $(mandir)/$(FLEX)doc.$(manext) + $(INSTALL_DATA) $(srcdir)/flex.1 $(mandir)/$(FLEX).$(manext) + +install.cat: $(FLEX).man + rm -f $(mandir)/$(FLEX)doc.$(manext) + $(INSTALL_DATA) $(srcdir)/$(FLEX).man $(mandir)/$(FLEX).$(manext) + +installdirs: + $(SHELL) $(srcdir)/mkinstalldirs \ + $(bindir) $(libdir) $(includedir) $(mandir) + +uninstall: + rm -f $(bindir)/$(FLEX) $(bindir)/$(FLEX)++ + rm -f $(libdir)/$(FLEXLIB) + rm -f $(includedir)/FlexLexer.h + rm -f $(mandir)/$(FLEX).$(manext) $(mandir)/$(FLEX)doc.$(manext) + +tags: $(SOURCES) + ctags $(SOURCES) + +TAGS: $(SOURCES) + etags $(SOURCES) + +lint: $(LINTSRCS) + lint -Dconst= $(LINTSRCS) > flex.lint + +gcc-lint: $(LINTSRCS) + gcc -Dlint -Wall $(LINTSRCS) >flex.gcc-lint 2>&1 + +mostlyclean: + rm -f a.out *.bak core errs scan.tmp + +clean: mostlyclean + rm -f flex parse.c parse.h *.o alloca.c *.lint lex.yy.c lex.yy.cc \ + $(FLEXLIB) config.log config.cache + +distclean: clean + rm -f .bootstrap $(FLEX) scan.c tags TAGS Makefile config.status \ + config.h stamp-h config.log config.cache + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(FLEX).man skel.c flex*.tar.gz flex*.tar.Z + +dist: $(FLEX) $(DISTFILES) parse.c parse.h $(srcdir)/$(FLEX).man + $(MAKE) DIST_NAME=flex-`sed $(DIST_NAME)/MISC/flex.man + tar chf $(DIST_NAME).tar $(DIST_NAME) + compress <$(DIST_NAME).tar >$(DIST_NAME).tar.Z + gzip <$(DIST_NAME).tar >$(DIST_NAME).tar.gz + @rm $(DIST_NAME).tar + +# For an explanation of the following Makefile rules, see node +# `Automatic Remaking' in GNU Autoconf documentation. +Makefile: $(srcdir)/Makefile.in config.status + CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status +config.status: configure + ./config.status --recheck +configure: configure.in + cd $(srcdir) && autoconf +#config.h: stamp-h +stamp-h: conf.in config.status + CONFIG_FILES= CONFIG_HEADERS=config.h:conf.in ./config.status + echo timestamp >stamp-h +# conf.in: stamp-h.in +# stamp-h.in: configure.in acconfig.h +# cd $(srcdir) && autoheader +# config.h.in conf.in +# cho timestamp > $(srcdir)/stamp-h.in + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/commands/flex-2.5.4/NEWS b/commands/flex-2.5.4/NEWS new file mode 100644 index 000000000..3e23e7d9f --- /dev/null +++ b/commands/flex-2.5.4/NEWS @@ -0,0 +1,1233 @@ +Changes between release 2.5.4 (11Sep96) and release 2.5.3: + + - Fixed a bug introduced in 2.5.3 that blew it when a call + to input() occurred at the end of an input file. + + - Fixed scanner skeleton so the example in the man page of + scanning strings using exclusive start conditions works. + + - Minor Makefile tweaks. + + +Changes between release 2.5.3 (29May96) and release 2.5.2: + + - Some serious bugs in yymore() have been fixed. In particular, + when using AT&T-lex-compatibility or %array, you can intermix + calls to input(), unput(), and yymore(). (This still doesn't + work for %pointer, and isn't likely to in the future.) + + - A bug in handling NUL's in the input stream of scanners using + REJECT has been fixed. + + - The default main() in libfl.a now repeatedly calls yylex() until + it returns 0, rather than just calling it once. + + - Minor tweak for Windows NT Makefile, MISC/NT/Makefile. + + +Changes between release 2.5.2 (25Apr95) and release 2.5.1: + + - The --prefix configuration option now works. + + - A bug that completely broke the "-Cf" table compression + option has been fixed. + + - A major headache involving "const" declarators and Solaris + systems has been fixed. + + - An octal escape sequence in a flex regular expression must + now contain only the digits 0-7. + + - You can now use "--" on the flex command line to mark the + end of flex options. + + - You can now specify the filename '-' as a synonym for stdin. + + - By default, the scanners generated by flex no longer + statically initialize yyin and yyout to stdin and stdout. + This change is necessary because in some ANSI environments, + stdin and stdout are not compile-time constant. You can + force the initialization using "%option stdinit" in the first + section of your flex input. + + - "%option nounput" now correctly omits the unput() routine + from the output. + + - "make clean" now removes config.log, config.cache, and the + flex binary. The fact that it removes the flex binary means + you should take care if making changes to scan.l, to make + sure you don't wind up in a bootstrap problem. + + - In general, the Makefile has been reworked somewhat (thanks + to Francois Pinard) for added flexibility - more changes will + follow in subsequent releases. + + - The .texi and .info files in MISC/texinfo/ have been updated, + thanks also to Francois Pinard. + + - The FlexLexer::yylex(istream* new_in, ostream* new_out) method + now does not have a default for the first argument, to disambiguate + it from FlexLexer::yylex(). + + - A bug in destructing a FlexLexer object before doing any scanning + with it has been fixed. + + - A problem with including FlexLexer.h multiple times has been fixed. + + - The alloca() chud necessary to accommodate bison has grown + even uglier, but hopefully more correct. + + - A portability tweak has been added to accommodate compilers that + use char* generic pointers. + + - EBCDIC contact information in the file MISC/EBCDIC has been updated. + + - An OS/2 Makefile and config.h for flex 2.5 is now available in + MISC/OS2/, contributed by Kai Uwe Rommel. + + - The descrip.mms file for building flex under VMS has been updated, + thanks to Pat Rankin. + + - The notes on building flex for the Amiga have been updated for + flex 2.5, contributed by Andreas Scherer. + + +Changes between release 2.5.1 (28Mar95) and release 2.4.7: + + - A new concept of "start condition" scope has been introduced. + A start condition scope is begun with: + + { + + where SCs is a list of one or more start conditions. Inside + the start condition scope, every rule automatically has the + prefix applied to it, until a '}' which matches the + initial '{'. So, for example: + + { + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + } + + is equivalent to: + + "\\n" return '\n'; + "\\r" return '\r'; + "\\f" return '\f'; + "\\0" return '\0'; + + As indicated in this example, rules inside start condition scopes + (and any rule, actually, other than the first) can be indented, + to better show the extent of the scope. + + Start condition scopes may be nested. + + - The new %option directive can be used in the first section of + a flex scanner to control scanner-generation options. Most + options are given simply as names, optionally preceded by the + word "no" (with no intervening whitespace) to negate their + meaning. Some are equivalent to flex flags, so putting them + in your scanner source is equivalent to always specifying + the flag (%option's take precedence over flags): + + 7bit -7 option + 8bit -8 option + align -Ca option + backup -b option + batch -B option + c++ -+ option + caseful opposite of -i option (caseful is the default); + case-sensitive same as above + caseless -i option; + case-insensitive same as above + debug -d option + default opposite of -s option + ecs -Ce option + fast -F option + full -f option + interactive -I option + lex-compat -l option + meta-ecs -Cm option + perf-report -p option + read -Cr option + stdout -t option + verbose -v option + warn opposite of -w option (so use "%option nowarn" for -w) + + array equivalent to "%array" + pointer equivalent to "%pointer" (default) + + Some provide new features: + + always-interactive generate a scanner which always + considers its input "interactive" (no call to isatty() + will be made when the scanner runs) + main supply a main program for the scanner, which + simply calls yylex(). Implies %option noyywrap. + never-interactive generate a scanner which never + considers its input "interactive" (no call to isatty() + will be made when the scanner runs) + stack if set, enable start condition stacks (see below) + stdinit if unset ("%option nostdinit"), initialize yyin + and yyout statically to nil FILE* pointers, instead + of stdin and stdout + yylineno if set, keep track of the current line + number in global yylineno (this option is expensive + in terms of performance). The line number is available + to C++ scanning objects via the new member function + lineno(). + yywrap if unset ("%option noyywrap"), scanner does not + call yywrap() upon EOF but simply assumes there + are no more files to scan + + Flex scans your rule actions to determine whether you use the + REJECT or yymore features (this is not new). Two %options can be + used to override its decision, either by setting them to indicate + the feature is indeed used, or unsetting them to indicate it + actually is not used: + + reject + yymore + + Three %option's take string-delimited values, offset with '=': + + outfile="" equivalent to -o + prefix="" equivalent to -P + yyclass="" set the name of the C++ scanning class + (see below) + + A number of %option's are available for lint purists who + want to suppress the appearance of unneeded routines in + the generated scanner. Each of the following, if unset, + results in the corresponding routine not appearing in the + generated scanner: + + input, unput + yy_push_state, yy_pop_state, yy_top_state + yy_scan_buffer, yy_scan_bytes, yy_scan_string + + You can specify multiple options with a single %option directive, + and multiple directives in the first section of your flex input file. + + - The new function: + + YY_BUFFER_STATE yy_scan_string( const char *str ) + + returns a YY_BUFFER_STATE (which also becomes the current input + buffer) for scanning the given string, which occurs starting + with the next call to yylex(). The string must be NUL-terminated. + A related function: + + YY_BUFFER_STATE yy_scan_bytes( const char *bytes, int len ) + + creates a buffer for scanning "len" bytes (including possibly NUL's) + starting at location "bytes". + + Note that both of these functions create and scan a *copy* of + the string/bytes. (This may be desirable, since yylex() modifies + the contents of the buffer it is scanning.) You can avoid the + copy by using: + + YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) + + which scans in place the buffer starting at "base", consisting + of "size" bytes, the last two bytes of which *must* be + YY_END_OF_BUFFER_CHAR (these bytes are not scanned; thus, scanning + consists of base[0] through base[size-2], inclusive). If you + fail to set up "base" in this manner, yy_scan_buffer returns a + nil pointer instead of creating a new input buffer. + + The type yy_size_t is an integral type to which you can cast + an integer expression reflecting the size of the buffer. + + - Three new routines are available for manipulating stacks of + start conditions: + + void yy_push_state( int new_state ) + + pushes the current start condition onto the top of the stack + and BEGIN's "new_state" (recall that start condition names are + also integers). + + void yy_pop_state() + + pops the top of the stack and BEGIN's to it, and + + int yy_top_state() + + returns the top of the stack without altering the stack's + contents. + + The start condition stack grows dynamically and so has no built-in + size limitation. If memory is exhausted, program execution + is aborted. + + To use start condition stacks, your scanner must include + a "%option stack" directive. + + - flex now supports POSIX character class expressions. These + are expressions enclosed inside "[:" and ":]" delimiters (which + themselves must appear between the '[' and ']' of a character + class; other elements may occur inside the character class, too). + The expressions flex recognizes are: + + [:alnum:] [:alpha:] [:blank:] [:cntrl:] [:digit:] [:graph:] + [:lower:] [:print:] [:punct:] [:space:] [:upper:] [:xdigit:] + + These expressions all designate a set of characters equivalent to + the corresponding isXXX function (for example, [:alnum:] designates + those characters for which isalnum() returns true - i.e., any + alphabetic or numeric). Some systems don't provide isblank(), + so flex defines [:blank:] as a blank or a tab. + + For example, the following character classes are all equivalent: + + [[:alnum:]] + [[:alpha:][:digit:] + [[:alpha:]0-9] + [a-zA-Z0-9] + + If your scanner is case-insensitive (-i flag), then [:upper:] + and [:lower:] are equivalent to [:alpha:]. + + - The promised rewrite of the C++ FlexLexer class has not yet + been done. Support for FlexLexer is limited at the moment to + fixing show-stopper bugs, so, for example, the new functions + yy_scan_string() & friends are not available to FlexLexer + objects. + + - The new macro + + yy_set_interactive(is_interactive) + + can be used to control whether the current buffer is considered + "interactive". An interactive buffer is processed more slowly, + but must be used when the scanner's input source is indeed + interactive to avoid problems due to waiting to fill buffers + (see the discussion of the -I flag in flex.1). A non-zero value + in the macro invocation marks the buffer as interactive, a zero + value as non-interactive. Note that use of this macro overrides + "%option always-interactive" or "%option never-interactive". + + yy_set_interactive() must be invoked prior to beginning to + scan the buffer. + + - The new macro + + yy_set_bol(at_bol) + + can be used to control whether the current buffer's scanning + context for the next token match is done as though at the + beginning of a line (non-zero macro argument; makes '^' anchored + rules active) or not at the beginning of a line (zero argument, + '^' rules inactive). + + - Related to this change, the mechanism for determining when a scan is + starting at the beginning of a line has changed. It used to be + that '^' was active iff the character prior to that at which the + scan started was a newline. The mechanism now is that '^' is + active iff the last token ended in a newline (or the last call to + input() returned a newline). For most users, the difference in + mechanisms is negligible. Where it will make a difference, + however, is if unput() or yyless() is used to alter the input + stream. When in doubt, use yy_set_bol(). + + - The new beginning-of-line mechanism involved changing some fairly + twisted code, so it may have introduced bugs - beware ... + + - The macro YY_AT_BOL() returns true if the next token scanned from + the current buffer will have '^' rules active, false otherwise. + + - The new function + + void yy_flush_buffer( struct yy_buffer_state* b ) + + flushes the contents of the current buffer (i.e., next time + the scanner attempts to match a token using b as the current + buffer, it will begin by invoking YY_INPUT to fill the buffer). + This routine is also available to C++ scanners (unlike some + of the other new routines). + + The related macro + + YY_FLUSH_BUFFER + + flushes the contents of the current buffer. + + - A new "-ooutput" option writes the generated scanner to "output". + If used with -t, the scanner is still written to stdout, but + its internal #line directives (see previous item) use "output". + + - Flex now generates #line directives relating the code it + produces to the output file; this means that error messages + in the flex-generated code should be correctly pinpointed. + + - When generating #line directives, filenames with embedded '\'s + have those characters escaped (i.e., turned into '\\'). This + feature helps with reporting filenames for some MS-DOS and OS/2 + systems. + + - The FlexLexer class includes two new public member functions: + + virtual void switch_streams( istream* new_in = 0, + ostream* new_out = 0 ) + + reassigns yyin to new_in (if non-nil) and yyout to new_out + (ditto), deleting the previous input buffer if yyin is + reassigned. It is used by: + + int yylex( istream* new_in = 0, ostream* new_out = 0 ) + + which first calls switch_streams() and then returns the value + of calling yylex(). + + - C++ scanners now have yy_flex_debug as a member variable of + FlexLexer rather than a global, and member functions for testing + and setting it. + + - When generating a C++ scanning class, you can now use + + %option yyclass="foo" + + to inform flex that you have derived "foo" as a subclass of + yyFlexLexer, so flex will place your actions in the member + function foo::yylex() instead of yyFlexLexer::yylex(). It also + generates a yyFlexLexer::yylex() member function that generates a + run-time error if called (by invoking yyFlexLexer::LexerError()). + This feature is necessary if your subclass "foo" introduces some + additional member functions or variables that you need to access + from yylex(). + + - Current texinfo files in MISC/texinfo, contributed by Francois + Pinard. + + - You can now change the name "flex" to something else (e.g., "lex") + by redefining $(FLEX) in the Makefile. + + - Two bugs (one serious) that could cause "bigcheck" to fail have + been fixed. + + - A number of portability/configuration changes have been made + for easier portability. + + - You can use "YYSTATE" in your scanner as an alias for YY_START + (for AT&T lex compatibility). + + - input() now maintains yylineno. + + - input() no longer trashes yytext. + + - interactive scanners now read characters in YY_INPUT up to a + newline, a large performance gain. + + - C++ scanner objects now work with the -P option. You include + once per scanner - see comments in + (or flex.1) for details. + + - C++ FlexLexer objects now use the "cerr" stream to report -d output + instead of stdio. + + - The -c flag now has its full glorious POSIX interpretation (do + nothing), rather than being interpreted as an old-style -C flag. + + - Scanners generated by flex now include two #define's giving + the major and minor version numbers (YY_FLEX_MAJOR_VERSION, + YY_FLEX_MINOR_VERSION). These can then be tested to see + whether certain flex features are available. + + - Scanners generated using -l lex compatibility now have the symbol + YY_FLEX_LEX_COMPAT #define'd. + + - When initializing (i.e., yy_init is non-zero on entry to yylex()), + generated scanners now set yy_init to zero before executing + YY_USER_INIT. This means that you can set yy_init back to a + non-zero value in YY_USER_INIT if you need the scanner to be + reinitialized on the next call. + + - You can now use "#line" directives in the first section of your + scanner specification. + + - When generating full-table scanners (-Cf), flex now puts braces + around each row of the 2-d array initialization, to silence warnings + on over-zealous compilers. + + - Improved support for MS-DOS. The flex sources have been successfully + built, unmodified, for Borland 4.02 (all that's required is a + Borland Makefile and config.h file, which are supplied in + MISC/Borland - contributed by Terrence O Kane). + + - Improved support for Macintosh using Think C - the sources should + build for this platform "out of the box". Contributed by Scott + Hofmann. + + - Improved support for VMS, in MISC/VMS/, contributed by Pat Rankin. + + - Support for the Amiga, in MISC/Amiga/, contributed by Andreas + Scherer. Note that the contributed files were developed for + flex 2.4 and have not been tested with flex 2.5. + + - Some notes on support for the NeXT, in MISC/NeXT, contributed + by Raf Schietekat. + + - The MISC/ directory now includes a preformatted version of flex.1 + in flex.man, and pre-yacc'd versions of parse.y in parse.{c,h}. + + - The flex.1 and flexdoc.1 manual pages have been merged. There + is now just one document, flex.1, which includes an overview + at the beginning to help you find the section you need. + + - Documentation now clarifies that start conditions persist across + switches to new input files or different input buffers. If you + want to e.g., return to INITIAL, you must explicitly do so. + + - The "Performance Considerations" section of the manual has been + updated. + + - Documented the "yy_act" variable, which when YY_USER_ACTION is + invoked holds the number of the matched rule, and added an + example of using yy_act to profile how often each rule is matched. + + - Added YY_NUM_RULES, a definition that gives the total number + of rules in the file, including the default rule (even if you + use -s). + + - Documentation now clarifies that you can pass a nil FILE* pointer + to yy_create_buffer() or yyrestart() if you've arrange YY_INPUT + to not need yyin. + + - Documentation now clarifies that YY_BUFFER_STATE is a pointer to + an opaque "struct yy_buffer_state". + + - Documentation now stresses that you gain the benefits of removing + backing-up states only if you remove *all* of them. + + - Documentation now points out that traditional lex allows you + to put the action on a separate line from the rule pattern if + the pattern has trailing whitespace (ugh!), but flex doesn't + support this. + + - A broken example in documentation of the difference between + inclusive and exclusive start conditions is now fixed. + + - Usage (-h) report now goes to stdout. + + - Version (-V) info now goes to stdout. + + - More #ifdef chud has been added to the parser in attempt to + deal with bison's use of alloca(). + + - "make clean" no longer deletes emacs backup files (*~). + + - Some memory leaks have been fixed. + + - A bug was fixed in which dynamically-expanded buffers were + reallocated a couple of bytes too small. + + - A bug was fixed which could cause flex to read and write beyond + the end of the input buffer. + + - -S will not be going away. + + +Changes between release 2.4.7 (03Aug94) and release 2.4.6: + + - Fixed serious bug in reading multiple files. + + - Fixed bug in scanning NUL's. + + - Fixed bug in input() returning 8-bit characters. + + - Fixed bug in matching text with embedded NUL's when + using %array or lex compatibility. + + - Fixed multiple invocations of YY_USER_ACTION when using '|' + continuation action. + + - Minor prototyping fixes. + +Changes between release 2.4.6 (04Jan94) and release 2.4.5: + + - Linking with -lfl no longer required if your program includes + its own yywrap() and main() functions. (This change will cause + problems if you have a non-ANSI compiler on a system for which + sizeof(int) != sizeof(void*) or sizeof(int) != sizeof(size_t).) + + - The use of 'extern "C++"' in FlexLexer.h has been modified to + get around an incompatibility with g++'s header files. + +Changes between release 2.4.5 (11Dec93) and release 2.4.4: + + - Fixed bug breaking C++ scanners that use REJECT or variable + trailing context. + + - Fixed serious input problem for interactive scanners on + systems for which char is unsigned. + + - Fixed bug in incorrectly treating '$' operator as variable + trailing context. + + - Fixed bug in -CF table representation that could lead to + corrupt tables. + + - Fixed fairly benign memory leak. + + - Added `extern "C++"' wrapper to FlexLexer.h header. This + should overcome the g++ 2.5.X problems mentioned in the + NEWS for release 2.4.3. + + - Changed #include of FlexLexer.h to use <> instead of "". + + - Added feature to control whether the scanner attempts to + refill the input buffer once it's exhausted. This feature + will be documented in the 2.5 release. + + +Changes between release 2.4.4 (07Dec93) and release 2.4.3: + + - Fixed two serious bugs in scanning 8-bit characters. + + - Fixed bug in YY_USER_ACTION that caused it to be executed + inappropriately (on the scanner's own internal actions, and + with incorrect yytext/yyleng values). + + - Fixed bug in pointing yyin at a new file and resuming scanning. + + - Portability fix regarding min/max/abs macros conflicting with + function definitions in standard header files. + + - Added a virtual LexerError() method to the C++ yyFlexLexer class + for reporting error messages instead of always using cerr. + + - Added warning in flexdoc that the C++ scanning class is presently + experimental and subject to considerable change between major + releases. + + +Changes between release 2.4.3 (03Dec93) and release 2.4.2: + + - Fixed bug causing fatal scanner messages to fail to print. + + - Fixed things so FlexLexer.h can be included in other C++ + sources. One side-effect of this change is that -+ and -CF + are now incompatible. + + - libfl.a now supplies private versions of the the / + string routines needed by flex and the scanners + it generates, to enhance portability to some BSD systems. + + - More robust solution to 2.4.2's flexfatal() bug fix. + + - Added ranlib of installed libfl.a. + + - Some lint tweaks. + + - NOTE: problems have been encountered attempting to build flex + C++ scanners using g++ version 2.5.X. The problem is due to an + unfortunate heuristic in g++ 2.5.X that attempts to discern between + C and C++ headers. Because FlexLexer.h is installed (by default) + in /usr/local/include and not /usr/local/lib/g++-include, g++ 2.5.X + decides that it's a C header :-(. So if you have problems, install + the header in /usr/local/lib/g++-include instead. + + +Changes between release 2.4.2 (01Dec93) and release 2.4.1: + + - Fixed bug in libfl.a referring to non-existent "flexfatal" function. + + - Modified to produce both compress'd and gzip'd tar files for + distributions (you probably don't care about this change!). + + +Changes between release 2.4.1 (30Nov93) and release 2.3.8: + + - The new '-+' flag instructs flex to generate a C++ scanner class + (thanks to Kent Williams). flex writes an implementation of the + class defined in FlexLexer.h to lex.yy.cc. You may include + multiple scanner classes in your program using the -P flag. Note + that the scanner class also provides a mechanism for creating + reentrant scanners. The scanner class uses C++ streams for I/O + instead of FILE*'s (thanks to Tom Epperly). If the flex executable's + name ends in '+' then the '-+' flag is automatically on, so creating + a symlink or copy of "flex" to "flex++" results in a version of + flex that can be used exclusively for C++ scanners. + + Note that without the '-+' flag, flex-generated scanners can still + be compiled using C++ compilers, though they use FILE*'s for I/O + instead of streams. + + See the "GENERATING C++ SCANNERS" section of flexdoc for details. + + - The new '-l' flag turns on maximum AT&T lex compatibility. In + particular, -l includes support for "yylineno" and makes yytext + be an array instead of a pointer. It does not, however, do away + with all incompatibilities. See the "INCOMPATIBILITIES WITH LEX + AND POSIX" section of flexdoc for details. + + - The new '-P' option specifies a prefix to use other than "yy" + for the scanner's globally-visible variables, and for the + "lex.yy.c" filename. Using -P you can link together multiple + flex scanners in the same executable. + + - The distribution includes a "texinfo" version of flexdoc.1, + contributed by Roland Pesch (thanks also to Marq Kole, who + contributed another version). It has not been brought up to + date, but reflects version 2.3. See MISC/flex.texinfo. + + The flex distribution will soon include G.T. Nicol's flex + manual; he is presently bringing it up-to-date for version 2.4. + + - yywrap() is now a function, and you now *must* link flex scanners + with libfl.a. + + - Site-configuration is now done via an autoconf-generated + "configure" script contributed by Francois Pinard. + + - Scanners now use fread() (or getc(), if interactive) and not + read() for input. A new "table compression" option, -Cr, + overrides this change and causes the scanner to use read() + (because read() is a bit faster than fread()). -f and -F + are now equivalent to -Cfr and -CFr; i.e., they imply the + -Cr option. + + - In the blessed name of POSIX compliance, flex supports "%array" + and "%pointer" directives in the definitions (first) section of + the scanner specification. The former specifies that yytext + should be an array (of size YYLMAX), the latter, that it should + be a pointer. The array version of yytext is universally slower + than the pointer version, but has the advantage that its contents + remain unmodified across calls to input() and unput() (the pointer + version of yytext is, still, trashed by such calls). + + "%array" cannot be used with the '-+' C++ scanner class option. + + - The new '-Ca' option directs flex to trade off memory for + natural alignment when generating a scanner's tables. In + particular, table entries that would otherwise be "short" + become "long". + + - The new '-h' option produces a summary of the flex flags. + + - The new '-V' option reports the flex version number and exits. + + - The new scanner macro YY_START returns an integer value + corresponding to the current start condition. You can return + to that start condition by passing the value to a subsequent + "BEGIN" action. You also can implement "start condition stacks" + by storing the values in an integer stack. + + - You can now redefine macros such as YY_INPUT by just #define'ing + them to some other value in the first section of the flex input; + no need to first #undef them. + + - flex now generates warnings for rules that can't be matched. + These warnings can be turned off using the new '-w' flag. If + your scanner uses REJECT then you will not get these warnings. + + - If you specify the '-s' flag but the default rule can be matched, + flex now generates a warning. + + - "yyleng" is now a global, and may be modified by the user (though + doing so and then using yymore() will yield weird results). + + - Name definitions in the first section of a scanner specification + can now include a leading '^' or trailing '$' operator. In this + case, the definition is *not* pushed back inside of parentheses. + + - Scanners with compressed tables are now "interactive" (-I option) + by default. You can suppress this attribute (which makes them + run slightly slower) using the new '-B' flag. + + - Flex now generates 8-bit scanners by default, unless you use the + -Cf or -CF compression options (-Cfe and -CFe result in 8-bit + scanners). You can force it to generate a 7-bit scanner using + the new '-7' flag. You can build flex to generate 8-bit scanners + for -Cf and -CF, too, by adding -DDEFAULT_CSIZE=256 to CFLAGS + in the Makefile. + + - You no longer need to call the scanner routine yyrestart() to + inform the scanner that you have switched to a new file after + having seen an EOF on the current input file. Instead, just + point yyin at the new file and continue scanning. + + - You no longer need to invoke YY_NEW_FILE in an <> action + to indicate you wish to continue scanning. Simply point yyin + at a new file. + + - A leading '#' no longer introduces a comment in a flex input. + + - flex no longer considers formfeed ('\f') a whitespace character. + + - %t, I'm happy to report, has been nuked. + + - The '-p' option may be given twice ('-pp') to instruct flex to + report minor performance problems as well as major ones. + + - The '-v' verbose output no longer includes start/finish time + information. + + - Newlines in flex inputs can optionally include leading or + trailing carriage-returns ('\r'), in support of several PC/Mac + run-time libraries that automatically include these. + + - A start condition of the form "<*>" makes the following rule + active in every start condition, whether exclusive or inclusive. + + - The following items have been corrected in the flex documentation: + + - '-C' table compression options *are* cumulative. + + - You may modify yytext but not lengthen it by appending + characters to the end. Modifying its final character + will affect '^' anchoring for the next rule matched + if the character is changed to or from a newline. + + - The term "backtracking" has been renamed "backing up", + since it is a one-time repositioning and not a repeated + search. What used to be the "lex.backtrack" file is now + "lex.backup". + + - Unindented "/* ... */" comments are allowed in the first + flex input section, but not in the second. + + - yyless() can only be used in the flex input source, not + externally. + + - You can use "yyrestart(yyin)" to throw away the + current contents of the input buffer. + + - To write high-speed scanners, attempt to match as much + text as possible with each rule. See MISC/fastwc/README + for more information. + + - Using the beginning-of-line operator ('^') is fairly + cheap. Using unput() is expensive. Using yyless() is + cheap. + + - An example of scanning strings with embedded escape + sequences has been added. + + - The example of backing-up in flexdoc was erroneous; it + has been corrected. + + - A flex scanner's internal buffer now dynamically grows if needed + to match large tokens. Note that growing the buffer presently + requires rescanning the (large) token, so consuming a lot of + text this way is a slow process. Also note that presently the + buffer does *not* grow if you unput() more text than can fit + into the buffer. + + - The MISC/ directory has been reorganized; see MISC/README for + details. + + - yyless() can now be used in the third (user action) section + of a scanner specification, thanks to Ceriel Jacobs. yyless() + remains a macro and cannot be used outside of the scanner source. + + - The skeleton file is no longer opened at run-time, but instead + compiled into a large string array (thanks to John Gilmore and + friends at Cygnus). You can still use the -S flag to point flex + at a different skeleton file. + + - flex no longer uses a temporary file to store the scanner's + actions. + + - A number of changes have been made to decrease porting headaches. + In particular, flex no longer uses memset() or ctime(), and + provides a single simple mechanism for dealing with C compilers + that still define malloc() as returning char* instead of void*. + + - Flex now detects if the scanner specification requires the -8 flag + but the flag was not given or on by default. + + - A number of table-expansion fencepost bugs have been fixed, + making flex more robust for generating large scanners. + + - flex more consistently identifies the location of errors in + its input. + + - YY_USER_ACTION is now invoked only for "real" actions, not for + internal actions used by the scanner for things like filling + the buffer or handling EOF. + + - The rule "[^]]" now matches any character other than a ']'; + formerly it matched any character at all followed by a ']'. + This change was made for compatibility with AT&T lex. + + - A large number of miscellaneous bugs have been found and fixed + thanks to Gerhard Wilhelms. + + - The source code has been heavily reformatted, making patches + relative to previous flex releases no longer accurate. + + +Changes between 2.3 Patch #8 (21Feb93) and 2.3 Patch #7: + + - Fixed bugs in dynamic memory allocation leading to grievous + fencepost problems when generating large scanners. + - Fixed bug causing infinite loops on character classes with 8-bit + characters in them. + - Fixed bug in matching repetitions with a lower bound of 0. + - Fixed bug in scanning NUL characters using an "interactive" scanner. + - Fixed bug in using yymore() at the end of a file. + - Fixed bug in misrecognizing rules with variable trailing context. + - Fixed bug compiling flex on Suns using gcc 2. + - Fixed bug in not recognizing that input files with the character + ASCII 128 in them require the -8 flag. + - Fixed bug that could cause an infinite loop writing out + error messages. + - Fixed bug in not recognizing old-style lex % declarations if + followed by a tab instead of a space. + - Fixed potential crash when flex terminated early (usually due + to a bad flag) and the -v flag had been given. + - Added some missing declarations of void functions. + - Changed to only use '\a' for __STDC__ compilers. + - Updated mailing addresses. + + +Changes between 2.3 Patch #7 (28Mar91) and 2.3 Patch #6: + + - Fixed out-of-bounds array access that caused bad tables + to be produced on machines where the bad reference happened + to yield a 1. This caused problems installing or running + flex on some Suns, in particular. + + +Changes between 2.3 Patch #6 (29Aug90) and 2.3 Patch #5: + + - Fixed a serious bug in yymore() which basically made it + completely broken. Thanks goes to Jean Christophe of + the Nethack development team for finding the problem + and passing along the fix. + + +Changes between 2.3 Patch #5 (16Aug90) and 2.3 Patch #4: + + - An up-to-date version of initscan.c so "make test" will + work after applying the previous patches + + +Changes between 2.3 Patch #4 (14Aug90) and 2.3 Patch #3: + + - Fixed bug in hexadecimal escapes which allowed only digits, + not letters, in escapes + - Fixed bug in previous "Changes" file! + + +Changes between 2.3 Patch #3 (03Aug90) and 2.3 Patch #2: + + - Correction to patch #2 for gcc compilation; thanks goes to + Paul Eggert for catching this. + + +Changes between 2.3 Patch #2 (02Aug90) and original 2.3 release: + + - Fixed (hopefully) headaches involving declaring malloc() + and free() for gcc, which defines __STDC__ but (often) doesn't + come with the standard include files such as . + Reordered #ifdef maze in the scanner skeleton in the hope of + getting the declarations right for cfront and g++, too. + + - Note that this patch supercedes patch #1 for release 2.3, + which was never announced but was available briefly for + anonymous ftp. + + +Changes between 2.3 (full) release of 28Jun90 and 2.2 (alpha) release: + + User-visible: + + - A lone <> rule (that is, one which is not qualified with + a list of start conditions) now specifies the EOF action for + *all* start conditions which haven't already had <> actions + given. To specify an end-of-file action for just the initial + state, use <>. + + - -d debug output is now contigent on the global yy_flex_debug + being set to a non-zero value, which it is by default. + + - A new macro, YY_USER_INIT, is provided for the user to specify + initialization action to be taken on the first call to the + scanner. This action is done before the scanner does its + own initialization. + + - yy_new_buffer() has been added as an alias for yy_create_buffer() + + - Comments beginning with '#' and extending to the end of the line + now work, but have been deprecated (in anticipation of making + flex recognize #line directives). + + - The funky restrictions on when semi-colons could follow the + YY_NEW_FILE and yyless macros have been removed. They now + behave identically to functions. + + - A bug in the sample redefinition of YY_INPUT in the documentation + has been corrected. + + - A bug in the sample simple tokener in the documentation has + been corrected. + + - The documentation on the incompatibilities between flex and + lex has been reordered so that the discussion of yylineno + and input() come first, as it's anticipated that these will + be the most common source of headaches. + + + Things which didn't used to be documented but now are: + + - flex interprets "^foo|bar" differently from lex. flex interprets + it as "match either a 'foo' or a 'bar', providing it comes at the + beginning of a line", whereas lex interprets it as "match either + a 'foo' at the beginning of a line, or a 'bar' anywhere". + + - flex initializes the global "yyin" on the first call to the + scanner, while lex initializes it at compile-time. + + - yy_switch_to_buffer() can be used in the yywrap() macro/routine. + + - flex scanners do not use stdio for their input, and hence when + writing an interactive scanner one must explictly call fflush() + after writing out a prompt. + + - flex scanner can be made reentrant (after a fashion) by using + "yyrestart( yyin );". This is useful for interactive scanners + which have interrupt handlers that long-jump out of the scanner. + + - a defense of why yylineno is not supported is included, along + with a suggestion on how to convert scanners which rely on it. + + + Other changes: + + - Prototypes and proper declarations of void routines have + been added to the flex source code, courtesy of Kevin B. Kenny. + + - Routines dealing with memory allocation now use void* pointers + instead of char* - see Makefile for porting implications. + + - Error-checking is now done when flex closes a file. + + - Various lint tweaks were added to reduce the number of gripes. + + - Makefile has been further parameterized to aid in porting. + + - Support for SCO Unix added. + + - Flex now sports the latest & greatest UC copyright notice + (which is only slightly different from the previous one). + + - A note has been added to flexdoc.1 mentioning work in progress + on modifying flex to generate straight C code rather than a + table-driven automaton, with an email address of whom to contact + if you are working along similar lines. + + +Changes between 2.2 Patch #3 (30Mar90) and 2.2 Patch #2: + + - fixed bug which caused -I scanners to bomb + + +Changes between 2.2 Patch #2 (27Mar90) and 2.2 Patch #1: + + - fixed bug writing past end of input buffer in yyunput() + - fixed bug detecting NUL's at the end of a buffer + + +Changes between 2.2 Patch #1 (23Mar90) and 2.2 (alpha) release: + + - Makefile fixes: definition of MAKE variable for systems + which don't have it; installation of flexdoc.1 along with + flex.1; fixed two bugs which could cause "bigtest" to fail. + + - flex.skel fix for compiling with g++. + + - README and flexdoc.1 no longer list an out-of-date BITNET address + for contacting me. + + - minor typos and formatting changes to flex.1 and flexdoc.1. + + +Changes between 2.2 (alpha) release of March '90 and previous release: + + User-visible: + + - Full user documentation now available. + + - Support for 8-bit scanners. + + - Scanners now accept NUL's. + + - A facility has been added for dealing with multiple + input buffers. + + - Two manual entries now. One which fully describes flex + (rather than just its differences from lex), and the + other for quick(er) reference. + + - A number of changes to bring flex closer into compliance + with the latest POSIX lex draft: + + %t support + flex now accepts multiple input files and concatenates + them together to form its input + previous -c (compress) flag renamed -C + do-nothing -c and -n flags added + Any indented code or code within %{}'s in section 2 is + now copied to the output + + - yyleng is now a bona fide global integer. + + - -d debug information now gives the line number of the + matched rule instead of which number rule it was from + the beginning of the file. + + - -v output now includes a summary of the flags used to generate + the scanner. + + - unput() and yyrestart() are now globally callable. + + - yyrestart() no longer closes the previous value of yyin. + + - C++ support; generated scanners can be compiled with C++ compiler. + + - Primitive -lfl library added, containing default main() + which calls yylex(). A number of routines currently living + in the scanner skeleton will probably migrate to here + in the future (in particular, yywrap() will probably cease + to be a macro and instead be a function in the -lfl library). + + - Hexadecimal (\x) escape sequences added. + + - Support for MS-DOS, VMS, and Turbo-C integrated. + + - The %used/%unused operators have been deprecated. They + may go away soon. + + + Other changes: + + - Makefile enhanced for easier testing and installation. + - The parser has been tweaked to detect some erroneous + constructions which previously were missed. + - Scanner input buffer overflow is now detected. + - Bugs with missing "const" declarations fixed. + - Out-of-date Minix/Atari patches provided. + - Scanners no longer require printf() unless FLEX_DEBUG is being used. + - A subtle input() bug has been fixed. + - Line numbers for "continued action" rules (those following + the special '|' action) are now correct. + - unput() bug fixed; had been causing problems porting flex to VMS. + - yymore() handling rewritten to fix bug with interaction + between yymore() and trailing context. + - EOF in actions now generates an error message. + - Bug involving -CFe and generating equivalence classes fixed. + - Bug which made -CF be treated as -Cf fixed. + - Support for SysV tmpnam() added. + - Unused #define's for scanner no longer generated. + - Error messages which are associated with a particular input + line are now all identified with their input line in standard + format. + - % directives which are valid to lex but not to flex are + now ignored instead of generating warnings. + - -DSYS_V flag can now also be specified -DUSG for System V + compilation. + + +Changes between 2.1 beta-test release of June '89 and previous release: + + User-visible: + + - -p flag generates a performance report to stderr. The report + consists of comments regarding features of the scanner rules + which result in slower scanners. + + - -b flag generates backtracking information to lex.backtrack. + This is a list of scanner states which require backtracking + and the characters on which they do so. By adding rules + one can remove backtracking states. If all backtracking states + are eliminated, the generated scanner will run faster. + Backtracking is not yet documented in the manual entry. + + - Variable trailing context now works, i.e., one can have + rules like "(foo)*/[ \t]*bletch". Some trailing context + patterns still cannot be properly matched and generate + error messages. These are patterns where the ending of the + first part of the rule matches the beginning of the second + part, such as "zx*/xy*", where the 'x*' matches the 'x' at + the beginning of the trailing context. Lex won't get these + patterns right either. + + - Faster scanners. + + - End-of-file rules. The special rule "<>" indicates + actions which are to be taken when an end-of-file is + encountered and yywrap() returns non-zero (i.e., indicates + no further files to process). See manual entry for example. + + - The -r (reject used) flag is gone. flex now scans the input + for occurrences of the string "REJECT" to determine if the + action is needed. It tries to be intelligent about this but + can be fooled. One can force the presence or absence of + REJECT by adding a line in the first section of the form + "%used REJECT" or "%unused REJECT". + + - yymore() has been implemented. Similarly to REJECT, flex + detects the use of yymore(), which can be overridden using + "%used" or "%unused". + + - Patterns like "x{0,3}" now work (i.e., with lower-limit == 0). + + - Removed '\^x' for ctrl-x misfeature. + + - Added '\a' and '\v' escape sequences. + + - \ now works for octal escape sequences; previously + \0 was required. + + - Better error reporting; line numbers are associated with rules. + + - yyleng is a macro; it cannot be accessed outside of the + scanner source file. + + - yytext and yyleng should not be modified within a flex action. + + - Generated scanners #define the name FLEX_SCANNER. + + - Rules are internally separated by YY_BREAK in lex.yy.c rather + than break, to allow redefinition. + + - The macro YY_USER_ACTION can be redefined to provide an action + which is always executed prior to the matched rule's action. + + - yyrestart() is a new action which can be used to restart + the scanner after it has seen an end-of-file (a "real" one, + that is, one for which yywrap() returned non-zero). It takes + a FILE* argument indicating a new file to scan and sets + things up so that a subsequent call to yylex() will start + scanning that file. + + - Internal scanner names all preceded by "yy_" + + - lex.yy.c is deleted if errors are encountered during processing. + + - Comments may be put in the first section of the input by preceding + them with '#'. + + + + Other changes: + + - Some portability-related bugs fixed, in particular for machines + with unsigned characters or sizeof( int* ) != sizeof( int ). + Also, tweaks for VMS and Microsoft C (MS-DOS), and identifiers all + trimmed to be 31 or fewer characters. Shortened file names + for dinosaur OS's. Checks for allocating > 64K memory + on 16 bit'ers. Amiga tweaks. Compiles using gcc on a Sun-3. + - Compressed and fast scanner skeletons merged. + - Skeleton header files done away with. + - Generated scanner uses prototypes and "const" for __STDC__. + - -DSV flag is now -DSYS_V for System V compilation. + - Removed all references to FTL language. + - Software now covered by BSD Copyright. + - flex will replace lex in subsequent BSD releases. diff --git a/commands/flex-2.5.4/README b/commands/flex-2.5.4/README new file mode 100644 index 000000000..7a4224dca --- /dev/null +++ b/commands/flex-2.5.4/README @@ -0,0 +1,60 @@ +This is release 2.5 of flex. See "version.h" for the exact patch-level. + +See the file "NEWS" to find out what is new in this Flex release. + +Read the file "INSTALL" for general installation directives. Peek near +the beginning of the file "Makefile.in" for special DEFS values. On most +systems, you can just run the "configure" script and type "make" to build +flex; then "make check" to test whether it built correctly; and if it did, +then "make install" to install it. + +If you're feeling adventurous, you can also issue "make bigcheck" (be +prepared to wait a while). + +Note that flex is distributed under a copyright very similar to that of +BSD Unix, and not under the GNU General Public License (GPL), except for +the "configure" script, which is covered by the GPL. + +Many thanks to the 2.5 beta-testers for finding bugs and helping test and +increase portability: Stan Adermann, Scott David Daniels, Charles Elliott, +Joe Gayda, Chris Meier, James Nordby, Terrence O'Kane, Karsten Pahnke, +Francois Pinard, Pat Rankin, Andreas Scherer, Marc Wiese, Nathan Zelle. + +Please send bug reports and feedback to: Vern Paxson (vern@ee.lbl.gov). + + +The flex distribution consists of the following files: + + README This message + + NEWS Differences between the various releases + + INSTALL General installation information + + COPYING flex's copyright + + conf.in, configure.in, configure, Makefile.in, install.sh, + mkinstalldirs + elements of the "autoconf" auto-configuration process + + flexdef.h, parse.y, scan.l, ccl.c, dfa.c, ecs.c, gen.c, main.c, + misc.c, nfa.c, sym.c, tblcmp.c, yylex.c + source files + + version.h version of this flex release + + flex.skl flex scanner skeleton + mkskel.sh script for converting flex.skl to C source file skel.c + skel.c pre-converted C version of flex.skl + + libmain.c flex library (-lfl) sources + libyywrap.c + + initscan.c pre-flex'd version of scan.l + + FlexLexer.h header file for C++ lexer class + + flex.1 user documentation + + MISC/ a directory containing miscellaneous contributions. + See MISC/README for details. diff --git a/commands/flex-2.5.4/ccl.c b/commands/flex-2.5.4/ccl.c new file mode 100644 index 000000000..12e992c03 --- /dev/null +++ b/commands/flex-2.5.4/ccl.c @@ -0,0 +1,149 @@ +/* ccl - routines for character classes */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + +#include "flexdef.h" + +/* ccladd - add a single character to a ccl */ + +void ccladd( cclp, ch ) +int cclp; +int ch; + { + int ind, len, newpos, i; + + check_char( ch ); + + len = ccllen[cclp]; + ind = cclmap[cclp]; + + /* check to see if the character is already in the ccl */ + + for ( i = 0; i < len; ++i ) + if ( ccltbl[ind + i] == ch ) + return; + + newpos = ind + len; + + if ( newpos >= current_max_ccl_tbl_size ) + { + current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT; + + ++num_reallocs; + + ccltbl = reallocate_Character_array( ccltbl, + current_max_ccl_tbl_size ); + } + + ccllen[cclp] = len + 1; + ccltbl[newpos] = ch; + } + + +/* cclinit - return an empty ccl */ + +int cclinit() + { + if ( ++lastccl >= current_maxccls ) + { + current_maxccls += MAX_CCLS_INCREMENT; + + ++num_reallocs; + + cclmap = reallocate_integer_array( cclmap, current_maxccls ); + ccllen = reallocate_integer_array( ccllen, current_maxccls ); + cclng = reallocate_integer_array( cclng, current_maxccls ); + } + + if ( lastccl == 1 ) + /* we're making the first ccl */ + cclmap[lastccl] = 0; + + else + /* The new pointer is just past the end of the last ccl. + * Since the cclmap points to the \first/ character of a + * ccl, adding the length of the ccl to the cclmap pointer + * will produce a cursor to the first free space. + */ + cclmap[lastccl] = cclmap[lastccl - 1] + ccllen[lastccl - 1]; + + ccllen[lastccl] = 0; + cclng[lastccl] = 0; /* ccl's start out life un-negated */ + + return lastccl; + } + + +/* cclnegate - negate the given ccl */ + +void cclnegate( cclp ) +int cclp; + { + cclng[cclp] = 1; + } + + +/* list_character_set - list the members of a set of characters in CCL form + * + * Writes to the given file a character-class representation of those + * characters present in the given CCL. A character is present if it + * has a non-zero value in the cset array. + */ + +void list_character_set( file, cset ) +FILE *file; +int cset[]; + { + register int i; + + putc( '[', file ); + + for ( i = 0; i < csize; ++i ) + { + if ( cset[i] ) + { + register int start_char = i; + + putc( ' ', file ); + + fputs( readable_form( i ), file ); + + while ( ++i < csize && cset[i] ) + ; + + if ( i - 1 > start_char ) + /* this was a run */ + fprintf( file, "-%s", readable_form( i - 1 ) ); + + putc( ' ', file ); + } + } + + putc( ']', file ); + } diff --git a/commands/flex-2.5.4/conf.in b/commands/flex-2.5.4/conf.in new file mode 100644 index 000000000..6cdcebebf --- /dev/null +++ b/commands/flex-2.5.4/conf.in @@ -0,0 +1,25 @@ +/* $Header$ */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define if platform-specific command line handling is necessary. */ +#undef NEED_ARGV_FIXUP diff --git a/commands/flex-2.5.4/configure b/commands/flex-2.5.4/configure new file mode 100755 index 000000000..be7f861b8 --- /dev/null +++ b/commands/flex-2.5.4/configure @@ -0,0 +1,1632 @@ +#!/bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.1 +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE + +# Initialize some other variables. +subdirs= + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -build | --build | --buil | --bui | --bu | --b) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=PREFIX install architecture-dependent files in PREFIX + [same as prefix] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +--enable and --with options recognized:$ac_help +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.1" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 unused; standard input +# 1 file creation +# 2 errors and warnings +# 3 unused; some systems may open it to /dev/tty +# 4 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 4>/dev/null +else + exec 4>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=initscan.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} $CFLAGS $CPPFLAGS conftest.$ac_ext -c 1>&5 2>&5' +ac_link='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext -o conftest $LIBS 1>&5 2>&5' + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + +for ac_prog in 'bison -y' byacc +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_YACC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_YACC="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +YACC="$ac_cv_prog_YACC" +if test -n "$YACC"; then + echo "$ac_t""$YACC" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + +test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.c <&5 | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi +echo "$ac_t""$ac_cv_prog_gcc" 1>&4 +if test $ac_cv_prog_gcc = yes; then + GCC=yes + if test "${CFLAGS+set}" != set; then + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_gcc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_gcc_g=yes +else + ac_cv_prog_gcc_g=no +fi +rm -f conftest* + +fi + echo "$ac_t""$ac_cv_prog_gcc_g" 1>&4 + if test $ac_cv_prog_gcc_g = yes; then + CFLAGS="-g -O" + else + CFLAGS="-O" + fi + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&4 +else + echo "$ac_t""no" 1>&4 +fi + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&4 +if test -z "$INSTALL"; then +if eval "test \"`echo '${'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + case "$ac_dir" in + ''|.|/etc|/usr/sbin|/usr/etc|/sbin|/usr/afsws/bin|/usr/ucb) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in ginstall installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_ifs" + # As a last resort, use the slow shell script. + test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh" +fi + INSTALL="$ac_cv_path_install" +fi +echo "$ac_t""$INSTALL" 1>&4 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether ${MAKE-make} sets \$MAKE""... $ac_c" 1>&4 +set dummy ${MAKE-make}; ac_make=$2 +if eval "test \"`echo '${'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&4 + SET_MAKE= +else + echo "$ac_t""no" 1>&4 + SET_MAKE="MAKE=${MAKE-make}" +fi + +echo $ac_n "checking for working const""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_c_const'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_c_const=yes +else + rm -rf conftest* + ac_cv_c_const=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_c_const" 1>&4 +if test $ac_cv_c_const = no; then + cat >> confdefs.h <<\EOF +#define const +EOF + +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&4 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '${'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi +fi +CPP="$ac_cv_prog_CPP" +echo "$ac_t""$CPP" 1>&4 + +# If we cannot run a trivial program, we must be cross compiling. +echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_c_cross'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test "$cross_compiling" = yes; then + ac_cv_cross=yes +else +cat > conftest.$ac_ext </dev/null; then + ac_cv_c_cross=no +else + ac_cv_c_cross=yes +fi +fi +rm -fr conftest* +fi +cross_compiling=$ac_cv_c_cross +echo "$ac_t""$ac_cv_c_cross" 1>&4 + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + ac_cv_header_stdc=no +else +cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + ac_cv_header_stdc=no +fi +fi +rm -fr conftest* +fi +fi +echo "$ac_t""$ac_cv_header_stdc" 1>&4 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +echo $ac_n "checking for size_t""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_type_size_t'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < +#if STDC_HEADERS +#include +#endif +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "size_t" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_type_size_t=yes +else + rm -rf conftest* + ac_cv_type_size_t=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_type_size_t" 1>&4 +if test $ac_cv_type_size_t = no; then + cat >> confdefs.h <<\EOF +#define size_t unsigned +EOF + +fi + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + ac_cv_header_stdc=no +else +cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + ac_cv_header_stdc=no +fi +fi +rm -fr conftest* +fi +fi +echo "$ac_t""$ac_cv_header_stdc" 1>&4 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + +for ac_hdr in string.h malloc.h sys/types.h +do +ac_safe=`echo "$ac_hdr" | tr './\055' '___'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < +EOF +eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&4 + ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'` + cat >> confdefs.h <&4 +fi +done + + +case "$YACC" in +*bison*) + # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo $ac_n "checking for working alloca.h""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_header_alloca_h'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < +int main() { return 0; } +int t() { +char *p = alloca(2 * sizeof(int)); +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + ac_cv_header_alloca_h=yes +else + rm -rf conftest* + ac_cv_header_alloca_h=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_header_alloca_h" 1>&4 +if test $ac_cv_header_alloca_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA_H 1 +EOF + +fi + +echo $ac_n "checking for alloca""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_func_alloca'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +#endif + +int main() { return 0; } +int t() { +char *p = (char *) alloca(1); +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + ac_cv_func_alloca=yes +else + rm -rf conftest* + ac_cv_func_alloca=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_func_alloca" 1>&4 +if test $ac_cv_func_alloca = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_ALLOCA 1 +EOF + +fi + +if test $ac_cv_func_alloca = no; then + # The SVR3 libPW and SVR4 libucb both contain incompatible functions + # that cause trouble. Some versions do not even contain alloca or + # contain a buggy version. If you still want to use their alloca, + # use ar to extract alloca.o from them instead of compiling alloca.c. + ALLOCA=alloca.o + cat >> confdefs.h <<\EOF +#define C_ALLOCA 1 +EOF + + +echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_os_cray'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext <&5 | + egrep "webecray" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_os_cray=yes +else + rm -rf conftest* + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +echo "$ac_t""$ac_cv_os_cray" 1>&4 +if test $ac_cv_os_cray = yes; then +echo $ac_n "checking for _getb67""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_func__getb67'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < /* Arbitrary system header to define __stub macros. */ +/* Override any gcc2 internal prototype to avoid an error. */ +char _getb67(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub__getb67) || defined (__stub____getb67) +choke me +#else +_getb67(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func__getb67=yes" +else + rm -rf conftest* + eval "ac_cv_func__getb67=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'_getb67`\" = yes"; then + echo "$ac_t""yes" 1>&4 + cat >> confdefs.h <<\EOF +#define CRAY_STACKSEG_END _getb67 +EOF + +else + echo "$ac_t""no" 1>&4 +echo $ac_n "checking for GETB67""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_func_GETB67'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < /* Arbitrary system header to define __stub macros. */ +/* Override any gcc2 internal prototype to avoid an error. */ +char GETB67(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_GETB67) || defined (__stub___GETB67) +choke me +#else +GETB67(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func_GETB67=yes" +else + rm -rf conftest* + eval "ac_cv_func_GETB67=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'GETB67`\" = yes"; then + echo "$ac_t""yes" 1>&4 + cat >> confdefs.h <<\EOF +#define CRAY_STACKSEG_END GETB67 +EOF + +else + echo "$ac_t""no" 1>&4 +echo $ac_n "checking for getb67""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_func_getb67'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + cat > conftest.$ac_ext < /* Arbitrary system header to define __stub macros. */ +/* Override any gcc2 internal prototype to avoid an error. */ +char getb67(); + +int main() { return 0; } +int t() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getb67) || defined (__stub___getb67) +choke me +#else +getb67(); +#endif + +; return 0; } +EOF +if eval $ac_link; then + rm -rf conftest* + eval "ac_cv_func_getb67=yes" +else + rm -rf conftest* + eval "ac_cv_func_getb67=no" +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_func_'getb67`\" = yes"; then + echo "$ac_t""yes" 1>&4 + cat >> confdefs.h <<\EOF +#define CRAY_STACKSEG_END getb67 +EOF + +else + echo "$ac_t""no" 1>&4 +fi + +fi + +fi + +fi + +echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&4 +if eval "test \"`echo '${'ac_cv_c_stack_direction'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&4 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else +cat > conftest.$ac_ext < addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +eval $ac_link +if test -s conftest && (./conftest; exit) 2>/dev/null; then + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +fi +rm -fr conftest* +fi +echo "$ac_t""$ac_cv_c_stack_direction" 1>&4 +cat >> confdefs.h < $cache_file <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# Ultrix sh set writes to stderr and can't be redirected directly. +(set) 2>&1 | + sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/: \${\1='\2'}/p" \ + >> $cache_file +else +echo "not updating unwritable cache $cache_file" +fi + +trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +DEFS=-DHAVE_CONFIG_H + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.1" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr Makefile config.h:conf.in conftest*; exit 1' 1 2 15 + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF +$ac_vpsub +$extrasub +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@LN_S@%$LN_S%g +s%@YACC@%$YACC%g +s%@CC@%$CC%g +s%@RANLIB@%$RANLIB%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CPP@%$CPP%g +s%@ALLOCA@%$ALLOCA%g + +CEOF +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust relative srcdir, etc. for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/$ac_dir" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file +fi; done +rm -f conftest.subs + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' +ac_dC='\3' +ac_dD='%g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)%\1#\2define\3' +ac_uC=' ' +ac_uD='\4%g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$%\1#\2define\3' +ac_eC=' ' +ac_eD='%g' + +CONFIG_HEADERS=${CONFIG_HEADERS-"config.h:conf.in"} +for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then + # Support "outfile[:infile]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + echo creating $ac_file + + rm -f conftest.frag conftest.in conftest.out + cp $ac_given_srcdir/$ac_file_in conftest.in + +EOF + +# Transform confdefs.h into a sed script conftest.vals that substitutes +# the proper values into config.h.in to produce config.h. And first: +# Protect against being on the right side of a sed subst in config.status. +# Protect against being in an unquoted here document in config.status. +rm -f conftest.vals +cat > conftest.hdr <<\EOF +s/[\\&%]/\\&/g +s%[\\$`]%\\&%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%ac_d%ac_u%gp +s%ac_u%ac_e%gp +EOF +sed -n -f conftest.hdr confdefs.h > conftest.vals +rm -f conftest.hdr + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >> conftest.vals <<\EOF +s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% +EOF + +# Break up conftest.vals because some shells have a limit on +# the size of here documents, and old seds have small limits too. +# Maximum number of lines to put in a single here document. +ac_max_here_lines=12 + +rm -f conftest.tail +while : +do + ac_lines=`grep -c . conftest.vals` + # grep -c gives empty output for an empty file on some AIX systems. + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + # Write a limited-size here document to conftest.frag. + echo ' cat > conftest.frag <> $CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS + echo 'CEOF + sed -f conftest.frag conftest.in > conftest.out + rm -f conftest.in + mv conftest.out conftest.in +' >> $CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail + rm -f conftest.vals + mv conftest.tail conftest.vals +done +rm -f conftest.vals + +cat >> $CONFIG_STATUS <<\EOF + rm -f conftest.frag conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.in >> conftest.h + rm -f conftest.in + if cmp -s $ac_file conftest.h 2>/dev/null; then + echo "$ac_file is unchanged" + rm -f conftest.h + else + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done + + +test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS + diff --git a/commands/flex-2.5.4/configure.in b/commands/flex-2.5.4/configure.in new file mode 100644 index 000000000..366e65e15 --- /dev/null +++ b/commands/flex-2.5.4/configure.in @@ -0,0 +1,24 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +AC_INIT(initscan.c) +AC_CONFIG_HEADER(config.h:conf.in) + +AC_LN_S +AC_PROG_YACC +AC_PROG_CC +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_PROG_MAKE_SET +AC_CONST +AC_TYPE_SIZE_T +AC_HEADER_STDC +AC_HAVE_HEADERS(string.h malloc.h sys/types.h) + +case "$YACC" in +*bison*) + AC_ALLOCA + ;; +esac + +AC_OUTPUT(Makefile, +[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h]) diff --git a/commands/flex-2.5.4/configure.minix b/commands/flex-2.5.4/configure.minix new file mode 100755 index 000000000..9c4da93e8 --- /dev/null +++ b/commands/flex-2.5.4/configure.minix @@ -0,0 +1,2 @@ +#!/bin/sh +./configure --prefix=/usr diff --git a/commands/flex-2.5.4/dfa.c b/commands/flex-2.5.4/dfa.c new file mode 100644 index 000000000..52dbceb57 --- /dev/null +++ b/commands/flex-2.5.4/dfa.c @@ -0,0 +1,1095 @@ +/* dfa - DFA construction routines */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + +#include "flexdef.h" + + +/* declare functions that have forward references */ + +void dump_associated_rules PROTO((FILE*, int)); +void dump_transitions PROTO((FILE*, int[])); +void sympartition PROTO((int[], int, int[], int[])); +int symfollowset PROTO((int[], int, int, int[])); + + +/* check_for_backing_up - check a DFA state for backing up + * + * synopsis + * void check_for_backing_up( int ds, int state[numecs] ); + * + * ds is the number of the state to check and state[] is its out-transitions, + * indexed by equivalence class. + */ + +void check_for_backing_up( ds, state ) +int ds; +int state[]; + { + if ( (reject && ! dfaacc[ds].dfaacc_set) || + (! reject && ! dfaacc[ds].dfaacc_state) ) + { /* state is non-accepting */ + ++num_backing_up; + + if ( backing_up_report ) + { + fprintf( backing_up_file, + _( "State #%d is non-accepting -\n" ), ds ); + + /* identify the state */ + dump_associated_rules( backing_up_file, ds ); + + /* Now identify it further using the out- and + * jam-transitions. + */ + dump_transitions( backing_up_file, state ); + + putc( '\n', backing_up_file ); + } + } + } + + +/* check_trailing_context - check to see if NFA state set constitutes + * "dangerous" trailing context + * + * synopsis + * void check_trailing_context( int nfa_states[num_states+1], int num_states, + * int accset[nacc+1], int nacc ); + * + * NOTES + * Trailing context is "dangerous" if both the head and the trailing + * part are of variable size \and/ there's a DFA state which contains + * both an accepting state for the head part of the rule and NFA states + * which occur after the beginning of the trailing context. + * + * When such a rule is matched, it's impossible to tell if having been + * in the DFA state indicates the beginning of the trailing context or + * further-along scanning of the pattern. In these cases, a warning + * message is issued. + * + * nfa_states[1 .. num_states] is the list of NFA states in the DFA. + * accset[1 .. nacc] is the list of accepting numbers for the DFA state. + */ + +void check_trailing_context( nfa_states, num_states, accset, nacc ) +int *nfa_states, num_states; +int *accset; +int nacc; + { + register int i, j; + + for ( i = 1; i <= num_states; ++i ) + { + int ns = nfa_states[i]; + register int type = state_type[ns]; + register int ar = assoc_rule[ns]; + + if ( type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE ) + { /* do nothing */ + } + + else if ( type == STATE_TRAILING_CONTEXT ) + { + /* Potential trouble. Scan set of accepting numbers + * for the one marking the end of the "head". We + * assume that this looping will be fairly cheap + * since it's rare that an accepting number set + * is large. + */ + for ( j = 1; j <= nacc; ++j ) + if ( accset[j] & YY_TRAILING_HEAD_MASK ) + { + line_warning( + _( "dangerous trailing context" ), + rule_linenum[ar] ); + return; + } + } + } + } + + +/* dump_associated_rules - list the rules associated with a DFA state + * + * Goes through the set of NFA states associated with the DFA and + * extracts the first MAX_ASSOC_RULES unique rules, sorts them, + * and writes a report to the given file. + */ + +void dump_associated_rules( file, ds ) +FILE *file; +int ds; + { + register int i, j; + register int num_associated_rules = 0; + int rule_set[MAX_ASSOC_RULES + 1]; + int *dset = dss[ds]; + int size = dfasiz[ds]; + + for ( i = 1; i <= size; ++i ) + { + register int rule_num = rule_linenum[assoc_rule[dset[i]]]; + + for ( j = 1; j <= num_associated_rules; ++j ) + if ( rule_num == rule_set[j] ) + break; + + if ( j > num_associated_rules ) + { /* new rule */ + if ( num_associated_rules < MAX_ASSOC_RULES ) + rule_set[++num_associated_rules] = rule_num; + } + } + + bubble( rule_set, num_associated_rules ); + + fprintf( file, _( " associated rule line numbers:" ) ); + + for ( i = 1; i <= num_associated_rules; ++i ) + { + if ( i % 8 == 1 ) + putc( '\n', file ); + + fprintf( file, "\t%d", rule_set[i] ); + } + + putc( '\n', file ); + } + + +/* dump_transitions - list the transitions associated with a DFA state + * + * synopsis + * dump_transitions( FILE *file, int state[numecs] ); + * + * Goes through the set of out-transitions and lists them in human-readable + * form (i.e., not as equivalence classes); also lists jam transitions + * (i.e., all those which are not out-transitions, plus EOF). The dump + * is done to the given file. + */ + +void dump_transitions( file, state ) +FILE *file; +int state[]; + { + register int i, ec; + int out_char_set[CSIZE]; + + for ( i = 0; i < csize; ++i ) + { + ec = ABS( ecgroup[i] ); + out_char_set[i] = state[ec]; + } + + fprintf( file, _( " out-transitions: " ) ); + + list_character_set( file, out_char_set ); + + /* now invert the members of the set to get the jam transitions */ + for ( i = 0; i < csize; ++i ) + out_char_set[i] = ! out_char_set[i]; + + fprintf( file, _( "\n jam-transitions: EOF " ) ); + + list_character_set( file, out_char_set ); + + putc( '\n', file ); + } + + +/* epsclosure - construct the epsilon closure of a set of ndfa states + * + * synopsis + * int *epsclosure( int t[num_states], int *numstates_addr, + * int accset[num_rules+1], int *nacc_addr, + * int *hashval_addr ); + * + * NOTES + * The epsilon closure is the set of all states reachable by an arbitrary + * number of epsilon transitions, which themselves do not have epsilon + * transitions going out, unioned with the set of states which have non-null + * accepting numbers. t is an array of size numstates of nfa state numbers. + * Upon return, t holds the epsilon closure and *numstates_addr is updated. + * accset holds a list of the accepting numbers, and the size of accset is + * given by *nacc_addr. t may be subjected to reallocation if it is not + * large enough to hold the epsilon closure. + * + * hashval is the hash value for the dfa corresponding to the state set. + */ + +int *epsclosure( t, ns_addr, accset, nacc_addr, hv_addr ) +int *t, *ns_addr, accset[], *nacc_addr, *hv_addr; + { + register int stkpos, ns, tsp; + int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum; + int stkend, nstate; + static int did_stk_init = false, *stk; + +#define MARK_STATE(state) \ +trans1[state] = trans1[state] - MARKER_DIFFERENCE; + +#define IS_MARKED(state) (trans1[state] < 0) + +#define UNMARK_STATE(state) \ +trans1[state] = trans1[state] + MARKER_DIFFERENCE; + +#define CHECK_ACCEPT(state) \ +{ \ +nfaccnum = accptnum[state]; \ +if ( nfaccnum != NIL ) \ +accset[++nacc] = nfaccnum; \ +} + +#define DO_REALLOCATION \ +{ \ +current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \ +++num_reallocs; \ +t = reallocate_integer_array( t, current_max_dfa_size ); \ +stk = reallocate_integer_array( stk, current_max_dfa_size ); \ +} \ + +#define PUT_ON_STACK(state) \ +{ \ +if ( ++stkend >= current_max_dfa_size ) \ +DO_REALLOCATION \ +stk[stkend] = state; \ +MARK_STATE(state) \ +} + +#define ADD_STATE(state) \ +{ \ +if ( ++numstates >= current_max_dfa_size ) \ +DO_REALLOCATION \ +t[numstates] = state; \ +hashval += state; \ +} + +#define STACK_STATE(state) \ +{ \ +PUT_ON_STACK(state) \ +CHECK_ACCEPT(state) \ +if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \ +ADD_STATE(state) \ +} + + + if ( ! did_stk_init ) + { + stk = allocate_integer_array( current_max_dfa_size ); + did_stk_init = true; + } + + nacc = stkend = hashval = 0; + + for ( nstate = 1; nstate <= numstates; ++nstate ) + { + ns = t[nstate]; + + /* The state could be marked if we've already pushed it onto + * the stack. + */ + if ( ! IS_MARKED(ns) ) + { + PUT_ON_STACK(ns) + CHECK_ACCEPT(ns) + hashval += ns; + } + } + + for ( stkpos = 1; stkpos <= stkend; ++stkpos ) + { + ns = stk[stkpos]; + transsym = transchar[ns]; + + if ( transsym == SYM_EPSILON ) + { + tsp = trans1[ns] + MARKER_DIFFERENCE; + + if ( tsp != NO_TRANSITION ) + { + if ( ! IS_MARKED(tsp) ) + STACK_STATE(tsp) + + tsp = trans2[ns]; + + if ( tsp != NO_TRANSITION && ! IS_MARKED(tsp) ) + STACK_STATE(tsp) + } + } + } + + /* Clear out "visit" markers. */ + + for ( stkpos = 1; stkpos <= stkend; ++stkpos ) + { + if ( IS_MARKED(stk[stkpos]) ) + UNMARK_STATE(stk[stkpos]) + else + flexfatal( + _( "consistency check failed in epsclosure()" ) ); + } + + *ns_addr = numstates; + *hv_addr = hashval; + *nacc_addr = nacc; + + return t; + } + + +/* increase_max_dfas - increase the maximum number of DFAs */ + +void increase_max_dfas() + { + current_max_dfas += MAX_DFAS_INCREMENT; + + ++num_reallocs; + + base = reallocate_integer_array( base, current_max_dfas ); + def = reallocate_integer_array( def, current_max_dfas ); + dfasiz = reallocate_integer_array( dfasiz, current_max_dfas ); + accsiz = reallocate_integer_array( accsiz, current_max_dfas ); + dhash = reallocate_integer_array( dhash, current_max_dfas ); + dss = reallocate_int_ptr_array( dss, current_max_dfas ); + dfaacc = reallocate_dfaacc_union( dfaacc, current_max_dfas ); + + if ( nultrans ) + nultrans = + reallocate_integer_array( nultrans, current_max_dfas ); + } + + +/* ntod - convert an ndfa to a dfa + * + * Creates the dfa corresponding to the ndfa we've constructed. The + * dfa starts out in state #1. + */ + +void ntod() + { + int *accset, ds, nacc, newds; + int sym, hashval, numstates, dsize; + int num_full_table_rows; /* used only for -f */ + int *nset, *dset; + int targptr, totaltrans, i, comstate, comfreq, targ; + int symlist[CSIZE + 1]; + int num_start_states; + int todo_head, todo_next; + + /* Note that the following are indexed by *equivalence classes* + * and not by characters. Since equivalence classes are indexed + * beginning with 1, even if the scanner accepts NUL's, this + * means that (since every character is potentially in its own + * equivalence class) these arrays must have room for indices + * from 1 to CSIZE, so their size must be CSIZE + 1. + */ + int duplist[CSIZE + 1], state[CSIZE + 1]; + int targfreq[CSIZE + 1], targstate[CSIZE + 1]; + + accset = allocate_integer_array( num_rules + 1 ); + nset = allocate_integer_array( current_max_dfa_size ); + + /* The "todo" queue is represented by the head, which is the DFA + * state currently being processed, and the "next", which is the + * next DFA state number available (not in use). We depend on the + * fact that snstods() returns DFA's \in increasing order/, and thus + * need only know the bounds of the dfas to be processed. + */ + todo_head = todo_next = 0; + + for ( i = 0; i <= csize; ++i ) + { + duplist[i] = NIL; + symlist[i] = false; + } + + for ( i = 0; i <= num_rules; ++i ) + accset[i] = NIL; + + if ( trace ) + { + dumpnfa( scset[1] ); + fputs( _( "\n\nDFA Dump:\n\n" ), stderr ); + } + + inittbl(); + + /* Check to see whether we should build a separate table for + * transitions on NUL characters. We don't do this for full-speed + * (-F) scanners, since for them we don't have a simple state + * number lying around with which to index the table. We also + * don't bother doing it for scanners unless (1) NUL is in its own + * equivalence class (indicated by a positive value of + * ecgroup[NUL]), (2) NUL's equivalence class is the last + * equivalence class, and (3) the number of equivalence classes is + * the same as the number of characters. This latter case comes + * about when useecs is false or when it's true but every character + * still manages to land in its own class (unlikely, but it's + * cheap to check for). If all these things are true then the + * character code needed to represent NUL's equivalence class for + * indexing the tables is going to take one more bit than the + * number of characters, and therefore we won't be assured of + * being able to fit it into a YY_CHAR variable. This rules out + * storing the transitions in a compressed table, since the code + * for interpreting them uses a YY_CHAR variable (perhaps it + * should just use an integer, though; this is worth pondering ... + * ###). + * + * Finally, for full tables, we want the number of entries in the + * table to be a power of two so the array references go fast (it + * will just take a shift to compute the major index). If + * encoding NUL's transitions in the table will spoil this, we + * give it its own table (note that this will be the case if we're + * not using equivalence classes). + */ + + /* Note that the test for ecgroup[0] == numecs below accomplishes + * both (1) and (2) above + */ + if ( ! fullspd && ecgroup[0] == numecs ) + { + /* NUL is alone in its equivalence class, which is the + * last one. + */ + int use_NUL_table = (numecs == csize); + + if ( fulltbl && ! use_NUL_table ) + { + /* We still may want to use the table if numecs + * is a power of 2. + */ + int power_of_two; + + for ( power_of_two = 1; power_of_two <= csize; + power_of_two *= 2 ) + if ( numecs == power_of_two ) + { + use_NUL_table = true; + break; + } + } + + if ( use_NUL_table ) + nultrans = allocate_integer_array( current_max_dfas ); + + /* From now on, nultrans != nil indicates that we're + * saving null transitions for later, separate encoding. + */ + } + + + if ( fullspd ) + { + for ( i = 0; i <= numecs; ++i ) + state[i] = 0; + + place_state( state, 0, 0 ); + dfaacc[0].dfaacc_state = 0; + } + + else if ( fulltbl ) + { + if ( nultrans ) + /* We won't be including NUL's transitions in the + * table, so build it for entries from 0 .. numecs - 1. + */ + num_full_table_rows = numecs; + + else + /* Take into account the fact that we'll be including + * the NUL entries in the transition table. Build it + * from 0 .. numecs. + */ + num_full_table_rows = numecs + 1; + + /* Unless -Ca, declare it "short" because it's a real + * long-shot that that won't be large enough. + */ + out_str_dec( "static yyconst %s yy_nxt[][%d] =\n {\n", + /* '}' so vi doesn't get too confused */ + long_align ? "long" : "short", num_full_table_rows ); + + outn( " {" ); + + /* Generate 0 entries for state #0. */ + for ( i = 0; i < num_full_table_rows; ++i ) + mk2data( 0 ); + + dataflush(); + outn( " },\n" ); + } + + /* Create the first states. */ + + num_start_states = lastsc * 2; + + for ( i = 1; i <= num_start_states; ++i ) + { + numstates = 1; + + /* For each start condition, make one state for the case when + * we're at the beginning of the line (the '^' operator) and + * one for the case when we're not. + */ + if ( i % 2 == 1 ) + nset[numstates] = scset[(i / 2) + 1]; + else + nset[numstates] = + mkbranch( scbol[i / 2], scset[i / 2] ); + + nset = epsclosure( nset, &numstates, accset, &nacc, &hashval ); + + if ( snstods( nset, numstates, accset, nacc, hashval, &ds ) ) + { + numas += nacc; + totnst += numstates; + ++todo_next; + + if ( variable_trailing_context_rules && nacc > 0 ) + check_trailing_context( nset, numstates, + accset, nacc ); + } + } + + if ( ! fullspd ) + { + if ( ! snstods( nset, 0, accset, 0, 0, &end_of_buffer_state ) ) + flexfatal( + _( "could not create unique end-of-buffer state" ) ); + + ++numas; + ++num_start_states; + ++todo_next; + } + + while ( todo_head < todo_next ) + { + targptr = 0; + totaltrans = 0; + + for ( i = 1; i <= numecs; ++i ) + state[i] = 0; + + ds = ++todo_head; + + dset = dss[ds]; + dsize = dfasiz[ds]; + + if ( trace ) + fprintf( stderr, _( "state # %d:\n" ), ds ); + + sympartition( dset, dsize, symlist, duplist ); + + for ( sym = 1; sym <= numecs; ++sym ) + { + if ( symlist[sym] ) + { + symlist[sym] = 0; + + if ( duplist[sym] == NIL ) + { + /* Symbol has unique out-transitions. */ + numstates = symfollowset( dset, dsize, + sym, nset ); + nset = epsclosure( nset, &numstates, + accset, &nacc, &hashval ); + + if ( snstods( nset, numstates, accset, + nacc, hashval, &newds ) ) + { + totnst = totnst + numstates; + ++todo_next; + numas += nacc; + + if ( + variable_trailing_context_rules && + nacc > 0 ) + check_trailing_context( + nset, numstates, + accset, nacc ); + } + + state[sym] = newds; + + if ( trace ) + fprintf( stderr, "\t%d\t%d\n", + sym, newds ); + + targfreq[++targptr] = 1; + targstate[targptr] = newds; + ++numuniq; + } + + else + { + /* sym's equivalence class has the same + * transitions as duplist(sym)'s + * equivalence class. + */ + targ = state[duplist[sym]]; + state[sym] = targ; + + if ( trace ) + fprintf( stderr, "\t%d\t%d\n", + sym, targ ); + + /* Update frequency count for + * destination state. + */ + + i = 0; + while ( targstate[++i] != targ ) + ; + + ++targfreq[i]; + ++numdup; + } + + ++totaltrans; + duplist[sym] = NIL; + } + } + + if ( caseins && ! useecs ) + { + register int j; + + for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j ) + { + if ( state[i] == 0 && state[j] != 0 ) + /* We're adding a transition. */ + ++totaltrans; + + else if ( state[i] != 0 && state[j] == 0 ) + /* We're taking away a transition. */ + --totaltrans; + + state[i] = state[j]; + } + } + + numsnpairs += totaltrans; + + if ( ds > num_start_states ) + check_for_backing_up( ds, state ); + + if ( nultrans ) + { + nultrans[ds] = state[NUL_ec]; + state[NUL_ec] = 0; /* remove transition */ + } + + if ( fulltbl ) + { + outn( " {" ); + + /* Supply array's 0-element. */ + if ( ds == end_of_buffer_state ) + mk2data( -end_of_buffer_state ); + else + mk2data( end_of_buffer_state ); + + for ( i = 1; i < num_full_table_rows; ++i ) + /* Jams are marked by negative of state + * number. + */ + mk2data( state[i] ? state[i] : -ds ); + + dataflush(); + outn( " },\n" ); + } + + else if ( fullspd ) + place_state( state, ds, totaltrans ); + + else if ( ds == end_of_buffer_state ) + /* Special case this state to make sure it does what + * it's supposed to, i.e., jam on end-of-buffer. + */ + stack1( ds, 0, 0, JAMSTATE ); + + else /* normal, compressed state */ + { + /* Determine which destination state is the most + * common, and how many transitions to it there are. + */ + + comfreq = 0; + comstate = 0; + + for ( i = 1; i <= targptr; ++i ) + if ( targfreq[i] > comfreq ) + { + comfreq = targfreq[i]; + comstate = targstate[i]; + } + + bldtbl( state, ds, totaltrans, comstate, comfreq ); + } + } + + if ( fulltbl ) + dataend(); + + else if ( ! fullspd ) + { + cmptmps(); /* create compressed template entries */ + + /* Create tables for all the states with only one + * out-transition. + */ + while ( onesp > 0 ) + { + mk1tbl( onestate[onesp], onesym[onesp], onenext[onesp], + onedef[onesp] ); + --onesp; + } + + mkdeftbl(); + } + + flex_free( (void *) accset ); + flex_free( (void *) nset ); + } + + +/* snstods - converts a set of ndfa states into a dfa state + * + * synopsis + * is_new_state = snstods( int sns[numstates], int numstates, + * int accset[num_rules+1], int nacc, + * int hashval, int *newds_addr ); + * + * On return, the dfa state number is in newds. + */ + +int snstods( sns, numstates, accset, nacc, hashval, newds_addr ) +int sns[], numstates, accset[], nacc, hashval, *newds_addr; + { + int didsort = 0; + register int i, j; + int newds, *oldsns; + + for ( i = 1; i <= lastdfa; ++i ) + if ( hashval == dhash[i] ) + { + if ( numstates == dfasiz[i] ) + { + oldsns = dss[i]; + + if ( ! didsort ) + { + /* We sort the states in sns so we + * can compare it to oldsns quickly. + * We use bubble because there probably + * aren't very many states. + */ + bubble( sns, numstates ); + didsort = 1; + } + + for ( j = 1; j <= numstates; ++j ) + if ( sns[j] != oldsns[j] ) + break; + + if ( j > numstates ) + { + ++dfaeql; + *newds_addr = i; + return 0; + } + + ++hshcol; + } + + else + ++hshsave; + } + + /* Make a new dfa. */ + + if ( ++lastdfa >= current_max_dfas ) + increase_max_dfas(); + + newds = lastdfa; + + dss[newds] = allocate_integer_array( numstates + 1 ); + + /* If we haven't already sorted the states in sns, we do so now, + * so that future comparisons with it can be made quickly. + */ + + if ( ! didsort ) + bubble( sns, numstates ); + + for ( i = 1; i <= numstates; ++i ) + dss[newds][i] = sns[i]; + + dfasiz[newds] = numstates; + dhash[newds] = hashval; + + if ( nacc == 0 ) + { + if ( reject ) + dfaacc[newds].dfaacc_set = (int *) 0; + else + dfaacc[newds].dfaacc_state = 0; + + accsiz[newds] = 0; + } + + else if ( reject ) + { + /* We sort the accepting set in increasing order so the + * disambiguating rule that the first rule listed is considered + * match in the event of ties will work. We use a bubble + * sort since the list is probably quite small. + */ + + bubble( accset, nacc ); + + dfaacc[newds].dfaacc_set = allocate_integer_array( nacc + 1 ); + + /* Save the accepting set for later */ + for ( i = 1; i <= nacc; ++i ) + { + dfaacc[newds].dfaacc_set[i] = accset[i]; + + if ( accset[i] <= num_rules ) + /* Who knows, perhaps a REJECT can yield + * this rule. + */ + rule_useful[accset[i]] = true; + } + + accsiz[newds] = nacc; + } + + else + { + /* Find lowest numbered rule so the disambiguating rule + * will work. + */ + j = num_rules + 1; + + for ( i = 1; i <= nacc; ++i ) + if ( accset[i] < j ) + j = accset[i]; + + dfaacc[newds].dfaacc_state = j; + + if ( j <= num_rules ) + rule_useful[j] = true; + } + + *newds_addr = newds; + + return 1; + } + + +/* symfollowset - follow the symbol transitions one step + * + * synopsis + * numstates = symfollowset( int ds[current_max_dfa_size], int dsize, + * int transsym, int nset[current_max_dfa_size] ); + */ + +int symfollowset( ds, dsize, transsym, nset ) +int ds[], dsize, transsym, nset[]; + { + int ns, tsp, sym, i, j, lenccl, ch, numstates, ccllist; + + numstates = 0; + + for ( i = 1; i <= dsize; ++i ) + { /* for each nfa state ns in the state set of ds */ + ns = ds[i]; + sym = transchar[ns]; + tsp = trans1[ns]; + + if ( sym < 0 ) + { /* it's a character class */ + sym = -sym; + ccllist = cclmap[sym]; + lenccl = ccllen[sym]; + + if ( cclng[sym] ) + { + for ( j = 0; j < lenccl; ++j ) + { + /* Loop through negated character + * class. + */ + ch = ccltbl[ccllist + j]; + + if ( ch == 0 ) + ch = NUL_ec; + + if ( ch > transsym ) + /* Transsym isn't in negated + * ccl. + */ + break; + + else if ( ch == transsym ) + /* next 2 */ goto bottom; + } + + /* Didn't find transsym in ccl. */ + nset[++numstates] = tsp; + } + + else + for ( j = 0; j < lenccl; ++j ) + { + ch = ccltbl[ccllist + j]; + + if ( ch == 0 ) + ch = NUL_ec; + + if ( ch > transsym ) + break; + else if ( ch == transsym ) + { + nset[++numstates] = tsp; + break; + } + } + } + + else if ( sym >= 'A' && sym <= 'Z' && caseins ) + flexfatal( + _( "consistency check failed in symfollowset" ) ); + + else if ( sym == SYM_EPSILON ) + { /* do nothing */ + } + + else if ( ABS( ecgroup[sym] ) == transsym ) + nset[++numstates] = tsp; + + bottom: ; + } + + return numstates; + } + + +/* sympartition - partition characters with same out-transitions + * + * synopsis + * sympartition( int ds[current_max_dfa_size], int numstates, + * int symlist[numecs], int duplist[numecs] ); + */ + +void sympartition( ds, numstates, symlist, duplist ) +int ds[], numstates; +int symlist[], duplist[]; + { + int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich; + + /* Partitioning is done by creating equivalence classes for those + * characters which have out-transitions from the given state. Thus + * we are really creating equivalence classes of equivalence classes. + */ + + for ( i = 1; i <= numecs; ++i ) + { /* initialize equivalence class list */ + duplist[i] = i - 1; + dupfwd[i] = i + 1; + } + + duplist[1] = NIL; + dupfwd[numecs] = NIL; + + for ( i = 1; i <= numstates; ++i ) + { + ns = ds[i]; + tch = transchar[ns]; + + if ( tch != SYM_EPSILON ) + { + if ( tch < -lastccl || tch >= csize ) + { + flexfatal( + _( "bad transition character detected in sympartition()" ) ); + } + + if ( tch >= 0 ) + { /* character transition */ + int ec = ecgroup[tch]; + + mkechar( ec, dupfwd, duplist ); + symlist[ec] = 1; + } + + else + { /* character class */ + tch = -tch; + + lenccl = ccllen[tch]; + cclp = cclmap[tch]; + mkeccl( ccltbl + cclp, lenccl, dupfwd, + duplist, numecs, NUL_ec ); + + if ( cclng[tch] ) + { + j = 0; + + for ( k = 0; k < lenccl; ++k ) + { + ich = ccltbl[cclp + k]; + + if ( ich == 0 ) + ich = NUL_ec; + + for ( ++j; j < ich; ++j ) + symlist[j] = 1; + } + + for ( ++j; j <= numecs; ++j ) + symlist[j] = 1; + } + + else + for ( k = 0; k < lenccl; ++k ) + { + ich = ccltbl[cclp + k]; + + if ( ich == 0 ) + ich = NUL_ec; + + symlist[ich] = 1; + } + } + } + } + } diff --git a/commands/flex-2.5.4/ecs.c b/commands/flex-2.5.4/ecs.c new file mode 100644 index 000000000..cdbd86fa8 --- /dev/null +++ b/commands/flex-2.5.4/ecs.c @@ -0,0 +1,225 @@ +/* ecs - equivalence class routines */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + +#include "flexdef.h" + +/* ccl2ecl - convert character classes to set of equivalence classes */ + +void ccl2ecl() + { + int i, ich, newlen, cclp, ccls, cclmec; + + for ( i = 1; i <= lastccl; ++i ) + { + /* We loop through each character class, and for each character + * in the class, add the character's equivalence class to the + * new "character" class we are creating. Thus when we are all + * done, character classes will really consist of collections + * of equivalence classes + */ + + newlen = 0; + cclp = cclmap[i]; + + for ( ccls = 0; ccls < ccllen[i]; ++ccls ) + { + ich = ccltbl[cclp + ccls]; + cclmec = ecgroup[ich]; + + if ( cclmec > 0 ) + { + ccltbl[cclp + newlen] = cclmec; + ++newlen; + } + } + + ccllen[i] = newlen; + } + } + + +/* cre8ecs - associate equivalence class numbers with class members + * + * fwd is the forward linked-list of equivalence class members. bck + * is the backward linked-list, and num is the number of class members. + * + * Returned is the number of classes. + */ + +int cre8ecs( fwd, bck, num ) +int fwd[], bck[], num; + { + int i, j, numcl; + + numcl = 0; + + /* Create equivalence class numbers. From now on, ABS( bck(x) ) + * is the equivalence class number for object x. If bck(x) + * is positive, then x is the representative of its equivalence + * class. + */ + for ( i = 1; i <= num; ++i ) + if ( bck[i] == NIL ) + { + bck[i] = ++numcl; + for ( j = fwd[i]; j != NIL; j = fwd[j] ) + bck[j] = -numcl; + } + + return numcl; + } + + +/* mkeccl - update equivalence classes based on character class xtions + * + * synopsis + * Char ccls[]; + * int lenccl, fwd[llsiz], bck[llsiz], llsiz, NUL_mapping; + * void mkeccl( Char ccls[], int lenccl, int fwd[llsiz], int bck[llsiz], + * int llsiz, int NUL_mapping ); + * + * ccls contains the elements of the character class, lenccl is the + * number of elements in the ccl, fwd is the forward link-list of equivalent + * characters, bck is the backward link-list, and llsiz size of the link-list. + * + * NUL_mapping is the value which NUL (0) should be mapped to. + */ + +void mkeccl( ccls, lenccl, fwd, bck, llsiz, NUL_mapping ) +Char ccls[]; +int lenccl, fwd[], bck[], llsiz, NUL_mapping; + { + int cclp, oldec, newec; + int cclm, i, j; + static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */ + + /* Note that it doesn't matter whether or not the character class is + * negated. The same results will be obtained in either case. + */ + + cclp = 0; + + while ( cclp < lenccl ) + { + cclm = ccls[cclp]; + + if ( NUL_mapping && cclm == 0 ) + cclm = NUL_mapping; + + oldec = bck[cclm]; + newec = cclm; + + j = cclp + 1; + + for ( i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i] ) + { /* look for the symbol in the character class */ + for ( ; j < lenccl; ++j ) + { + register int ccl_char; + + if ( NUL_mapping && ccls[j] == 0 ) + ccl_char = NUL_mapping; + else + ccl_char = ccls[j]; + + if ( ccl_char > i ) + break; + + if ( ccl_char == i && ! cclflags[j] ) + { + /* We found an old companion of cclm + * in the ccl. Link it into the new + * equivalence class and flag it as + * having been processed. + */ + + bck[i] = newec; + fwd[newec] = i; + newec = i; + /* Set flag so we don't reprocess. */ + cclflags[j] = 1; + + /* Get next equivalence class member. */ + /* continue 2 */ + goto next_pt; + } + } + + /* Symbol isn't in character class. Put it in the old + * equivalence class. + */ + + bck[i] = oldec; + + if ( oldec != NIL ) + fwd[oldec] = i; + + oldec = i; + + next_pt: ; + } + + if ( bck[cclm] != NIL || oldec != bck[cclm] ) + { + bck[cclm] = NIL; + fwd[oldec] = NIL; + } + + fwd[newec] = NIL; + + /* Find next ccl member to process. */ + + for ( ++cclp; cclflags[cclp] && cclp < lenccl; ++cclp ) + { + /* Reset "doesn't need processing" flag. */ + cclflags[cclp] = 0; + } + } + } + + +/* mkechar - create equivalence class for single character */ + +void mkechar( tch, fwd, bck ) +int tch, fwd[], bck[]; + { + /* If until now the character has been a proper subset of + * an equivalence class, break it away to create a new ec + */ + + if ( fwd[tch] != NIL ) + bck[fwd[tch]] = bck[tch]; + + if ( bck[tch] != NIL ) + fwd[bck[tch]] = fwd[tch]; + + fwd[tch] = NIL; + bck[tch] = NIL; + } diff --git a/commands/flex-2.5.4/flex.1 b/commands/flex-2.5.4/flex.1 new file mode 100644 index 000000000..f79a3ef40 --- /dev/null +++ b/commands/flex-2.5.4/flex.1 @@ -0,0 +1,4060 @@ +.TH FLEX 1 "April 1995" "Version 2.5" +.SH NAME +flex \- fast lexical analyzer generator +.SH SYNOPSIS +.B flex +.B [\-bcdfhilnpstvwBFILTV78+? \-C[aefFmr] \-ooutput \-Pprefix \-Sskeleton] +.B [\-\-help \-\-version] +.I [filename ...] +.SH OVERVIEW +This manual describes +.I flex, +a tool for generating programs that perform pattern-matching on text. The +manual includes both tutorial and reference sections: +.nf + + Description + a brief overview of the tool + + Some Simple Examples + + Format Of The Input File + + Patterns + the extended regular expressions used by flex + + How The Input Is Matched + the rules for determining what has been matched + + Actions + how to specify what to do when a pattern is matched + + The Generated Scanner + details regarding the scanner that flex produces; + how to control the input source + + Start Conditions + introducing context into your scanners, and + managing "mini-scanners" + + Multiple Input Buffers + how to manipulate multiple input sources; how to + scan from strings instead of files + + End-of-file Rules + special rules for matching the end of the input + + Miscellaneous Macros + a summary of macros available to the actions + + Values Available To The User + a summary of values available to the actions + + Interfacing With Yacc + connecting flex scanners together with yacc parsers + + Options + flex command-line options, and the "%option" + directive + + Performance Considerations + how to make your scanner go as fast as possible + + Generating C++ Scanners + the (experimental) facility for generating C++ + scanner classes + + Incompatibilities With Lex And POSIX + how flex differs from AT&T lex and the POSIX lex + standard + + Diagnostics + those error messages produced by flex (or scanners + it generates) whose meanings might not be apparent + + Files + files used by flex + + Deficiencies / Bugs + known problems with flex + + See Also + other documentation, related tools + + Author + includes contact information + +.fi +.SH DESCRIPTION +.I flex +is a tool for generating +.I scanners: +programs which recognized lexical patterns in text. +.I flex +reads +the given input files, or its standard input if no file names are given, +for a description of a scanner to generate. The description is in +the form of pairs +of regular expressions and C code, called +.I rules. flex +generates as output a C source file, +.B lex.yy.c, +which defines a routine +.B yylex(). +This file is compiled and linked with the +.B \-lfl +library to produce an executable. When the executable is run, +it analyzes its input for occurrences +of the regular expressions. Whenever it finds one, it executes +the corresponding C code. +.SH SOME SIMPLE EXAMPLES +.PP +First some simple examples to get the flavor of how one uses +.I flex. +The following +.I flex +input specifies a scanner which whenever it encounters the string +"username" will replace it with the user's login name: +.nf + + %% + username printf( "%s", getlogin() ); + +.fi +By default, any text not matched by a +.I flex +scanner +is copied to the output, so the net effect of this scanner is +to copy its input file to its output with each occurrence +of "username" expanded. +In this input, there is just one rule. "username" is the +.I pattern +and the "printf" is the +.I action. +The "%%" marks the beginning of the rules. +.PP +Here's another simple example: +.nf + + int num_lines = 0, num_chars = 0; + + %% + \\n ++num_lines; ++num_chars; + . ++num_chars; + + %% + main() + { + yylex(); + printf( "# of lines = %d, # of chars = %d\\n", + num_lines, num_chars ); + } + +.fi +This scanner counts the number of characters and the number +of lines in its input (it produces no output other than the +final report on the counts). The first line +declares two globals, "num_lines" and "num_chars", which are accessible +both inside +.B yylex() +and in the +.B main() +routine declared after the second "%%". There are two rules, one +which matches a newline ("\\n") and increments both the line count and +the character count, and one which matches any character other than +a newline (indicated by the "." regular expression). +.PP +A somewhat more complicated example: +.nf + + /* scanner for a toy Pascal-like language */ + + %{ + /* need this for the call to atof() below */ + #include + %} + + DIGIT [0-9] + ID [a-z][a-z0-9]* + + %% + + {DIGIT}+ { + printf( "An integer: %s (%d)\\n", yytext, + atoi( yytext ) ); + } + + {DIGIT}+"."{DIGIT}* { + printf( "A float: %s (%g)\\n", yytext, + atof( yytext ) ); + } + + if|then|begin|end|procedure|function { + printf( "A keyword: %s\\n", yytext ); + } + + {ID} printf( "An identifier: %s\\n", yytext ); + + "+"|"-"|"*"|"/" printf( "An operator: %s\\n", yytext ); + + "{"[^}\\n]*"}" /* eat up one-line comments */ + + [ \\t\\n]+ /* eat up whitespace */ + + . printf( "Unrecognized character: %s\\n", yytext ); + + %% + + main( argc, argv ) + int argc; + char **argv; + { + ++argv, --argc; /* skip over program name */ + if ( argc > 0 ) + yyin = fopen( argv[0], "r" ); + else + yyin = stdin; + + yylex(); + } + +.fi +This is the beginnings of a simple scanner for a language like +Pascal. It identifies different types of +.I tokens +and reports on what it has seen. +.PP +The details of this example will be explained in the following +sections. +.SH FORMAT OF THE INPUT FILE +The +.I flex +input file consists of three sections, separated by a line with just +.B %% +in it: +.nf + + definitions + %% + rules + %% + user code + +.fi +The +.I definitions +section contains declarations of simple +.I name +definitions to simplify the scanner specification, and declarations of +.I start conditions, +which are explained in a later section. +.PP +Name definitions have the form: +.nf + + name definition + +.fi +The "name" is a word beginning with a letter or an underscore ('_') +followed by zero or more letters, digits, '_', or '-' (dash). +The definition is taken to begin at the first non-white-space character +following the name and continuing to the end of the line. +The definition can subsequently be referred to using "{name}", which +will expand to "(definition)". For example, +.nf + + DIGIT [0-9] + ID [a-z][a-z0-9]* + +.fi +defines "DIGIT" to be a regular expression which matches a +single digit, and +"ID" to be a regular expression which matches a letter +followed by zero-or-more letters-or-digits. +A subsequent reference to +.nf + + {DIGIT}+"."{DIGIT}* + +.fi +is identical to +.nf + + ([0-9])+"."([0-9])* + +.fi +and matches one-or-more digits followed by a '.' followed +by zero-or-more digits. +.PP +The +.I rules +section of the +.I flex +input contains a series of rules of the form: +.nf + + pattern action + +.fi +where the pattern must be unindented and the action must begin +on the same line. +.PP +See below for a further description of patterns and actions. +.PP +Finally, the user code section is simply copied to +.B lex.yy.c +verbatim. +It is used for companion routines which call or are called +by the scanner. The presence of this section is optional; +if it is missing, the second +.B %% +in the input file may be skipped, too. +.PP +In the definitions and rules sections, any +.I indented +text or text enclosed in +.B %{ +and +.B %} +is copied verbatim to the output (with the %{}'s removed). +The %{}'s must appear unindented on lines by themselves. +.PP +In the rules section, +any indented or %{} text appearing before the +first rule may be used to declare variables +which are local to the scanning routine and (after the declarations) +code which is to be executed whenever the scanning routine is entered. +Other indented or %{} text in the rule section is still copied to the output, +but its meaning is not well-defined and it may well cause compile-time +errors (this feature is present for +.I POSIX +compliance; see below for other such features). +.PP +In the definitions section (but not in the rules section), +an unindented comment (i.e., a line +beginning with "/*") is also copied verbatim to the output up +to the next "*/". +.SH PATTERNS +The patterns in the input are written using an extended set of regular +expressions. These are: +.nf + + x match the character 'x' + . any character (byte) except newline + [xyz] a "character class"; in this case, the pattern + matches either an 'x', a 'y', or a 'z' + [abj-oZ] a "character class" with a range in it; matches + an 'a', a 'b', any letter from 'j' through 'o', + or a 'Z' + [^A-Z] a "negated character class", i.e., any character + but those in the class. In this case, any + character EXCEPT an uppercase letter. + [^A-Z\\n] any character EXCEPT an uppercase letter or + a newline + r* zero or more r's, where r is any regular expression + r+ one or more r's + r? zero or one r's (that is, "an optional r") + r{2,5} anywhere from two to five r's + r{2,} two or more r's + r{4} exactly 4 r's + {name} the expansion of the "name" definition + (see above) + "[xyz]\\"foo" + the literal string: [xyz]"foo + \\X if X is an 'a', 'b', 'f', 'n', 'r', 't', or 'v', + then the ANSI-C interpretation of \\x. + Otherwise, a literal 'X' (used to escape + operators such as '*') + \\0 a NUL character (ASCII code 0) + \\123 the character with octal value 123 + \\x2a the character with hexadecimal value 2a + (r) match an r; parentheses are used to override + precedence (see below) + + + rs the regular expression r followed by the + regular expression s; called "concatenation" + + + r|s either an r or an s + + + r/s an r but only if it is followed by an s. The + text matched by s is included when determining + whether this rule is the "longest match", + but is then returned to the input before + the action is executed. So the action only + sees the text matched by r. This type + of pattern is called trailing context". + (There are some combinations of r/s that flex + cannot match correctly; see notes in the + Deficiencies / Bugs section below regarding + "dangerous trailing context".) + ^r an r, but only at the beginning of a line (i.e., + which just starting to scan, or right after a + newline has been scanned). + r$ an r, but only at the end of a line (i.e., just + before a newline). Equivalent to "r/\\n". + + Note that flex's notion of "newline" is exactly + whatever the C compiler used to compile flex + interprets '\\n' as; in particular, on some DOS + systems you must either filter out \\r's in the + input yourself, or explicitly use r/\\r\\n for "r$". + + + r an r, but only in start condition s (see + below for discussion of start conditions) + r + same, but in any of start conditions s1, + s2, or s3 + <*>r an r in any start condition, even an exclusive one. + + + <> an end-of-file + <> + an end-of-file when in start condition s1 or s2 + +.fi +Note that inside of a character class, all regular expression operators +lose their special meaning except escape ('\\') and the character class +operators, '-', ']', and, at the beginning of the class, '^'. +.PP +The regular expressions listed above are grouped according to +precedence, from highest precedence at the top to lowest at the bottom. +Those grouped together have equal precedence. For example, +.nf + + foo|bar* + +.fi +is the same as +.nf + + (foo)|(ba(r*)) + +.fi +since the '*' operator has higher precedence than concatenation, +and concatenation higher than alternation ('|'). This pattern +therefore matches +.I either +the string "foo" +.I or +the string "ba" followed by zero-or-more r's. +To match "foo" or zero-or-more "bar"'s, use: +.nf + + foo|(bar)* + +.fi +and to match zero-or-more "foo"'s-or-"bar"'s: +.nf + + (foo|bar)* + +.fi +.PP +In addition to characters and ranges of characters, character classes +can also contain character class +.I expressions. +These are expressions enclosed inside +.B [: +and +.B :] +delimiters (which themselves must appear between the '[' and ']' of the +character class; other elements may occur inside the character class, too). +The valid expressions are: +.nf + + [:alnum:] [:alpha:] [:blank:] + [:cntrl:] [:digit:] [:graph:] + [:lower:] [:print:] [:punct:] + [:space:] [:upper:] [:xdigit:] + +.fi +These expressions all designate a set of characters equivalent to +the corresponding standard C +.B isXXX +function. For example, +.B [:alnum:] +designates those characters for which +.B isalnum() +returns true - i.e., any alphabetic or numeric. +Some systems don't provide +.B isblank(), +so flex defines +.B [:blank:] +as a blank or a tab. +.PP +For example, the following character classes are all equivalent: +.nf + + [[:alnum:]] + [[:alpha:][:digit:] + [[:alpha:]0-9] + [a-zA-Z0-9] + +.fi +If your scanner is case-insensitive (the +.B \-i +flag), then +.B [:upper:] +and +.B [:lower:] +are equivalent to +.B [:alpha:]. +.PP +Some notes on patterns: +.IP - +A negated character class such as the example "[^A-Z]" +above +.I will match a newline +unless "\\n" (or an equivalent escape sequence) is one of the +characters explicitly present in the negated character class +(e.g., "[^A-Z\\n]"). This is unlike how many other regular +expression tools treat negated character classes, but unfortunately +the inconsistency is historically entrenched. +Matching newlines means that a pattern like [^"]* can match the entire +input unless there's another quote in the input. +.IP - +A rule can have at most one instance of trailing context (the '/' operator +or the '$' operator). The start condition, '^', and "<>" patterns +can only occur at the beginning of a pattern, and, as well as with '/' and '$', +cannot be grouped inside parentheses. A '^' which does not occur at +the beginning of a rule or a '$' which does not occur at the end of +a rule loses its special properties and is treated as a normal character. +.IP +The following are illegal: +.nf + + foo/bar$ + foobar + +.fi +Note that the first of these, can be written "foo/bar\\n". +.IP +The following will result in '$' or '^' being treated as a normal character: +.nf + + foo|(bar$) + foo|^bar + +.fi +If what's wanted is a "foo" or a bar-followed-by-a-newline, the following +could be used (the special '|' action is explained below): +.nf + + foo | + bar$ /* action goes here */ + +.fi +A similar trick will work for matching a foo or a +bar-at-the-beginning-of-a-line. +.SH HOW THE INPUT IS MATCHED +When the generated scanner is run, it analyzes its input looking +for strings which match any of its patterns. If it finds more than +one match, it takes the one matching the most text (for trailing +context rules, this includes the length of the trailing part, even +though it will then be returned to the input). If it finds two +or more matches of the same length, the +rule listed first in the +.I flex +input file is chosen. +.PP +Once the match is determined, the text corresponding to the match +(called the +.I token) +is made available in the global character pointer +.B yytext, +and its length in the global integer +.B yyleng. +The +.I action +corresponding to the matched pattern is then executed (a more +detailed description of actions follows), and then the remaining +input is scanned for another match. +.PP +If no match is found, then the +.I default rule +is executed: the next character in the input is considered matched and +copied to the standard output. Thus, the simplest legal +.I flex +input is: +.nf + + %% + +.fi +which generates a scanner that simply copies its input (one character +at a time) to its output. +.PP +Note that +.B yytext +can be defined in two different ways: either as a character +.I pointer +or as a character +.I array. +You can control which definition +.I flex +uses by including one of the special directives +.B %pointer +or +.B %array +in the first (definitions) section of your flex input. The default is +.B %pointer, +unless you use the +.B -l +lex compatibility option, in which case +.B yytext +will be an array. +The advantage of using +.B %pointer +is substantially faster scanning and no buffer overflow when matching +very large tokens (unless you run out of dynamic memory). The disadvantage +is that you are restricted in how your actions can modify +.B yytext +(see the next section), and calls to the +.B unput() +function destroys the present contents of +.B yytext, +which can be a considerable porting headache when moving between different +.I lex +versions. +.PP +The advantage of +.B %array +is that you can then modify +.B yytext +to your heart's content, and calls to +.B unput() +do not destroy +.B yytext +(see below). Furthermore, existing +.I lex +programs sometimes access +.B yytext +externally using declarations of the form: +.nf + extern char yytext[]; +.fi +This definition is erroneous when used with +.B %pointer, +but correct for +.B %array. +.PP +.B %array +defines +.B yytext +to be an array of +.B YYLMAX +characters, which defaults to a fairly large value. You can change +the size by simply #define'ing +.B YYLMAX +to a different value in the first section of your +.I flex +input. As mentioned above, with +.B %pointer +yytext grows dynamically to accommodate large tokens. While this means your +.B %pointer +scanner can accommodate very large tokens (such as matching entire blocks +of comments), bear in mind that each time the scanner must resize +.B yytext +it also must rescan the entire token from the beginning, so matching such +tokens can prove slow. +.B yytext +presently does +.I not +dynamically grow if a call to +.B unput() +results in too much text being pushed back; instead, a run-time error results. +.PP +Also note that you cannot use +.B %array +with C++ scanner classes +(the +.B c++ +option; see below). +.SH ACTIONS +Each pattern in a rule has a corresponding action, which can be any +arbitrary C statement. The pattern ends at the first non-escaped +whitespace character; the remainder of the line is its action. If the +action is empty, then when the pattern is matched the input token +is simply discarded. For example, here is the specification for a program +which deletes all occurrences of "zap me" from its input: +.nf + + %% + "zap me" + +.fi +(It will copy all other characters in the input to the output since +they will be matched by the default rule.) +.PP +Here is a program which compresses multiple blanks and tabs down to +a single blank, and throws away whitespace found at the end of a line: +.nf + + %% + [ \\t]+ putchar( ' ' ); + [ \\t]+$ /* ignore this token */ + +.fi +.PP +If the action contains a '{', then the action spans till the balancing '}' +is found, and the action may cross multiple lines. +.I flex +knows about C strings and comments and won't be fooled by braces found +within them, but also allows actions to begin with +.B %{ +and will consider the action to be all the text up to the next +.B %} +(regardless of ordinary braces inside the action). +.PP +An action consisting solely of a vertical bar ('|') means "same as +the action for the next rule." See below for an illustration. +.PP +Actions can include arbitrary C code, including +.B return +statements to return a value to whatever routine called +.B yylex(). +Each time +.B yylex() +is called it continues processing tokens from where it last left +off until it either reaches +the end of the file or executes a return. +.PP +Actions are free to modify +.B yytext +except for lengthening it (adding +characters to its end--these will overwrite later characters in the +input stream). This however does not apply when using +.B %array +(see above); in that case, +.B yytext +may be freely modified in any way. +.PP +Actions are free to modify +.B yyleng +except they should not do so if the action also includes use of +.B yymore() +(see below). +.PP +There are a number of special directives which can be included within +an action: +.IP - +.B ECHO +copies yytext to the scanner's output. +.IP - +.B BEGIN +followed by the name of a start condition places the scanner in the +corresponding start condition (see below). +.IP - +.B REJECT +directs the scanner to proceed on to the "second best" rule which matched the +input (or a prefix of the input). The rule is chosen as described +above in "How the Input is Matched", and +.B yytext +and +.B yyleng +set up appropriately. +It may either be one which matched as much text +as the originally chosen rule but came later in the +.I flex +input file, or one which matched less text. +For example, the following will both count the +words in the input and call the routine special() whenever "frob" is seen: +.nf + + int word_count = 0; + %% + + frob special(); REJECT; + [^ \\t\\n]+ ++word_count; + +.fi +Without the +.B REJECT, +any "frob"'s in the input would not be counted as words, since the +scanner normally executes only one action per token. +Multiple +.B REJECT's +are allowed, each one finding the next best choice to the currently +active rule. For example, when the following scanner scans the token +"abcd", it will write "abcdabcaba" to the output: +.nf + + %% + a | + ab | + abc | + abcd ECHO; REJECT; + .|\\n /* eat up any unmatched character */ + +.fi +(The first three rules share the fourth's action since they use +the special '|' action.) +.B REJECT +is a particularly expensive feature in terms of scanner performance; +if it is used in +.I any +of the scanner's actions it will slow down +.I all +of the scanner's matching. Furthermore, +.B REJECT +cannot be used with the +.I -Cf +or +.I -CF +options (see below). +.IP +Note also that unlike the other special actions, +.B REJECT +is a +.I branch; +code immediately following it in the action will +.I not +be executed. +.IP - +.B yymore() +tells the scanner that the next time it matches a rule, the corresponding +token should be +.I appended +onto the current value of +.B yytext +rather than replacing it. For example, given the input "mega-kludge" +the following will write "mega-mega-kludge" to the output: +.nf + + %% + mega- ECHO; yymore(); + kludge ECHO; + +.fi +First "mega-" is matched and echoed to the output. Then "kludge" +is matched, but the previous "mega-" is still hanging around at the +beginning of +.B yytext +so the +.B ECHO +for the "kludge" rule will actually write "mega-kludge". +.PP +Two notes regarding use of +.B yymore(). +First, +.B yymore() +depends on the value of +.I yyleng +correctly reflecting the size of the current token, so you must not +modify +.I yyleng +if you are using +.B yymore(). +Second, the presence of +.B yymore() +in the scanner's action entails a minor performance penalty in the +scanner's matching speed. +.IP - +.B yyless(n) +returns all but the first +.I n +characters of the current token back to the input stream, where they +will be rescanned when the scanner looks for the next match. +.B yytext +and +.B yyleng +are adjusted appropriately (e.g., +.B yyleng +will now be equal to +.I n +). For example, on the input "foobar" the following will write out +"foobarbar": +.nf + + %% + foobar ECHO; yyless(3); + [a-z]+ ECHO; + +.fi +An argument of 0 to +.B yyless +will cause the entire current input string to be scanned again. Unless you've +changed how the scanner will subsequently process its input (using +.B BEGIN, +for example), this will result in an endless loop. +.PP +Note that +.B yyless +is a macro and can only be used in the flex input file, not from +other source files. +.IP - +.B unput(c) +puts the character +.I c +back onto the input stream. It will be the next character scanned. +The following action will take the current token and cause it +to be rescanned enclosed in parentheses. +.nf + + { + int i; + /* Copy yytext because unput() trashes yytext */ + char *yycopy = strdup( yytext ); + unput( ')' ); + for ( i = yyleng - 1; i >= 0; --i ) + unput( yycopy[i] ); + unput( '(' ); + free( yycopy ); + } + +.fi +Note that since each +.B unput() +puts the given character back at the +.I beginning +of the input stream, pushing back strings must be done back-to-front. +.PP +An important potential problem when using +.B unput() +is that if you are using +.B %pointer +(the default), a call to +.B unput() +.I destroys +the contents of +.I yytext, +starting with its rightmost character and devouring one character to +the left with each call. If you need the value of yytext preserved +after a call to +.B unput() +(as in the above example), +you must either first copy it elsewhere, or build your scanner using +.B %array +instead (see How The Input Is Matched). +.PP +Finally, note that you cannot put back +.B EOF +to attempt to mark the input stream with an end-of-file. +.IP - +.B input() +reads the next character from the input stream. For example, +the following is one way to eat up C comments: +.nf + + %% + "/*" { + register int c; + + for ( ; ; ) + { + while ( (c = input()) != '*' && + c != EOF ) + ; /* eat up text of comment */ + + if ( c == '*' ) + { + while ( (c = input()) == '*' ) + ; + if ( c == '/' ) + break; /* found the end */ + } + + if ( c == EOF ) + { + error( "EOF in comment" ); + break; + } + } + } + +.fi +(Note that if the scanner is compiled using +.B C++, +then +.B input() +is instead referred to as +.B yyinput(), +in order to avoid a name clash with the +.B C++ +stream by the name of +.I input.) +.IP - +.B YY_FLUSH_BUFFER +flushes the scanner's internal buffer +so that the next time the scanner attempts to match a token, it will +first refill the buffer using +.B YY_INPUT +(see The Generated Scanner, below). This action is a special case +of the more general +.B yy_flush_buffer() +function, described below in the section Multiple Input Buffers. +.IP - +.B yyterminate() +can be used in lieu of a return statement in an action. It terminates +the scanner and returns a 0 to the scanner's caller, indicating "all done". +By default, +.B yyterminate() +is also called when an end-of-file is encountered. It is a macro and +may be redefined. +.SH THE GENERATED SCANNER +The output of +.I flex +is the file +.B lex.yy.c, +which contains the scanning routine +.B yylex(), +a number of tables used by it for matching tokens, and a number +of auxiliary routines and macros. By default, +.B yylex() +is declared as follows: +.nf + + int yylex() + { + ... various definitions and the actions in here ... + } + +.fi +(If your environment supports function prototypes, then it will +be "int yylex( void )".) This definition may be changed by defining +the "YY_DECL" macro. For example, you could use: +.nf + + #define YY_DECL float lexscan( a, b ) float a, b; + +.fi +to give the scanning routine the name +.I lexscan, +returning a float, and taking two floats as arguments. Note that +if you give arguments to the scanning routine using a +K&R-style/non-prototyped function declaration, you must terminate +the definition with a semi-colon (;). +.PP +Whenever +.B yylex() +is called, it scans tokens from the global input file +.I yyin +(which defaults to stdin). It continues until it either reaches +an end-of-file (at which point it returns the value 0) or +one of its actions executes a +.I return +statement. +.PP +If the scanner reaches an end-of-file, subsequent calls are undefined +unless either +.I yyin +is pointed at a new input file (in which case scanning continues from +that file), or +.B yyrestart() +is called. +.B yyrestart() +takes one argument, a +.B FILE * +pointer (which can be nil, if you've set up +.B YY_INPUT +to scan from a source other than +.I yyin), +and initializes +.I yyin +for scanning from that file. Essentially there is no difference between +just assigning +.I yyin +to a new input file or using +.B yyrestart() +to do so; the latter is available for compatibility with previous versions +of +.I flex, +and because it can be used to switch input files in the middle of scanning. +It can also be used to throw away the current input buffer, by calling +it with an argument of +.I yyin; +but better is to use +.B YY_FLUSH_BUFFER +(see above). +Note that +.B yyrestart() +does +.I not +reset the start condition to +.B INITIAL +(see Start Conditions, below). +.PP +If +.B yylex() +stops scanning due to executing a +.I return +statement in one of the actions, the scanner may then be called again and it +will resume scanning where it left off. +.PP +By default (and for purposes of efficiency), the scanner uses +block-reads rather than simple +.I getc() +calls to read characters from +.I yyin. +The nature of how it gets its input can be controlled by defining the +.B YY_INPUT +macro. +YY_INPUT's calling sequence is "YY_INPUT(buf,result,max_size)". Its +action is to place up to +.I max_size +characters in the character array +.I buf +and return in the integer variable +.I result +either the +number of characters read or the constant YY_NULL (0 on Unix systems) +to indicate EOF. The default YY_INPUT reads from the +global file-pointer "yyin". +.PP +A sample definition of YY_INPUT (in the definitions +section of the input file): +.nf + + %{ + #define YY_INPUT(buf,result,max_size) \\ + { \\ + int c = getchar(); \\ + result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \\ + } + %} + +.fi +This definition will change the input processing to occur +one character at a time. +.PP +When the scanner receives an end-of-file indication from YY_INPUT, +it then checks the +.B yywrap() +function. If +.B yywrap() +returns false (zero), then it is assumed that the +function has gone ahead and set up +.I yyin +to point to another input file, and scanning continues. If it returns +true (non-zero), then the scanner terminates, returning 0 to its +caller. Note that in either case, the start condition remains unchanged; +it does +.I not +revert to +.B INITIAL. +.PP +If you do not supply your own version of +.B yywrap(), +then you must either use +.B %option noyywrap +(in which case the scanner behaves as though +.B yywrap() +returned 1), or you must link with +.B \-lfl +to obtain the default version of the routine, which always returns 1. +.PP +Three routines are available for scanning from in-memory buffers rather +than files: +.B yy_scan_string(), yy_scan_bytes(), +and +.B yy_scan_buffer(). +See the discussion of them below in the section Multiple Input Buffers. +.PP +The scanner writes its +.B ECHO +output to the +.I yyout +global (default, stdout), which may be redefined by the user simply +by assigning it to some other +.B FILE +pointer. +.SH START CONDITIONS +.I flex +provides a mechanism for conditionally activating rules. Any rule +whose pattern is prefixed with "" will only be active when +the scanner is in the start condition named "sc". For example, +.nf + + [^"]* { /* eat up the string body ... */ + ... + } + +.fi +will be active only when the scanner is in the "STRING" start +condition, and +.nf + + \\. { /* handle an escape ... */ + ... + } + +.fi +will be active only when the current start condition is +either "INITIAL", "STRING", or "QUOTE". +.PP +Start conditions +are declared in the definitions (first) section of the input +using unindented lines beginning with either +.B %s +or +.B %x +followed by a list of names. +The former declares +.I inclusive +start conditions, the latter +.I exclusive +start conditions. A start condition is activated using the +.B BEGIN +action. Until the next +.B BEGIN +action is executed, rules with the given start +condition will be active and +rules with other start conditions will be inactive. +If the start condition is +.I inclusive, +then rules with no start conditions at all will also be active. +If it is +.I exclusive, +then +.I only +rules qualified with the start condition will be active. +A set of rules contingent on the same exclusive start condition +describe a scanner which is independent of any of the other rules in the +.I flex +input. Because of this, +exclusive start conditions make it easy to specify "mini-scanners" +which scan portions of the input that are syntactically different +from the rest (e.g., comments). +.PP +If the distinction between inclusive and exclusive start conditions +is still a little vague, here's a simple example illustrating the +connection between the two. The set of rules: +.nf + + %s example + %% + + foo do_something(); + + bar something_else(); + +.fi +is equivalent to +.nf + + %x example + %% + + foo do_something(); + + bar something_else(); + +.fi +Without the +.B +qualifier, the +.I bar +pattern in the second example wouldn't be active (i.e., couldn't match) +when in start condition +.B example. +If we just used +.B +to qualify +.I bar, +though, then it would only be active in +.B example +and not in +.B INITIAL, +while in the first example it's active in both, because in the first +example the +.B example +startion condition is an +.I inclusive +.B (%s) +start condition. +.PP +Also note that the special start-condition specifier +.B <*> +matches every start condition. Thus, the above example could also +have been written; +.nf + + %x example + %% + + foo do_something(); + + <*>bar something_else(); + +.fi +.PP +The default rule (to +.B ECHO +any unmatched character) remains active in start conditions. It +is equivalent to: +.nf + + <*>.|\\n ECHO; + +.fi +.PP +.B BEGIN(0) +returns to the original state where only the rules with +no start conditions are active. This state can also be +referred to as the start-condition "INITIAL", so +.B BEGIN(INITIAL) +is equivalent to +.B BEGIN(0). +(The parentheses around the start condition name are not required but +are considered good style.) +.PP +.B BEGIN +actions can also be given as indented code at the beginning +of the rules section. For example, the following will cause +the scanner to enter the "SPECIAL" start condition whenever +.B yylex() +is called and the global variable +.I enter_special +is true: +.nf + + int enter_special; + + %x SPECIAL + %% + if ( enter_special ) + BEGIN(SPECIAL); + + blahblahblah + ...more rules follow... + +.fi +.PP +To illustrate the uses of start conditions, +here is a scanner which provides two different interpretations +of a string like "123.456". By default it will treat it as +three tokens, the integer "123", a dot ('.'), and the integer "456". +But if the string is preceded earlier in the line by the string +"expect-floats" +it will treat it as a single token, the floating-point number +123.456: +.nf + + %{ + #include + %} + %s expect + + %% + expect-floats BEGIN(expect); + + [0-9]+"."[0-9]+ { + printf( "found a float, = %f\\n", + atof( yytext ) ); + } + \\n { + /* that's the end of the line, so + * we need another "expect-number" + * before we'll recognize any more + * numbers + */ + BEGIN(INITIAL); + } + + [0-9]+ { + printf( "found an integer, = %d\\n", + atoi( yytext ) ); + } + + "." printf( "found a dot\\n" ); + +.fi +Here is a scanner which recognizes (and discards) C comments while +maintaining a count of the current input line. +.nf + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\\n]* /* eat anything that's not a '*' */ + "*"+[^*/\\n]* /* eat up '*'s not followed by '/'s */ + \\n ++line_num; + "*"+"/" BEGIN(INITIAL); + +.fi +This scanner goes to a bit of trouble to match as much +text as possible with each rule. In general, when attempting to write +a high-speed scanner try to match as much possible in each rule, as +it's a big win. +.PP +Note that start-conditions names are really integer values and +can be stored as such. Thus, the above could be extended in the +following fashion: +.nf + + %x comment foo + %% + int line_num = 1; + int comment_caller; + + "/*" { + comment_caller = INITIAL; + BEGIN(comment); + } + + ... + + "/*" { + comment_caller = foo; + BEGIN(comment); + } + + [^*\\n]* /* eat anything that's not a '*' */ + "*"+[^*/\\n]* /* eat up '*'s not followed by '/'s */ + \\n ++line_num; + "*"+"/" BEGIN(comment_caller); + +.fi +Furthermore, you can access the current start condition using +the integer-valued +.B YY_START +macro. For example, the above assignments to +.I comment_caller +could instead be written +.nf + + comment_caller = YY_START; + +.fi +Flex provides +.B YYSTATE +as an alias for +.B YY_START +(since that is what's used by AT&T +.I lex). +.PP +Note that start conditions do not have their own name-space; %s's and %x's +declare names in the same fashion as #define's. +.PP +Finally, here's an example of how to match C-style quoted strings using +exclusive start conditions, including expanded escape sequences (but +not including checking for a string that's too long): +.nf + + %x str + + %% + char string_buf[MAX_STR_CONST]; + char *string_buf_ptr; + + + \\" string_buf_ptr = string_buf; BEGIN(str); + + \\" { /* saw closing quote - all done */ + BEGIN(INITIAL); + *string_buf_ptr = '\\0'; + /* return string constant token type and + * value to parser + */ + } + + \\n { + /* error - unterminated string constant */ + /* generate error message */ + } + + \\\\[0-7]{1,3} { + /* octal escape sequence */ + int result; + + (void) sscanf( yytext + 1, "%o", &result ); + + if ( result > 0xff ) + /* error, constant is out-of-bounds */ + + *string_buf_ptr++ = result; + } + + \\\\[0-9]+ { + /* generate error - bad escape sequence; something + * like '\\48' or '\\0777777' + */ + } + + \\\\n *string_buf_ptr++ = '\\n'; + \\\\t *string_buf_ptr++ = '\\t'; + \\\\r *string_buf_ptr++ = '\\r'; + \\\\b *string_buf_ptr++ = '\\b'; + \\\\f *string_buf_ptr++ = '\\f'; + + \\\\(.|\\n) *string_buf_ptr++ = yytext[1]; + + [^\\\\\\n\\"]+ { + char *yptr = yytext; + + while ( *yptr ) + *string_buf_ptr++ = *yptr++; + } + +.fi +.PP +Often, such as in some of the examples above, you wind up writing a +whole bunch of rules all preceded by the same start condition(s). Flex +makes this a little easier and cleaner by introducing a notion of +start condition +.I scope. +A start condition scope is begun with: +.nf + + { + +.fi +where +.I SCs +is a list of one or more start conditions. Inside the start condition +scope, every rule automatically has the prefix +.I +applied to it, until a +.I '}' +which matches the initial +.I '{'. +So, for example, +.nf + + { + "\\\\n" return '\\n'; + "\\\\r" return '\\r'; + "\\\\f" return '\\f'; + "\\\\0" return '\\0'; + } + +.fi +is equivalent to: +.nf + + "\\\\n" return '\\n'; + "\\\\r" return '\\r'; + "\\\\f" return '\\f'; + "\\\\0" return '\\0'; + +.fi +Start condition scopes may be nested. +.PP +Three routines are available for manipulating stacks of start conditions: +.TP +.B void yy_push_state(int new_state) +pushes the current start condition onto the top of the start condition +stack and switches to +.I new_state +as though you had used +.B BEGIN new_state +(recall that start condition names are also integers). +.TP +.B void yy_pop_state() +pops the top of the stack and switches to it via +.B BEGIN. +.TP +.B int yy_top_state() +returns the top of the stack without altering the stack's contents. +.PP +The start condition stack grows dynamically and so has no built-in +size limitation. If memory is exhausted, program execution aborts. +.PP +To use start condition stacks, your scanner must include a +.B %option stack +directive (see Options below). +.SH MULTIPLE INPUT BUFFERS +Some scanners (such as those which support "include" files) +require reading from several input streams. As +.I flex +scanners do a large amount of buffering, one cannot control +where the next input will be read from by simply writing a +.B YY_INPUT +which is sensitive to the scanning context. +.B YY_INPUT +is only called when the scanner reaches the end of its buffer, which +may be a long time after scanning a statement such as an "include" +which requires switching the input source. +.PP +To negotiate these sorts of problems, +.I flex +provides a mechanism for creating and switching between multiple +input buffers. An input buffer is created by using: +.nf + + YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) + +.fi +which takes a +.I FILE +pointer and a size and creates a buffer associated with the given +file and large enough to hold +.I size +characters (when in doubt, use +.B YY_BUF_SIZE +for the size). It returns a +.B YY_BUFFER_STATE +handle, which may then be passed to other routines (see below). The +.B YY_BUFFER_STATE +type is a pointer to an opaque +.B struct yy_buffer_state +structure, so you may safely initialize YY_BUFFER_STATE variables to +.B ((YY_BUFFER_STATE) 0) +if you wish, and also refer to the opaque structure in order to +correctly declare input buffers in source files other than that +of your scanner. Note that the +.I FILE +pointer in the call to +.B yy_create_buffer +is only used as the value of +.I yyin +seen by +.B YY_INPUT; +if you redefine +.B YY_INPUT +so it no longer uses +.I yyin, +then you can safely pass a nil +.I FILE +pointer to +.B yy_create_buffer. +You select a particular buffer to scan from using: +.nf + + void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) + +.fi +switches the scanner's input buffer so subsequent tokens will +come from +.I new_buffer. +Note that +.B yy_switch_to_buffer() +may be used by yywrap() to set things up for continued scanning, instead +of opening a new file and pointing +.I yyin +at it. Note also that switching input sources via either +.B yy_switch_to_buffer() +or +.B yywrap() +does +.I not +change the start condition. +.nf + + void yy_delete_buffer( YY_BUFFER_STATE buffer ) + +.fi +is used to reclaim the storage associated with a buffer. ( +.B buffer +can be nil, in which case the routine does nothing.) +You can also clear the current contents of a buffer using: +.nf + + void yy_flush_buffer( YY_BUFFER_STATE buffer ) + +.fi +This function discards the buffer's contents, +so the next time the scanner attempts to match a token from the +buffer, it will first fill the buffer anew using +.B YY_INPUT. +.PP +.B yy_new_buffer() +is an alias for +.B yy_create_buffer(), +provided for compatibility with the C++ use of +.I new +and +.I delete +for creating and destroying dynamic objects. +.PP +Finally, the +.B YY_CURRENT_BUFFER +macro returns a +.B YY_BUFFER_STATE +handle to the current buffer. +.PP +Here is an example of using these features for writing a scanner +which expands include files (the +.B <> +feature is discussed below): +.nf + + /* the "incl" state is used for picking up the name + * of an include file + */ + %x incl + + %{ + #define MAX_INCLUDE_DEPTH 10 + YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; + int include_stack_ptr = 0; + %} + + %% + include BEGIN(incl); + + [a-z]+ ECHO; + [^a-z\\n]*\\n? ECHO; + + [ \\t]* /* eat the whitespace */ + [^ \\t\\n]+ { /* got the include file name */ + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) + { + fprintf( stderr, "Includes nested too deeply" ); + exit( 1 ); + } + + include_stack[include_stack_ptr++] = + YY_CURRENT_BUFFER; + + yyin = fopen( yytext, "r" ); + + if ( ! yyin ) + error( ... ); + + yy_switch_to_buffer( + yy_create_buffer( yyin, YY_BUF_SIZE ) ); + + BEGIN(INITIAL); + } + + <> { + if ( --include_stack_ptr < 0 ) + { + yyterminate(); + } + + else + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( + include_stack[include_stack_ptr] ); + } + } + +.fi +Three routines are available for setting up input buffers for +scanning in-memory strings instead of files. All of them create +a new input buffer for scanning the string, and return a corresponding +.B YY_BUFFER_STATE +handle (which you should delete with +.B yy_delete_buffer() +when done with it). They also switch to the new buffer using +.B yy_switch_to_buffer(), +so the next call to +.B yylex() +will start scanning the string. +.TP +.B yy_scan_string(const char *str) +scans a NUL-terminated string. +.TP +.B yy_scan_bytes(const char *bytes, int len) +scans +.I len +bytes (including possibly NUL's) +starting at location +.I bytes. +.PP +Note that both of these functions create and scan a +.I copy +of the string or bytes. (This may be desirable, since +.B yylex() +modifies the contents of the buffer it is scanning.) You can avoid the +copy by using: +.TP +.B yy_scan_buffer(char *base, yy_size_t size) +which scans in place the buffer starting at +.I base, +consisting of +.I size +bytes, the last two bytes of which +.I must +be +.B YY_END_OF_BUFFER_CHAR +(ASCII NUL). +These last two bytes are not scanned; thus, scanning +consists of +.B base[0] +through +.B base[size-2], +inclusive. +.IP +If you fail to set up +.I base +in this manner (i.e., forget the final two +.B YY_END_OF_BUFFER_CHAR +bytes), then +.B yy_scan_buffer() +returns a nil pointer instead of creating a new input buffer. +.IP +The type +.B yy_size_t +is an integral type to which you can cast an integer expression +reflecting the size of the buffer. +.SH END-OF-FILE RULES +The special rule "<>" indicates +actions which are to be taken when an end-of-file is +encountered and yywrap() returns non-zero (i.e., indicates +no further files to process). The action must finish +by doing one of four things: +.IP - +assigning +.I yyin +to a new input file (in previous versions of flex, after doing the +assignment you had to call the special action +.B YY_NEW_FILE; +this is no longer necessary); +.IP - +executing a +.I return +statement; +.IP - +executing the special +.B yyterminate() +action; +.IP - +or, switching to a new buffer using +.B yy_switch_to_buffer() +as shown in the example above. +.PP +<> rules may not be used with other +patterns; they may only be qualified with a list of start +conditions. If an unqualified <> rule is given, it +applies to +.I all +start conditions which do not already have <> actions. To +specify an <> rule for only the initial start condition, use +.nf + + <> + +.fi +.PP +These rules are useful for catching things like unclosed comments. +An example: +.nf + + %x quote + %% + + ...other rules for dealing with quotes... + + <> { + error( "unterminated quote" ); + yyterminate(); + } + <> { + if ( *++filelist ) + yyin = fopen( *filelist, "r" ); + else + yyterminate(); + } + +.fi +.SH MISCELLANEOUS MACROS +The macro +.B YY_USER_ACTION +can be defined to provide an action +which is always executed prior to the matched rule's action. For example, +it could be #define'd to call a routine to convert yytext to lower-case. +When +.B YY_USER_ACTION +is invoked, the variable +.I yy_act +gives the number of the matched rule (rules are numbered starting with 1). +Suppose you want to profile how often each of your rules is matched. The +following would do the trick: +.nf + + #define YY_USER_ACTION ++ctr[yy_act] + +.fi +where +.I ctr +is an array to hold the counts for the different rules. Note that +the macro +.B YY_NUM_RULES +gives the total number of rules (including the default rule, even if +you use +.B \-s), +so a correct declaration for +.I ctr +is: +.nf + + int ctr[YY_NUM_RULES]; + +.fi +.PP +The macro +.B YY_USER_INIT +may be defined to provide an action which is always executed before +the first scan (and before the scanner's internal initializations are done). +For example, it could be used to call a routine to read +in a data table or open a logging file. +.PP +The macro +.B yy_set_interactive(is_interactive) +can be used to control whether the current buffer is considered +.I interactive. +An interactive buffer is processed more slowly, +but must be used when the scanner's input source is indeed +interactive to avoid problems due to waiting to fill buffers +(see the discussion of the +.B \-I +flag below). A non-zero value +in the macro invocation marks the buffer as interactive, a zero +value as non-interactive. Note that use of this macro overrides +.B %option always-interactive +or +.B %option never-interactive +(see Options below). +.B yy_set_interactive() +must be invoked prior to beginning to scan the buffer that is +(or is not) to be considered interactive. +.PP +The macro +.B yy_set_bol(at_bol) +can be used to control whether the current buffer's scanning +context for the next token match is done as though at the +beginning of a line. A non-zero macro argument makes rules anchored with +'^' active, while a zero argument makes '^' rules inactive. +.PP +The macro +.B YY_AT_BOL() +returns true if the next token scanned from the current buffer +will have '^' rules active, false otherwise. +.PP +In the generated scanner, the actions are all gathered in one large +switch statement and separated using +.B YY_BREAK, +which may be redefined. By default, it is simply a "break", to separate +each rule's action from the following rule's. +Redefining +.B YY_BREAK +allows, for example, C++ users to +#define YY_BREAK to do nothing (while being very careful that every +rule ends with a "break" or a "return"!) to avoid suffering from +unreachable statement warnings where because a rule's action ends with +"return", the +.B YY_BREAK +is inaccessible. +.SH VALUES AVAILABLE TO THE USER +This section summarizes the various values available to the user +in the rule actions. +.IP - +.B char *yytext +holds the text of the current token. It may be modified but not lengthened +(you cannot append characters to the end). +.IP +If the special directive +.B %array +appears in the first section of the scanner description, then +.B yytext +is instead declared +.B char yytext[YYLMAX], +where +.B YYLMAX +is a macro definition that you can redefine in the first section +if you don't like the default value (generally 8KB). Using +.B %array +results in somewhat slower scanners, but the value of +.B yytext +becomes immune to calls to +.I input() +and +.I unput(), +which potentially destroy its value when +.B yytext +is a character pointer. The opposite of +.B %array +is +.B %pointer, +which is the default. +.IP +You cannot use +.B %array +when generating C++ scanner classes +(the +.B \-+ +flag). +.IP - +.B int yyleng +holds the length of the current token. +.IP - +.B FILE *yyin +is the file which by default +.I flex +reads from. It may be redefined but doing so only makes sense before +scanning begins or after an EOF has been encountered. Changing it in +the midst of scanning will have unexpected results since +.I flex +buffers its input; use +.B yyrestart() +instead. +Once scanning terminates because an end-of-file +has been seen, you can assign +.I yyin +at the new input file and then call the scanner again to continue scanning. +.IP - +.B void yyrestart( FILE *new_file ) +may be called to point +.I yyin +at the new input file. The switch-over to the new file is immediate +(any previously buffered-up input is lost). Note that calling +.B yyrestart() +with +.I yyin +as an argument thus throws away the current input buffer and continues +scanning the same input file. +.IP - +.B FILE *yyout +is the file to which +.B ECHO +actions are done. It can be reassigned by the user. +.IP - +.B YY_CURRENT_BUFFER +returns a +.B YY_BUFFER_STATE +handle to the current buffer. +.IP - +.B YY_START +returns an integer value corresponding to the current start +condition. You can subsequently use this value with +.B BEGIN +to return to that start condition. +.SH INTERFACING WITH YACC +One of the main uses of +.I flex +is as a companion to the +.I yacc +parser-generator. +.I yacc +parsers expect to call a routine named +.B yylex() +to find the next input token. The routine is supposed to +return the type of the next token as well as putting any associated +value in the global +.B yylval. +To use +.I flex +with +.I yacc, +one specifies the +.B \-d +option to +.I yacc +to instruct it to generate the file +.B y.tab.h +containing definitions of all the +.B %tokens +appearing in the +.I yacc +input. This file is then included in the +.I flex +scanner. For example, if one of the tokens is "TOK_NUMBER", +part of the scanner might look like: +.nf + + %{ + #include "y.tab.h" + %} + + %% + + [0-9]+ yylval = atoi( yytext ); return TOK_NUMBER; + +.fi +.SH OPTIONS +.I flex +has the following options: +.TP +.B \-b +Generate backing-up information to +.I lex.backup. +This is a list of scanner states which require backing up +and the input characters on which they do so. By adding rules one +can remove backing-up states. If +.I all +backing-up states are eliminated and +.B \-Cf +or +.B \-CF +is used, the generated scanner will run faster (see the +.B \-p +flag). Only users who wish to squeeze every last cycle out of their +scanners need worry about this option. (See the section on Performance +Considerations below.) +.TP +.B \-c +is a do-nothing, deprecated option included for POSIX compliance. +.TP +.B \-d +makes the generated scanner run in +.I debug +mode. Whenever a pattern is recognized and the global +.B yy_flex_debug +is non-zero (which is the default), +the scanner will write to +.I stderr +a line of the form: +.nf + + --accepting rule at line 53 ("the matched text") + +.fi +The line number refers to the location of the rule in the file +defining the scanner (i.e., the file that was fed to flex). Messages +are also generated when the scanner backs up, accepts the +default rule, reaches the end of its input buffer (or encounters +a NUL; at this point, the two look the same as far as the scanner's concerned), +or reaches an end-of-file. +.TP +.B \-f +specifies +.I fast scanner. +No table compression is done and stdio is bypassed. +The result is large but fast. This option is equivalent to +.B \-Cfr +(see below). +.TP +.B \-h +generates a "help" summary of +.I flex's +options to +.I stdout +and then exits. +.B \-? +and +.B \-\-help +are synonyms for +.B \-h. +.TP +.B \-i +instructs +.I flex +to generate a +.I case-insensitive +scanner. The case of letters given in the +.I flex +input patterns will +be ignored, and tokens in the input will be matched regardless of case. The +matched text given in +.I yytext +will have the preserved case (i.e., it will not be folded). +.TP +.B \-l +turns on maximum compatibility with the original AT&T +.I lex +implementation. Note that this does not mean +.I full +compatibility. Use of this option costs a considerable amount of +performance, and it cannot be used with the +.B \-+, -f, -F, -Cf, +or +.B -CF +options. For details on the compatibilities it provides, see the section +"Incompatibilities With Lex And POSIX" below. This option also results +in the name +.B YY_FLEX_LEX_COMPAT +being #define'd in the generated scanner. +.TP +.B \-n +is another do-nothing, deprecated option included only for +POSIX compliance. +.TP +.B \-p +generates a performance report to stderr. The report +consists of comments regarding features of the +.I flex +input file which will cause a serious loss of performance in the resulting +scanner. If you give the flag twice, you will also get comments regarding +features that lead to minor performance losses. +.IP +Note that the use of +.B REJECT, +.B %option yylineno, +and variable trailing context (see the Deficiencies / Bugs section below) +entails a substantial performance penalty; use of +.I yymore(), +the +.B ^ +operator, +and the +.B \-I +flag entail minor performance penalties. +.TP +.B \-s +causes the +.I default rule +(that unmatched scanner input is echoed to +.I stdout) +to be suppressed. If the scanner encounters input that does not +match any of its rules, it aborts with an error. This option is +useful for finding holes in a scanner's rule set. +.TP +.B \-t +instructs +.I flex +to write the scanner it generates to standard output instead +of +.B lex.yy.c. +.TP +.B \-v +specifies that +.I flex +should write to +.I stderr +a summary of statistics regarding the scanner it generates. +Most of the statistics are meaningless to the casual +.I flex +user, but the first line identifies the version of +.I flex +(same as reported by +.B \-V), +and the next line the flags used when generating the scanner, including +those that are on by default. +.TP +.B \-w +suppresses warning messages. +.TP +.B \-B +instructs +.I flex +to generate a +.I batch +scanner, the opposite of +.I interactive +scanners generated by +.B \-I +(see below). In general, you use +.B \-B +when you are +.I certain +that your scanner will never be used interactively, and you want to +squeeze a +.I little +more performance out of it. If your goal is instead to squeeze out a +.I lot +more performance, you should be using the +.B \-Cf +or +.B \-CF +options (discussed below), which turn on +.B \-B +automatically anyway. +.TP +.B \-F +specifies that the +.ul +fast +scanner table representation should be used (and stdio +bypassed). This representation is +about as fast as the full table representation +.B (-f), +and for some sets of patterns will be considerably smaller (and for +others, larger). In general, if the pattern set contains both "keywords" +and a catch-all, "identifier" rule, such as in the set: +.nf + + "case" return TOK_CASE; + "switch" return TOK_SWITCH; + ... + "default" return TOK_DEFAULT; + [a-z]+ return TOK_ID; + +.fi +then you're better off using the full table representation. If only +the "identifier" rule is present and you then use a hash table or some such +to detect the keywords, you're better off using +.B -F. +.IP +This option is equivalent to +.B \-CFr +(see below). It cannot be used with +.B \-+. +.TP +.B \-I +instructs +.I flex +to generate an +.I interactive +scanner. An interactive scanner is one that only looks ahead to decide +what token has been matched if it absolutely must. It turns out that +always looking one extra character ahead, even if the scanner has already +seen enough text to disambiguate the current token, is a bit faster than +only looking ahead when necessary. But scanners that always look ahead +give dreadful interactive performance; for example, when a user types +a newline, it is not recognized as a newline token until they enter +.I another +token, which often means typing in another whole line. +.IP +.I Flex +scanners default to +.I interactive +unless you use the +.B \-Cf +or +.B \-CF +table-compression options (see below). That's because if you're looking +for high-performance you should be using one of these options, so if you +didn't, +.I flex +assumes you'd rather trade off a bit of run-time performance for intuitive +interactive behavior. Note also that you +.I cannot +use +.B \-I +in conjunction with +.B \-Cf +or +.B \-CF. +Thus, this option is not really needed; it is on by default for all those +cases in which it is allowed. +.IP +You can force a scanner to +.I not +be interactive by using +.B \-B +(see above). +.TP +.B \-L +instructs +.I flex +not to generate +.B #line +directives. Without this option, +.I flex +peppers the generated scanner +with #line directives so error messages in the actions will be correctly +located with respect to either the original +.I flex +input file (if the errors are due to code in the input file), or +.B lex.yy.c +(if the errors are +.I flex's +fault -- you should report these sorts of errors to the email address +given below). +.TP +.B \-T +makes +.I flex +run in +.I trace +mode. It will generate a lot of messages to +.I stderr +concerning +the form of the input and the resultant non-deterministic and deterministic +finite automata. This option is mostly for use in maintaining +.I flex. +.TP +.B \-V +prints the version number to +.I stdout +and exits. +.B \-\-version +is a synonym for +.B \-V. +.TP +.B \-7 +instructs +.I flex +to generate a 7-bit scanner, i.e., one which can only recognized 7-bit +characters in its input. The advantage of using +.B \-7 +is that the scanner's tables can be up to half the size of those generated +using the +.B \-8 +option (see below). The disadvantage is that such scanners often hang +or crash if their input contains an 8-bit character. +.IP +Note, however, that unless you generate your scanner using the +.B \-Cf +or +.B \-CF +table compression options, use of +.B \-7 +will save only a small amount of table space, and make your scanner +considerably less portable. +.I Flex's +default behavior is to generate an 8-bit scanner unless you use the +.B \-Cf +or +.B \-CF, +in which case +.I flex +defaults to generating 7-bit scanners unless your site was always +configured to generate 8-bit scanners (as will often be the case +with non-USA sites). You can tell whether flex generated a 7-bit +or an 8-bit scanner by inspecting the flag summary in the +.B \-v +output as described above. +.IP +Note that if you use +.B \-Cfe +or +.B \-CFe +(those table compression options, but also using equivalence classes as +discussed see below), flex still defaults to generating an 8-bit +scanner, since usually with these compression options full 8-bit tables +are not much more expensive than 7-bit tables. +.TP +.B \-8 +instructs +.I flex +to generate an 8-bit scanner, i.e., one which can recognize 8-bit +characters. This flag is only needed for scanners generated using +.B \-Cf +or +.B \-CF, +as otherwise flex defaults to generating an 8-bit scanner anyway. +.IP +See the discussion of +.B \-7 +above for flex's default behavior and the tradeoffs between 7-bit +and 8-bit scanners. +.TP +.B \-+ +specifies that you want flex to generate a C++ +scanner class. See the section on Generating C++ Scanners below for +details. +.TP +.B \-C[aefFmr] +controls the degree of table compression and, more generally, trade-offs +between small scanners and fast scanners. +.IP +.B \-Ca +("align") instructs flex to trade off larger tables in the +generated scanner for faster performance because the elements of +the tables are better aligned for memory access and computation. On some +RISC architectures, fetching and manipulating longwords is more efficient +than with smaller-sized units such as shortwords. This option can +double the size of the tables used by your scanner. +.IP +.B \-Ce +directs +.I flex +to construct +.I equivalence classes, +i.e., sets of characters +which have identical lexical properties (for example, if the only +appearance of digits in the +.I flex +input is in the character class +"[0-9]" then the digits '0', '1', ..., '9' will all be put +in the same equivalence class). Equivalence classes usually give +dramatic reductions in the final table/object file sizes (typically +a factor of 2-5) and are pretty cheap performance-wise (one array +look-up per character scanned). +.IP +.B \-Cf +specifies that the +.I full +scanner tables should be generated - +.I flex +should not compress the +tables by taking advantages of similar transition functions for +different states. +.IP +.B \-CF +specifies that the alternate fast scanner representation (described +above under the +.B \-F +flag) +should be used. This option cannot be used with +.B \-+. +.IP +.B \-Cm +directs +.I flex +to construct +.I meta-equivalence classes, +which are sets of equivalence classes (or characters, if equivalence +classes are not being used) that are commonly used together. Meta-equivalence +classes are often a big win when using compressed tables, but they +have a moderate performance impact (one or two "if" tests and one +array look-up per character scanned). +.IP +.B \-Cr +causes the generated scanner to +.I bypass +use of the standard I/O library (stdio) for input. Instead of calling +.B fread() +or +.B getc(), +the scanner will use the +.B read() +system call, resulting in a performance gain which varies from system +to system, but in general is probably negligible unless you are also using +.B \-Cf +or +.B \-CF. +Using +.B \-Cr +can cause strange behavior if, for example, you read from +.I yyin +using stdio prior to calling the scanner (because the scanner will miss +whatever text your previous reads left in the stdio input buffer). +.IP +.B \-Cr +has no effect if you define +.B YY_INPUT +(see The Generated Scanner above). +.IP +A lone +.B \-C +specifies that the scanner tables should be compressed but neither +equivalence classes nor meta-equivalence classes should be used. +.IP +The options +.B \-Cf +or +.B \-CF +and +.B \-Cm +do not make sense together - there is no opportunity for meta-equivalence +classes if the table is not being compressed. Otherwise the options +may be freely mixed, and are cumulative. +.IP +The default setting is +.B \-Cem, +which specifies that +.I flex +should generate equivalence classes +and meta-equivalence classes. This setting provides the highest +degree of table compression. You can trade off +faster-executing scanners at the cost of larger tables with +the following generally being true: +.nf + + slowest & smallest + -Cem + -Cm + -Ce + -C + -C{f,F}e + -C{f,F} + -C{f,F}a + fastest & largest + +.fi +Note that scanners with the smallest tables are usually generated and +compiled the quickest, so +during development you will usually want to use the default, maximal +compression. +.IP +.B \-Cfe +is often a good compromise between speed and size for production +scanners. +.TP +.B \-ooutput +directs flex to write the scanner to the file +.B output +instead of +.B lex.yy.c. +If you combine +.B \-o +with the +.B \-t +option, then the scanner is written to +.I stdout +but its +.B #line +directives (see the +.B \\-L +option above) refer to the file +.B output. +.TP +.B \-Pprefix +changes the default +.I "yy" +prefix used by +.I flex +for all globally-visible variable and function names to instead be +.I prefix. +For example, +.B \-Pfoo +changes the name of +.B yytext +to +.B footext. +It also changes the name of the default output file from +.B lex.yy.c +to +.B lex.foo.c. +Here are all of the names affected: +.nf + + yy_create_buffer + yy_delete_buffer + yy_flex_debug + yy_init_buffer + yy_flush_buffer + yy_load_buffer_state + yy_switch_to_buffer + yyin + yyleng + yylex + yylineno + yyout + yyrestart + yytext + yywrap + +.fi +(If you are using a C++ scanner, then only +.B yywrap +and +.B yyFlexLexer +are affected.) +Within your scanner itself, you can still refer to the global variables +and functions using either version of their name; but externally, they +have the modified name. +.IP +This option lets you easily link together multiple +.I flex +programs into the same executable. Note, though, that using this +option also renames +.B yywrap(), +so you now +.I must +either +provide your own (appropriately-named) version of the routine for your +scanner, or use +.B %option noyywrap, +as linking with +.B \-lfl +no longer provides one for you by default. +.TP +.B \-Sskeleton_file +overrides the default skeleton file from which +.I flex +constructs its scanners. You'll never need this option unless you are doing +.I flex +maintenance or development. +.PP +.I flex +also provides a mechanism for controlling options within the +scanner specification itself, rather than from the flex command-line. +This is done by including +.B %option +directives in the first section of the scanner specification. +You can specify multiple options with a single +.B %option +directive, and multiple directives in the first section of your flex input +file. +.PP +Most options are given simply as names, optionally preceded by the +word "no" (with no intervening whitespace) to negate their meaning. +A number are equivalent to flex flags or their negation: +.nf + + 7bit -7 option + 8bit -8 option + align -Ca option + backup -b option + batch -B option + c++ -+ option + + caseful or + case-sensitive opposite of -i (default) + + case-insensitive or + caseless -i option + + debug -d option + default opposite of -s option + ecs -Ce option + fast -F option + full -f option + interactive -I option + lex-compat -l option + meta-ecs -Cm option + perf-report -p option + read -Cr option + stdout -t option + verbose -v option + warn opposite of -w option + (use "%option nowarn" for -w) + + array equivalent to "%array" + pointer equivalent to "%pointer" (default) + +.fi +Some +.B %option's +provide features otherwise not available: +.TP +.B always-interactive +instructs flex to generate a scanner which always considers its input +"interactive". Normally, on each new input file the scanner calls +.B isatty() +in an attempt to determine whether +the scanner's input source is interactive and thus should be read a +character at a time. When this option is used, however, then no +such call is made. +.TP +.B main +directs flex to provide a default +.B main() +program for the scanner, which simply calls +.B yylex(). +This option implies +.B noyywrap +(see below). +.TP +.B never-interactive +instructs flex to generate a scanner which never considers its input +"interactive" (again, no call made to +.B isatty()). +This is the opposite of +.B always-interactive. +.TP +.B stack +enables the use of start condition stacks (see Start Conditions above). +.TP +.B stdinit +if set (i.e., +.B %option stdinit) +initializes +.I yyin +and +.I yyout +to +.I stdin +and +.I stdout, +instead of the default of +.I nil. +Some existing +.I lex +programs depend on this behavior, even though it is not compliant with +ANSI C, which does not require +.I stdin +and +.I stdout +to be compile-time constant. +.TP +.B yylineno +directs +.I flex +to generate a scanner that maintains the number of the current line +read from its input in the global variable +.B yylineno. +This option is implied by +.B %option lex-compat. +.TP +.B yywrap +if unset (i.e., +.B %option noyywrap), +makes the scanner not call +.B yywrap() +upon an end-of-file, but simply assume that there are no more +files to scan (until the user points +.I yyin +at a new file and calls +.B yylex() +again). +.PP +.I flex +scans your rule actions to determine whether you use the +.B REJECT +or +.B yymore() +features. The +.B reject +and +.B yymore +options are available to override its decision as to whether you use the +options, either by setting them (e.g., +.B %option reject) +to indicate the feature is indeed used, or +unsetting them to indicate it actually is not used +(e.g., +.B %option noyymore). +.PP +Three options take string-delimited values, offset with '=': +.nf + + %option outfile="ABC" + +.fi +is equivalent to +.B -oABC, +and +.nf + + %option prefix="XYZ" + +.fi +is equivalent to +.B -PXYZ. +Finally, +.nf + + %option yyclass="foo" + +.fi +only applies when generating a C++ scanner ( +.B \-+ +option). It informs +.I flex +that you have derived +.B foo +as a subclass of +.B yyFlexLexer, +so +.I flex +will place your actions in the member function +.B foo::yylex() +instead of +.B yyFlexLexer::yylex(). +It also generates a +.B yyFlexLexer::yylex() +member function that emits a run-time error (by invoking +.B yyFlexLexer::LexerError()) +if called. +See Generating C++ Scanners, below, for additional information. +.PP +A number of options are available for lint purists who want to suppress +the appearance of unneeded routines in the generated scanner. Each of the +following, if unset +(e.g., +.B %option nounput +), results in the corresponding routine not appearing in +the generated scanner: +.nf + + input, unput + yy_push_state, yy_pop_state, yy_top_state + yy_scan_buffer, yy_scan_bytes, yy_scan_string + +.fi +(though +.B yy_push_state() +and friends won't appear anyway unless you use +.B %option stack). +.SH PERFORMANCE CONSIDERATIONS +The main design goal of +.I flex +is that it generate high-performance scanners. It has been optimized +for dealing well with large sets of rules. Aside from the effects on +scanner speed of the table compression +.B \-C +options outlined above, +there are a number of options/actions which degrade performance. These +are, from most expensive to least: +.nf + + REJECT + %option yylineno + arbitrary trailing context + + pattern sets that require backing up + %array + %option interactive + %option always-interactive + + '^' beginning-of-line operator + yymore() + +.fi +with the first three all being quite expensive and the last two +being quite cheap. Note also that +.B unput() +is implemented as a routine call that potentially does quite a bit of +work, while +.B yyless() +is a quite-cheap macro; so if just putting back some excess text you +scanned, use +.B yyless(). +.PP +.B REJECT +should be avoided at all costs when performance is important. +It is a particularly expensive option. +.PP +Getting rid of backing up is messy and often may be an enormous +amount of work for a complicated scanner. In principal, one begins +by using the +.B \-b +flag to generate a +.I lex.backup +file. For example, on the input +.nf + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + +.fi +the file looks like: +.nf + + State #6 is non-accepting - + associated rule line numbers: + 2 3 + out-transitions: [ o ] + jam-transitions: EOF [ \\001-n p-\\177 ] + + State #8 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ a ] + jam-transitions: EOF [ \\001-` b-\\177 ] + + State #9 is non-accepting - + associated rule line numbers: + 3 + out-transitions: [ r ] + jam-transitions: EOF [ \\001-q s-\\177 ] + + Compressed tables always back up. + +.fi +The first few lines tell us that there's a scanner state in +which it can make a transition on an 'o' but not on any other +character, and that in that state the currently scanned text does not match +any rule. The state occurs when trying to match the rules found +at lines 2 and 3 in the input file. +If the scanner is in that state and then reads +something other than an 'o', it will have to back up to find +a rule which is matched. With +a bit of headscratching one can see that this must be the +state it's in when it has seen "fo". When this has happened, +if anything other than another 'o' is seen, the scanner will +have to back up to simply match the 'f' (by the default rule). +.PP +The comment regarding State #8 indicates there's a problem +when "foob" has been scanned. Indeed, on any character other +than an 'a', the scanner will have to back up to accept "foo". +Similarly, the comment for State #9 concerns when "fooba" has +been scanned and an 'r' does not follow. +.PP +The final comment reminds us that there's no point going to +all the trouble of removing backing up from the rules unless +we're using +.B \-Cf +or +.B \-CF, +since there's no performance gain doing so with compressed scanners. +.PP +The way to remove the backing up is to add "error" rules: +.nf + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + fooba | + foob | + fo { + /* false alarm, not really a keyword */ + return TOK_ID; + } + +.fi +.PP +Eliminating backing up among a list of keywords can also be +done using a "catch-all" rule: +.nf + + %% + foo return TOK_KEYWORD; + foobar return TOK_KEYWORD; + + [a-z]+ return TOK_ID; + +.fi +This is usually the best solution when appropriate. +.PP +Backing up messages tend to cascade. +With a complicated set of rules it's not uncommon to get hundreds +of messages. If one can decipher them, though, it often +only takes a dozen or so rules to eliminate the backing up (though +it's easy to make a mistake and have an error rule accidentally match +a valid token. A possible future +.I flex +feature will be to automatically add rules to eliminate backing up). +.PP +It's important to keep in mind that you gain the benefits of eliminating +backing up only if you eliminate +.I every +instance of backing up. Leaving just one means you gain nothing. +.PP +.I Variable +trailing context (where both the leading and trailing parts do not have +a fixed length) entails almost the same performance loss as +.B REJECT +(i.e., substantial). So when possible a rule like: +.nf + + %% + mouse|rat/(cat|dog) run(); + +.fi +is better written: +.nf + + %% + mouse/cat|dog run(); + rat/cat|dog run(); + +.fi +or as +.nf + + %% + mouse|rat/cat run(); + mouse|rat/dog run(); + +.fi +Note that here the special '|' action does +.I not +provide any savings, and can even make things worse (see +Deficiencies / Bugs below). +.LP +Another area where the user can increase a scanner's performance +(and one that's easier to implement) arises from the fact that +the longer the tokens matched, the faster the scanner will run. +This is because with long tokens the processing of most input +characters takes place in the (short) inner scanning loop, and +does not often have to go through the additional work of setting up +the scanning environment (e.g., +.B yytext) +for the action. Recall the scanner for C comments: +.nf + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\\n]* + "*"+[^*/\\n]* + \\n ++line_num; + "*"+"/" BEGIN(INITIAL); + +.fi +This could be sped up by writing it as: +.nf + + %x comment + %% + int line_num = 1; + + "/*" BEGIN(comment); + + [^*\\n]* + [^*\\n]*\\n ++line_num; + "*"+[^*/\\n]* + "*"+[^*/\\n]*\\n ++line_num; + "*"+"/" BEGIN(INITIAL); + +.fi +Now instead of each newline requiring the processing of another +action, recognizing the newlines is "distributed" over the other rules +to keep the matched text as long as possible. Note that +.I adding +rules does +.I not +slow down the scanner! The speed of the scanner is independent +of the number of rules or (modulo the considerations given at the +beginning of this section) how complicated the rules are with +regard to operators such as '*' and '|'. +.PP +A final example in speeding up a scanner: suppose you want to scan +through a file containing identifiers and keywords, one per line +and with no other extraneous characters, and recognize all the +keywords. A natural first approach is: +.nf + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + .|\\n /* it's not a keyword */ + +.fi +To eliminate the back-tracking, introduce a catch-all rule: +.nf + + %% + asm | + auto | + break | + ... etc ... + volatile | + while /* it's a keyword */ + + [a-z]+ | + .|\\n /* it's not a keyword */ + +.fi +Now, if it's guaranteed that there's exactly one word per line, +then we can reduce the total number of matches by a half by +merging in the recognition of newlines with that of the other +tokens: +.nf + + %% + asm\\n | + auto\\n | + break\\n | + ... etc ... + volatile\\n | + while\\n /* it's a keyword */ + + [a-z]+\\n | + .|\\n /* it's not a keyword */ + +.fi +One has to be careful here, as we have now reintroduced backing up +into the scanner. In particular, while +.I we +know that there will never be any characters in the input stream +other than letters or newlines, +.I flex +can't figure this out, and it will plan for possibly needing to back up +when it has scanned a token like "auto" and then the next character +is something other than a newline or a letter. Previously it would +then just match the "auto" rule and be done, but now it has no "auto" +rule, only a "auto\\n" rule. To eliminate the possibility of backing up, +we could either duplicate all rules but without final newlines, or, +since we never expect to encounter such an input and therefore don't +how it's classified, we can introduce one more catch-all rule, this +one which doesn't include a newline: +.nf + + %% + asm\\n | + auto\\n | + break\\n | + ... etc ... + volatile\\n | + while\\n /* it's a keyword */ + + [a-z]+\\n | + [a-z]+ | + .|\\n /* it's not a keyword */ + +.fi +Compiled with +.B \-Cf, +this is about as fast as one can get a +.I flex +scanner to go for this particular problem. +.PP +A final note: +.I flex +is slow when matching NUL's, particularly when a token contains +multiple NUL's. +It's best to write rules which match +.I short +amounts of text if it's anticipated that the text will often include NUL's. +.PP +Another final note regarding performance: as mentioned above in the section +How the Input is Matched, dynamically resizing +.B yytext +to accommodate huge tokens is a slow process because it presently requires that +the (huge) token be rescanned from the beginning. Thus if performance is +vital, you should attempt to match "large" quantities of text but not +"huge" quantities, where the cutoff between the two is at about 8K +characters/token. +.SH GENERATING C++ SCANNERS +.I flex +provides two different ways to generate scanners for use with C++. The +first way is to simply compile a scanner generated by +.I flex +using a C++ compiler instead of a C compiler. You should not encounter +any compilations errors (please report any you find to the email address +given in the Author section below). You can then use C++ code in your +rule actions instead of C code. Note that the default input source for +your scanner remains +.I yyin, +and default echoing is still done to +.I yyout. +Both of these remain +.I FILE * +variables and not C++ +.I streams. +.PP +You can also use +.I flex +to generate a C++ scanner class, using the +.B \-+ +option (or, equivalently, +.B %option c++), +which is automatically specified if the name of the flex +executable ends in a '+', such as +.I flex++. +When using this option, flex defaults to generating the scanner to the file +.B lex.yy.cc +instead of +.B lex.yy.c. +The generated scanner includes the header file +.I FlexLexer.h, +which defines the interface to two C++ classes. +.PP +The first class, +.B FlexLexer, +provides an abstract base class defining the general scanner class +interface. It provides the following member functions: +.TP +.B const char* YYText() +returns the text of the most recently matched token, the equivalent of +.B yytext. +.TP +.B int YYLeng() +returns the length of the most recently matched token, the equivalent of +.B yyleng. +.TP +.B int lineno() const +returns the current input line number +(see +.B %option yylineno), +or +.B 1 +if +.B %option yylineno +was not used. +.TP +.B void set_debug( int flag ) +sets the debugging flag for the scanner, equivalent to assigning to +.B yy_flex_debug +(see the Options section above). Note that you must build the scanner +using +.B %option debug +to include debugging information in it. +.TP +.B int debug() const +returns the current setting of the debugging flag. +.PP +Also provided are member functions equivalent to +.B yy_switch_to_buffer(), +.B yy_create_buffer() +(though the first argument is an +.B istream* +object pointer and not a +.B FILE*), +.B yy_flush_buffer(), +.B yy_delete_buffer(), +and +.B yyrestart() +(again, the first argument is a +.B istream* +object pointer). +.PP +The second class defined in +.I FlexLexer.h +is +.B yyFlexLexer, +which is derived from +.B FlexLexer. +It defines the following additional member functions: +.TP +.B +yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 ) +constructs a +.B yyFlexLexer +object using the given streams for input and output. If not specified, +the streams default to +.B cin +and +.B cout, +respectively. +.TP +.B virtual int yylex() +performs the same role is +.B yylex() +does for ordinary flex scanners: it scans the input stream, consuming +tokens, until a rule's action returns a value. If you derive a subclass +.B S +from +.B yyFlexLexer +and want to access the member functions and variables of +.B S +inside +.B yylex(), +then you need to use +.B %option yyclass="S" +to inform +.I flex +that you will be using that subclass instead of +.B yyFlexLexer. +In this case, rather than generating +.B yyFlexLexer::yylex(), +.I flex +generates +.B S::yylex() +(and also generates a dummy +.B yyFlexLexer::yylex() +that calls +.B yyFlexLexer::LexerError() +if called). +.TP +.B +virtual void switch_streams(istream* new_in = 0, +.B +ostream* new_out = 0) +reassigns +.B yyin +to +.B new_in +(if non-nil) +and +.B yyout +to +.B new_out +(ditto), deleting the previous input buffer if +.B yyin +is reassigned. +.TP +.B +int yylex( istream* new_in, ostream* new_out = 0 ) +first switches the input streams via +.B switch_streams( new_in, new_out ) +and then returns the value of +.B yylex(). +.PP +In addition, +.B yyFlexLexer +defines the following protected virtual functions which you can redefine +in derived classes to tailor the scanner: +.TP +.B +virtual int LexerInput( char* buf, int max_size ) +reads up to +.B max_size +characters into +.B buf +and returns the number of characters read. To indicate end-of-input, +return 0 characters. Note that "interactive" scanners (see the +.B \-B +and +.B \-I +flags) define the macro +.B YY_INTERACTIVE. +If you redefine +.B LexerInput() +and need to take different actions depending on whether or not +the scanner might be scanning an interactive input source, you can +test for the presence of this name via +.B #ifdef. +.TP +.B +virtual void LexerOutput( const char* buf, int size ) +writes out +.B size +characters from the buffer +.B buf, +which, while NUL-terminated, may also contain "internal" NUL's if +the scanner's rules can match text with NUL's in them. +.TP +.B +virtual void LexerError( const char* msg ) +reports a fatal error message. The default version of this function +writes the message to the stream +.B cerr +and exits. +.PP +Note that a +.B yyFlexLexer +object contains its +.I entire +scanning state. Thus you can use such objects to create reentrant +scanners. You can instantiate multiple instances of the same +.B yyFlexLexer +class, and you can also combine multiple C++ scanner classes together +in the same program using the +.B \-P +option discussed above. +.PP +Finally, note that the +.B %array +feature is not available to C++ scanner classes; you must use +.B %pointer +(the default). +.PP +Here is an example of a simple C++ scanner: +.nf + + // An example of using the flex C++ scanner class. + + %{ + int mylineno = 0; + %} + + string \\"[^\\n"]+\\" + + ws [ \\t]+ + + alpha [A-Za-z] + dig [0-9] + name ({alpha}|{dig}|\\$)({alpha}|{dig}|[_.\\-/$])* + num1 [-+]?{dig}+\\.?([eE][-+]?{dig}+)? + num2 [-+]?{dig}*\\.{dig}+([eE][-+]?{dig}+)? + number {num1}|{num2} + + %% + + {ws} /* skip blanks and tabs */ + + "/*" { + int c; + + while((c = yyinput()) != 0) + { + if(c == '\\n') + ++mylineno; + + else if(c == '*') + { + if((c = yyinput()) == '/') + break; + else + unput(c); + } + } + } + + {number} cout << "number " << YYText() << '\\n'; + + \\n mylineno++; + + {name} cout << "name " << YYText() << '\\n'; + + {string} cout << "string " << YYText() << '\\n'; + + %% + + int main( int /* argc */, char** /* argv */ ) + { + FlexLexer* lexer = new yyFlexLexer; + while(lexer->yylex() != 0) + ; + return 0; + } +.fi +If you want to create multiple (different) lexer classes, you use the +.B \-P +flag (or the +.B prefix= +option) to rename each +.B yyFlexLexer +to some other +.B xxFlexLexer. +You then can include +.B +in your other sources once per lexer class, first renaming +.B yyFlexLexer +as follows: +.nf + + #undef yyFlexLexer + #define yyFlexLexer xxFlexLexer + #include + + #undef yyFlexLexer + #define yyFlexLexer zzFlexLexer + #include + +.fi +if, for example, you used +.B %option prefix="xx" +for one of your scanners and +.B %option prefix="zz" +for the other. +.PP +IMPORTANT: the present form of the scanning class is +.I experimental +and may change considerably between major releases. +.SH INCOMPATIBILITIES WITH LEX AND POSIX +.I flex +is a rewrite of the AT&T Unix +.I lex +tool (the two implementations do not share any code, though), +with some extensions and incompatibilities, both of which +are of concern to those who wish to write scanners acceptable +to either implementation. Flex is fully compliant with the POSIX +.I lex +specification, except that when using +.B %pointer +(the default), a call to +.B unput() +destroys the contents of +.B yytext, +which is counter to the POSIX specification. +.PP +In this section we discuss all of the known areas of incompatibility +between flex, AT&T lex, and the POSIX specification. +.PP +.I flex's +.B \-l +option turns on maximum compatibility with the original AT&T +.I lex +implementation, at the cost of a major loss in the generated scanner's +performance. We note below which incompatibilities can be overcome +using the +.B \-l +option. +.PP +.I flex +is fully compatible with +.I lex +with the following exceptions: +.IP - +The undocumented +.I lex +scanner internal variable +.B yylineno +is not supported unless +.B \-l +or +.B %option yylineno +is used. +.IP +.B yylineno +should be maintained on a per-buffer basis, rather than a per-scanner +(single global variable) basis. +.IP +.B yylineno +is not part of the POSIX specification. +.IP - +The +.B input() +routine is not redefinable, though it may be called to read characters +following whatever has been matched by a rule. If +.B input() +encounters an end-of-file the normal +.B yywrap() +processing is done. A ``real'' end-of-file is returned by +.B input() +as +.I EOF. +.IP +Input is instead controlled by defining the +.B YY_INPUT +macro. +.IP +The +.I flex +restriction that +.B input() +cannot be redefined is in accordance with the POSIX specification, +which simply does not specify any way of controlling the +scanner's input other than by making an initial assignment to +.I yyin. +.IP - +The +.B unput() +routine is not redefinable. This restriction is in accordance with POSIX. +.IP - +.I flex +scanners are not as reentrant as +.I lex +scanners. In particular, if you have an interactive scanner and +an interrupt handler which long-jumps out of the scanner, and +the scanner is subsequently called again, you may get the following +message: +.nf + + fatal flex scanner internal error--end of buffer missed + +.fi +To reenter the scanner, first use +.nf + + yyrestart( yyin ); + +.fi +Note that this call will throw away any buffered input; usually this +isn't a problem with an interactive scanner. +.IP +Also note that flex C++ scanner classes +.I are +reentrant, so if using C++ is an option for you, you should use +them instead. See "Generating C++ Scanners" above for details. +.IP - +.B output() +is not supported. +Output from the +.B ECHO +macro is done to the file-pointer +.I yyout +(default +.I stdout). +.IP +.B output() +is not part of the POSIX specification. +.IP - +.I lex +does not support exclusive start conditions (%x), though they +are in the POSIX specification. +.IP - +When definitions are expanded, +.I flex +encloses them in parentheses. +With lex, the following: +.nf + + NAME [A-Z][A-Z0-9]* + %% + foo{NAME}? printf( "Found it\\n" ); + %% + +.fi +will not match the string "foo" because when the macro +is expanded the rule is equivalent to "foo[A-Z][A-Z0-9]*?" +and the precedence is such that the '?' is associated with +"[A-Z0-9]*". With +.I flex, +the rule will be expanded to +"foo([A-Z][A-Z0-9]*)?" and so the string "foo" will match. +.IP +Note that if the definition begins with +.B ^ +or ends with +.B $ +then it is +.I not +expanded with parentheses, to allow these operators to appear in +definitions without losing their special meanings. But the +.B , /, +and +.B <> +operators cannot be used in a +.I flex +definition. +.IP +Using +.B \-l +results in the +.I lex +behavior of no parentheses around the definition. +.IP +The POSIX specification is that the definition be enclosed in parentheses. +.IP - +Some implementations of +.I lex +allow a rule's action to begin on a separate line, if the rule's pattern +has trailing whitespace: +.nf + + %% + foo|bar + { foobar_action(); } + +.fi +.I flex +does not support this feature. +.IP - +The +.I lex +.B %r +(generate a Ratfor scanner) option is not supported. It is not part +of the POSIX specification. +.IP - +After a call to +.B unput(), +.I yytext +is undefined until the next token is matched, unless the scanner +was built using +.B %array. +This is not the case with +.I lex +or the POSIX specification. The +.B \-l +option does away with this incompatibility. +.IP - +The precedence of the +.B {} +(numeric range) operator is different. +.I lex +interprets "abc{1,3}" as "match one, two, or +three occurrences of 'abc'", whereas +.I flex +interprets it as "match 'ab' +followed by one, two, or three occurrences of 'c'". The latter is +in agreement with the POSIX specification. +.IP - +The precedence of the +.B ^ +operator is different. +.I lex +interprets "^foo|bar" as "match either 'foo' at the beginning of a line, +or 'bar' anywhere", whereas +.I flex +interprets it as "match either 'foo' or 'bar' if they come at the beginning +of a line". The latter is in agreement with the POSIX specification. +.IP - +The special table-size declarations such as +.B %a +supported by +.I lex +are not required by +.I flex +scanners; +.I flex +ignores them. +.IP - +The name +.bd +FLEX_SCANNER +is #define'd so scanners may be written for use with either +.I flex +or +.I lex. +Scanners also include +.B YY_FLEX_MAJOR_VERSION +and +.B YY_FLEX_MINOR_VERSION +indicating which version of +.I flex +generated the scanner +(for example, for the 2.5 release, these defines would be 2 and 5 +respectively). +.PP +The following +.I flex +features are not included in +.I lex +or the POSIX specification: +.nf + + C++ scanners + %option + start condition scopes + start condition stacks + interactive/non-interactive scanners + yy_scan_string() and friends + yyterminate() + yy_set_interactive() + yy_set_bol() + YY_AT_BOL() + <> + <*> + YY_DECL + YY_START + YY_USER_ACTION + YY_USER_INIT + #line directives + %{}'s around actions + multiple actions on a line + +.fi +plus almost all of the flex flags. +The last feature in the list refers to the fact that with +.I flex +you can put multiple actions on the same line, separated with +semi-colons, while with +.I lex, +the following +.nf + + foo handle_foo(); ++num_foos_seen; + +.fi +is (rather surprisingly) truncated to +.nf + + foo handle_foo(); + +.fi +.I flex +does not truncate the action. Actions that are not enclosed in +braces are simply terminated at the end of the line. +.SH DIAGNOSTICS +.PP +.I warning, rule cannot be matched +indicates that the given rule +cannot be matched because it follows other rules that will +always match the same text as it. For +example, in the following "foo" cannot be matched because it comes after +an identifier "catch-all" rule: +.nf + + [a-z]+ got_identifier(); + foo got_foo(); + +.fi +Using +.B REJECT +in a scanner suppresses this warning. +.PP +.I warning, +.B \-s +.I +option given but default rule can be matched +means that it is possible (perhaps only in a particular start condition) +that the default rule (match any single character) is the only one +that will match a particular input. Since +.B \-s +was given, presumably this is not intended. +.PP +.I reject_used_but_not_detected undefined +or +.I yymore_used_but_not_detected undefined - +These errors can occur at compile time. They indicate that the +scanner uses +.B REJECT +or +.B yymore() +but that +.I flex +failed to notice the fact, meaning that +.I flex +scanned the first two sections looking for occurrences of these actions +and failed to find any, but somehow you snuck some in (via a #include +file, for example). Use +.B %option reject +or +.B %option yymore +to indicate to flex that you really do use these features. +.PP +.I flex scanner jammed - +a scanner compiled with +.B \-s +has encountered an input string which wasn't matched by +any of its rules. This error can also occur due to internal problems. +.PP +.I token too large, exceeds YYLMAX - +your scanner uses +.B %array +and one of its rules matched a string longer than the +.B YYLMAX +constant (8K bytes by default). You can increase the value by +#define'ing +.B YYLMAX +in the definitions section of your +.I flex +input. +.PP +.I scanner requires \-8 flag to +.I use the character 'x' - +Your scanner specification includes recognizing the 8-bit character +.I 'x' +and you did not specify the \-8 flag, and your scanner defaulted to 7-bit +because you used the +.B \-Cf +or +.B \-CF +table compression options. See the discussion of the +.B \-7 +flag for details. +.PP +.I flex scanner push-back overflow - +you used +.B unput() +to push back so much text that the scanner's buffer could not hold +both the pushed-back text and the current token in +.B yytext. +Ideally the scanner should dynamically resize the buffer in this case, but at +present it does not. +.PP +.I +input buffer overflow, can't enlarge buffer because scanner uses REJECT - +the scanner was working on matching an extremely large token and needed +to expand the input buffer. This doesn't work with scanners that use +.B +REJECT. +.PP +.I +fatal flex scanner internal error--end of buffer missed - +This can occur in an scanner which is reentered after a long-jump +has jumped out (or over) the scanner's activation frame. Before +reentering the scanner, use: +.nf + + yyrestart( yyin ); + +.fi +or, as noted above, switch to using the C++ scanner class. +.PP +.I too many start conditions in <> construct! - +you listed more start conditions in a <> construct than exist (so +you must have listed at least one of them twice). +.SH FILES +.TP +.B \-lfl +library with which scanners must be linked. +.TP +.I lex.yy.c +generated scanner (called +.I lexyy.c +on some systems). +.TP +.I lex.yy.cc +generated C++ scanner class, when using +.B -+. +.TP +.I +header file defining the C++ scanner base class, +.B FlexLexer, +and its derived class, +.B yyFlexLexer. +.TP +.I flex.skl +skeleton scanner. This file is only used when building flex, not when +flex executes. +.TP +.I lex.backup +backing-up information for +.B \-b +flag (called +.I lex.bck +on some systems). +.SH DEFICIENCIES / BUGS +.PP +Some trailing context +patterns cannot be properly matched and generate +warning messages ("dangerous trailing context"). These are +patterns where the ending of the +first part of the rule matches the beginning of the second +part, such as "zx*/xy*", where the 'x*' matches the 'x' at +the beginning of the trailing context. (Note that the POSIX draft +states that the text matched by such patterns is undefined.) +.PP +For some trailing context rules, parts which are actually fixed-length are +not recognized as such, leading to the abovementioned performance loss. +In particular, parts using '|' or {n} (such as "foo{3}") are always +considered variable-length. +.PP +Combining trailing context with the special '|' action can result in +.I fixed +trailing context being turned into the more expensive +.I variable +trailing context. For example, in the following: +.nf + + %% + abc | + xyz/def + +.fi +.PP +Use of +.B unput() +invalidates yytext and yyleng, unless the +.B %array +directive +or the +.B \-l +option has been used. +.PP +Pattern-matching of NUL's is substantially slower than matching other +characters. +.PP +Dynamic resizing of the input buffer is slow, as it entails rescanning +all the text matched so far by the current (generally huge) token. +.PP +Due to both buffering of input and read-ahead, you cannot intermix +calls to routines, such as, for example, +.B getchar(), +with +.I flex +rules and expect it to work. Call +.B input() +instead. +.PP +The total table entries listed by the +.B \-v +flag excludes the number of table entries needed to determine +what rule has been matched. The number of entries is equal +to the number of DFA states if the scanner does not use +.B REJECT, +and somewhat greater than the number of states if it does. +.PP +.B REJECT +cannot be used with the +.B \-f +or +.B \-F +options. +.PP +The +.I flex +internal algorithms need documentation. +.SH SEE ALSO +.PP +lex(1), yacc(1), sed(1), awk(1). +.PP +John Levine, Tony Mason, and Doug Brown, +.I Lex & Yacc, +O'Reilly and Associates. Be sure to get the 2nd edition. +.PP +M. E. Lesk and E. Schmidt, +.I LEX \- Lexical Analyzer Generator +.PP +Alfred Aho, Ravi Sethi and Jeffrey Ullman, +.I Compilers: Principles, Techniques and Tools, +Addison-Wesley (1986). Describes the pattern-matching techniques used by +.I flex +(deterministic finite automata). +.SH AUTHOR +Vern Paxson, with the help of many ideas and much inspiration from +Van Jacobson. Original version by Jef Poskanzer. The fast table +representation is a partial implementation of a design done by Van +Jacobson. The implementation was done by Kevin Gong and Vern Paxson. +.PP +Thanks to the many +.I flex +beta-testers, feedbackers, and contributors, especially Francois Pinard, +Casey Leedom, +Robert Abramovitz, +Stan Adermann, Terry Allen, David Barker-Plummer, John Basrai, +Neal Becker, Nelson H.F. Beebe, benson@odi.com, +Karl Berry, Peter A. Bigot, Simon Blanchard, +Keith Bostic, Frederic Brehm, Ian Brockbank, Kin Cho, Nick Christopher, +Brian Clapper, J.T. Conklin, +Jason Coughlin, Bill Cox, Nick Cropper, Dave Curtis, Scott David +Daniels, Chris G. Demetriou, Theo Deraadt, +Mike Donahue, Chuck Doucette, Tom Epperly, Leo Eskin, +Chris Faylor, Chris Flatters, Jon Forrest, Jeffrey Friedl, +Joe Gayda, Kaveh R. Ghazi, Wolfgang Glunz, +Eric Goldman, Christopher M. Gould, Ulrich Grepel, Peer Griebel, +Jan Hajic, Charles Hemphill, NORO Hideo, +Jarkko Hietaniemi, Scott Hofmann, +Jeff Honig, Dana Hudes, Eric Hughes, John Interrante, +Ceriel Jacobs, Michal Jaegermann, Sakari Jalovaara, Jeffrey R. Jones, +Henry Juengst, Klaus Kaempf, Jonathan I. Kamens, Terrence O Kane, +Amir Katz, ken@ken.hilco.com, Kevin B. Kenny, +Steve Kirsch, Winfried Koenig, Marq Kole, Ronald Lamprecht, +Greg Lee, Rohan Lenard, Craig Leres, John Levine, Steve Liddle, +David Loffredo, Mike Long, +Mohamed el Lozy, Brian Madsen, Malte, Joe Marshall, +Bengt Martensson, Chris Metcalf, +Luke Mewburn, Jim Meyering, R. Alexander Milowski, Erik Naggum, +G.T. Nicol, Landon Noll, James Nordby, Marc Nozell, +Richard Ohnemus, Karsten Pahnke, +Sven Panne, Roland Pesch, Walter Pelissero, Gaumond +Pierre, Esmond Pitt, Jef Poskanzer, Joe Rahmeh, Jarmo Raiha, +Frederic Raimbault, Pat Rankin, Rick Richardson, +Kevin Rodgers, Kai Uwe Rommel, Jim Roskind, Alberto Santini, +Andreas Scherer, Darrell Schiebel, Raf Schietekat, +Doug Schmidt, Philippe Schnoebelen, Andreas Schwab, +Larry Schwimmer, Alex Siegel, Eckehard Stolz, Jan-Erik Strvmquist, +Mike Stump, Paul Stuart, Dave Tallman, Ian Lance Taylor, +Chris Thewalt, Richard M. Timoney, Jodi Tsai, +Paul Tuinenga, Gary Weik, Frank Whaley, Gerhard Wilhelms, Kent Williams, Ken +Yap, Ron Zellar, Nathan Zelle, David Zuhn, +and those whose names have slipped my marginal +mail-archiving skills but whose contributions are appreciated all the +same. +.PP +Thanks to Keith Bostic, Jon Forrest, Noah Friedman, +John Gilmore, Craig Leres, John Levine, Bob Mulcahy, G.T. +Nicol, Francois Pinard, Rich Salz, and Richard Stallman for help with various +distribution headaches. +.PP +Thanks to Esmond Pitt and Earle Horton for 8-bit character support; to +Benson Margulies and Fred Burke for C++ support; to Kent Williams and Tom +Epperly for C++ class support; to Ove Ewerlid for support of NUL's; and to +Eric Hughes for support of multiple buffers. +.PP +This work was primarily done when I was with the Real Time Systems Group +at the Lawrence Berkeley Laboratory in Berkeley, CA. Many thanks to all there +for the support I received. +.PP +Send comments to vern@ee.lbl.gov. diff --git a/commands/flex-2.5.4/flex.skl b/commands/flex-2.5.4/flex.skl new file mode 100644 index 000000000..ec80e94be --- /dev/null +++ b/commands/flex-2.5.4/flex.skl @@ -0,0 +1,1541 @@ +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header$ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +%- +#include +%* + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +%+ +class istream; +%* +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +%- +extern FILE *yyin, *yyout; +%* + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { +%- + FILE *yy_input_file; +%+ + istream* yy_input_file; +%* + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +%- Standard (non-C++) definition +static YY_BUFFER_STATE yy_current_buffer = 0; +%* + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +%- Standard (non-C++) definition +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); +%* + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + +%% yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here + +%- Standard (non-C++) definition +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); +%* + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ +%% code to fiddle yytext and yyleng for yymore() goes here + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ +%% code to copy yytext_ptr to yytext[] goes here, if %array + yy_c_buf_p = yy_cp; + +%% data tables for the DFA and the user's section 1 definitions go here + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +%- +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif +%* + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +%- Standard (non-C++) definition +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +%* +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +%- Standard (non-C++) definition +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +%+ C++ definition +#define ECHO LexerOutput( yytext, yyleng ) +%* +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +%% fread()/read() definition of YY_INPUT goes here unless we're doing C++ +%+ C++ definition + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +%* +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +%- +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +%+ +#define YY_FATAL_ERROR(msg) LexerError( msg ) +%* +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +%- Standard (non-C++) definition +#define YY_DECL int yylex YY_PROTO(( void )) +%+ C++ definition +#define YY_DECL int yyFlexLexer::yylex() +%* +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +%% YY_RULE_SETUP definition goes here + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +%% user's declarations go here + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) +%- + yyin = stdin; +%+ + yyin = &cin; +%* + + if ( ! yyout ) +%- + yyout = stdout; +%+ + yyout = &cout; +%* + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { +%% yymore()-related code goes here + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + +%% code to set up and find next match goes here + +yy_find_action: +%% code to find the action number goes here + + YY_DO_BEFORE_ACTION; + +%% code for yylineno update goes here + +do_action: /* This label is used only to access EOF actions. */ + +%% debug code goes here + + switch ( yy_act ) + { /* beginning of action switch */ +%% actions go here + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { +%% code to do back-up for compressed tables and set up yy_cp goes here + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + +%+ +yyFlexLexer::yyFlexLexer( istream* arg_yyin, ostream* arg_yyout ) + { + yyin = arg_yyin; + yyout = arg_yyout; + yy_c_buf_p = 0; + yy_init = 1; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + yy_more_offset = yy_prev_more_offset = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = 0; + + yy_current_buffer = 0; + +#ifdef YY_USES_REJECT + yy_state_buf = new yy_state_type[YY_BUF_SIZE + 2]; +#else + yy_state_buf = 0; +#endif + } + +yyFlexLexer::~yyFlexLexer() + { + delete yy_state_buf; + yy_delete_buffer( yy_current_buffer ); + } + +void yyFlexLexer::switch_streams( istream* new_in, ostream* new_out ) + { + if ( new_in ) + { + yy_delete_buffer( yy_current_buffer ); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); + } + + if ( new_out ) + yyout = new_out; + } + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif + { + if ( yyin->eof() || yyin->fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin->get( buf[0] ); + + if ( yyin->eof() ) + return 0; + + if ( yyin->bad() ) + return -1; + + return 1; + +#else + (void) yyin->read( buf, max_size ); + + if ( yyin->bad() ) + return -1; + else + return yyin->gcount(); +#endif + } + +void yyFlexLexer::LexerOutput( const char* buf, int size ) + { + (void) yyout->write( buf, size ); + } +%* + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +%- +static int yy_get_next_buffer() +%+ +int yyFlexLexer::yy_get_next_buffer() +%* + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +%- +static yy_state_type yy_get_previous_state() +%+ +yy_state_type yyFlexLexer::yy_get_previous_state() +%* + { + register yy_state_type yy_current_state; + register char *yy_cp; + +%% code to get the start state into yy_current_state goes here + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { +%% code to find the next state goes here + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +%- +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif +%+ +yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +%* + { + register int yy_is_jam; +%% code to find the next state, and perhaps do backing up, goes here + + return yy_is_jam ? 0 : yy_current_state; + } + + +%- +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif +%+ +void yyFlexLexer::yyunput( int c, register char* yy_bp ) +%* + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + +%% update yylineno here + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +%- +#endif /* ifndef YY_NO_UNPUT */ +%* + + +%- +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif +%+ +int yyFlexLexer::yyinput() +%* + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + +%% update BOL and yylineno + + return c; + } + + +%- +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif +%+ +void yyFlexLexer::yyrestart( istream* input_file ) +%* + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +%- +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif +%+ +void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +%* + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +%- +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif +%+ +void yyFlexLexer::yy_load_buffer_state() +%* + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif +%+ +YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size ) +%* + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +%- +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif +%+ +void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +%* + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +%- +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + +%+ +extern "C" int isatty YY_PROTO(( int )); +void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file ) +%* + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +%- +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif +%+ + b->yy_is_interactive = 0; +%* + } + + +%- +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + +%+ +void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +%* + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } +%* + + +#ifndef YY_NO_SCAN_BUFFER +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +%* +#endif + + +#ifndef YY_NO_SCAN_STRING +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +%* +#endif + + +#ifndef YY_NO_SCAN_BYTES +%- +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +%* +#endif + + +#ifndef YY_NO_PUSH_STATE +%- +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif +%+ +void yyFlexLexer::yy_push_state( int new_state ) +%* + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +%- +static void yy_pop_state() +%+ +void yyFlexLexer::yy_pop_state() +%* + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +%- +static int yy_top_state() +%+ +int yyFlexLexer::yy_top_state() +%* + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +%- +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + +%+ + +void yyFlexLexer::LexerError( yyconst char msg[] ) + { + cerr << msg << '\n'; + exit( YY_EXIT_FAILURE ); + } +%* + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif diff --git a/commands/flex-2.5.4/flexdef.h b/commands/flex-2.5.4/flexdef.h new file mode 100644 index 000000000..bc70df3cc --- /dev/null +++ b/commands/flex-2.5.4/flexdef.h @@ -0,0 +1,1048 @@ +/* flexdef - definitions file for flex */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* @(#) $Header$ (LBL) */ + +#include +#include + +#include "config.h" + +#ifdef __TURBOC__ +#define HAVE_STRING_H 1 +#define MS_DOS 1 +#ifndef __STDC__ +#define __STDC__ 1 +#endif + #pragma warn -pro + #pragma warn -rch + #pragma warn -use + #pragma warn -aus + #pragma warn -par + #pragma warn -pia +#endif + +#ifdef HAVE_STRING_H +#include +#else +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_MALLOC_H +#include +#endif + +#ifdef STDC_HEADERS +#include +#endif + +/* As an aid for the internationalization patch to flex, which + * is maintained outside this distribution for copyright reasons. + */ +#define _(String) (String) + +/* Always be prepared to generate an 8-bit scanner. */ +#define CSIZE 256 +#define Char unsigned char + +/* Size of input alphabet - should be size of ASCII set. */ +#ifndef DEFAULT_CSIZE +#define DEFAULT_CSIZE 128 +#endif + +#ifndef PROTO +#if __STDC__ +#define PROTO(proto) proto +#else +#define PROTO(proto) () +#endif +#endif + +#ifdef VMS +#ifndef __VMS_POSIX +#define unlink remove +#define SHORT_FILE_NAMES +#endif +#endif + +#ifdef MS_DOS +#define SHORT_FILE_NAMES +#endif + + +/* Maximum line length we'll have to deal with. */ +#define MAXLINE 2048 + +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef ABS +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#endif + + +/* ANSI C does not guarantee that isascii() is defined */ +#ifndef isascii +#define isascii(c) ((c) <= 0177) +#endif + + +#define true 1 +#define false 0 +#define unspecified -1 + + +/* Special chk[] values marking the slots taking by end-of-buffer and action + * numbers. + */ +#define EOB_POSITION -1 +#define ACTION_POSITION -2 + +/* Number of data items per line for -f output. */ +#define NUMDATAITEMS 10 + +/* Number of lines of data in -f output before inserting a blank line for + * readability. + */ +#define NUMDATALINES 10 + +/* transition_struct_out() definitions. */ +#define TRANS_STRUCT_PRINT_LENGTH 14 + +/* Returns true if an nfa state has an epsilon out-transition slot + * that can be used. This definition is currently not used. + */ +#define FREE_EPSILON(state) \ + (transchar[state] == SYM_EPSILON && \ + trans2[state] == NO_TRANSITION && \ + finalst[state] != state) + +/* Returns true if an nfa state has an epsilon out-transition character + * and both slots are free + */ +#define SUPER_FREE_EPSILON(state) \ + (transchar[state] == SYM_EPSILON && \ + trans1[state] == NO_TRANSITION) \ + +/* Maximum number of NFA states that can comprise a DFA state. It's real + * big because if there's a lot of rules, the initial state will have a + * huge epsilon closure. + */ +#define INITIAL_MAX_DFA_SIZE 750 +#define MAX_DFA_SIZE_INCREMENT 750 + + +/* A note on the following masks. They are used to mark accepting numbers + * as being special. As such, they implicitly limit the number of accepting + * numbers (i.e., rules) because if there are too many rules the rule numbers + * will overload the mask bits. Fortunately, this limit is \large/ (0x2000 == + * 8192) so unlikely to actually cause any problems. A check is made in + * new_rule() to ensure that this limit is not reached. + */ + +/* Mask to mark a trailing context accepting number. */ +#define YY_TRAILING_MASK 0x2000 + +/* Mask to mark the accepting number of the "head" of a trailing context + * rule. + */ +#define YY_TRAILING_HEAD_MASK 0x4000 + +/* Maximum number of rules, as outlined in the above note. */ +#define MAX_RULE (YY_TRAILING_MASK - 1) + + +/* NIL must be 0. If not, its special meaning when making equivalence classes + * (it marks the representative of a given e.c.) will be unidentifiable. + */ +#define NIL 0 + +#define JAM -1 /* to mark a missing DFA transition */ +#define NO_TRANSITION NIL +#define UNIQUE -1 /* marks a symbol as an e.c. representative */ +#define INFINITY -1 /* for x{5,} constructions */ + +#define INITIAL_MAX_CCLS 100 /* max number of unique character classes */ +#define MAX_CCLS_INCREMENT 100 + +/* Size of table holding members of character classes. */ +#define INITIAL_MAX_CCL_TBL_SIZE 500 +#define MAX_CCL_TBL_SIZE_INCREMENT 250 + +#define INITIAL_MAX_RULES 100 /* default maximum number of rules */ +#define MAX_RULES_INCREMENT 100 + +#define INITIAL_MNS 2000 /* default maximum number of nfa states */ +#define MNS_INCREMENT 1000 /* amount to bump above by if it's not enough */ + +#define INITIAL_MAX_DFAS 1000 /* default maximum number of dfa states */ +#define MAX_DFAS_INCREMENT 1000 + +#define JAMSTATE -32766 /* marks a reference to the state that always jams */ + +/* Maximum number of NFA states. */ +#define MAXIMUM_MNS 31999 + +/* Enough so that if it's subtracted from an NFA state number, the result + * is guaranteed to be negative. + */ +#define MARKER_DIFFERENCE (MAXIMUM_MNS+2) + +/* Maximum number of nxt/chk pairs for non-templates. */ +#define INITIAL_MAX_XPAIRS 2000 +#define MAX_XPAIRS_INCREMENT 2000 + +/* Maximum number of nxt/chk pairs needed for templates. */ +#define INITIAL_MAX_TEMPLATE_XPAIRS 2500 +#define MAX_TEMPLATE_XPAIRS_INCREMENT 2500 + +#define SYM_EPSILON (CSIZE + 1) /* to mark transitions on the symbol epsilon */ + +#define INITIAL_MAX_SCS 40 /* maximum number of start conditions */ +#define MAX_SCS_INCREMENT 40 /* amount to bump by if it's not enough */ + +#define ONE_STACK_SIZE 500 /* stack of states with only one out-transition */ +#define SAME_TRANS -1 /* transition is the same as "default" entry for state */ + +/* The following percentages are used to tune table compression: + + * The percentage the number of out-transitions a state must be of the + * number of equivalence classes in order to be considered for table + * compaction by using protos. + */ +#define PROTO_SIZE_PERCENTAGE 15 + +/* The percentage the number of homogeneous out-transitions of a state + * must be of the number of total out-transitions of the state in order + * that the state's transition table is first compared with a potential + * template of the most common out-transition instead of with the first + * proto in the proto queue. + */ +#define CHECK_COM_PERCENTAGE 50 + +/* The percentage the number of differences between a state's transition + * table and the proto it was first compared with must be of the total + * number of out-transitions of the state in order to keep the first + * proto as a good match and not search any further. + */ +#define FIRST_MATCH_DIFF_PERCENTAGE 10 + +/* The percentage the number of differences between a state's transition + * table and the most similar proto must be of the state's total number + * of out-transitions to use the proto as an acceptable close match. + */ +#define ACCEPTABLE_DIFF_PERCENTAGE 50 + +/* The percentage the number of homogeneous out-transitions of a state + * must be of the number of total out-transitions of the state in order + * to consider making a template from the state. + */ +#define TEMPLATE_SAME_PERCENTAGE 60 + +/* The percentage the number of differences between a state's transition + * table and the most similar proto must be of the state's total number + * of out-transitions to create a new proto from the state. + */ +#define NEW_PROTO_DIFF_PERCENTAGE 20 + +/* The percentage the total number of out-transitions of a state must be + * of the number of equivalence classes in order to consider trying to + * fit the transition table into "holes" inside the nxt/chk table. + */ +#define INTERIOR_FIT_PERCENTAGE 15 + +/* Size of region set aside to cache the complete transition table of + * protos on the proto queue to enable quick comparisons. + */ +#define PROT_SAVE_SIZE 2000 + +#define MSP 50 /* maximum number of saved protos (protos on the proto queue) */ + +/* Maximum number of out-transitions a state can have that we'll rummage + * around through the interior of the internal fast table looking for a + * spot for it. + */ +#define MAX_XTIONS_FULL_INTERIOR_FIT 4 + +/* Maximum number of rules which will be reported as being associated + * with a DFA state. + */ +#define MAX_ASSOC_RULES 100 + +/* Number that, if used to subscript an array, has a good chance of producing + * an error; should be small enough to fit into a short. + */ +#define BAD_SUBSCRIPT -32767 + +/* Absolute value of largest number that can be stored in a short, with a + * bit of slop thrown in for general paranoia. + */ +#define MAX_SHORT 32700 + + +/* Declarations for global variables. */ + +/* Variables for symbol tables: + * sctbl - start-condition symbol table + * ndtbl - name-definition symbol table + * ccltab - character class text symbol table + */ + +struct hash_entry + { + struct hash_entry *prev, *next; + char *name; + char *str_val; + int int_val; + } ; + +typedef struct hash_entry **hash_table; + +#define NAME_TABLE_HASH_SIZE 101 +#define START_COND_HASH_SIZE 101 +#define CCL_HASH_SIZE 101 + +extern struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE]; +extern struct hash_entry *sctbl[START_COND_HASH_SIZE]; +extern struct hash_entry *ccltab[CCL_HASH_SIZE]; + + +/* Variables for flags: + * printstats - if true (-v), dump statistics + * syntaxerror - true if a syntax error has been found + * eofseen - true if we've seen an eof in the input file + * ddebug - if true (-d), make a "debug" scanner + * trace - if true (-T), trace processing + * nowarn - if true (-w), do not generate warnings + * spprdflt - if true (-s), suppress the default rule + * interactive - if true (-I), generate an interactive scanner + * caseins - if true (-i), generate a case-insensitive scanner + * lex_compat - if true (-l), maximize compatibility with AT&T lex + * do_yylineno - if true, generate code to maintain yylineno + * useecs - if true (-Ce flag), use equivalence classes + * fulltbl - if true (-Cf flag), don't compress the DFA state table + * usemecs - if true (-Cm flag), use meta-equivalence classes + * fullspd - if true (-F flag), use Jacobson method of table representation + * gen_line_dirs - if true (i.e., no -L flag), generate #line directives + * performance_report - if > 0 (i.e., -p flag), generate a report relating + * to scanner performance; if > 1 (-p -p), report on minor performance + * problems, too + * backing_up_report - if true (i.e., -b flag), generate "lex.backup" file + * listing backing-up states + * C_plus_plus - if true (i.e., -+ flag), generate a C++ scanner class; + * otherwise, a standard C scanner + * long_align - if true (-Ca flag), favor long-word alignment. + * use_read - if true (-f, -F, or -Cr) then use read() for scanner input; + * otherwise, use fread(). + * yytext_is_array - if true (i.e., %array directive), then declare + * yytext as a array instead of a character pointer. Nice and inefficient. + * do_yywrap - do yywrap() processing on EOF. If false, EOF treated as + * "no more files". + * csize - size of character set for the scanner we're generating; + * 128 for 7-bit chars and 256 for 8-bit + * yymore_used - if true, yymore() is used in input rules + * reject - if true, generate back-up tables for REJECT macro + * real_reject - if true, scanner really uses REJECT (as opposed to just + * having "reject" set for variable trailing context) + * continued_action - true if this rule's action is to "fall through" to + * the next rule's action (i.e., the '|' action) + * in_rule - true if we're inside an individual rule, false if not. + * yymore_really_used - whether to treat yymore() as really used, regardless + * of what we think based on references to it in the user's actions. + * reject_really_used - same for REJECT + */ + +extern int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; +extern int interactive, caseins, lex_compat, do_yylineno; +extern int useecs, fulltbl, usemecs, fullspd; +extern int gen_line_dirs, performance_report, backing_up_report; +extern int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap; +extern int csize; +extern int yymore_used, reject, real_reject, continued_action, in_rule; + +extern int yymore_really_used, reject_really_used; + + +/* Variables used in the flex input routines: + * datapos - characters on current output line + * dataline - number of contiguous lines of data in current data + * statement. Used to generate readable -f output + * linenum - current input line number + * out_linenum - current output line number + * skelfile - the skeleton file + * skel - compiled-in skeleton array + * skel_ind - index into "skel" array, if skelfile is nil + * yyin - input file + * backing_up_file - file to summarize backing-up states to + * infilename - name of input file + * outfilename - name of output file + * did_outfilename - whether outfilename was explicitly set + * prefix - the prefix used for externally visible names ("yy" by default) + * yyclass - yyFlexLexer subclass to use for YY_DECL + * do_stdinit - whether to initialize yyin/yyout to stdin/stdout + * use_stdout - the -t flag + * input_files - array holding names of input files + * num_input_files - size of input_files array + * program_name - name with which program was invoked + * + * action_array - array to hold the rule actions + * action_size - size of action_array + * defs1_offset - index where the user's section 1 definitions start + * in action_array + * prolog_offset - index where the prolog starts in action_array + * action_offset - index where the non-prolog starts in action_array + * action_index - index where the next action should go, with respect + * to "action_array" + */ + +extern int datapos, dataline, linenum, out_linenum; +extern FILE *skelfile, *yyin, *backing_up_file; +extern const char *skel[]; +extern int skel_ind; +extern char *infilename, *outfilename; +extern int did_outfilename; +extern char *prefix, *yyclass; +extern int do_stdinit, use_stdout; +extern char **input_files; +extern int num_input_files; +extern char *program_name; + +extern char *action_array; +extern int action_size; +extern int defs1_offset, prolog_offset, action_offset, action_index; + + +/* Variables for stack of states having only one out-transition: + * onestate - state number + * onesym - transition symbol + * onenext - target state + * onedef - default base entry + * onesp - stack pointer + */ + +extern int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; +extern int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; + + +/* Variables for nfa machine data: + * current_mns - current maximum on number of NFA states + * num_rules - number of the last accepting state; also is number of + * rules created so far + * num_eof_rules - number of <> rules + * default_rule - number of the default rule + * current_max_rules - current maximum number of rules + * lastnfa - last nfa state number created + * firstst - physically the first state of a fragment + * lastst - last physical state of fragment + * finalst - last logical state of fragment + * transchar - transition character + * trans1 - transition state + * trans2 - 2nd transition state for epsilons + * accptnum - accepting number + * assoc_rule - rule associated with this NFA state (or 0 if none) + * state_type - a STATE_xxx type identifying whether the state is part + * of a normal rule, the leading state in a trailing context + * rule (i.e., the state which marks the transition from + * recognizing the text-to-be-matched to the beginning of + * the trailing context), or a subsequent state in a trailing + * context rule + * rule_type - a RULE_xxx type identifying whether this a ho-hum + * normal rule or one which has variable head & trailing + * context + * rule_linenum - line number associated with rule + * rule_useful - true if we've determined that the rule can be matched + */ + +extern int current_mns, current_max_rules; +extern int num_rules, num_eof_rules, default_rule, lastnfa; +extern int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; +extern int *accptnum, *assoc_rule, *state_type; +extern int *rule_type, *rule_linenum, *rule_useful; + +/* Different types of states; values are useful as masks, as well, for + * routines like check_trailing_context(). + */ +#define STATE_NORMAL 0x1 +#define STATE_TRAILING_CONTEXT 0x2 + +/* Global holding current type of state we're making. */ + +extern int current_state_type; + +/* Different types of rules. */ +#define RULE_NORMAL 0 +#define RULE_VARIABLE 1 + +/* True if the input rules include a rule with both variable-length head + * and trailing context, false otherwise. + */ +extern int variable_trailing_context_rules; + + +/* Variables for protos: + * numtemps - number of templates created + * numprots - number of protos created + * protprev - backlink to a more-recently used proto + * protnext - forward link to a less-recently used proto + * prottbl - base/def table entry for proto + * protcomst - common state of proto + * firstprot - number of the most recently used proto + * lastprot - number of the least recently used proto + * protsave contains the entire state array for protos + */ + +extern int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; +extern int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; + + +/* Variables for managing equivalence classes: + * numecs - number of equivalence classes + * nextecm - forward link of Equivalence Class members + * ecgroup - class number or backward link of EC members + * nummecs - number of meta-equivalence classes (used to compress + * templates) + * tecfwd - forward link of meta-equivalence classes members + * tecbck - backward link of MEC's + */ + +/* Reserve enough room in the equivalence class arrays so that we + * can use the CSIZE'th element to hold equivalence class information + * for the NUL character. Later we'll move this information into + * the 0th element. + */ +extern int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs; + +/* Meta-equivalence classes are indexed starting at 1, so it's possible + * that they will require positions from 1 .. CSIZE, i.e., CSIZE + 1 + * slots total (since the arrays are 0-based). nextecm[] and ecgroup[] + * don't require the extra position since they're indexed from 1 .. CSIZE - 1. + */ +extern int tecfwd[CSIZE + 1], tecbck[CSIZE + 1]; + + +/* Variables for start conditions: + * lastsc - last start condition created + * current_max_scs - current limit on number of start conditions + * scset - set of rules active in start condition + * scbol - set of rules active only at the beginning of line in a s.c. + * scxclu - true if start condition is exclusive + * sceof - true if start condition has EOF rule + * scname - start condition name + */ + +extern int lastsc, *scset, *scbol, *scxclu, *sceof; +extern int current_max_scs; +extern char **scname; + + +/* Variables for dfa machine data: + * current_max_dfa_size - current maximum number of NFA states in DFA + * current_max_xpairs - current maximum number of non-template xtion pairs + * current_max_template_xpairs - current maximum number of template pairs + * current_max_dfas - current maximum number DFA states + * lastdfa - last dfa state number created + * nxt - state to enter upon reading character + * chk - check value to see if "nxt" applies + * tnxt - internal nxt table for templates + * base - offset into "nxt" for given state + * def - where to go if "chk" disallows "nxt" entry + * nultrans - NUL transition for each state + * NUL_ec - equivalence class of the NUL character + * tblend - last "nxt/chk" table entry being used + * firstfree - first empty entry in "nxt/chk" table + * dss - nfa state set for each dfa + * dfasiz - size of nfa state set for each dfa + * dfaacc - accepting set for each dfa state (if using REJECT), or accepting + * number, if not + * accsiz - size of accepting set for each dfa state + * dhash - dfa state hash value + * numas - number of DFA accepting states created; note that this + * is not necessarily the same value as num_rules, which is the analogous + * value for the NFA + * numsnpairs - number of state/nextstate transition pairs + * jambase - position in base/def where the default jam table starts + * jamstate - state number corresponding to "jam" state + * end_of_buffer_state - end-of-buffer dfa state number + */ + +extern int current_max_dfa_size, current_max_xpairs; +extern int current_max_template_xpairs, current_max_dfas; +extern int lastdfa, *nxt, *chk, *tnxt; +extern int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; +extern union dfaacc_union + { + int *dfaacc_set; + int dfaacc_state; + } *dfaacc; +extern int *accsiz, *dhash, numas; +extern int numsnpairs, jambase, jamstate; +extern int end_of_buffer_state; + +/* Variables for ccl information: + * lastccl - ccl index of the last created ccl + * current_maxccls - current limit on the maximum number of unique ccl's + * cclmap - maps a ccl index to its set pointer + * ccllen - gives the length of a ccl + * cclng - true for a given ccl if the ccl is negated + * cclreuse - counts how many times a ccl is re-used + * current_max_ccl_tbl_size - current limit on number of characters needed + * to represent the unique ccl's + * ccltbl - holds the characters in each ccl - indexed by cclmap + */ + +extern int lastccl, *cclmap, *ccllen, *cclng, cclreuse; +extern int current_maxccls, current_max_ccl_tbl_size; +extern Char *ccltbl; + + +/* Variables for miscellaneous information: + * nmstr - last NAME scanned by the scanner + * sectnum - section number currently being parsed + * nummt - number of empty nxt/chk table entries + * hshcol - number of hash collisions detected by snstods + * dfaeql - number of times a newly created dfa was equal to an old one + * numeps - number of epsilon NFA states created + * eps2 - number of epsilon states which have 2 out-transitions + * num_reallocs - number of times it was necessary to realloc() a group + * of arrays + * tmpuses - number of DFA states that chain to templates + * totnst - total number of NFA states used to make DFA states + * peakpairs - peak number of transition pairs we had to store internally + * numuniq - number of unique transitions + * numdup - number of duplicate transitions + * hshsave - number of hash collisions saved by checking number of states + * num_backing_up - number of DFA states requiring backing up + * bol_needed - whether scanner needs beginning-of-line recognition + */ + +extern char nmstr[MAXLINE]; +extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; +extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; +extern int num_backing_up, bol_needed; + +void *allocate_array PROTO((int, size_t)); +void *reallocate_array PROTO((void*, int, size_t)); + +void *flex_alloc PROTO((size_t)); +void *flex_realloc PROTO((void*, size_t)); +void flex_free PROTO((void*)); + +#define allocate_integer_array(size) \ + (int *) allocate_array( size, sizeof( int ) ) + +#define reallocate_integer_array(array,size) \ + (int *) reallocate_array( (void *) array, size, sizeof( int ) ) + +#define allocate_int_ptr_array(size) \ + (int **) allocate_array( size, sizeof( int * ) ) + +#define allocate_char_ptr_array(size) \ + (char **) allocate_array( size, sizeof( char * ) ) + +#define allocate_dfaacc_union(size) \ + (union dfaacc_union *) \ + allocate_array( size, sizeof( union dfaacc_union ) ) + +#define reallocate_int_ptr_array(array,size) \ + (int **) reallocate_array( (void *) array, size, sizeof( int * ) ) + +#define reallocate_char_ptr_array(array,size) \ + (char **) reallocate_array( (void *) array, size, sizeof( char * ) ) + +#define reallocate_dfaacc_union(array, size) \ + (union dfaacc_union *) \ + reallocate_array( (void *) array, size, sizeof( union dfaacc_union ) ) + +#define allocate_character_array(size) \ + (char *) allocate_array( size, sizeof( char ) ) + +#define reallocate_character_array(array,size) \ + (char *) reallocate_array( (void *) array, size, sizeof( char ) ) + +#define allocate_Character_array(size) \ + (Char *) allocate_array( size, sizeof( Char ) ) + +#define reallocate_Character_array(array,size) \ + (Char *) reallocate_array( (void *) array, size, sizeof( Char ) ) + + +/* Used to communicate between scanner and parser. The type should really + * be YYSTYPE, but we can't easily get our hands on it. + */ +extern int yylval; + + +/* External functions that are cross-referenced among the flex source files. */ + + +/* from file ccl.c */ + +extern void ccladd PROTO((int, int)); /* add a single character to a ccl */ +extern int cclinit PROTO((void)); /* make an empty ccl */ +extern void cclnegate PROTO((int)); /* negate a ccl */ + +/* List the members of a set of characters in CCL form. */ +extern void list_character_set PROTO((FILE*, int[])); + + +/* from file dfa.c */ + +/* Check a DFA state for backing up. */ +extern void check_for_backing_up PROTO((int, int[])); + +/* Check to see if NFA state set constitutes "dangerous" trailing context. */ +extern void check_trailing_context PROTO((int*, int, int*, int)); + +/* Construct the epsilon closure of a set of ndfa states. */ +extern int *epsclosure PROTO((int*, int*, int[], int*, int*)); + +/* Increase the maximum number of dfas. */ +extern void increase_max_dfas PROTO((void)); + +extern void ntod PROTO((void)); /* convert a ndfa to a dfa */ + +/* Converts a set of ndfa states into a dfa state. */ +extern int snstods PROTO((int[], int, int[], int, int, int*)); + + +/* from file ecs.c */ + +/* Convert character classes to set of equivalence classes. */ +extern void ccl2ecl PROTO((void)); + +/* Associate equivalence class numbers with class members. */ +extern int cre8ecs PROTO((int[], int[], int)); + +/* Update equivalence classes based on character class transitions. */ +extern void mkeccl PROTO((Char[], int, int[], int[], int, int)); + +/* Create equivalence class for single character. */ +extern void mkechar PROTO((int, int[], int[])); + + +/* from file gen.c */ + +extern void do_indent PROTO((void)); /* indent to the current level */ + +/* Generate the code to keep backing-up information. */ +extern void gen_backing_up PROTO((void)); + +/* Generate the code to perform the backing up. */ +extern void gen_bu_action PROTO((void)); + +/* Generate full speed compressed transition table. */ +extern void genctbl PROTO((void)); + +/* Generate the code to find the action number. */ +extern void gen_find_action PROTO((void)); + +extern void genftbl PROTO((void)); /* generate full transition table */ + +/* Generate the code to find the next compressed-table state. */ +extern void gen_next_compressed_state PROTO((char*)); + +/* Generate the code to find the next match. */ +extern void gen_next_match PROTO((void)); + +/* Generate the code to find the next state. */ +extern void gen_next_state PROTO((int)); + +/* Generate the code to make a NUL transition. */ +extern void gen_NUL_trans PROTO((void)); + +/* Generate the code to find the start state. */ +extern void gen_start_state PROTO((void)); + +/* Generate data statements for the transition tables. */ +extern void gentabs PROTO((void)); + +/* Write out a formatted string at the current indentation level. */ +extern void indent_put2s PROTO((char[], char[])); + +/* Write out a string + newline at the current indentation level. */ +extern void indent_puts PROTO((char[])); + +extern void make_tables PROTO((void)); /* generate transition tables */ + + +/* from file main.c */ + +extern void check_options PROTO((void)); +extern void flexend PROTO((int)); +extern void usage PROTO((void)); + + +/* from file misc.c */ + +/* Add a #define to the action file. */ +extern void action_define PROTO(( char *defname, int value )); + +/* Add the given text to the stored actions. */ +extern void add_action PROTO(( char *new_text )); + +/* True if a string is all lower case. */ +extern int all_lower PROTO((register char *)); + +/* True if a string is all upper case. */ +extern int all_upper PROTO((register char *)); + +/* Bubble sort an integer array. */ +extern void bubble PROTO((int [], int)); + +/* Check a character to make sure it's in the expected range. */ +extern void check_char PROTO((int c)); + +/* Replace upper-case letter to lower-case. */ +extern Char clower PROTO((int)); + +/* Returns a dynamically allocated copy of a string. */ +extern char *copy_string PROTO((register const char *)); + +/* Returns a dynamically allocated copy of a (potentially) unsigned string. */ +extern Char *copy_unsigned_string PROTO((register Char *)); + +/* Shell sort a character array. */ +extern void cshell PROTO((Char [], int, int)); + +/* Finish up a block of data declarations. */ +extern void dataend PROTO((void)); + +/* Flush generated data statements. */ +extern void dataflush PROTO((void)); + +/* Report an error message and terminate. */ +extern void flexerror PROTO((const char[])); + +/* Report a fatal error message and terminate. */ +extern void flexfatal PROTO((const char[])); + +/* Convert a hexadecimal digit string to an integer value. */ +extern int htoi PROTO((Char[])); + +/* Report an error message formatted with one integer argument. */ +extern void lerrif PROTO((const char[], int)); + +/* Report an error message formatted with one string argument. */ +extern void lerrsf PROTO((const char[], const char[])); + +/* Spit out a "#line" statement. */ +extern void line_directive_out PROTO((FILE*, int)); + +/* Mark the current position in the action array as the end of the section 1 + * user defs. + */ +extern void mark_defs1 PROTO((void)); + +/* Mark the current position in the action array as the end of the prolog. */ +extern void mark_prolog PROTO((void)); + +/* Generate a data statment for a two-dimensional array. */ +extern void mk2data PROTO((int)); + +extern void mkdata PROTO((int)); /* generate a data statement */ + +/* Return the integer represented by a string of digits. */ +extern int myctoi PROTO((char [])); + +/* Return character corresponding to escape sequence. */ +extern Char myesc PROTO((Char[])); + +/* Convert an octal digit string to an integer value. */ +extern int otoi PROTO((Char [] )); + +/* Output a (possibly-formatted) string to the generated scanner. */ +extern void out PROTO((const char [])); +extern void out_dec PROTO((const char [], int)); +extern void out_dec2 PROTO((const char [], int, int)); +extern void out_hex PROTO((const char [], unsigned int)); +extern void out_line_count PROTO((const char [])); +extern void out_str PROTO((const char [], const char [])); +extern void out_str3 + PROTO((const char [], const char [], const char [], const char [])); +extern void out_str_dec PROTO((const char [], const char [], int)); +extern void outc PROTO((int)); +extern void outn PROTO((const char [])); + +/* Return a printable version of the given character, which might be + * 8-bit. + */ +extern char *readable_form PROTO((int)); + +/* Write out one section of the skeleton file. */ +extern void skelout PROTO((void)); + +/* Output a yy_trans_info structure. */ +extern void transition_struct_out PROTO((int, int)); + +/* Only needed when using certain broken versions of bison to build parse.c. */ +extern void *yy_flex_xmalloc PROTO(( int )); + +/* Set a region of memory to 0. */ +extern void zero_out PROTO((char *, size_t)); + + +/* from file nfa.c */ + +/* Add an accepting state to a machine. */ +extern void add_accept PROTO((int, int)); + +/* Make a given number of copies of a singleton machine. */ +extern int copysingl PROTO((int, int)); + +/* Debugging routine to write out an nfa. */ +extern void dumpnfa PROTO((int)); + +/* Finish up the processing for a rule. */ +extern void finish_rule PROTO((int, int, int, int)); + +/* Connect two machines together. */ +extern int link_machines PROTO((int, int)); + +/* Mark each "beginning" state in a machine as being a "normal" (i.e., + * not trailing context associated) state. + */ +extern void mark_beginning_as_normal PROTO((register int)); + +/* Make a machine that branches to two machines. */ +extern int mkbranch PROTO((int, int)); + +extern int mkclos PROTO((int)); /* convert a machine into a closure */ +extern int mkopt PROTO((int)); /* make a machine optional */ + +/* Make a machine that matches either one of two machines. */ +extern int mkor PROTO((int, int)); + +/* Convert a machine into a positive closure. */ +extern int mkposcl PROTO((int)); + +extern int mkrep PROTO((int, int, int)); /* make a replicated machine */ + +/* Create a state with a transition on a given symbol. */ +extern int mkstate PROTO((int)); + +extern void new_rule PROTO((void)); /* initialize for a new rule */ + + +/* from file parse.y */ + +/* Build the "<>" action for the active start conditions. */ +extern void build_eof_action PROTO((void)); + +/* Write out a message formatted with one string, pinpointing its location. */ +extern void format_pinpoint_message PROTO((char[], char[])); + +/* Write out a message, pinpointing its location. */ +extern void pinpoint_message PROTO((char[])); + +/* Write out a warning, pinpointing it at the given line. */ +extern void line_warning PROTO(( char[], int )); + +/* Write out a message, pinpointing it at the given line. */ +extern void line_pinpoint PROTO(( char[], int )); + +/* Report a formatted syntax error. */ +extern void format_synerr PROTO((char [], char[])); +extern void synerr PROTO((char [])); /* report a syntax error */ +extern void format_warn PROTO((char [], char[])); +extern void warn PROTO((char [])); /* report a warning */ +extern void yyerror PROTO((char [])); /* report a parse error */ +extern int yyparse PROTO((void)); /* the YACC parser */ + + +/* from file scan.l */ + +/* The Flex-generated scanner for flex. */ +extern int flexscan PROTO((void)); + +/* Open the given file (if NULL, stdin) for scanning. */ +extern void set_input_file PROTO((char*)); + +/* Wrapup a file in the lexical analyzer. */ +extern int yywrap PROTO((void)); + + +/* from file sym.c */ + +/* Add symbol and definitions to symbol table. */ +extern int addsym PROTO((register char[], char*, int, hash_table, int)); + +/* Save the text of a character class. */ +extern void cclinstal PROTO ((Char [], int)); + +/* Lookup the number associated with character class. */ +extern int ccllookup PROTO((Char [])); + +/* Find symbol in symbol table. */ +extern struct hash_entry *findsym PROTO((register char[], hash_table, int )); + +extern void ndinstal PROTO((char[], Char[])); /* install a name definition */ +extern Char *ndlookup PROTO((char[])); /* lookup a name definition */ + +/* Increase maximum number of SC's. */ +extern void scextend PROTO((void)); +extern void scinstal PROTO((char[], int)); /* make a start condition */ + +/* Lookup the number associated with a start condition. */ +extern int sclookup PROTO((char[])); + + +/* from file tblcmp.c */ + +/* Build table entries for dfa state. */ +extern void bldtbl PROTO((int[], int, int, int, int)); + +extern void cmptmps PROTO((void)); /* compress template table entries */ +extern void expand_nxt_chk PROTO((void)); /* increase nxt/chk arrays */ +/* Finds a space in the table for a state to be placed. */ +extern int find_table_space PROTO((int*, int)); +extern void inittbl PROTO((void)); /* initialize transition tables */ +/* Make the default, "jam" table entries. */ +extern void mkdeftbl PROTO((void)); + +/* Create table entries for a state (or state fragment) which has + * only one out-transition. + */ +extern void mk1tbl PROTO((int, int, int, int)); + +/* Place a state into full speed transition table. */ +extern void place_state PROTO((int*, int, int)); + +/* Save states with only one out-transition to be processed later. */ +extern void stack1 PROTO((int, int, int, int)); + + +/* from file yylex.c */ + +extern int yylex PROTO((void)); diff --git a/commands/flex-2.5.4/gen.c b/commands/flex-2.5.4/gen.c new file mode 100644 index 000000000..545671e25 --- /dev/null +++ b/commands/flex-2.5.4/gen.c @@ -0,0 +1,1625 @@ +/* gen - actual generation (writing) of flex scanners */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + +#include "flexdef.h" + + +/* declare functions that have forward references */ + +void gen_next_state PROTO((int)); +void genecs PROTO((void)); +void indent_put2s PROTO((char [], char [])); +void indent_puts PROTO((char [])); + + +static int indent_level = 0; /* each level is 8 spaces */ + +#define indent_up() (++indent_level) +#define indent_down() (--indent_level) +#define set_indent(indent_val) indent_level = indent_val + +/* Almost everything is done in terms of arrays starting at 1, so provide + * a null entry for the zero element of all C arrays. (The exception + * to this is that the fast table representation generally uses the + * 0 elements of its arrays, too.) + */ +static char C_int_decl[] = "static yyconst int %s[%d] =\n { 0,\n"; +static char C_short_decl[] = "static yyconst short int %s[%d] =\n { 0,\n"; +static char C_long_decl[] = "static yyconst long int %s[%d] =\n { 0,\n"; +static char C_state_decl[] = + "static yyconst yy_state_type %s[%d] =\n { 0,\n"; + + +/* Indent to the current level. */ + +void do_indent() + { + register int i = indent_level * 8; + + while ( i >= 8 ) + { + outc( '\t' ); + i -= 8; + } + + while ( i > 0 ) + { + outc( ' ' ); + --i; + } + } + + +/* Generate the code to keep backing-up information. */ + +void gen_backing_up() + { + if ( reject || num_backing_up == 0 ) + return; + + if ( fullspd ) + indent_puts( "if ( yy_current_state[-1].yy_nxt )" ); + else + indent_puts( "if ( yy_accept[yy_current_state] )" ); + + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_last_accepting_state = yy_current_state;" ); + indent_puts( "yy_last_accepting_cpos = yy_cp;" ); + indent_puts( "}" ); + indent_down(); + } + + +/* Generate the code to perform the backing up. */ + +void gen_bu_action() + { + if ( reject || num_backing_up == 0 ) + return; + + set_indent( 3 ); + + indent_puts( "case 0: /* must back up */" ); + indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" ); + indent_puts( "*yy_cp = yy_hold_char;" ); + + if ( fullspd || fulltbl ) + indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" ); + else + /* Backing-up info for compressed tables is taken \after/ + * yy_cp has been incremented for the next state. + */ + indent_puts( "yy_cp = yy_last_accepting_cpos;" ); + + indent_puts( "yy_current_state = yy_last_accepting_state;" ); + indent_puts( "goto yy_find_action;" ); + outc( '\n' ); + + set_indent( 0 ); + } + + +/* genctbl - generates full speed compressed transition table */ + +void genctbl() + { + register int i; + int end_of_buffer_action = num_rules + 1; + + /* Table of verify for transition and offset to next state. */ + out_dec( "static yyconst struct yy_trans_info yy_transition[%d] =\n", + tblend + numecs + 1 ); + outn( " {" ); + + /* We want the transition to be represented as the offset to the + * next state, not the actual state number, which is what it currently + * is. The offset is base[nxt[i]] - (base of current state)]. That's + * just the difference between the starting points of the two involved + * states (to - from). + * + * First, though, we need to find some way to put in our end-of-buffer + * flags and states. We do this by making a state with absolutely no + * transitions. We put it at the end of the table. + */ + + /* We need to have room in nxt/chk for two more slots: One for the + * action and one for the end-of-buffer transition. We now *assume* + * that we're guaranteed the only character we'll try to index this + * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure + * there's room for jam entries for other characters. + */ + + while ( tblend + 2 >= current_max_xpairs ) + expand_nxt_chk(); + + while ( lastdfa + 1 >= current_max_dfas ) + increase_max_dfas(); + + base[lastdfa + 1] = tblend + 2; + nxt[tblend + 1] = end_of_buffer_action; + chk[tblend + 1] = numecs + 1; + chk[tblend + 2] = 1; /* anything but EOB */ + + /* So that "make test" won't show arb. differences. */ + nxt[tblend + 2] = 0; + + /* Make sure every state has an end-of-buffer transition and an + * action #. + */ + for ( i = 0; i <= lastdfa; ++i ) + { + int anum = dfaacc[i].dfaacc_state; + int offset = base[i]; + + chk[offset] = EOB_POSITION; + chk[offset - 1] = ACTION_POSITION; + nxt[offset - 1] = anum; /* action number */ + } + + for ( i = 0; i <= tblend; ++i ) + { + if ( chk[i] == EOB_POSITION ) + transition_struct_out( 0, base[lastdfa + 1] - i ); + + else if ( chk[i] == ACTION_POSITION ) + transition_struct_out( 0, nxt[i] ); + + else if ( chk[i] > numecs || chk[i] == 0 ) + transition_struct_out( 0, 0 ); /* unused slot */ + + else /* verify, transition */ + transition_struct_out( chk[i], + base[nxt[i]] - (i - chk[i]) ); + } + + + /* Here's the final, end-of-buffer state. */ + transition_struct_out( chk[tblend + 1], nxt[tblend + 1] ); + transition_struct_out( chk[tblend + 2], nxt[tblend + 2] ); + + outn( " };\n" ); + + /* Table of pointers to start states. */ + out_dec( + "static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", + lastsc * 2 + 1 ); + outn( " {" ); /* } so vi doesn't get confused */ + + for ( i = 0; i <= lastsc * 2; ++i ) + out_dec( " &yy_transition[%d],\n", base[i] ); + + dataend(); + + if ( useecs ) + genecs(); + } + + +/* Generate equivalence-class tables. */ + +void genecs() + { + register int i, j; + int numrows; + + out_str_dec( C_int_decl, "yy_ec", csize ); + + for ( i = 1; i < csize; ++i ) + { + if ( caseins && (i >= 'A') && (i <= 'Z') ) + ecgroup[i] = ecgroup[clower( i )]; + + ecgroup[i] = ABS( ecgroup[i] ); + mkdata( ecgroup[i] ); + } + + dataend(); + + if ( trace ) + { + fputs( _( "\n\nEquivalence Classes:\n\n" ), stderr ); + + numrows = csize / 8; + + for ( j = 0; j < numrows; ++j ) + { + for ( i = j; i < csize; i = i + numrows ) + { + fprintf( stderr, "%4s = %-2d", + readable_form( i ), ecgroup[i] ); + + putc( ' ', stderr ); + } + + putc( '\n', stderr ); + } + } + } + + +/* Generate the code to find the action number. */ + +void gen_find_action() + { + if ( fullspd ) + indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" ); + + else if ( fulltbl ) + indent_puts( "yy_act = yy_accept[yy_current_state];" ); + + else if ( reject ) + { + indent_puts( "yy_current_state = *--yy_state_ptr;" ); + indent_puts( "yy_lp = yy_accept[yy_current_state];" ); + + outn( + "find_rule: /* we branch to this label when backing up */" ); + + indent_puts( + "for ( ; ; ) /* until we find what rule we matched */" ); + + indent_up(); + + indent_puts( "{" ); + + indent_puts( + "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" ); + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_act = yy_acclist[yy_lp];" ); + + if ( variable_trailing_context_rules ) + { + indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" ); + indent_puts( " yy_looking_for_trail_begin )" ); + indent_up(); + indent_puts( "{" ); + + indent_puts( + "if ( yy_act == yy_looking_for_trail_begin )" ); + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_looking_for_trail_begin = 0;" ); + indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" ); + indent_puts( "break;" ); + indent_puts( "}" ); + indent_down(); + + indent_puts( "}" ); + indent_down(); + + indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" ); + indent_up(); + indent_puts( "{" ); + indent_puts( + "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" ); + indent_puts( + "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" ); + + if ( real_reject ) + { + /* Remember matched text in case we back up + * due to REJECT. + */ + indent_puts( "yy_full_match = yy_cp;" ); + indent_puts( "yy_full_state = yy_state_ptr;" ); + indent_puts( "yy_full_lp = yy_lp;" ); + } + + indent_puts( "}" ); + indent_down(); + + indent_puts( "else" ); + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_full_match = yy_cp;" ); + indent_puts( "yy_full_state = yy_state_ptr;" ); + indent_puts( "yy_full_lp = yy_lp;" ); + indent_puts( "break;" ); + indent_puts( "}" ); + indent_down(); + + indent_puts( "++yy_lp;" ); + indent_puts( "goto find_rule;" ); + } + + else + { + /* Remember matched text in case we back up due to + * trailing context plus REJECT. + */ + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_full_match = yy_cp;" ); + indent_puts( "break;" ); + indent_puts( "}" ); + indent_down(); + } + + indent_puts( "}" ); + indent_down(); + + indent_puts( "--yy_cp;" ); + + /* We could consolidate the following two lines with those at + * the beginning, but at the cost of complaints that we're + * branching inside a loop. + */ + indent_puts( "yy_current_state = *--yy_state_ptr;" ); + indent_puts( "yy_lp = yy_accept[yy_current_state];" ); + + indent_puts( "}" ); + + indent_down(); + } + + else + { /* compressed */ + indent_puts( "yy_act = yy_accept[yy_current_state];" ); + + if ( interactive && ! reject ) + { + /* Do the guaranteed-needed backing up to figure out + * the match. + */ + indent_puts( "if ( yy_act == 0 )" ); + indent_up(); + indent_puts( "{ /* have to back up */" ); + indent_puts( "yy_cp = yy_last_accepting_cpos;" ); + indent_puts( + "yy_current_state = yy_last_accepting_state;" ); + indent_puts( "yy_act = yy_accept[yy_current_state];" ); + indent_puts( "}" ); + indent_down(); + } + } + } + + +/* genftbl - generate full transition table */ + +void genftbl() + { + register int i; + int end_of_buffer_action = num_rules + 1; + + out_str_dec( long_align ? C_long_decl : C_short_decl, + "yy_accept", lastdfa + 1 ); + + dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; + + for ( i = 1; i <= lastdfa; ++i ) + { + register int anum = dfaacc[i].dfaacc_state; + + mkdata( anum ); + + if ( trace && anum ) + fprintf( stderr, _( "state # %d accepts: [%d]\n" ), + i, anum ); + } + + dataend(); + + if ( useecs ) + genecs(); + + /* Don't have to dump the actual full table entries - they were + * created on-the-fly. + */ + } + + +/* Generate the code to find the next compressed-table state. */ + +void gen_next_compressed_state( char_map ) +char *char_map; + { + indent_put2s( "register YY_CHAR yy_c = %s;", char_map ); + + /* Save the backing-up info \before/ computing the next state + * because we always compute one more state than needed - we + * always proceed until we reach a jam state + */ + gen_backing_up(); + + indent_puts( +"while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" ); + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_current_state = (int) yy_def[yy_current_state];" ); + + if ( usemecs ) + { + /* We've arrange it so that templates are never chained + * to one another. This means we can afford to make a + * very simple test to see if we need to convert to + * yy_c's meta-equivalence class without worrying + * about erroneously looking up the meta-equivalence + * class twice + */ + do_indent(); + + /* lastdfa + 2 is the beginning of the templates */ + out_dec( "if ( yy_current_state >= %d )\n", lastdfa + 2 ); + + indent_up(); + indent_puts( "yy_c = yy_meta[(unsigned int) yy_c];" ); + indent_down(); + } + + indent_puts( "}" ); + indent_down(); + + indent_puts( +"yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];" ); + } + + +/* Generate the code to find the next match. */ + +void gen_next_match() + { + /* NOTE - changes in here should be reflected in gen_next_state() and + * gen_NUL_trans(). + */ + char *char_map = useecs ? + "yy_ec[YY_SC_TO_UI(*yy_cp)]" : + "YY_SC_TO_UI(*yy_cp)"; + + char *char_map_2 = useecs ? + "yy_ec[YY_SC_TO_UI(*++yy_cp)]" : + "YY_SC_TO_UI(*++yy_cp)"; + + if ( fulltbl ) + { + indent_put2s( + "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )", + char_map ); + + indent_up(); + + if ( num_backing_up > 0 ) + { + indent_puts( "{" ); /* } for vi */ + gen_backing_up(); + outc( '\n' ); + } + + indent_puts( "++yy_cp;" ); + + if ( num_backing_up > 0 ) + /* { for vi */ + indent_puts( "}" ); + + indent_down(); + + outc( '\n' ); + indent_puts( "yy_current_state = -yy_current_state;" ); + } + + else if ( fullspd ) + { + indent_puts( "{" ); /* } for vi */ + indent_puts( + "register yyconst struct yy_trans_info *yy_trans_info;\n" ); + indent_puts( "register YY_CHAR yy_c;\n" ); + indent_put2s( "for ( yy_c = %s;", char_map ); + indent_puts( + " (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->" ); + indent_puts( "yy_verify == yy_c;" ); + indent_put2s( " yy_c = %s )", char_map_2 ); + + indent_up(); + + if ( num_backing_up > 0 ) + indent_puts( "{" ); /* } for vi */ + + indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); + + if ( num_backing_up > 0 ) + { + outc( '\n' ); + gen_backing_up(); /* { for vi */ + indent_puts( "}" ); + } + + indent_down(); /* { for vi */ + indent_puts( "}" ); + } + + else + { /* compressed */ + indent_puts( "do" ); + + indent_up(); + indent_puts( "{" ); /* } for vi */ + + gen_next_state( false ); + + indent_puts( "++yy_cp;" ); + + /* { for vi */ + indent_puts( "}" ); + indent_down(); + + do_indent(); + + if ( interactive ) + out_dec( "while ( yy_base[yy_current_state] != %d );\n", + jambase ); + else + out_dec( "while ( yy_current_state != %d );\n", + jamstate ); + + if ( ! reject && ! interactive ) + { + /* Do the guaranteed-needed backing up to figure out + * the match. + */ + indent_puts( "yy_cp = yy_last_accepting_cpos;" ); + indent_puts( + "yy_current_state = yy_last_accepting_state;" ); + } + } + } + + +/* Generate the code to find the next state. */ + +void gen_next_state( worry_about_NULs ) +int worry_about_NULs; + { /* NOTE - changes in here should be reflected in gen_next_match() */ + char char_map[256]; + + if ( worry_about_NULs && ! nultrans ) + { + if ( useecs ) + (void) sprintf( char_map, + "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)", + NUL_ec ); + else + (void) sprintf( char_map, + "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", NUL_ec ); + } + + else + strcpy( char_map, useecs ? + "yy_ec[YY_SC_TO_UI(*yy_cp)]" : "YY_SC_TO_UI(*yy_cp)" ); + + if ( worry_about_NULs && nultrans ) + { + if ( ! fulltbl && ! fullspd ) + /* Compressed tables back up *before* they match. */ + gen_backing_up(); + + indent_puts( "if ( *yy_cp )" ); + indent_up(); + indent_puts( "{" ); /* } for vi */ + } + + if ( fulltbl ) + indent_put2s( + "yy_current_state = yy_nxt[yy_current_state][%s];", + char_map ); + + else if ( fullspd ) + indent_put2s( + "yy_current_state += yy_current_state[%s].yy_nxt;", + char_map ); + + else + gen_next_compressed_state( char_map ); + + if ( worry_about_NULs && nultrans ) + { + /* { for vi */ + indent_puts( "}" ); + indent_down(); + indent_puts( "else" ); + indent_up(); + indent_puts( + "yy_current_state = yy_NUL_trans[yy_current_state];" ); + indent_down(); + } + + if ( fullspd || fulltbl ) + gen_backing_up(); + + if ( reject ) + indent_puts( "*yy_state_ptr++ = yy_current_state;" ); + } + + +/* Generate the code to make a NUL transition. */ + +void gen_NUL_trans() + { /* NOTE - changes in here should be reflected in gen_next_match() */ + /* Only generate a definition for "yy_cp" if we'll generate code + * that uses it. Otherwise lint and the like complain. + */ + int need_backing_up = (num_backing_up > 0 && ! reject); + + if ( need_backing_up && (! nultrans || fullspd || fulltbl) ) + /* We're going to need yy_cp lying around for the call + * below to gen_backing_up(). + */ + indent_puts( "register char *yy_cp = yy_c_buf_p;" ); + + outc( '\n' ); + + if ( nultrans ) + { + indent_puts( + "yy_current_state = yy_NUL_trans[yy_current_state];" ); + indent_puts( "yy_is_jam = (yy_current_state == 0);" ); + } + + else if ( fulltbl ) + { + do_indent(); + out_dec( "yy_current_state = yy_nxt[yy_current_state][%d];\n", + NUL_ec ); + indent_puts( "yy_is_jam = (yy_current_state <= 0);" ); + } + + else if ( fullspd ) + { + do_indent(); + out_dec( "register int yy_c = %d;\n", NUL_ec ); + + indent_puts( + "register yyconst struct yy_trans_info *yy_trans_info;\n" ); + indent_puts( + "yy_trans_info = &yy_current_state[(unsigned int) yy_c];" ); + indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); + + indent_puts( + "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" ); + } + + else + { + char NUL_ec_str[20]; + + (void) sprintf( NUL_ec_str, "%d", NUL_ec ); + gen_next_compressed_state( NUL_ec_str ); + + do_indent(); + out_dec( "yy_is_jam = (yy_current_state == %d);\n", jamstate ); + + if ( reject ) + { + /* Only stack this state if it's a transition we + * actually make. If we stack it on a jam, then + * the state stack and yy_c_buf_p get out of sync. + */ + indent_puts( "if ( ! yy_is_jam )" ); + indent_up(); + indent_puts( "*yy_state_ptr++ = yy_current_state;" ); + indent_down(); + } + } + + /* If we've entered an accepting state, back up; note that + * compressed tables have *already* done such backing up, so + * we needn't bother with it again. + */ + if ( need_backing_up && (fullspd || fulltbl) ) + { + outc( '\n' ); + indent_puts( "if ( ! yy_is_jam )" ); + indent_up(); + indent_puts( "{" ); + gen_backing_up(); + indent_puts( "}" ); + indent_down(); + } + } + + +/* Generate the code to find the start state. */ + +void gen_start_state() + { + if ( fullspd ) + { + if ( bol_needed ) + { + indent_puts( + "yy_current_state = yy_start_state_list[yy_start + YY_AT_BOL()];" ); + } + else + indent_puts( + "yy_current_state = yy_start_state_list[yy_start];" ); + } + + else + { + indent_puts( "yy_current_state = yy_start;" ); + + if ( bol_needed ) + indent_puts( "yy_current_state += YY_AT_BOL();" ); + + if ( reject ) + { + /* Set up for storing up states. */ + indent_puts( "yy_state_ptr = yy_state_buf;" ); + indent_puts( "*yy_state_ptr++ = yy_current_state;" ); + } + } + } + + +/* gentabs - generate data statements for the transition tables */ + +void gentabs() + { + int i, j, k, *accset, nacc, *acc_array, total_states; + int end_of_buffer_action = num_rules + 1; + + acc_array = allocate_integer_array( current_max_dfas ); + nummt = 0; + + /* The compressed table format jams by entering the "jam state", + * losing information about the previous state in the process. + * In order to recover the previous state, we effectively need + * to keep backing-up information. + */ + ++num_backing_up; + + if ( reject ) + { + /* Write out accepting list and pointer list. + * + * First we generate the "yy_acclist" array. In the process, + * we compute the indices that will go into the "yy_accept" + * array, and save the indices in the dfaacc array. + */ + int EOB_accepting_list[2]; + + /* Set up accepting structures for the End Of Buffer state. */ + EOB_accepting_list[0] = 0; + EOB_accepting_list[1] = end_of_buffer_action; + accsiz[end_of_buffer_state] = 1; + dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list; + + out_str_dec( long_align ? C_long_decl : C_short_decl, + "yy_acclist", MAX( numas, 1 ) + 1 ); + + j = 1; /* index into "yy_acclist" array */ + + for ( i = 1; i <= lastdfa; ++i ) + { + acc_array[i] = j; + + if ( accsiz[i] != 0 ) + { + accset = dfaacc[i].dfaacc_set; + nacc = accsiz[i]; + + if ( trace ) + fprintf( stderr, + _( "state # %d accepts: " ), + i ); + + for ( k = 1; k <= nacc; ++k ) + { + int accnum = accset[k]; + + ++j; + + if ( variable_trailing_context_rules && + ! (accnum & YY_TRAILING_HEAD_MASK) && + accnum > 0 && accnum <= num_rules && + rule_type[accnum] == RULE_VARIABLE ) + { + /* Special hack to flag + * accepting number as part + * of trailing context rule. + */ + accnum |= YY_TRAILING_MASK; + } + + mkdata( accnum ); + + if ( trace ) + { + fprintf( stderr, "[%d]", + accset[k] ); + + if ( k < nacc ) + fputs( ", ", stderr ); + else + putc( '\n', stderr ); + } + } + } + } + + /* add accepting number for the "jam" state */ + acc_array[i] = j; + + dataend(); + } + + else + { + dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; + + for ( i = 1; i <= lastdfa; ++i ) + acc_array[i] = dfaacc[i].dfaacc_state; + + /* add accepting number for jam state */ + acc_array[i] = 0; + } + + /* Spit out "yy_accept" array. If we're doing "reject", it'll be + * pointers into the "yy_acclist" array. Otherwise it's actual + * accepting numbers. In either case, we just dump the numbers. + */ + + /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays + * beginning at 0 and for "jam" state. + */ + k = lastdfa + 2; + + if ( reject ) + /* We put a "cap" on the table associating lists of accepting + * numbers with state numbers. This is needed because we tell + * where the end of an accepting list is by looking at where + * the list for the next state starts. + */ + ++k; + + out_str_dec( long_align ? C_long_decl : C_short_decl, "yy_accept", k ); + + for ( i = 1; i <= lastdfa; ++i ) + { + mkdata( acc_array[i] ); + + if ( ! reject && trace && acc_array[i] ) + fprintf( stderr, _( "state # %d accepts: [%d]\n" ), + i, acc_array[i] ); + } + + /* Add entry for "jam" state. */ + mkdata( acc_array[i] ); + + if ( reject ) + /* Add "cap" for the list. */ + mkdata( acc_array[i] ); + + dataend(); + + if ( useecs ) + genecs(); + + if ( usemecs ) + { + /* Write out meta-equivalence classes (used to index + * templates with). + */ + + if ( trace ) + fputs( _( "\n\nMeta-Equivalence Classes:\n" ), + stderr ); + + out_str_dec( C_int_decl, "yy_meta", numecs + 1 ); + + for ( i = 1; i <= numecs; ++i ) + { + if ( trace ) + fprintf( stderr, "%d = %d\n", + i, ABS( tecbck[i] ) ); + + mkdata( ABS( tecbck[i] ) ); + } + + dataend(); + } + + total_states = lastdfa + numtemps; + + out_str_dec( (tblend >= MAX_SHORT || long_align) ? + C_long_decl : C_short_decl, + "yy_base", total_states + 1 ); + + for ( i = 1; i <= lastdfa; ++i ) + { + register int d = def[i]; + + if ( base[i] == JAMSTATE ) + base[i] = jambase; + + if ( d == JAMSTATE ) + def[i] = jamstate; + + else if ( d < 0 ) + { + /* Template reference. */ + ++tmpuses; + def[i] = lastdfa - d + 1; + } + + mkdata( base[i] ); + } + + /* Generate jam state's base index. */ + mkdata( base[i] ); + + for ( ++i /* skip jam state */; i <= total_states; ++i ) + { + mkdata( base[i] ); + def[i] = jamstate; + } + + dataend(); + + out_str_dec( (total_states >= MAX_SHORT || long_align) ? + C_long_decl : C_short_decl, + "yy_def", total_states + 1 ); + + for ( i = 1; i <= total_states; ++i ) + mkdata( def[i] ); + + dataend(); + + out_str_dec( (total_states >= MAX_SHORT || long_align) ? + C_long_decl : C_short_decl, + "yy_nxt", tblend + 1 ); + + for ( i = 1; i <= tblend; ++i ) + { + /* Note, the order of the following test is important. + * If chk[i] is 0, then nxt[i] is undefined. + */ + if ( chk[i] == 0 || nxt[i] == 0 ) + nxt[i] = jamstate; /* new state is the JAM state */ + + mkdata( nxt[i] ); + } + + dataend(); + + out_str_dec( (total_states >= MAX_SHORT || long_align) ? + C_long_decl : C_short_decl, + "yy_chk", tblend + 1 ); + + for ( i = 1; i <= tblend; ++i ) + { + if ( chk[i] == 0 ) + ++nummt; + + mkdata( chk[i] ); + } + + dataend(); + } + + +/* Write out a formatted string (with a secondary string argument) at the + * current indentation level, adding a final newline. + */ + +void indent_put2s( fmt, arg ) +char fmt[], arg[]; + { + do_indent(); + out_str( fmt, arg ); + outn( "" ); + } + + +/* Write out a string at the current indentation level, adding a final + * newline. + */ + +void indent_puts( str ) +char str[]; + { + do_indent(); + outn( str ); + } + + +/* make_tables - generate transition tables and finishes generating output file + */ + +void make_tables() + { + register int i; + int did_eof_rule = false; + + skelout(); + + /* First, take care of YY_DO_BEFORE_ACTION depending on yymore + * being used. + */ + set_indent( 1 ); + + if ( yymore_used && ! yytext_is_array ) + { + indent_puts( "yytext_ptr -= yy_more_len; \\" ); + indent_puts( "yyleng = (int) (yy_cp - yytext_ptr); \\" ); + } + + else + indent_puts( "yyleng = (int) (yy_cp - yy_bp); \\" ); + + /* Now also deal with copying yytext_ptr to yytext if needed. */ + skelout(); + if ( yytext_is_array ) + { + if ( yymore_used ) + indent_puts( + "if ( yyleng + yy_more_offset >= YYLMAX ) \\" ); + else + indent_puts( "if ( yyleng >= YYLMAX ) \\" ); + + indent_up(); + indent_puts( + "YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\" ); + indent_down(); + + if ( yymore_used ) + { + indent_puts( +"yy_flex_strncpy( &yytext[yy_more_offset], yytext_ptr, yyleng + 1 ); \\" ); + indent_puts( "yyleng += yy_more_offset; \\" ); + indent_puts( + "yy_prev_more_offset = yy_more_offset; \\" ); + indent_puts( "yy_more_offset = 0; \\" ); + } + else + { + indent_puts( + "yy_flex_strncpy( yytext, yytext_ptr, yyleng + 1 ); \\" ); + } + } + + set_indent( 0 ); + + skelout(); + + + out_dec( "#define YY_NUM_RULES %d\n", num_rules ); + out_dec( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 ); + + if ( fullspd ) + { + /* Need to define the transet type as a size large + * enough to hold the biggest offset. + */ + int total_table_size = tblend + numecs + 1; + char *trans_offset_type = + (total_table_size >= MAX_SHORT || long_align) ? + "long" : "short"; + + set_indent( 0 ); + indent_puts( "struct yy_trans_info" ); + indent_up(); + indent_puts( "{" ); /* } for vi */ + + if ( long_align ) + indent_puts( "long yy_verify;" ); + else + indent_puts( "short yy_verify;" ); + + /* In cases where its sister yy_verify *is* a "yes, there is + * a transition", yy_nxt is the offset (in records) to the + * next state. In most cases where there is no transition, + * the value of yy_nxt is irrelevant. If yy_nxt is the -1th + * record of a state, though, then yy_nxt is the action number + * for that state. + */ + + indent_put2s( "%s yy_nxt;", trans_offset_type ); + indent_puts( "};" ); + indent_down(); + } + + if ( fullspd ) + genctbl(); + else if ( fulltbl ) + genftbl(); + else + gentabs(); + + /* Definitions for backing up. We don't need them if REJECT + * is being used because then we use an alternative backin-up + * technique instead. + */ + if ( num_backing_up > 0 && ! reject ) + { + if ( ! C_plus_plus ) + { + indent_puts( + "static yy_state_type yy_last_accepting_state;" ); + indent_puts( + "static char *yy_last_accepting_cpos;\n" ); + } + } + + if ( nultrans ) + { + out_str_dec( C_state_decl, "yy_NUL_trans", lastdfa + 1 ); + + for ( i = 1; i <= lastdfa; ++i ) + { + if ( fullspd ) + out_dec( " &yy_transition[%d],\n", base[i] ); + else + mkdata( nultrans[i] ); + } + + dataend(); + } + + if ( ddebug ) + { /* Spit out table mapping rules to line numbers. */ + if ( ! C_plus_plus ) + { + indent_puts( "extern int yy_flex_debug;" ); + indent_puts( "int yy_flex_debug = 1;\n" ); + } + + out_str_dec( long_align ? C_long_decl : C_short_decl, + "yy_rule_linenum", num_rules ); + for ( i = 1; i < num_rules; ++i ) + mkdata( rule_linenum[i] ); + dataend(); + } + + if ( reject ) + { + /* Declare state buffer variables. */ + if ( ! C_plus_plus ) + { + outn( + "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" ); + outn( "static char *yy_full_match;" ); + outn( "static int yy_lp;" ); + } + + if ( variable_trailing_context_rules ) + { + if ( ! C_plus_plus ) + { + outn( + "static int yy_looking_for_trail_begin = 0;" ); + outn( "static int yy_full_lp;" ); + outn( "static int *yy_full_state;" ); + } + + out_hex( "#define YY_TRAILING_MASK 0x%x\n", + (unsigned int) YY_TRAILING_MASK ); + out_hex( "#define YY_TRAILING_HEAD_MASK 0x%x\n", + (unsigned int) YY_TRAILING_HEAD_MASK ); + } + + outn( "#define REJECT \\" ); + outn( "{ \\" ); /* } for vi */ + outn( + "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" ); + outn( + "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" ); + + if ( variable_trailing_context_rules ) + { + outn( + "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" ); + outn( + "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" ); + outn( + "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" ); + } + + outn( "++yy_lp; \\" ); + outn( "goto find_rule; \\" ); + /* { for vi */ + outn( "}" ); + } + + else + { + outn( + "/* The intent behind this definition is that it'll catch" ); + outn( " * any uses of REJECT which flex missed." ); + outn( " */" ); + outn( "#define REJECT reject_used_but_not_detected" ); + } + + if ( yymore_used ) + { + if ( ! C_plus_plus ) + { + if ( yytext_is_array ) + { + indent_puts( "static int yy_more_offset = 0;" ); + indent_puts( + "static int yy_prev_more_offset = 0;" ); + } + else + { + indent_puts( "static int yy_more_flag = 0;" ); + indent_puts( "static int yy_more_len = 0;" ); + } + } + + if ( yytext_is_array ) + { + indent_puts( + "#define yymore() (yy_more_offset = yy_flex_strlen( yytext ))" ); + indent_puts( "#define YY_NEED_STRLEN" ); + indent_puts( "#define YY_MORE_ADJ 0" ); + indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET \\" ); + indent_up(); + indent_puts( "{ \\" ); + indent_puts( "yy_more_offset = yy_prev_more_offset; \\" ); + indent_puts( "yyleng -= yy_more_offset; \\" ); + indent_puts( "}" ); + indent_down(); + } + else + { + indent_puts( "#define yymore() (yy_more_flag = 1)" ); + indent_puts( "#define YY_MORE_ADJ yy_more_len" ); + indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET" ); + } + } + + else + { + indent_puts( "#define yymore() yymore_used_but_not_detected" ); + indent_puts( "#define YY_MORE_ADJ 0" ); + indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET" ); + } + + if ( ! C_plus_plus ) + { + if ( yytext_is_array ) + { + outn( "#ifndef YYLMAX" ); + outn( "#define YYLMAX 8192" ); + outn( "#endif\n" ); + outn( "char yytext[YYLMAX];" ); + outn( "char *yytext_ptr;" ); + } + + else + outn( "char *yytext;" ); + } + + out( &action_array[defs1_offset] ); + + line_directive_out( stdout, 0 ); + + skelout(); + + if ( ! C_plus_plus ) + { + if ( use_read ) + { + outn( +"\tif ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\" ); + outn( + "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" ); + } + + else + { + outn( + "\tif ( yy_current_buffer->yy_is_interactive ) \\" ); + outn( "\t\t{ \\" ); + outn( "\t\tint c = '*', n; \\" ); + outn( "\t\tfor ( n = 0; n < max_size && \\" ); + outn( "\t\t\t (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\" ); + outn( "\t\t\tbuf[n] = (char) c; \\" ); + outn( "\t\tif ( c == '\\n' ) \\" ); + outn( "\t\t\tbuf[n++] = (char) c; \\" ); + outn( "\t\tif ( c == EOF && ferror( yyin ) ) \\" ); + outn( + "\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\" ); + outn( "\t\tresult = n; \\" ); + outn( "\t\t} \\" ); + outn( + "\telse if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \\" ); + outn( "\t\t && ferror( yyin ) ) \\" ); + outn( + "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" ); + } + } + + skelout(); + + indent_puts( "#define YY_RULE_SETUP \\" ); + indent_up(); + if ( bol_needed ) + { + indent_puts( "if ( yyleng > 0 ) \\" ); + indent_up(); + indent_puts( "yy_current_buffer->yy_at_bol = \\" ); + indent_puts( "\t\t(yytext[yyleng - 1] == '\\n'); \\" ); + indent_down(); + } + indent_puts( "YY_USER_ACTION" ); + indent_down(); + + skelout(); + + /* Copy prolog to output file. */ + out( &action_array[prolog_offset] ); + + line_directive_out( stdout, 0 ); + + skelout(); + + set_indent( 2 ); + + if ( yymore_used && ! yytext_is_array ) + { + indent_puts( "yy_more_len = 0;" ); + indent_puts( "if ( yy_more_flag )" ); + indent_up(); + indent_puts( "{" ); + indent_puts( "yy_more_len = yy_c_buf_p - yytext_ptr;" ); + indent_puts( "yy_more_flag = 0;" ); + indent_puts( "}" ); + indent_down(); + } + + skelout(); + + gen_start_state(); + + /* Note, don't use any indentation. */ + outn( "yy_match:" ); + gen_next_match(); + + skelout(); + set_indent( 2 ); + gen_find_action(); + + skelout(); + if ( do_yylineno ) + { + indent_puts( "if ( yy_act != YY_END_OF_BUFFER )" ); + indent_up(); + indent_puts( "{" ); + indent_puts( "int yyl;" ); + indent_puts( "for ( yyl = 0; yyl < yyleng; ++yyl )" ); + indent_up(); + indent_puts( "if ( yytext[yyl] == '\\n' )" ); + indent_up(); + indent_puts( "++yylineno;" ); + indent_down(); + indent_down(); + indent_puts( "}" ); + indent_down(); + } + + skelout(); + if ( ddebug ) + { + indent_puts( "if ( yy_flex_debug )" ); + indent_up(); + + indent_puts( "{" ); + indent_puts( "if ( yy_act == 0 )" ); + indent_up(); + indent_puts( C_plus_plus ? + "cerr << \"--scanner backing up\\n\";" : + "fprintf( stderr, \"--scanner backing up\\n\" );" ); + indent_down(); + + do_indent(); + out_dec( "else if ( yy_act < %d )\n", num_rules ); + indent_up(); + + if ( C_plus_plus ) + { + indent_puts( + "cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<" ); + indent_puts( + " \"(\\\"\" << yytext << \"\\\")\\n\";" ); + } + else + { + indent_puts( + "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," ); + + indent_puts( + " yy_rule_linenum[yy_act], yytext );" ); + } + + indent_down(); + + do_indent(); + out_dec( "else if ( yy_act == %d )\n", num_rules ); + indent_up(); + + if ( C_plus_plus ) + { + indent_puts( +"cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";" ); + } + else + { + indent_puts( + "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," ); + indent_puts( " yytext );" ); + } + + indent_down(); + + do_indent(); + out_dec( "else if ( yy_act == %d )\n", num_rules + 1 ); + indent_up(); + + indent_puts( C_plus_plus ? + "cerr << \"--(end of buffer or a NUL)\\n\";" : + "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" ); + + indent_down(); + + do_indent(); + outn( "else" ); + indent_up(); + + if ( C_plus_plus ) + { + indent_puts( + "cerr << \"--EOF (start condition \" << YY_START << \")\\n\";" ); + } + else + { + indent_puts( + "fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );" ); + } + + indent_down(); + + indent_puts( "}" ); + indent_down(); + } + + /* Copy actions to output file. */ + skelout(); + indent_up(); + gen_bu_action(); + out( &action_array[action_offset] ); + + line_directive_out( stdout, 0 ); + + /* generate cases for any missing EOF rules */ + for ( i = 1; i <= lastsc; ++i ) + if ( ! sceof[i] ) + { + do_indent(); + out_str( "case YY_STATE_EOF(%s):\n", scname[i] ); + did_eof_rule = true; + } + + if ( did_eof_rule ) + { + indent_up(); + indent_puts( "yyterminate();" ); + indent_down(); + } + + + /* Generate code for handling NUL's, if needed. */ + + /* First, deal with backing up and setting up yy_cp if the scanner + * finds that it should JAM on the NUL. + */ + skelout(); + set_indent( 4 ); + + if ( fullspd || fulltbl ) + indent_puts( "yy_cp = yy_c_buf_p;" ); + + else + { /* compressed table */ + if ( ! reject && ! interactive ) + { + /* Do the guaranteed-needed backing up to figure + * out the match. + */ + indent_puts( "yy_cp = yy_last_accepting_cpos;" ); + indent_puts( + "yy_current_state = yy_last_accepting_state;" ); + } + + else + /* Still need to initialize yy_cp, though + * yy_current_state was set up by + * yy_get_previous_state(). + */ + indent_puts( "yy_cp = yy_c_buf_p;" ); + } + + + /* Generate code for yy_get_previous_state(). */ + set_indent( 1 ); + skelout(); + + gen_start_state(); + + set_indent( 2 ); + skelout(); + gen_next_state( true ); + + set_indent( 1 ); + skelout(); + gen_NUL_trans(); + + skelout(); + if ( do_yylineno ) + { /* update yylineno inside of unput() */ + indent_puts( "if ( c == '\\n' )" ); + indent_up(); + indent_puts( "--yylineno;" ); + indent_down(); + } + + skelout(); + /* Update BOL and yylineno inside of input(). */ + if ( bol_needed ) + { + indent_puts( "yy_current_buffer->yy_at_bol = (c == '\\n');" ); + if ( do_yylineno ) + { + indent_puts( "if ( yy_current_buffer->yy_at_bol )" ); + indent_up(); + indent_puts( "++yylineno;" ); + indent_down(); + } + } + + else if ( do_yylineno ) + { + indent_puts( "if ( c == '\\n' )" ); + indent_up(); + indent_puts( "++yylineno;" ); + indent_down(); + } + + skelout(); + + /* Copy remainder of input to output. */ + + line_directive_out( stdout, 1 ); + + if ( sectnum == 3 ) + (void) flexscan(); /* copy remainder of input to output */ + } diff --git a/commands/flex-2.5.4/initscan.c b/commands/flex-2.5.4/initscan.c new file mode 100644 index 000000000..381644dde --- /dev/null +++ b/commands/flex-2.5.4/initscan.c @@ -0,0 +1,3697 @@ +#line 2 "scan.c" +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header$ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 165 +#define YY_END_OF_BUFFER 166 +static yyconst short int yy_accept[769] = + { 0, + 0, 0, 0, 0, 87, 87, 163, 163, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 166, 164, + 7, 18, 164, 16, 1, 17, 164, 164, 164, 164, + 15, 108, 100, 101, 108, 93, 108, 107, 108, 108, + 108, 107, 99, 89, 108, 108, 91, 92, 87, 88, + 87, 86, 85, 86, 86, 163, 163, 28, 29, 28, + 28, 28, 28, 28, 28, 31, 30, 32, 31, 113, + 109, 110, 112, 114, 141, 142, 141, 139, 138, 140, + + 115, 117, 115, 116, 115, 120, 120, 120, 120, 122, + 124, 122, 122, 122, 122, 123, 151, 155, 151, 154, + 156, 156, 152, 152, 152, 149, 150, 164, 82, 164, + 21, 22, 21, 20, 157, 159, 157, 160, 161, 147, + 147, 148, 147, 147, 147, 147, 147, 147, 147, 81, + 34, 33, 81, 81, 81, 81, 35, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 26, 23, 26, 24, + 7, 18, 0, 16, 1, 17, 0, 0, 0, 14, + 8, 0, 0, 0, 0, 4, 5, 0, 2, 15, + + 100, 101, 0, 0, 0, 95, 0, 0, 105, 105, + 0, 162, 162, 162, 94, 0, 99, 89, 0, 0, + 0, 91, 92, 104, 90, 0, 87, 88, 86, 85, + 85, 83, 84, 163, 163, 28, 29, 28, 28, 28, + 28, 31, 30, 32, 111, 112, 142, 138, 117, 0, + 118, 119, 124, 121, 151, 155, 0, 153, 0, 144, + 152, 152, 152, 0, 82, 0, 21, 22, 21, 19, + 157, 159, 158, 147, 147, 147, 148, 143, 147, 147, + 147, 34, 33, 0, 80, 0, 0, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + + 81, 81, 81, 36, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 0, 25, 24, 0, 14, 8, + 0, 12, 0, 0, 0, 0, 0, 4, 5, 0, + 6, 0, 96, 0, 97, 0, 0, 105, 105, 0, + 105, 105, 105, 162, 162, 0, 106, 90, 98, 0, + 104, 0, 83, 84, 28, 28, 28, 27, 28, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 152, 152, 143, 143, 147, 147, 0, 0, 81, + 81, 81, 81, 81, 44, 81, 81, 81, 49, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + + 81, 81, 81, 81, 81, 81, 81, 81, 0, 81, + 81, 81, 81, 0, 0, 0, 12, 0, 0, 0, + 0, 0, 0, 4, 5, 0, 105, 105, 105, 105, + 105, 105, 162, 0, 0, 28, 28, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 152, 152, 147, 147, 37, 38, 81, 81, 81, 81, + 81, 81, 81, 81, 50, 51, 81, 81, 81, 55, + 81, 81, 81, 81, 81, 81, 60, 81, 81, 81, + 81, 81, 81, 67, 0, 0, 0, 81, 81, 81, + 81, 0, 13, 0, 0, 0, 0, 0, 0, 105, + + 105, 105, 105, 105, 105, 0, 0, 28, 28, 137, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 152, 152, 147, 147, 39, 81, 41, 81, + 43, 81, 81, 81, 47, 81, 52, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 62, 81, 81, 65, + 81, 0, 0, 0, 0, 81, 81, 81, 81, 3, + 0, 0, 0, 0, 105, 105, 105, 0, 0, 28, + 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 145, 146, 145, 146, 81, 42, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + + 81, 78, 61, 81, 64, 81, 0, 0, 0, 0, + 81, 81, 69, 70, 0, 10, 0, 11, 0, 103, + 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 81, 81, 81, 45, 81, 48, + 81, 81, 81, 81, 77, 81, 59, 63, 66, 0, + 0, 0, 0, 79, 81, 0, 102, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, + 81, 81, 46, 81, 81, 56, 81, 81, 0, 0, + 0, 0, 68, 0, 9, 0, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 0, 81, 81, + + 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, + 136, 81, 81, 81, 81, 54, 81, 81, 0, 0, + 0, 0, 0, 0, 81, 81, 81, 53, 81, 58, + 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, + 72, 0, 0, 0, 0, 73, 81, 81, 81, 81, + 71, 0, 75, 0, 81, 81, 81, 74, 76, 81, + 81, 81, 81, 81, 81, 57, 40, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 5, 6, 7, 8, 1, 9, 10, + 10, 11, 12, 13, 14, 10, 15, 16, 16, 16, + 16, 16, 16, 16, 17, 18, 19, 20, 1, 21, + 22, 23, 10, 1, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 47, + 26, 27, 28, 29, 30, 1, 31, 32, 33, 34, + + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 47, 56, 57, 58, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[59] = + { 0, + 1, 1, 2, 1, 3, 1, 1, 1, 4, 1, + 5, 6, 1, 7, 4, 8, 8, 8, 8, 1, + 1, 1, 1, 9, 10, 1, 11, 12, 1, 13, + 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 4, 1, 16 + } ; + +static yyconst short int yy_base[858] = + { 0, + 0, 58, 115, 172, 120, 129, 2712, 2711, 230, 2705, + 136, 141, 288, 0, 2683, 2682, 144, 151, 185, 191, + 178, 188, 344, 347, 375, 0, 125, 131, 147, 216, + 431, 434, 461, 0, 519, 0, 205, 349, 2710, 2716, + 353, 2716, 2706, 0, 360, 2716, 2705, 144, 570, 2696, + 0, 2716, 577, 2716, 2703, 2716, 438, 2716, 2684, 126, + 149, 427, 591, 2716, 2701, 141, 2682, 2716, 0, 2716, + 2699, 0, 2699, 2697, 155, 2696, 2716, 0, 2716, 2695, + 2716, 0, 2662, 2641, 2637, 0, 2692, 2716, 2690, 2716, + 2716, 2663, 0, 2716, 2716, 2716, 2688, 2716, 431, 2716, + + 2716, 2716, 2687, 2716, 567, 2716, 2669, 571, 164, 2716, + 2716, 2685, 0, 2667, 573, 2716, 0, 2716, 2683, 2716, + 573, 2674, 0, 2649, 2628, 2716, 2716, 222, 2716, 356, + 448, 2716, 450, 2667, 0, 2716, 2678, 2716, 0, 0, + 198, 2716, 2677, 2621, 2716, 2667, 0, 2642, 2621, 2716, + 2673, 2716, 2671, 2668, 2640, 2639, 2716, 544, 2639, 579, + 2634, 2635, 318, 0, 2623, 2631, 424, 562, 2614, 587, + 2629, 2613, 2618, 2626, 2629, 2604, 2716, 2716, 2653, 612, + 634, 2716, 2654, 0, 637, 2716, 2653, 600, 2616, 0, + 0, 641, 647, 651, 669, 0, 0, 453, 2716, 0, + + 672, 2716, 2651, 2597, 605, 2716, 2649, 2616, 620, 657, + 645, 2716, 662, 0, 2716, 2592, 688, 2716, 2646, 2592, + 2636, 2625, 2716, 0, 2716, 2610, 0, 2716, 0, 0, + 2642, 0, 0, 2640, 2716, 0, 2716, 0, 2602, 2598, + 745, 0, 2638, 2716, 2716, 0, 2716, 688, 2716, 773, + 2716, 2716, 2716, 2716, 0, 2716, 673, 2716, 0, 2716, + 0, 2599, 2595, 690, 2716, 698, 707, 2716, 709, 2716, + 0, 2716, 2716, 0, 596, 2579, 2716, 827, 0, 2596, + 2592, 2632, 2716, 2628, 2716, 2593, 2592, 0, 642, 2582, + 563, 2617, 2579, 620, 2578, 2577, 2583, 669, 2570, 2584, + + 2572, 0, 2569, 2716, 2570, 2571, 2579, 2582, 685, 125, + 2570, 2567, 2566, 688, 2608, 2716, 716, 2568, 0, 0, + 720, 2716, 2608, 884, 2562, 2559, 2569, 0, 0, 723, + 2716, 739, 2716, 805, 2716, 808, 2562, 787, 869, 876, + 930, 881, 973, 800, 0, 2548, 2716, 2716, 2716, 2570, + 0, 2559, 0, 0, 2568, 2557, 0, 2716, 0, 1009, + 2581, 678, 870, 871, 874, 879, 913, 992, 974, 1013, + 885, 2565, 2554, 0, 1067, 2563, 2552, 2546, 2545, 2557, + 2562, 2561, 2550, 2557, 0, 2554, 2537, 2556, 0, 2536, + 2543, 2533, 2548, 2568, 2537, 2549, 2544, 2542, 2541, 2532, + + 2539, 2540, 2538, 2539, 578, 2520, 2538, 2525, 860, 2526, + 2528, 2521, 2517, 2529, 817, 1044, 2716, 822, 1095, 914, + 2532, 2523, 2517, 0, 0, 2524, 1102, 1025, 1142, 2539, + 1028, 1163, 2716, 2513, 2521, 2523, 2507, 0, 2526, 1058, + 891, 1014, 1019, 894, 1038, 1080, 1072, 1086, 1083, 1081, + 2520, 2504, 2518, 2502, 2716, 2716, 2505, 2493, 2492, 2495, + 2507, 1148, 2507, 2492, 0, 0, 2492, 2493, 2507, 0, + 2525, 2490, 2498, 2522, 2485, 2495, 0, 2500, 2491, 2487, + 2479, 2479, 2483, 0, 875, 2494, 2481, 2494, 2480, 2475, + 2491, 2519, 2716, 920, 999, 2465, 2474, 2468, 2494, 2496, + + 1105, 1184, 1081, 902, 969, 2479, 2491, 2463, 2477, 2716, + 165, 1090, 1144, 1143, 1147, 1163, 1095, 1145, 1037, 1085, + 1150, 1173, 2461, 2475, 2459, 2473, 0, 2458, 0, 2460, + 0, 1165, 2454, 2469, 0, 2461, 0, 2471, 2410, 2414, + 2434, 2400, 2393, 2405, 2385, 2382, 0, 2383, 2335, 0, + 2335, 2330, 2326, 2309, 2278, 2259, 2269, 2268, 2256, 2297, + 1046, 2238, 2242, 2253, 1179, 1142, 1145, 2247, 2246, 0, + 0, 1191, 1192, 1172, 1201, 1202, 1204, 1205, 1206, 1207, + 1209, 1210, 1208, 0, 0, 0, 0, 2254, 0, 2221, + 2229, 2218, 2208, 2200, 2209, 2198, 2195, 2165, 2168, 2149, + + 2132, 0, 0, 2129, 0, 2139, 2143, 2134, 2124, 2137, + 2117, 2116, 0, 0, 1228, 2716, 1232, 2716, 2111, 2716, + 2117, 2716, 2115, 2114, 2108, 2107, 2106, 2103, 2102, 2098, + 2095, 2063, 2047, 1213, 2012, 1986, 1975, 0, 1954, 0, + 1947, 1950, 1941, 1945, 0, 1942, 0, 0, 0, 1938, + 1940, 1934, 1905, 0, 1872, 1234, 2716, 1888, 1882, 1881, + 1864, 1848, 1832, 1828, 1827, 1826, 1823, 1806, 1809, 1784, + 1787, 1772, 0, 1781, 1786, 0, 1766, 1767, 1759, 1744, + 1213, 1736, 0, 1236, 2716, 1245, 2716, 2716, 2716, 2716, + 2716, 2716, 2716, 2716, 2716, 2716, 2716, 1750, 1727, 1720, + + 1701, 1687, 1670, 1681, 1667, 1679, 1659, 689, 1658, 1671, + 2716, 1657, 1627, 1621, 1635, 0, 1603, 1596, 1595, 1608, + 1602, 1587, 1586, 1583, 1581, 1587, 1555, 0, 1547, 0, + 1527, 1507, 1520, 1503, 1483, 1482, 1485, 1443, 1440, 1228, + 2716, 1225, 1224, 1206, 1210, 2716, 1213, 1202, 1018, 948, + 2716, 945, 2716, 884, 780, 771, 779, 2716, 2716, 689, + 673, 581, 408, 318, 86, 0, 0, 2716, 1263, 1279, + 1295, 1311, 1327, 1343, 1359, 1375, 1391, 1407, 1423, 1439, + 1455, 1471, 1481, 1496, 1505, 1520, 1536, 1545, 1560, 1576, + 1592, 1608, 1624, 1634, 1649, 1659, 1674, 1690, 1706, 1718, + + 1728, 1743, 1759, 1775, 1791, 1807, 1817, 1832, 1843, 1236, + 1858, 1874, 1890, 1898, 1905, 1920, 1936, 1952, 1968, 1977, + 1985, 2001, 2017, 2033, 2049, 2065, 2081, 2097, 2113, 2123, + 2138, 2148, 2155, 2170, 2182, 2192, 2207, 2223, 2239, 2255, + 2265, 2280, 2291, 2306, 2322, 2338, 2354, 2364, 2373, 2388, + 2404, 2420, 2429, 2437, 2453, 2469, 2485 + } ; + +static yyconst short int yy_def[858] = + { 0, + 768, 768, 769, 769, 770, 771, 772, 772, 768, 9, + 773, 773, 768, 13, 774, 774, 775, 775, 776, 776, + 777, 777, 778, 778, 768, 25, 779, 779, 780, 780, + 781, 781, 768, 33, 768, 35, 782, 782, 768, 768, + 768, 768, 768, 783, 768, 768, 768, 768, 784, 768, + 785, 768, 768, 768, 768, 768, 768, 768, 768, 786, + 787, 788, 768, 768, 768, 768, 768, 768, 789, 768, + 789, 790, 791, 790, 790, 792, 768, 793, 768, 793, + 768, 794, 794, 794, 793, 795, 768, 768, 795, 768, + 768, 768, 796, 768, 768, 768, 768, 768, 768, 768, + + 768, 768, 768, 768, 787, 768, 768, 787, 797, 768, + 768, 768, 798, 768, 787, 768, 799, 768, 799, 768, + 800, 768, 801, 801, 801, 768, 768, 802, 768, 802, + 803, 768, 803, 768, 804, 768, 804, 768, 805, 806, + 806, 768, 806, 806, 768, 806, 807, 807, 807, 768, + 768, 768, 768, 808, 768, 768, 768, 809, 809, 809, + 809, 809, 809, 809, 809, 809, 809, 810, 809, 809, + 809, 809, 809, 809, 809, 809, 768, 768, 811, 768, + 768, 768, 768, 783, 768, 768, 768, 768, 768, 812, + 813, 768, 768, 768, 768, 814, 815, 816, 768, 785, + + 768, 768, 768, 768, 817, 768, 768, 768, 818, 818, + 819, 768, 768, 820, 768, 821, 768, 768, 768, 768, + 768, 768, 768, 822, 768, 768, 823, 768, 824, 825, + 825, 826, 827, 828, 768, 829, 768, 830, 830, 830, + 768, 831, 768, 768, 768, 832, 768, 768, 768, 833, + 768, 768, 768, 768, 834, 768, 835, 768, 835, 768, + 836, 836, 836, 837, 768, 837, 838, 768, 838, 768, + 839, 768, 768, 840, 840, 840, 768, 768, 841, 841, + 841, 768, 768, 842, 768, 768, 768, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + + 843, 843, 843, 768, 843, 843, 843, 843, 843, 843, + 843, 843, 843, 843, 844, 768, 768, 768, 845, 846, + 847, 768, 768, 768, 768, 768, 768, 848, 849, 850, + 768, 850, 768, 851, 768, 851, 768, 852, 852, 852, + 768, 852, 852, 768, 853, 854, 768, 768, 768, 768, + 855, 768, 826, 827, 830, 830, 241, 768, 241, 241, + 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, + 833, 836, 836, 278, 278, 841, 841, 768, 768, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + + 843, 843, 843, 843, 843, 843, 843, 843, 768, 843, + 843, 843, 843, 768, 847, 847, 768, 847, 847, 768, + 768, 768, 768, 848, 849, 768, 341, 852, 343, 341, + 852, 343, 768, 768, 768, 830, 830, 360, 768, 833, + 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, + 836, 836, 841, 841, 768, 768, 843, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + 843, 843, 843, 843, 768, 768, 768, 843, 843, 843, + 843, 768, 768, 847, 847, 768, 768, 768, 768, 427, + + 852, 343, 852, 852, 852, 768, 768, 830, 830, 768, + 833, 833, 833, 833, 833, 833, 833, 833, 833, 833, + 833, 833, 836, 836, 841, 841, 843, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + 843, 768, 768, 768, 768, 843, 843, 843, 843, 768, + 856, 768, 768, 768, 852, 852, 852, 768, 768, 830, + 830, 833, 833, 833, 833, 833, 833, 833, 833, 833, + 833, 833, 833, 836, 836, 841, 841, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + + 843, 843, 843, 843, 843, 843, 768, 768, 768, 768, + 843, 843, 843, 843, 856, 768, 856, 768, 768, 768, + 768, 768, 833, 833, 833, 833, 833, 833, 833, 833, + 833, 833, 833, 833, 843, 843, 843, 843, 843, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 768, + 768, 768, 768, 843, 843, 857, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 833, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 768, 768, + 768, 768, 843, 857, 768, 857, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 843, 843, + + 843, 843, 843, 843, 843, 768, 768, 768, 768, 768, + 768, 843, 843, 843, 843, 843, 843, 843, 768, 768, + 768, 768, 768, 768, 843, 843, 843, 843, 843, 843, + 768, 768, 768, 768, 768, 768, 843, 843, 843, 843, + 768, 768, 768, 768, 768, 768, 843, 843, 843, 843, + 768, 768, 768, 768, 843, 843, 843, 768, 768, 843, + 843, 843, 843, 843, 843, 843, 843, 0, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768 + } ; + +static yyconst short int yy_nxt[2775] = + { 0, + 40, 41, 42, 43, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 44, 44, 40, 40, 40, 40, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 40, 40, 40, 40, 45, + 46, 47, 40, 48, 40, 49, 40, 40, 40, 40, + 40, 40, 50, 40, 40, 40, 40, 40, 40, 40, + 40, 51, 51, 40, 40, 40, 40, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 40, 40, 40, 53, 54, 55, 56, + 767, 57, 70, 71, 58, 58, 58, 129, 130, 58, + 73, 70, 74, 129, 130, 59, 75, 87, 88, 89, + 60, 61, 87, 88, 89, 188, 96, 97, 224, 132, + 133, 210, 211, 96, 97, 404, 98, 134, 405, 99, + 99, 99, 99, 98, 213, 213, 99, 99, 99, 99, + 62, 58, 58, 63, 64, 65, 56, 252, 57, 66, + 40, 58, 58, 58, 439, 189, 58, 102, 103, 104, + 40, 252, 67, 102, 103, 104, 225, 60, 61, 275, + + 68, 100, 214, 107, 108, 276, 109, 178, 100, 179, + 232, 105, 233, 107, 108, 572, 109, 105, 132, 133, + 180, 180, 180, 180, 265, 266, 134, 62, 58, 58, + 78, 78, 79, 80, 78, 78, 78, 78, 78, 78, + 81, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 82, 82, 78, 78, 78, 78, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 83, 82, 82, + 82, 82, 82, 82, 84, 78, 78, 78, 90, 90, + 40, 90, 90, 90, 90, 90, 90, 90, 91, 90, + + 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 92, 93, 93, 90, 90, 90, 90, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 90, 90, 90, 111, 112, 296, 111, + 112, 178, 766, 179, 181, 182, 183, 113, 265, 266, + 113, 185, 186, 187, 180, 180, 180, 180, 297, 114, + 115, 116, 114, 115, 116, 117, 117, 118, 119, 120, + 117, 117, 117, 121, 117, 117, 117, 117, 117, 122, + 117, 117, 117, 117, 117, 117, 117, 117, 123, 123, + + 117, 117, 117, 117, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 124, 123, 123, 123, 123, 123, 123, 125, + 126, 117, 127, 136, 137, 138, 136, 137, 138, 206, + 206, 207, 215, 215, 215, 215, 248, 248, 248, 248, + 268, 269, 268, 269, 300, 331, 332, 139, 301, 765, + 139, 140, 141, 142, 143, 140, 140, 140, 144, 140, + 140, 145, 140, 140, 140, 146, 140, 140, 140, 140, + 140, 140, 140, 140, 147, 147, 140, 140, 140, 140, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + + 147, 147, 147, 147, 147, 147, 147, 147, 148, 147, + 147, 147, 147, 147, 147, 149, 140, 140, 140, 150, + 151, 152, 153, 154, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 155, 156, 150, 150, 150, + 157, 150, 150, 150, 150, 150, 150, 150, 150, 158, + 159, 160, 161, 162, 163, 164, 164, 165, 164, 164, + 166, 167, 168, 169, 170, 164, 171, 172, 164, 173, + 174, 175, 164, 176, 150, 150, 150, 191, 201, 202, + 203, 258, 213, 213, 204, 289, 213, 213, 213, 213, + 292, 290, 217, 218, 219, 383, 303, 275, 220, 259, + + 192, 188, 193, 276, 193, 221, 304, 335, 336, 293, + 193, 222, 384, 193, 194, 195, 480, 193, 196, 223, + 214, 306, 481, 197, 214, 198, 214, 317, 317, 317, + 317, 307, 764, 205, 308, 181, 182, 183, 185, 186, + 187, 189, 321, 322, 323, 339, 340, 205, 321, 322, + 323, 387, 321, 322, 323, 388, 324, 324, 324, 324, + 342, 342, 324, 324, 324, 324, 324, 324, 324, 324, + 321, 322, 323, 201, 202, 203, 341, 344, 344, 204, + 380, 258, 339, 340, 324, 324, 324, 324, 325, 217, + 218, 219, 265, 266, 381, 220, 326, 439, 343, 259, + + 265, 266, 221, 248, 248, 248, 248, 673, 222, 268, + 269, 268, 269, 327, 392, 402, 223, 409, 393, 440, + 410, 416, 417, 418, 403, 331, 332, 763, 205, 411, + 412, 317, 317, 317, 317, 419, 419, 419, 419, 721, + 413, 331, 332, 722, 205, 357, 357, 358, 359, 357, + 357, 357, 357, 357, 357, 360, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 360, 360, + 357, 357, 357, 357, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + + 357, 357, 357, 362, 363, 364, 365, 335, 336, 366, + 335, 336, 339, 340, 367, 212, 212, 762, 368, 493, + 494, 369, 761, 370, 417, 494, 371, 374, 374, 760, + 374, 374, 374, 374, 374, 374, 374, 375, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + 375, 375, 374, 374, 374, 374, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 374, 374, 374, 420, 322, 323, 427, 439, + 439, 428, 428, 439, 339, 340, 431, 431, 439, 324, + + 324, 324, 324, 338, 439, 485, 339, 340, 486, 487, + 439, 441, 443, 439, 442, 420, 322, 323, 450, 552, + 759, 513, 493, 494, 516, 553, 444, 339, 340, 429, + 338, 338, 439, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 430, 430, 339, 340, 445, 338, 338, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 430, 338, 338, 338, 432, 432, + 432, 432, 758, 439, 339, 340, 432, 757, 339, 340, + + 495, 417, 418, 432, 432, 432, 432, 432, 432, 360, + 360, 439, 438, 360, 360, 360, 360, 360, 360, 448, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 439, 439, 360, 360, 360, 360, 439, 446, + 501, 501, 447, 504, 504, 416, 417, 418, 616, 617, + 339, 340, 638, 339, 340, 515, 439, 439, 449, 419, + 419, 419, 419, 514, 360, 360, 360, 375, 375, 580, + 375, 375, 375, 375, 375, 375, 375, 439, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 517, 439, 375, 375, 375, 375, 495, 417, 418, 439, + + 439, 511, 439, 512, 439, 439, 339, 340, 209, 439, + 419, 419, 419, 419, 439, 519, 520, 581, 518, 522, + 566, 566, 375, 375, 375, 500, 500, 573, 521, 578, + 339, 340, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 502, 502, 502, + 502, 532, 439, 439, 439, 502, 439, 339, 340, 439, + 339, 340, 502, 502, 502, 502, 502, 502, 505, 505, + 505, 505, 439, 533, 582, 576, 505, 574, 579, 534, + 575, 439, 439, 505, 505, 505, 505, 505, 505, 567, + + 567, 567, 567, 590, 339, 340, 338, 567, 577, 583, + 439, 439, 625, 591, 567, 567, 567, 567, 567, 567, + 439, 439, 624, 439, 439, 439, 439, 439, 439, 439, + 616, 617, 439, 623, 616, 617, 685, 686, 685, 686, + 756, 628, 626, 632, 708, 755, 634, 685, 686, 302, + 302, 627, 629, 754, 753, 630, 631, 633, 752, 751, + 750, 709, 669, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 72, 72, 72, 72, 72, + + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 106, 106, 106, 106, 106, 106, 106, 106, 106, + + 106, 106, 106, 106, 106, 106, 106, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 184, 184, 184, + 184, 749, 748, 184, 184, 184, 190, 190, 190, 190, + + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 200, 200, 200, 200, 747, 746, 200, 200, 200, + 209, 745, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 212, 744, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 216, 216, 216, 743, 742, 216, 216, 216, + 227, 741, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 229, 740, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, + 229, 229, 230, 739, 230, 230, 230, 230, 230, 230, + + 230, 230, 230, 230, 230, 230, 230, 230, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 236, 738, 236, 236, 737, 236, + 236, 236, 736, 735, 236, 236, 734, 733, 732, 236, + 238, 238, 238, 238, 731, 730, 238, 238, 238, 242, + 729, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 246, 246, 246, 246, 728, + 727, 246, 246, 246, 251, 726, 251, 251, 251, 251, + 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, + 254, 725, 254, 254, 254, 254, 254, 254, 254, 254, + + 254, 724, 254, 254, 254, 254, 255, 723, 720, 719, + 255, 255, 255, 255, 718, 717, 255, 255, 257, 716, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 261, 261, 261, 261, 715, 714, + 261, 261, 261, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 267, + 267, 267, 267, 713, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 267, 267, 271, 712, 711, 271, 271, + 271, 271, 271, 271, 271, 710, 271, 271, 271, 271, + 271, 273, 707, 273, 273, 273, 273, 273, 273, 273, + + 273, 273, 273, 273, 273, 273, 273, 274, 706, 274, + 274, 705, 274, 274, 274, 704, 703, 274, 274, 702, + 701, 700, 274, 279, 279, 279, 279, 699, 698, 279, + 279, 279, 284, 697, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 288, 288, + 696, 288, 288, 695, 694, 693, 288, 288, 315, 692, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 319, 691, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 320, 690, 320, 320, 320, 320, 320, 320, 320, 320, + + 320, 320, 320, 320, 320, 320, 328, 328, 689, 688, + 328, 328, 328, 329, 329, 687, 683, 329, 329, 329, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 334, 338, 682, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 681, 338, 338, 338, 338, 209, 680, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 345, 345, 679, 678, 677, 676, + 345, 346, 346, 346, 346, 675, 674, 346, 346, 346, + + 346, 351, 673, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 227, 672, 227, + 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 229, 671, 229, 229, 229, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, 229, 230, + 670, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 353, 668, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, + 353, 354, 667, 354, 354, 354, 354, 354, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 234, 234, 234, + + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 236, 666, 236, 236, 665, 236, 236, + 236, 664, 663, 236, 236, 662, 661, 660, 236, 238, + 238, 238, 238, 659, 658, 238, 238, 238, 242, 657, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 246, 246, 246, 246, 656, 655, + 246, 246, 246, 361, 361, 654, 653, 652, 361, 361, + 255, 651, 650, 649, 255, 255, 255, 255, 648, 647, + 255, 255, 257, 646, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 261, 261, + + 261, 261, 645, 644, 261, 261, 261, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 267, 267, 267, 267, 643, 267, 267, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 271, + 642, 641, 271, 271, 271, 271, 271, 271, 271, 640, + 271, 271, 271, 271, 271, 274, 639, 274, 274, 638, + 274, 274, 274, 637, 636, 274, 274, 635, 622, 621, + 274, 279, 279, 279, 279, 620, 619, 279, 279, 279, + 284, 618, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 288, 288, 560, 288, + + 288, 614, 613, 612, 288, 288, 315, 611, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 319, 610, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 320, 609, + 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 415, 415, 415, 415, 415, 415, + 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, + 424, 424, 424, 424, 608, 607, 424, 424, 424, 425, + 425, 425, 425, 606, 605, 425, 425, 425, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + + 330, 330, 330, 330, 334, 334, 334, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 334, 334, 334, 334, + 338, 604, 338, 338, 338, 338, 338, 338, 338, 338, + 338, 603, 338, 338, 338, 338, 433, 433, 602, 601, + 600, 599, 433, 346, 346, 346, 346, 598, 597, 346, + 346, 346, 346, 351, 596, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 351, 615, + 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + + 684, 595, 594, 593, 592, 589, 588, 587, 586, 585, + 584, 571, 570, 569, 568, 565, 564, 563, 562, 561, + 560, 559, 558, 557, 556, 555, 554, 551, 550, 549, + 548, 547, 546, 545, 544, 543, 542, 541, 540, 539, + 538, 537, 536, 535, 531, 530, 529, 528, 527, 526, + 525, 524, 523, 510, 509, 508, 507, 506, 503, 499, + 498, 497, 496, 492, 491, 490, 489, 488, 484, 483, + 482, 479, 478, 477, 476, 475, 474, 473, 472, 471, + 470, 469, 468, 467, 466, 465, 464, 463, 462, 461, + 460, 459, 458, 457, 456, 455, 454, 453, 452, 451, + + 439, 437, 436, 435, 434, 347, 426, 423, 422, 421, + 322, 414, 316, 408, 407, 406, 401, 400, 399, 398, + 397, 396, 395, 394, 391, 390, 389, 386, 385, 382, + 379, 378, 285, 282, 377, 376, 278, 373, 372, 243, + 356, 355, 235, 231, 352, 350, 349, 348, 218, 347, + 337, 206, 333, 202, 318, 186, 182, 316, 314, 313, + 312, 311, 310, 309, 305, 299, 298, 295, 294, 291, + 287, 286, 285, 283, 282, 281, 280, 260, 278, 277, + 272, 270, 263, 262, 260, 256, 250, 253, 250, 249, + 247, 245, 244, 243, 241, 240, 239, 237, 235, 228, + + 231, 228, 226, 218, 208, 202, 199, 186, 182, 768, + 94, 94, 85, 77, 77, 39, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768 + } ; + +static yyconst short int yy_chk[2775] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, + 765, 3, 5, 5, 3, 3, 3, 27, 27, 3, + 6, 6, 6, 28, 28, 3, 6, 11, 11, 11, + 3, 3, 12, 12, 12, 48, 17, 17, 66, 29, + 29, 60, 60, 18, 18, 310, 17, 29, 310, 17, + 17, 17, 17, 18, 61, 61, 18, 18, 18, 18, + 3, 3, 3, 4, 4, 4, 4, 109, 4, 4, + 21, 4, 4, 4, 511, 48, 4, 19, 19, 19, + 22, 109, 4, 20, 20, 20, 66, 4, 4, 141, + + 4, 17, 61, 21, 21, 141, 21, 37, 18, 37, + 75, 19, 75, 22, 22, 511, 22, 20, 30, 30, + 37, 37, 37, 37, 128, 128, 30, 4, 4, 4, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 23, 23, 163, 24, + 24, 38, 764, 38, 41, 41, 41, 23, 130, 130, + 24, 45, 45, 45, 38, 38, 38, 38, 163, 23, + 23, 23, 24, 24, 24, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 31, 31, 31, 32, 32, 32, 57, + 57, 57, 62, 62, 62, 62, 99, 99, 99, 99, + 131, 131, 133, 133, 167, 198, 198, 31, 167, 763, + 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 49, 53, 53, + 53, 121, 105, 105, 53, 158, 108, 108, 115, 115, + 160, 158, 63, 63, 63, 291, 168, 275, 63, 121, + + 49, 188, 49, 275, 49, 63, 168, 205, 205, 160, + 49, 63, 291, 49, 49, 49, 405, 49, 49, 63, + 105, 170, 405, 49, 108, 49, 115, 180, 180, 180, + 180, 170, 762, 53, 170, 181, 181, 181, 185, 185, + 185, 188, 192, 192, 192, 209, 209, 63, 193, 193, + 193, 294, 194, 194, 194, 294, 192, 192, 192, 192, + 211, 211, 193, 193, 193, 193, 194, 194, 194, 194, + 195, 195, 195, 201, 201, 201, 210, 213, 213, 201, + 289, 257, 210, 210, 195, 195, 195, 195, 192, 217, + 217, 217, 264, 264, 289, 217, 194, 362, 211, 257, + + 266, 266, 217, 248, 248, 248, 248, 761, 217, 267, + 267, 269, 269, 195, 298, 309, 217, 314, 298, 362, + 314, 321, 321, 321, 309, 330, 330, 760, 201, 314, + 314, 317, 317, 317, 317, 321, 321, 321, 321, 708, + 314, 332, 332, 708, 217, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + + 241, 241, 241, 250, 250, 250, 250, 334, 334, 250, + 336, 336, 338, 338, 250, 344, 344, 757, 250, 415, + 415, 250, 756, 250, 418, 418, 250, 278, 278, 755, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 324, 324, 324, 339, 363, + 364, 340, 340, 365, 339, 339, 342, 342, 366, 324, + + 324, 324, 324, 340, 371, 409, 342, 342, 409, 409, + 441, 363, 365, 444, 364, 420, 420, 420, 371, 485, + 754, 441, 494, 494, 444, 485, 366, 504, 504, 340, + 341, 341, 367, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 367, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 343, 343, + 343, 343, 752, 369, 505, 505, 343, 750, 343, 343, + + 495, 495, 495, 343, 343, 343, 343, 343, 343, 360, + 360, 368, 360, 360, 360, 360, 360, 360, 360, 369, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 370, 442, 360, 360, 360, 360, 443, 368, + 428, 428, 368, 431, 431, 416, 416, 416, 561, 561, + 428, 428, 749, 431, 431, 443, 519, 445, 370, 416, + 416, 416, 416, 442, 360, 360, 360, 375, 375, 519, + 375, 375, 375, 375, 375, 375, 375, 440, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 445, 447, 375, 375, 375, 375, 419, 419, 419, 446, + + 450, 440, 449, 440, 520, 448, 503, 503, 503, 512, + 419, 419, 419, 419, 517, 447, 448, 520, 446, 450, + 501, 501, 375, 375, 375, 427, 427, 512, 449, 517, + 501, 501, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 429, 429, 429, + 429, 462, 514, 513, 518, 429, 515, 566, 566, 521, + 567, 567, 429, 429, 429, 429, 429, 429, 432, 432, + 432, 432, 516, 462, 521, 515, 432, 513, 518, 462, + 514, 574, 522, 432, 432, 432, 432, 432, 432, 502, + + 502, 502, 502, 532, 565, 565, 565, 502, 516, 522, + 572, 573, 574, 532, 502, 502, 502, 502, 502, 502, + 575, 576, 573, 577, 578, 579, 580, 583, 581, 582, + 615, 615, 634, 572, 617, 617, 656, 656, 684, 684, + 748, 577, 575, 581, 681, 747, 583, 686, 686, 810, + 810, 576, 578, 745, 744, 579, 580, 582, 743, 742, + 740, 681, 634, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 770, + 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, + 770, 770, 770, 770, 770, 771, 771, 771, 771, 771, + + 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, + 771, 772, 772, 772, 772, 772, 772, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 777, 777, 777, 777, 777, 777, 777, 777, 777, + + 777, 777, 777, 777, 777, 777, 777, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 779, 779, 779, 779, 779, 779, 779, + 779, 779, 779, 779, 779, 779, 779, 779, 779, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 781, 781, 781, 781, 781, + 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, + 781, 782, 782, 782, 782, 782, 782, 782, 782, 782, + 782, 782, 782, 782, 782, 782, 782, 783, 783, 783, + 783, 739, 738, 783, 783, 783, 784, 784, 784, 784, + + 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, + 784, 785, 785, 785, 785, 737, 736, 785, 785, 785, + 786, 735, 786, 786, 786, 786, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 787, 734, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 788, 788, 788, 733, 732, 788, 788, 788, + 789, 731, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 790, 729, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, + 790, 790, 791, 727, 791, 791, 791, 791, 791, 791, + + 791, 791, 791, 791, 791, 791, 791, 791, 792, 792, + 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, + 792, 792, 792, 792, 793, 726, 793, 793, 725, 793, + 793, 793, 724, 723, 793, 793, 722, 721, 720, 793, + 794, 794, 794, 794, 719, 718, 794, 794, 794, 795, + 717, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 796, 796, 796, 796, 715, + 714, 796, 796, 796, 797, 713, 797, 797, 797, 797, + 797, 797, 797, 797, 797, 797, 797, 797, 797, 797, + 798, 712, 798, 798, 798, 798, 798, 798, 798, 798, + + 798, 710, 798, 798, 798, 798, 799, 709, 707, 706, + 799, 799, 799, 799, 705, 704, 799, 799, 800, 703, + 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, + 800, 800, 800, 800, 801, 801, 801, 801, 702, 701, + 801, 801, 801, 802, 802, 802, 802, 802, 802, 802, + 802, 802, 802, 802, 802, 802, 802, 802, 802, 803, + 803, 803, 803, 700, 803, 803, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 804, 699, 698, 804, 804, + 804, 804, 804, 804, 804, 682, 804, 804, 804, 804, + 804, 805, 680, 805, 805, 805, 805, 805, 805, 805, + + 805, 805, 805, 805, 805, 805, 805, 806, 679, 806, + 806, 678, 806, 806, 806, 677, 675, 806, 806, 674, + 672, 671, 806, 807, 807, 807, 807, 670, 669, 807, + 807, 807, 808, 668, 808, 808, 808, 808, 808, 808, + 808, 808, 808, 808, 808, 808, 808, 808, 809, 809, + 667, 809, 809, 666, 665, 664, 809, 809, 811, 663, + 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, + 811, 811, 811, 811, 812, 662, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, 812, 812, + 813, 661, 813, 813, 813, 813, 813, 813, 813, 813, + + 813, 813, 813, 813, 813, 813, 814, 814, 660, 659, + 814, 814, 814, 815, 815, 658, 655, 815, 815, 815, + 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, 816, 816, 816, 817, 817, 817, 817, + 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, + 817, 817, 818, 653, 818, 818, 818, 818, 818, 818, + 818, 818, 818, 652, 818, 818, 818, 818, 819, 651, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 820, 820, 650, 646, 644, 643, + 820, 821, 821, 821, 821, 642, 641, 821, 821, 821, + + 821, 822, 639, 822, 822, 822, 822, 822, 822, 822, + 822, 822, 822, 822, 822, 822, 822, 823, 637, 823, + 823, 823, 823, 823, 823, 823, 823, 823, 823, 823, + 823, 823, 823, 824, 636, 824, 824, 824, 824, 824, + 824, 824, 824, 824, 824, 824, 824, 824, 824, 825, + 635, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, 825, 825, 826, 633, 826, 826, 826, + 826, 826, 826, 826, 826, 826, 826, 826, 826, 826, + 826, 827, 632, 827, 827, 827, 827, 827, 827, 827, + 827, 827, 827, 827, 827, 827, 827, 828, 828, 828, + + 828, 828, 828, 828, 828, 828, 828, 828, 828, 828, + 828, 828, 828, 829, 631, 829, 829, 630, 829, 829, + 829, 629, 628, 829, 829, 627, 626, 625, 829, 830, + 830, 830, 830, 624, 623, 830, 830, 830, 831, 621, + 831, 831, 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 832, 832, 832, 832, 619, 612, + 832, 832, 832, 833, 833, 611, 610, 609, 833, 833, + 834, 608, 607, 606, 834, 834, 834, 834, 604, 601, + 834, 834, 835, 600, 835, 835, 835, 835, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 836, 836, + + 836, 836, 599, 598, 836, 836, 836, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 838, 838, 838, 838, 597, 838, 838, + 838, 838, 838, 838, 838, 838, 838, 838, 838, 839, + 596, 595, 839, 839, 839, 839, 839, 839, 839, 594, + 839, 839, 839, 839, 839, 840, 593, 840, 840, 592, + 840, 840, 840, 591, 590, 840, 840, 588, 569, 568, + 840, 841, 841, 841, 841, 564, 563, 841, 841, 841, + 842, 562, 842, 842, 842, 842, 842, 842, 842, 842, + 842, 842, 842, 842, 842, 842, 843, 843, 560, 843, + + 843, 559, 558, 557, 843, 843, 844, 556, 844, 844, + 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, + 844, 844, 845, 555, 845, 845, 845, 845, 845, 845, + 845, 845, 845, 845, 845, 845, 845, 845, 846, 554, + 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, 847, 847, + 848, 848, 848, 848, 553, 552, 848, 848, 848, 849, + 849, 849, 849, 551, 549, 849, 849, 849, 850, 850, + 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, + + 850, 850, 850, 850, 851, 851, 851, 851, 851, 851, + 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, + 852, 548, 852, 852, 852, 852, 852, 852, 852, 852, + 852, 546, 852, 852, 852, 852, 853, 853, 545, 544, + 543, 542, 853, 854, 854, 854, 854, 541, 540, 854, + 854, 854, 854, 855, 539, 855, 855, 855, 855, 855, + 855, 855, 855, 855, 855, 855, 855, 855, 855, 856, + 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 857, 857, 857, 857, 857, + 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, + + 857, 538, 536, 534, 533, 530, 528, 526, 525, 524, + 523, 509, 508, 507, 506, 500, 499, 498, 497, 496, + 492, 491, 490, 489, 488, 487, 486, 483, 482, 481, + 480, 479, 478, 476, 475, 474, 473, 472, 471, 469, + 468, 467, 464, 463, 461, 460, 459, 458, 457, 454, + 453, 452, 451, 439, 437, 436, 435, 434, 430, 426, + 423, 422, 421, 414, 413, 412, 411, 410, 408, 407, + 406, 404, 403, 402, 401, 400, 399, 398, 397, 396, + 395, 394, 393, 392, 391, 390, 388, 387, 386, 384, + 383, 382, 381, 380, 379, 378, 377, 376, 373, 372, + + 361, 356, 355, 352, 350, 346, 337, 327, 326, 325, + 323, 318, 315, 313, 312, 311, 308, 307, 306, 305, + 303, 301, 300, 299, 297, 296, 295, 293, 292, 290, + 287, 286, 284, 282, 281, 280, 276, 263, 262, 243, + 240, 239, 234, 231, 226, 222, 221, 220, 219, 216, + 208, 207, 204, 203, 189, 187, 183, 179, 176, 175, + 174, 173, 172, 171, 169, 166, 165, 162, 161, 159, + 156, 155, 154, 153, 151, 149, 148, 146, 144, 143, + 137, 134, 125, 124, 122, 119, 114, 112, 107, 103, + 97, 92, 89, 87, 85, 84, 83, 80, 76, 74, + + 73, 71, 67, 65, 59, 55, 50, 47, 43, 39, + 16, 15, 10, 8, 7, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "scan.l" +#define INITIAL 0 +/* scan.l - scanner for flex input */ +#line 4 "scan.l" +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + +#include "flexdef.h" +#include "parse.h" + +#define ACTION_ECHO add_action( yytext ) +#define ACTION_IFDEF(def, should_define) \ + { \ + if ( should_define ) \ + action_define( def, 1 ); \ + } + +#define MARK_END_OF_PROLOG mark_prolog(); + +#define YY_DECL \ + int flexscan() + +#define RETURNCHAR \ + yylval = (unsigned char) yytext[0]; \ + return CHAR; + +#define RETURNNAME \ + strcpy( nmstr, yytext ); \ + return NAME; + +#define PUT_BACK_STRING(str, start) \ + for ( i = strlen( str ) - 1; i >= start; --i ) \ + unput((str)[i]) + +#define CHECK_REJECT(str) \ + if ( all_upper( str ) ) \ + reject = true; + +#define CHECK_YYMORE(str) \ + if ( all_lower( str ) ) \ + yymore_used = true; +#define YY_STACK_USED 1 +#define YY_NO_TOP_STATE 1 +#define SECT2 1 +#define SECT2PROLOG 2 +#define SECT3 3 +#define CODEBLOCK 4 +#define PICKUPDEF 5 +#define SC 6 +#define CARETISBOL 7 +#define NUM 8 +#define QUOTE 9 + +#define FIRSTCCL 10 +#define CCL 11 +#define ACTION 12 +#define RECOVER 13 +#define COMMENT 14 +#define ACTION_STRING 15 +#define PERCENT_BRACE_ACTION 16 + +#define OPTION 17 +#define LINEDIR 18 + +#line 1333 "scan.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + yy_current_buffer->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 94 "scan.l" + + static int bracelevel, didadef, indented_code; + static int doing_rule_action = false; + static int option_sense; + + int doing_codeblock = false; + int i; + Char nmdef[MAXLINE], myesc(); + + +#line 1498 "scan.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 769 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 2716 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + + +case 1: +YY_RULE_SETUP +#line 105 "scan.l" +indented_code = true; BEGIN(CODEBLOCK); + YY_BREAK +case 2: +YY_RULE_SETUP +#line 106 "scan.l" +ACTION_ECHO; yy_push_state( COMMENT ); + YY_BREAK +case 3: +YY_RULE_SETUP +#line 107 "scan.l" +yy_push_state( LINEDIR ); + YY_BREAK +case 4: +YY_RULE_SETUP +#line 108 "scan.l" +return SCDECL; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 109 "scan.l" +return XSCDECL; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 110 "scan.l" +{ + ++linenum; + line_directive_out( (FILE *) 0, 1 ); + indented_code = false; + BEGIN(CODEBLOCK); + } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 117 "scan.l" +/* discard */ + YY_BREAK +case 8: +YY_RULE_SETUP +#line 119 "scan.l" +{ + sectnum = 2; + bracelevel = 0; + mark_defs1(); + line_directive_out( (FILE *) 0, 1 ); + BEGIN(SECT2PROLOG); + return SECTEND; + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 128 "scan.l" +yytext_is_array = false; ++linenum; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 129 "scan.l" +yytext_is_array = true; ++linenum; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 131 "scan.l" +BEGIN(OPTION); return OPTION_OP; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 133 "scan.l" +++linenum; /* ignore */ + YY_BREAK +case 13: +YY_RULE_SETUP +#line 134 "scan.l" +++linenum; /* ignore */ + YY_BREAK +case 14: +YY_RULE_SETUP +#line 136 "scan.l" +synerr( _( "unrecognized '%' directive" ) ); + YY_BREAK +case 15: +YY_RULE_SETUP +#line 138 "scan.l" +{ + strcpy( nmstr, yytext ); + didadef = false; + BEGIN(PICKUPDEF); + } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 144 "scan.l" +RETURNNAME; + YY_BREAK +case 17: +YY_RULE_SETUP +#line 145 "scan.l" +++linenum; /* allows blank lines in section 1 */ + YY_BREAK +case 18: +YY_RULE_SETUP +#line 146 "scan.l" +ACTION_ECHO; ++linenum; /* maybe end of comment line */ + YY_BREAK + + +case 19: +YY_RULE_SETUP +#line 151 "scan.l" +ACTION_ECHO; yy_pop_state(); + YY_BREAK +case 20: +YY_RULE_SETUP +#line 152 "scan.l" +ACTION_ECHO; + YY_BREAK +case 21: +YY_RULE_SETUP +#line 153 "scan.l" +ACTION_ECHO; + YY_BREAK +case 22: +YY_RULE_SETUP +#line 154 "scan.l" +++linenum; ACTION_ECHO; + YY_BREAK + + +case 23: +YY_RULE_SETUP +#line 158 "scan.l" +yy_pop_state(); + YY_BREAK +case 24: +YY_RULE_SETUP +#line 159 "scan.l" +linenum = myctoi( yytext ); + YY_BREAK +case 25: +YY_RULE_SETUP +#line 161 "scan.l" +{ + flex_free( (void *) infilename ); + infilename = copy_string( yytext + 1 ); + infilename[strlen( infilename ) - 1] = '\0'; + } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 166 "scan.l" +/* ignore spurious characters */ + YY_BREAK + + +case 27: +YY_RULE_SETUP +#line 170 "scan.l" +++linenum; BEGIN(INITIAL); + YY_BREAK +case 28: +YY_RULE_SETUP +#line 172 "scan.l" +ACTION_ECHO; + YY_BREAK +case 29: +YY_RULE_SETUP +#line 174 "scan.l" +{ + ++linenum; + ACTION_ECHO; + if ( indented_code ) + BEGIN(INITIAL); + } + YY_BREAK + + +case 30: +YY_RULE_SETUP +#line 184 "scan.l" +/* separates name and definition */ + YY_BREAK +case 31: +YY_RULE_SETUP +#line 186 "scan.l" +{ + strcpy( (char *) nmdef, yytext ); + + /* Skip trailing whitespace. */ + for ( i = strlen( (char *) nmdef ) - 1; + i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t'); + --i ) + ; + + nmdef[i + 1] = '\0'; + + ndinstal( nmstr, nmdef ); + didadef = true; + } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 201 "scan.l" +{ + if ( ! didadef ) + synerr( _( "incomplete name definition" ) ); + BEGIN(INITIAL); + ++linenum; + } + YY_BREAK + + +case 33: +YY_RULE_SETUP +#line 211 "scan.l" +++linenum; BEGIN(INITIAL); + YY_BREAK +case 34: +YY_RULE_SETUP +#line 212 "scan.l" +option_sense = true; + YY_BREAK +case 35: +YY_RULE_SETUP +#line 214 "scan.l" +return '='; + YY_BREAK +case 36: +YY_RULE_SETUP +#line 216 "scan.l" +option_sense = ! option_sense; + YY_BREAK +case 37: +YY_RULE_SETUP +#line 218 "scan.l" +csize = option_sense ? 128 : 256; + YY_BREAK +case 38: +YY_RULE_SETUP +#line 219 "scan.l" +csize = option_sense ? 256 : 128; + YY_BREAK +case 39: +YY_RULE_SETUP +#line 221 "scan.l" +long_align = option_sense; + YY_BREAK +case 40: +YY_RULE_SETUP +#line 222 "scan.l" +{ + action_define( "YY_ALWAYS_INTERACTIVE", option_sense ); + } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 225 "scan.l" +yytext_is_array = option_sense; + YY_BREAK +case 42: +YY_RULE_SETUP +#line 226 "scan.l" +backing_up_report = option_sense; + YY_BREAK +case 43: +YY_RULE_SETUP +#line 227 "scan.l" +interactive = ! option_sense; + YY_BREAK +case 44: +YY_RULE_SETUP +#line 228 "scan.l" +C_plus_plus = option_sense; + YY_BREAK +case 45: +YY_RULE_SETUP +#line 229 "scan.l" +caseins = ! option_sense; + YY_BREAK +case 46: +YY_RULE_SETUP +#line 230 "scan.l" +caseins = option_sense; + YY_BREAK +case 47: +YY_RULE_SETUP +#line 231 "scan.l" +ddebug = option_sense; + YY_BREAK +case 48: +YY_RULE_SETUP +#line 232 "scan.l" +spprdflt = ! option_sense; + YY_BREAK +case 49: +YY_RULE_SETUP +#line 233 "scan.l" +useecs = option_sense; + YY_BREAK +case 50: +YY_RULE_SETUP +#line 234 "scan.l" +{ + useecs = usemecs = false; + use_read = fullspd = true; + } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 238 "scan.l" +{ + useecs = usemecs = false; + use_read = fulltbl = true; + } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 242 "scan.l" +ACTION_IFDEF("YY_NO_INPUT", ! option_sense); + YY_BREAK +case 53: +YY_RULE_SETUP +#line 243 "scan.l" +interactive = option_sense; + YY_BREAK +case 54: +YY_RULE_SETUP +#line 244 "scan.l" +lex_compat = option_sense; + YY_BREAK +case 55: +YY_RULE_SETUP +#line 245 "scan.l" +{ + action_define( "YY_MAIN", option_sense ); + do_yywrap = ! option_sense; + } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 249 "scan.l" +usemecs = option_sense; + YY_BREAK +case 57: +YY_RULE_SETUP +#line 250 "scan.l" +{ + action_define( "YY_NEVER_INTERACTIVE", option_sense ); + } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 253 "scan.l" +performance_report += option_sense ? 1 : -1; + YY_BREAK +case 59: +YY_RULE_SETUP +#line 254 "scan.l" +yytext_is_array = ! option_sense; + YY_BREAK +case 60: +YY_RULE_SETUP +#line 255 "scan.l" +use_read = option_sense; + YY_BREAK +case 61: +YY_RULE_SETUP +#line 256 "scan.l" +reject_really_used = option_sense; + YY_BREAK +case 62: +YY_RULE_SETUP +#line 257 "scan.l" +action_define( "YY_STACK_USED", option_sense ); + YY_BREAK +case 63: +YY_RULE_SETUP +#line 258 "scan.l" +do_stdinit = option_sense; + YY_BREAK +case 64: +YY_RULE_SETUP +#line 259 "scan.l" +use_stdout = option_sense; + YY_BREAK +case 65: +YY_RULE_SETUP +#line 260 "scan.l" +ACTION_IFDEF("YY_NO_UNPUT", ! option_sense); + YY_BREAK +case 66: +YY_RULE_SETUP +#line 261 "scan.l" +printstats = option_sense; + YY_BREAK +case 67: +YY_RULE_SETUP +#line 262 "scan.l" +nowarn = ! option_sense; + YY_BREAK +case 68: +YY_RULE_SETUP +#line 263 "scan.l" +do_yylineno = option_sense; + YY_BREAK +case 69: +YY_RULE_SETUP +#line 264 "scan.l" +yymore_really_used = option_sense; + YY_BREAK +case 70: +YY_RULE_SETUP +#line 265 "scan.l" +do_yywrap = option_sense; + YY_BREAK +case 71: +YY_RULE_SETUP +#line 267 "scan.l" +ACTION_IFDEF("YY_NO_PUSH_STATE", ! option_sense); + YY_BREAK +case 72: +YY_RULE_SETUP +#line 268 "scan.l" +ACTION_IFDEF("YY_NO_POP_STATE", ! option_sense); + YY_BREAK +case 73: +YY_RULE_SETUP +#line 269 "scan.l" +ACTION_IFDEF("YY_NO_TOP_STATE", ! option_sense); + YY_BREAK +case 74: +YY_RULE_SETUP +#line 271 "scan.l" +ACTION_IFDEF("YY_NO_SCAN_BUFFER", ! option_sense); + YY_BREAK +case 75: +YY_RULE_SETUP +#line 272 "scan.l" +ACTION_IFDEF("YY_NO_SCAN_BYTES", ! option_sense); + YY_BREAK +case 76: +YY_RULE_SETUP +#line 273 "scan.l" +ACTION_IFDEF("YY_NO_SCAN_STRING", ! option_sense); + YY_BREAK +case 77: +YY_RULE_SETUP +#line 275 "scan.l" +return OPT_OUTFILE; + YY_BREAK +case 78: +YY_RULE_SETUP +#line 276 "scan.l" +return OPT_PREFIX; + YY_BREAK +case 79: +YY_RULE_SETUP +#line 277 "scan.l" +return OPT_YYCLASS; + YY_BREAK +case 80: +YY_RULE_SETUP +#line 279 "scan.l" +{ + strcpy( nmstr, yytext + 1 ); + nmstr[strlen( nmstr ) - 1] = '\0'; + return NAME; + } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 285 "scan.l" +{ + format_synerr( _( "unrecognized %%option: %s" ), + yytext ); + BEGIN(RECOVER); + } + YY_BREAK + +case 82: +YY_RULE_SETUP +#line 292 "scan.l" +++linenum; BEGIN(INITIAL); + YY_BREAK + +case 83: +YY_RULE_SETUP +#line 296 "scan.l" +++bracelevel; yyless( 2 ); /* eat only %{ */ + YY_BREAK +case 84: +YY_RULE_SETUP +#line 297 "scan.l" +--bracelevel; yyless( 2 ); /* eat only %} */ + YY_BREAK +case 85: +YY_RULE_SETUP +#line 299 "scan.l" +ACTION_ECHO; /* indented code in prolog */ + YY_BREAK +case 86: +YY_RULE_SETUP +#line 301 "scan.l" +{ /* non-indented code */ + if ( bracelevel <= 0 ) + { /* not in %{ ... %} */ + yyless( 0 ); /* put it all back */ + yy_set_bol( 1 ); + mark_prolog(); + BEGIN(SECT2); + } + else + ACTION_ECHO; + } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 313 "scan.l" +ACTION_ECHO; + YY_BREAK +case 88: +YY_RULE_SETUP +#line 314 "scan.l" +++linenum; ACTION_ECHO; + YY_BREAK +case YY_STATE_EOF(SECT2PROLOG): +#line 316 "scan.l" +{ + mark_prolog(); + sectnum = 0; + yyterminate(); /* to stop the parser */ + } + YY_BREAK + + +case 89: +YY_RULE_SETUP +#line 324 "scan.l" +++linenum; /* allow blank lines in section 2 */ + YY_BREAK +case 90: +YY_RULE_SETUP +#line 326 "scan.l" +{ + indented_code = false; + doing_codeblock = true; + bracelevel = 1; + BEGIN(PERCENT_BRACE_ACTION); + } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 333 "scan.l" +BEGIN(SC); return '<'; + YY_BREAK +case 92: +YY_RULE_SETUP +#line 334 "scan.l" +return '^'; + YY_BREAK +case 93: +YY_RULE_SETUP +#line 335 "scan.l" +BEGIN(QUOTE); return '"'; + YY_BREAK +case 94: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 336 "scan.l" +BEGIN(NUM); return '{'; + YY_BREAK +case 95: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 337 "scan.l" +return '$'; + YY_BREAK +case 96: +YY_RULE_SETUP +#line 339 "scan.l" +{ + bracelevel = 1; + BEGIN(PERCENT_BRACE_ACTION); + + if ( in_rule ) + { + doing_rule_action = true; + in_rule = false; + return '\n'; + } + } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 350 "scan.l" +continued_action = true; ++linenum; return '\n'; + YY_BREAK +case 98: +YY_RULE_SETUP +#line 352 "scan.l" +{ + yyless( yyleng - 2 ); /* put back '/', '*' */ + bracelevel = 0; + continued_action = false; + BEGIN(ACTION); + } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 359 "scan.l" +/* allow indented rules */ + YY_BREAK +case 100: +YY_RULE_SETUP +#line 361 "scan.l" +{ + /* This rule is separate from the one below because + * otherwise we get variable trailing context, so + * we can't build the scanner using -{f,F}. + */ + bracelevel = 0; + continued_action = false; + BEGIN(ACTION); + + if ( in_rule ) + { + doing_rule_action = true; + in_rule = false; + return '\n'; + } + } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 378 "scan.l" +{ + bracelevel = 0; + continued_action = false; + BEGIN(ACTION); + unput( '\n' ); /* so sees it */ + + if ( in_rule ) + { + doing_rule_action = true; + in_rule = false; + return '\n'; + } + } + YY_BREAK +case 102: +#line 393 "scan.l" +case 103: +YY_RULE_SETUP +#line 393 "scan.l" +return EOF_OP; + YY_BREAK +case 104: +YY_RULE_SETUP +#line 395 "scan.l" +{ + sectnum = 3; + BEGIN(SECT3); + yyterminate(); /* to stop the parser */ + } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 401 "scan.l" +{ + int cclval; + + strcpy( nmstr, yytext ); + + /* Check to see if we've already encountered this + * ccl. + */ + if ( (cclval = ccllookup( (Char *) nmstr )) != 0 ) + { + if ( input() != ']' ) + synerr( _( "bad character class" ) ); + + yylval = cclval; + ++cclreuse; + return PREVCCL; + } + else + { + /* We fudge a bit. We know that this ccl will + * soon be numbered as lastccl + 1 by cclinit. + */ + cclinstal( (Char *) nmstr, lastccl + 1 ); + + /* Push back everything but the leading bracket + * so the ccl can be rescanned. + */ + yyless( 1 ); + + BEGIN(FIRSTCCL); + return '['; + } + } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 435 "scan.l" +{ + register Char *nmdefptr; + Char *ndlookup(); + + strcpy( nmstr, yytext + 1 ); + nmstr[yyleng - 2] = '\0'; /* chop trailing brace */ + + if ( (nmdefptr = ndlookup( nmstr )) == 0 ) + format_synerr( + _( "undefined definition {%s}" ), + nmstr ); + + else + { /* push back name surrounded by ()'s */ + int len = strlen( (char *) nmdefptr ); + + if ( lex_compat || nmdefptr[0] == '^' || + (len > 0 && nmdefptr[len - 1] == '$') ) + { /* don't use ()'s after all */ + PUT_BACK_STRING((char *) nmdefptr, 0); + + if ( nmdefptr[0] == '^' ) + BEGIN(CARETISBOL); + } + + else + { + unput(')'); + PUT_BACK_STRING((char *) nmdefptr, 0); + unput('('); + } + } + } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 469 "scan.l" +return (unsigned char) yytext[0]; + YY_BREAK +case 108: +YY_RULE_SETUP +#line 470 "scan.l" +RETURNCHAR; + YY_BREAK + + +case 109: +YY_RULE_SETUP +#line 475 "scan.l" +return (unsigned char) yytext[0]; + YY_BREAK +case 110: +YY_RULE_SETUP +#line 476 "scan.l" +BEGIN(SECT2); return '>'; + YY_BREAK +case 111: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 477 "scan.l" +BEGIN(CARETISBOL); return '>'; + YY_BREAK +case 112: +YY_RULE_SETUP +#line 478 "scan.l" +RETURNNAME; + YY_BREAK +case 113: +YY_RULE_SETUP +#line 479 "scan.l" +{ + format_synerr( _( "bad : %s" ), + yytext ); + } + YY_BREAK + +case 114: +YY_RULE_SETUP +#line 485 "scan.l" +BEGIN(SECT2); return '^'; + YY_BREAK + +case 115: +YY_RULE_SETUP +#line 489 "scan.l" +RETURNCHAR; + YY_BREAK +case 116: +YY_RULE_SETUP +#line 490 "scan.l" +BEGIN(SECT2); return '"'; + YY_BREAK +case 117: +YY_RULE_SETUP +#line 492 "scan.l" +{ + synerr( _( "missing quote" ) ); + BEGIN(SECT2); + ++linenum; + return '"'; + } + YY_BREAK + + +case 118: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 502 "scan.l" +BEGIN(CCL); return '^'; + YY_BREAK +case 119: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 503 "scan.l" +return '^'; + YY_BREAK +case 120: +YY_RULE_SETUP +#line 504 "scan.l" +BEGIN(CCL); RETURNCHAR; + YY_BREAK + + +case 121: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 508 "scan.l" +return '-'; + YY_BREAK +case 122: +YY_RULE_SETUP +#line 509 "scan.l" +RETURNCHAR; + YY_BREAK +case 123: +YY_RULE_SETUP +#line 510 "scan.l" +BEGIN(SECT2); return ']'; + YY_BREAK +case 124: +YY_RULE_SETUP +#line 511 "scan.l" +{ + synerr( _( "bad character class" ) ); + BEGIN(SECT2); + return ']'; + } + YY_BREAK + + +case 125: +YY_RULE_SETUP +#line 519 "scan.l" +BEGIN(CCL); return CCE_ALNUM; + YY_BREAK +case 126: +YY_RULE_SETUP +#line 520 "scan.l" +BEGIN(CCL); return CCE_ALPHA; + YY_BREAK +case 127: +YY_RULE_SETUP +#line 521 "scan.l" +BEGIN(CCL); return CCE_BLANK; + YY_BREAK +case 128: +YY_RULE_SETUP +#line 522 "scan.l" +BEGIN(CCL); return CCE_CNTRL; + YY_BREAK +case 129: +YY_RULE_SETUP +#line 523 "scan.l" +BEGIN(CCL); return CCE_DIGIT; + YY_BREAK +case 130: +YY_RULE_SETUP +#line 524 "scan.l" +BEGIN(CCL); return CCE_GRAPH; + YY_BREAK +case 131: +YY_RULE_SETUP +#line 525 "scan.l" +BEGIN(CCL); return CCE_LOWER; + YY_BREAK +case 132: +YY_RULE_SETUP +#line 526 "scan.l" +BEGIN(CCL); return CCE_PRINT; + YY_BREAK +case 133: +YY_RULE_SETUP +#line 527 "scan.l" +BEGIN(CCL); return CCE_PUNCT; + YY_BREAK +case 134: +YY_RULE_SETUP +#line 528 "scan.l" +BEGIN(CCL); return CCE_SPACE; + YY_BREAK +case 135: +YY_RULE_SETUP +#line 529 "scan.l" +BEGIN(CCL); return CCE_UPPER; + YY_BREAK +case 136: +YY_RULE_SETUP +#line 530 "scan.l" +BEGIN(CCL); return CCE_XDIGIT; + YY_BREAK +case 137: +YY_RULE_SETUP +#line 531 "scan.l" +{ + format_synerr( + _( "bad character class expression: %s" ), + yytext ); + BEGIN(CCL); return CCE_ALNUM; + } + YY_BREAK + + +case 138: +YY_RULE_SETUP +#line 540 "scan.l" +{ + yylval = myctoi( yytext ); + return NUMBER; + } + YY_BREAK +case 139: +YY_RULE_SETUP +#line 545 "scan.l" +return ','; + YY_BREAK +case 140: +YY_RULE_SETUP +#line 546 "scan.l" +BEGIN(SECT2); return '}'; + YY_BREAK +case 141: +YY_RULE_SETUP +#line 548 "scan.l" +{ + synerr( _( "bad character inside {}'s" ) ); + BEGIN(SECT2); + return '}'; + } + YY_BREAK +case 142: +YY_RULE_SETUP +#line 554 "scan.l" +{ + synerr( _( "missing }" ) ); + BEGIN(SECT2); + ++linenum; + return '}'; + } + YY_BREAK + + +case 143: +YY_RULE_SETUP +#line 564 "scan.l" +bracelevel = 0; + YY_BREAK +case 144: +YY_RULE_SETUP +#line 566 "scan.l" +ACTION_ECHO; yy_push_state( COMMENT ); + YY_BREAK + +case 145: +YY_RULE_SETUP +#line 569 "scan.l" +{ + ACTION_ECHO; + CHECK_REJECT(yytext); + } + YY_BREAK +case 146: +YY_RULE_SETUP +#line 573 "scan.l" +{ + ACTION_ECHO; + CHECK_YYMORE(yytext); + } + YY_BREAK + +case 147: +YY_RULE_SETUP +#line 579 "scan.l" +ACTION_ECHO; + YY_BREAK +case 148: +YY_RULE_SETUP +#line 580 "scan.l" +{ + ++linenum; + ACTION_ECHO; + if ( bracelevel == 0 || + (doing_codeblock && indented_code) ) + { + if ( doing_rule_action ) + add_action( "\tYY_BREAK\n" ); + + doing_rule_action = doing_codeblock = false; + BEGIN(SECT2); + } + } + YY_BREAK + +/* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ + +case 149: +YY_RULE_SETUP +#line 598 "scan.l" +ACTION_ECHO; ++bracelevel; + YY_BREAK +case 150: +YY_RULE_SETUP +#line 599 "scan.l" +ACTION_ECHO; --bracelevel; + YY_BREAK +case 151: +YY_RULE_SETUP +#line 600 "scan.l" +ACTION_ECHO; + YY_BREAK +case 152: +YY_RULE_SETUP +#line 601 "scan.l" +ACTION_ECHO; + YY_BREAK +case 153: +YY_RULE_SETUP +#line 602 "scan.l" +ACTION_ECHO; /* character constant */ + YY_BREAK +case 154: +YY_RULE_SETUP +#line 603 "scan.l" +ACTION_ECHO; BEGIN(ACTION_STRING); + YY_BREAK +case 155: +YY_RULE_SETUP +#line 604 "scan.l" +{ + ++linenum; + ACTION_ECHO; + if ( bracelevel == 0 ) + { + if ( doing_rule_action ) + add_action( "\tYY_BREAK\n" ); + + doing_rule_action = false; + BEGIN(SECT2); + } + } + YY_BREAK +case 156: +YY_RULE_SETUP +#line 616 "scan.l" +ACTION_ECHO; + YY_BREAK + + +case 157: +YY_RULE_SETUP +#line 620 "scan.l" +ACTION_ECHO; + YY_BREAK +case 158: +YY_RULE_SETUP +#line 621 "scan.l" +ACTION_ECHO; + YY_BREAK +case 159: +YY_RULE_SETUP +#line 622 "scan.l" +++linenum; ACTION_ECHO; + YY_BREAK +case 160: +YY_RULE_SETUP +#line 623 "scan.l" +ACTION_ECHO; BEGIN(ACTION); + YY_BREAK +case 161: +YY_RULE_SETUP +#line 624 "scan.l" +ACTION_ECHO; + YY_BREAK + +case YY_STATE_EOF(COMMENT): +case YY_STATE_EOF(ACTION): +case YY_STATE_EOF(ACTION_STRING): +#line 627 "scan.l" +{ + synerr( _( "EOF encountered inside an action" ) ); + yyterminate(); + } + YY_BREAK +case 162: +YY_RULE_SETUP +#line 633 "scan.l" +{ + yylval = myesc( (Char *) yytext ); + + if ( YY_START == FIRSTCCL ) + BEGIN(CCL); + + return CHAR; + } + YY_BREAK + +case 163: +YY_RULE_SETUP +#line 644 "scan.l" +ECHO; + YY_BREAK +case YY_STATE_EOF(SECT3): +#line 645 "scan.l" +sectnum = 0; yyterminate(); + YY_BREAK + +case 164: +YY_RULE_SETUP +#line 648 "scan.l" +format_synerr( _( "bad character: %s" ), yytext ); + YY_BREAK +case 165: +YY_RULE_SETUP +#line 650 "scan.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 2736 "scan.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(SECT2): +case YY_STATE_EOF(CODEBLOCK): +case YY_STATE_EOF(PICKUPDEF): +case YY_STATE_EOF(SC): +case YY_STATE_EOF(CARETISBOL): +case YY_STATE_EOF(NUM): +case YY_STATE_EOF(QUOTE): +case YY_STATE_EOF(FIRSTCCL): +case YY_STATE_EOF(CCL): +case YY_STATE_EOF(RECOVER): +case YY_STATE_EOF(PERCENT_BRACE_ACTION): +case YY_STATE_EOF(OPTION): +case YY_STATE_EOF(LINEDIR): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 769 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 769 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 768); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + yy_current_buffer->yy_at_bol = (c == '\n'); + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 650 "scan.l" + + + +int yywrap() + { + if ( --num_input_files > 0 ) + { + set_input_file( *++input_files ); + return 0; + } + + else + return 1; + } + + +/* set_input_file - open the given file (if NULL, stdin) for scanning */ + +void set_input_file( file ) +char *file; + { + if ( file && strcmp( file, "-" ) ) + { + infilename = copy_string( file ); + yyin = fopen( infilename, "r" ); + + if ( yyin == NULL ) + lerrsf( _( "can't open %s" ), file ); + } + + else + { + yyin = stdin; + infilename = copy_string( "" ); + } + + linenum = 1; + } + + +/* Wrapper routines for accessing the scanner's malloc routines. */ + +void *flex_alloc( size ) +size_t size; + { + return (void *) malloc( size ); + } + +void *flex_realloc( ptr, size ) +void *ptr; +size_t size; + { + return (void *) realloc( ptr, size ); + } + +void flex_free( ptr ) +void *ptr; + { + if ( ptr ) + free( ptr ); + } diff --git a/commands/flex-2.5.4/install.sh b/commands/flex-2.5.4/install.sh new file mode 100755 index 000000000..0ff4b6a08 --- /dev/null +++ b/commands/flex-2.5.4/install.sh @@ -0,0 +1,119 @@ +#!/bin/sh + +# +# install - install a program, script, or datafile +# This comes from X11R5; it is not part of GNU. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" + +instcmd="$mvprog" +chmodcmd="" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +fi + +if [ x"$dst" = x ] +then + echo "install: no destination specified" + exit 1 +fi + + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + +if [ -d $dst ] +then + dst="$dst"/`basename $src` +fi + +# Make a temp file name in the proper directory. + +dstdir=`dirname $dst` +dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + +$doit $instcmd $src $dsttmp + +# and set any options; do chmod last to preserve setuid bits + +if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi +if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi +if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi +if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi + +# Now rename the file to the real destination. + +$doit $rmcmd $dst +$doit $mvcmd $dsttmp $dst + + +exit 0 diff --git a/commands/flex-2.5.4/libmain.c b/commands/flex-2.5.4/libmain.c new file mode 100644 index 000000000..079e1eb6a --- /dev/null +++ b/commands/flex-2.5.4/libmain.c @@ -0,0 +1,15 @@ +/* libmain - flex run-time support library "main" function */ + +/* $Header$ */ + +extern int yylex(); + +int main( argc, argv ) +int argc; +char *argv[]; + { + while ( yylex() != 0 ) + ; + + return 0; + } diff --git a/commands/flex-2.5.4/libyywrap.c b/commands/flex-2.5.4/libyywrap.c new file mode 100644 index 000000000..aa2cb1376 --- /dev/null +++ b/commands/flex-2.5.4/libyywrap.c @@ -0,0 +1,8 @@ +/* libyywrap - flex run-time support library "yywrap" function */ + +/* $Header$ */ + +int yywrap() + { + return 1; + } diff --git a/commands/flex-2.5.4/main.c b/commands/flex-2.5.4/main.c new file mode 100644 index 000000000..23fd81799 --- /dev/null +++ b/commands/flex-2.5.4/main.c @@ -0,0 +1,1177 @@ +/* flex - tool to generate fast lexical analyzers */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1990 The Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +/* $Header$ */ + + +#include "flexdef.h" +#include "version.h" + +static char flex_version[] = FLEX_VERSION; + + +/* declare functions that have forward references */ + +void flexinit PROTO((int, char**)); +void readin PROTO((void)); +void set_up_initial_allocations PROTO((void)); + +#ifdef NEED_ARGV_FIXUP +extern void argv_fixup PROTO((int *, char ***)); +#endif + + +/* these globals are all defined and commented in flexdef.h */ +int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; +int interactive, caseins, lex_compat, do_yylineno, useecs, fulltbl, usemecs; +int fullspd, gen_line_dirs, performance_report, backing_up_report; +int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, csize; +int yymore_used, reject, real_reject, continued_action, in_rule; +int yymore_really_used, reject_really_used; +int datapos, dataline, linenum, out_linenum; +FILE *skelfile = NULL; +int skel_ind = 0; +char *action_array; +int action_size, defs1_offset, prolog_offset, action_offset, action_index; +char *infilename = NULL, *outfilename = NULL; +int did_outfilename; +char *prefix, *yyclass; +int do_stdinit, use_stdout; +int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; +int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; +int current_mns, current_max_rules; +int num_rules, num_eof_rules, default_rule, lastnfa; +int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; +int *accptnum, *assoc_rule, *state_type; +int *rule_type, *rule_linenum, *rule_useful; +int current_state_type; +int variable_trailing_context_rules; +int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; +int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; +int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1]; +int tecbck[CSIZE + 1]; +int lastsc, *scset, *scbol, *scxclu, *sceof; +int current_max_scs; +char **scname; +int current_max_dfa_size, current_max_xpairs; +int current_max_template_xpairs, current_max_dfas; +int lastdfa, *nxt, *chk, *tnxt; +int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; +union dfaacc_union *dfaacc; +int *accsiz, *dhash, numas; +int numsnpairs, jambase, jamstate; +int lastccl, *cclmap, *ccllen, *cclng, cclreuse; +int current_maxccls, current_max_ccl_tbl_size; +Char *ccltbl; +char nmstr[MAXLINE]; +int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; +int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; +int num_backing_up, bol_needed; +FILE *backing_up_file; +int end_of_buffer_state; +char **input_files; +int num_input_files; + +/* Make sure program_name is initialized so we don't crash if writing + * out an error message before getting the program name from argv[0]. + */ +char *program_name = "flex"; + +#ifndef SHORT_FILE_NAMES +static char *outfile_template = "lex.%s.%s"; +static char *backing_name = "lex.backup"; +#else +static char *outfile_template = "lex%s.%s"; +static char *backing_name = "lex.bck"; +#endif + +#ifdef THINK_C +#include +#endif + +#ifdef MS_DOS +extern unsigned _stklen = 16384; +#endif + +static char outfile_path[MAXLINE]; +static int outfile_created = 0; +static char *skelname = NULL; + + +int main( argc, argv ) +int argc; +char **argv; + { + int i; + +#ifdef THINK_C + argc = ccommand( &argv ); +#endif +#ifdef NEED_ARGV_FIXUP + argv_fixup( &argc, &argv ); +#endif + + flexinit( argc, argv ); + + readin(); + + ntod(); + + for ( i = 1; i <= num_rules; ++i ) + if ( ! rule_useful[i] && i != default_rule ) + line_warning( _( "rule cannot be matched" ), + rule_linenum[i] ); + + if ( spprdflt && ! reject && rule_useful[default_rule] ) + line_warning( + _( "-s option given but default rule can be matched" ), + rule_linenum[default_rule] ); + + /* Generate the C state transition tables from the DFA. */ + make_tables(); + + /* Note, flexend does not return. It exits with its argument + * as status. + */ + flexend( 0 ); + + return 0; /* keep compilers/lint happy */ + } + + +/* check_options - check user-specified options */ + +void check_options() + { + int i; + + if ( lex_compat ) + { + if ( C_plus_plus ) + flexerror( _( "Can't use -+ with -l option" ) ); + + if ( fulltbl || fullspd ) + flexerror( _( "Can't use -f or -F with -l option" ) ); + + /* Don't rely on detecting use of yymore() and REJECT, + * just assume they'll be used. + */ + yymore_really_used = reject_really_used = true; + + yytext_is_array = true; + do_yylineno = true; + use_read = false; + } + + if ( do_yylineno ) + /* This should really be "maintain_backup_tables = true" */ + reject_really_used = true; + + if ( csize == unspecified ) + { + if ( (fulltbl || fullspd) && ! useecs ) + csize = DEFAULT_CSIZE; + else + csize = CSIZE; + } + + if ( interactive == unspecified ) + { + if ( fulltbl || fullspd ) + interactive = false; + else + interactive = true; + } + + if ( fulltbl || fullspd ) + { + if ( usemecs ) + flexerror( + _( "-Cf/-CF and -Cm don't make sense together" ) ); + + if ( interactive ) + flexerror( _( "-Cf/-CF and -I are incompatible" ) ); + + if ( lex_compat ) + flexerror( + _( "-Cf/-CF are incompatible with lex-compatibility mode" ) ); + + if ( do_yylineno ) + flexerror( + _( "-Cf/-CF and %option yylineno are incompatible" ) ); + + if ( fulltbl && fullspd ) + flexerror( _( "-Cf and -CF are mutually exclusive" ) ); + } + + if ( C_plus_plus && fullspd ) + flexerror( _( "Can't use -+ with -CF option" ) ); + + if ( C_plus_plus && yytext_is_array ) + { + warn( _( "%array incompatible with -+ option" ) ); + yytext_is_array = false; + } + + if ( useecs ) + { /* Set up doubly-linked equivalence classes. */ + + /* We loop all the way up to csize, since ecgroup[csize] is + * the position used for NUL characters. + */ + ecgroup[1] = NIL; + + for ( i = 2; i <= csize; ++i ) + { + ecgroup[i] = i - 1; + nextecm[i - 1] = i; + } + + nextecm[csize] = NIL; + } + + else + { + /* Put everything in its own equivalence class. */ + for ( i = 1; i <= csize; ++i ) + { + ecgroup[i] = i; + nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ + } + } + + if ( ! use_stdout ) + { + FILE *prev_stdout; + + if ( ! did_outfilename ) + { + char *suffix; + + if ( C_plus_plus ) + suffix = "cc"; + else + suffix = "c"; + + sprintf( outfile_path, outfile_template, + prefix, suffix ); + + outfilename = outfile_path; + } + + prev_stdout = freopen( outfilename, "w", stdout ); + + if ( prev_stdout == NULL ) + lerrsf( _( "could not create %s" ), outfilename ); + + outfile_created = 1; + } + + if ( skelname && (skelfile = fopen( skelname, "r" )) == NULL ) + lerrsf( _( "can't open skeleton file %s" ), skelname ); + + if ( strcmp( prefix, "yy" ) ) + { +#define GEN_PREFIX(name) out_str3( "#define yy%s %s%s\n", name, prefix, name ) + if ( C_plus_plus ) + GEN_PREFIX( "FlexLexer" ); + else + { + GEN_PREFIX( "_create_buffer" ); + GEN_PREFIX( "_delete_buffer" ); + GEN_PREFIX( "_scan_buffer" ); + GEN_PREFIX( "_scan_string" ); + GEN_PREFIX( "_scan_bytes" ); + GEN_PREFIX( "_flex_debug" ); + GEN_PREFIX( "_init_buffer" ); + GEN_PREFIX( "_flush_buffer" ); + GEN_PREFIX( "_load_buffer_state" ); + GEN_PREFIX( "_switch_to_buffer" ); + GEN_PREFIX( "in" ); + GEN_PREFIX( "leng" ); + GEN_PREFIX( "lex" ); + GEN_PREFIX( "out" ); + GEN_PREFIX( "restart" ); + GEN_PREFIX( "text" ); + + if ( do_yylineno ) + GEN_PREFIX( "lineno" ); + } + + if ( do_yywrap ) + GEN_PREFIX( "wrap" ); + + outn( "" ); + } + + if ( did_outfilename ) + line_directive_out( stdout, 0 ); + + skelout(); + } + + +/* flexend - terminate flex + * + * note + * This routine does not return. + */ + +void flexend( exit_status ) +int exit_status; + + { + int tblsiz; + int unlink(); + + if ( skelfile != NULL ) + { + if ( ferror( skelfile ) ) + lerrsf( _( "input error reading skeleton file %s" ), + skelname ); + + else if ( fclose( skelfile ) ) + lerrsf( _( "error closing skeleton file %s" ), + skelname ); + } + + if ( exit_status != 0 && outfile_created ) + { + if ( ferror( stdout ) ) + lerrsf( _( "error writing output file %s" ), + outfilename ); + + else if ( fclose( stdout ) ) + lerrsf( _( "error closing output file %s" ), + outfilename ); + + else if ( unlink( outfilename ) ) + lerrsf( _( "error deleting output file %s" ), + outfilename ); + } + + if ( backing_up_report && backing_up_file ) + { + if ( num_backing_up == 0 ) + fprintf( backing_up_file, _( "No backing up.\n" ) ); + else if ( fullspd || fulltbl ) + fprintf( backing_up_file, + _( "%d backing up (non-accepting) states.\n" ), + num_backing_up ); + else + fprintf( backing_up_file, + _( "Compressed tables always back up.\n" ) ); + + if ( ferror( backing_up_file ) ) + lerrsf( _( "error writing backup file %s" ), + backing_name ); + + else if ( fclose( backing_up_file ) ) + lerrsf( _( "error closing backup file %s" ), + backing_name ); + } + + if ( printstats ) + { + fprintf( stderr, _( "%s version %s usage statistics:\n" ), + program_name, flex_version ); + + fprintf( stderr, _( " scanner options: -" ) ); + + if ( C_plus_plus ) + putc( '+', stderr ); + if ( backing_up_report ) + putc( 'b', stderr ); + if ( ddebug ) + putc( 'd', stderr ); + if ( caseins ) + putc( 'i', stderr ); + if ( lex_compat ) + putc( 'l', stderr ); + if ( performance_report > 0 ) + putc( 'p', stderr ); + if ( performance_report > 1 ) + putc( 'p', stderr ); + if ( spprdflt ) + putc( 's', stderr ); + if ( use_stdout ) + putc( 't', stderr ); + if ( printstats ) + putc( 'v', stderr ); /* always true! */ + if ( nowarn ) + putc( 'w', stderr ); + if ( interactive == false ) + putc( 'B', stderr ); + if ( interactive == true ) + putc( 'I', stderr ); + if ( ! gen_line_dirs ) + putc( 'L', stderr ); + if ( trace ) + putc( 'T', stderr ); + + if ( csize == unspecified ) + /* We encountered an error fairly early on, so csize + * never got specified. Define it now, to prevent + * bogus table sizes being written out below. + */ + csize = 256; + + if ( csize == 128 ) + putc( '7', stderr ); + else + putc( '8', stderr ); + + fprintf( stderr, " -C" ); + + if ( long_align ) + putc( 'a', stderr ); + if ( fulltbl ) + putc( 'f', stderr ); + if ( fullspd ) + putc( 'F', stderr ); + if ( useecs ) + putc( 'e', stderr ); + if ( usemecs ) + putc( 'm', stderr ); + if ( use_read ) + putc( 'r', stderr ); + + if ( did_outfilename ) + fprintf( stderr, " -o%s", outfilename ); + + if ( skelname ) + fprintf( stderr, " -S%s", skelname ); + + if ( strcmp( prefix, "yy" ) ) + fprintf( stderr, " -P%s", prefix ); + + putc( '\n', stderr ); + + fprintf( stderr, _( " %d/%d NFA states\n" ), + lastnfa, current_mns ); + fprintf( stderr, _( " %d/%d DFA states (%d words)\n" ), + lastdfa, current_max_dfas, totnst ); + fprintf( stderr, _( " %d rules\n" ), + num_rules + num_eof_rules - 1 /* - 1 for def. rule */ ); + + if ( num_backing_up == 0 ) + fprintf( stderr, _( " No backing up\n" ) ); + else if ( fullspd || fulltbl ) + fprintf( stderr, + _( " %d backing-up (non-accepting) states\n" ), + num_backing_up ); + else + fprintf( stderr, + _( " Compressed tables always back-up\n" ) ); + + if ( bol_needed ) + fprintf( stderr, + _( " Beginning-of-line patterns used\n" ) ); + + fprintf( stderr, _( " %d/%d start conditions\n" ), lastsc, + current_max_scs ); + fprintf( stderr, + _( " %d epsilon states, %d double epsilon states\n" ), + numeps, eps2 ); + + if ( lastccl == 0 ) + fprintf( stderr, _( " no character classes\n" ) ); + else + fprintf( stderr, +_( " %d/%d character classes needed %d/%d words of storage, %d reused\n" ), + lastccl, current_maxccls, + cclmap[lastccl] + ccllen[lastccl], + current_max_ccl_tbl_size, cclreuse ); + + fprintf( stderr, _( " %d state/nextstate pairs created\n" ), + numsnpairs ); + fprintf( stderr, _( " %d/%d unique/duplicate transitions\n" ), + numuniq, numdup ); + + if ( fulltbl ) + { + tblsiz = lastdfa * numecs; + fprintf( stderr, _( " %d table entries\n" ), tblsiz ); + } + + else + { + tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; + + fprintf( stderr, + _( " %d/%d base-def entries created\n" ), + lastdfa + numtemps, current_max_dfas ); + fprintf( stderr, + _( " %d/%d (peak %d) nxt-chk entries created\n" ), + tblend, current_max_xpairs, peakpairs ); + fprintf( stderr, + _( " %d/%d (peak %d) template nxt-chk entries created\n" ), + numtemps * nummecs, + current_max_template_xpairs, + numtemps * numecs ); + fprintf( stderr, _( " %d empty table entries\n" ), + nummt ); + fprintf( stderr, _( " %d protos created\n" ), + numprots ); + fprintf( stderr, + _( " %d templates created, %d uses\n" ), + numtemps, tmpuses ); + } + + if ( useecs ) + { + tblsiz = tblsiz + csize; + fprintf( stderr, + _( " %d/%d equivalence classes created\n" ), + numecs, csize ); + } + + if ( usemecs ) + { + tblsiz = tblsiz + numecs; + fprintf( stderr, + _( " %d/%d meta-equivalence classes created\n" ), + nummecs, csize ); + } + + fprintf( stderr, + _( " %d (%d saved) hash collisions, %d DFAs equal\n" ), + hshcol, hshsave, dfaeql ); + fprintf( stderr, _( " %d sets of reallocations needed\n" ), + num_reallocs ); + fprintf( stderr, _( " %d total table entries needed\n" ), + tblsiz ); + } + + exit( exit_status ); + } + + +/* flexinit - initialize flex */ + +void flexinit( argc, argv ) +int argc; +char **argv; + { + int i, sawcmpflag; + char *arg; + + printstats = syntaxerror = trace = spprdflt = caseins = false; + lex_compat = C_plus_plus = backing_up_report = ddebug = fulltbl = false; + fullspd = long_align = nowarn = yymore_used = continued_action = false; + do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = false; + yymore_really_used = reject_really_used = unspecified; + interactive = csize = unspecified; + do_yywrap = gen_line_dirs = usemecs = useecs = true; + performance_report = 0; + did_outfilename = 0; + prefix = "yy"; + yyclass = 0; + use_read = use_stdout = false; + + sawcmpflag = false; + + /* Initialize dynamic array for holding the rule actions. */ + action_size = 2048; /* default size of action array in bytes */ + action_array = allocate_character_array( action_size ); + defs1_offset = prolog_offset = action_offset = action_index = 0; + action_array[0] = '\0'; + + program_name = argv[0]; + + if ( program_name[0] != '\0' && + program_name[strlen( program_name ) - 1] == '+' ) + C_plus_plus = true; + + /* read flags */ + for ( --argc, ++argv; argc ; --argc, ++argv ) + { + arg = argv[0]; + + if ( arg[0] != '-' || arg[1] == '\0' ) + break; + + if ( arg[1] == '-' ) + { /* --option */ + if ( ! strcmp( arg, "--help" ) ) + arg = "-h"; + + else if ( ! strcmp( arg, "--version" ) ) + arg = "-V"; + + else if ( ! strcmp( arg, "--" ) ) + { /* end of options */ + --argc; + ++argv; + break; + } + } + + for ( i = 1; arg[i] != '\0'; ++i ) + switch ( arg[i] ) + { + case '+': + C_plus_plus = true; + break; + + case 'B': + interactive = false; + break; + + case 'b': + backing_up_report = true; + break; + + case 'c': + break; + + case 'C': + if ( i != 1 ) + flexerror( + _( "-C flag must be given separately" ) ); + + if ( ! sawcmpflag ) + { + useecs = false; + usemecs = false; + fulltbl = false; + sawcmpflag = true; + } + + for ( ++i; arg[i] != '\0'; ++i ) + switch ( arg[i] ) + { + case 'a': + long_align = + true; + break; + + case 'e': + useecs = true; + break; + + case 'F': + fullspd = true; + break; + + case 'f': + fulltbl = true; + break; + + case 'm': + usemecs = true; + break; + + case 'r': + use_read = true; + break; + + default: + lerrif( + _( "unknown -C option '%c'" ), + (int) arg[i] ); + break; + } + + goto get_next_arg; + + case 'd': + ddebug = true; + break; + + case 'f': + useecs = usemecs = false; + use_read = fulltbl = true; + break; + + case 'F': + useecs = usemecs = false; + use_read = fullspd = true; + break; + + case '?': + case 'h': + usage(); + exit( 0 ); + + case 'I': + interactive = true; + break; + + case 'i': + caseins = true; + break; + + case 'l': + lex_compat = true; + break; + + case 'L': + gen_line_dirs = false; + break; + + case 'n': + /* Stupid do-nothing deprecated + * option. + */ + break; + + case 'o': + if ( i != 1 ) + flexerror( + _( "-o flag must be given separately" ) ); + + outfilename = arg + i + 1; + did_outfilename = 1; + goto get_next_arg; + + case 'P': + if ( i != 1 ) + flexerror( + _( "-P flag must be given separately" ) ); + + prefix = arg + i + 1; + goto get_next_arg; + + case 'p': + ++performance_report; + break; + + case 'S': + if ( i != 1 ) + flexerror( + _( "-S flag must be given separately" ) ); + + skelname = arg + i + 1; + goto get_next_arg; + + case 's': + spprdflt = true; + break; + + case 't': + use_stdout = true; + break; + + case 'T': + trace = true; + break; + + case 'v': + printstats = true; + break; + + case 'V': + printf( _( "%s version %s\n" ), + program_name, flex_version ); + exit( 0 ); + + case 'w': + nowarn = true; + break; + + case '7': + csize = 128; + break; + + case '8': + csize = CSIZE; + break; + + default: + fprintf( stderr, + _( "%s: unknown flag '%c'. For usage, try\n\t%s --help\n" ), + program_name, (int) arg[i], + program_name ); + exit( 1 ); + } + + /* Used by -C, -S, -o, and -P flags in lieu of a "continue 2" + * control. + */ + get_next_arg: ; + } + + num_input_files = argc; + input_files = argv; + set_input_file( num_input_files > 0 ? input_files[0] : NULL ); + + lastccl = lastsc = lastdfa = lastnfa = 0; + num_rules = num_eof_rules = default_rule = 0; + numas = numsnpairs = tmpuses = 0; + numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0; + numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; + num_backing_up = onesp = numprots = 0; + variable_trailing_context_rules = bol_needed = false; + + out_linenum = linenum = sectnum = 1; + firstprot = NIL; + + /* Used in mkprot() so that the first proto goes in slot 1 + * of the proto queue. + */ + lastprot = 1; + + set_up_initial_allocations(); + } + + +/* readin - read in the rules section of the input file(s) */ + +void readin() + { + static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;"; + static char yy_nostdinit[] = + "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;"; + + line_directive_out( (FILE *) 0, 1 ); + + if ( yyparse() ) + { + pinpoint_message( _( "fatal parse error" ) ); + flexend( 1 ); + } + + if ( syntaxerror ) + flexend( 1 ); + + if ( backing_up_report ) + { + backing_up_file = fopen( backing_name, "w" ); + if ( backing_up_file == NULL ) + lerrsf( + _( "could not create backing-up info file %s" ), + backing_name ); + } + + else + backing_up_file = NULL; + + if ( yymore_really_used == true ) + yymore_used = true; + else if ( yymore_really_used == false ) + yymore_used = false; + + if ( reject_really_used == true ) + reject = true; + else if ( reject_really_used == false ) + reject = false; + + if ( performance_report > 0 ) + { + if ( lex_compat ) + { + fprintf( stderr, +_( "-l AT&T lex compatibility option entails a large performance penalty\n" ) ); + fprintf( stderr, +_( " and may be the actual source of other reported performance penalties\n" ) ); + } + + else if ( do_yylineno ) + { + fprintf( stderr, + _( "%%option yylineno entails a large performance penalty\n" ) ); + } + + if ( performance_report > 1 ) + { + if ( interactive ) + fprintf( stderr, + _( "-I (interactive) entails a minor performance penalty\n" ) ); + + if ( yymore_used ) + fprintf( stderr, + _( "yymore() entails a minor performance penalty\n" ) ); + } + + if ( reject ) + fprintf( stderr, + _( "REJECT entails a large performance penalty\n" ) ); + + if ( variable_trailing_context_rules ) + fprintf( stderr, +_( "Variable trailing context rules entail a large performance penalty\n" ) ); + } + + if ( reject ) + real_reject = true; + + if ( variable_trailing_context_rules ) + reject = true; + + if ( (fulltbl || fullspd) && reject ) + { + if ( real_reject ) + flexerror( + _( "REJECT cannot be used with -f or -F" ) ); + else if ( do_yylineno ) + flexerror( + _( "%option yylineno cannot be used with -f or -F" ) ); + else + flexerror( + _( "variable trailing context rules cannot be used with -f or -F" ) ); + } + + if ( reject ) + outn( "\n#define YY_USES_REJECT" ); + + if ( ! do_yywrap ) + { + outn( "\n#define yywrap() 1" ); + outn( "#define YY_SKIP_YYWRAP" ); + } + + if ( ddebug ) + outn( "\n#define FLEX_DEBUG" ); + + if ( csize == 256 ) + outn( "typedef unsigned char YY_CHAR;" ); + else + outn( "typedef char YY_CHAR;" ); + + if ( C_plus_plus ) + { + outn( "#define yytext_ptr yytext" ); + + if ( interactive ) + outn( "#define YY_INTERACTIVE" ); + } + + else + { + if ( do_stdinit ) + { + outn( "#ifdef VMS" ); + outn( "#ifndef __VMS_POSIX" ); + outn( yy_nostdinit ); + outn( "#else" ); + outn( yy_stdinit ); + outn( "#endif" ); + outn( "#else" ); + outn( yy_stdinit ); + outn( "#endif" ); + } + + else + outn( yy_nostdinit ); + } + + if ( fullspd ) + outn( "typedef yyconst struct yy_trans_info *yy_state_type;" ); + else if ( ! C_plus_plus ) + outn( "typedef int yy_state_type;" ); + + if ( ddebug ) + outn( "\n#define FLEX_DEBUG" ); + + if ( lex_compat ) + outn( "#define YY_FLEX_LEX_COMPAT" ); + + if ( do_yylineno && ! C_plus_plus ) + { + outn( "extern int yylineno;" ); + outn( "int yylineno = 1;" ); + } + + if ( C_plus_plus ) + { + outn( "\n#include " ); + + if ( yyclass ) + { + outn( "int yyFlexLexer::yylex()" ); + outn( "\t{" ); + outn( +"\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );" ); + outn( "\treturn 0;" ); + outn( "\t}" ); + + out_str( "\n#define YY_DECL int %s::yylex()\n", + yyclass ); + } + } + + else + { + if ( yytext_is_array ) + outn( "extern char yytext[];\n" ); + + else + { + outn( "extern char *yytext;" ); + outn( "#define yytext_ptr yytext" ); + } + + if ( yyclass ) + flexerror( + _( "%option yyclass only meaningful for C++ scanners" ) ); + } + + if ( useecs ) + numecs = cre8ecs( nextecm, ecgroup, csize ); + else + numecs = csize; + + /* Now map the equivalence class for NUL to its expected place. */ + ecgroup[0] = ecgroup[csize]; + NUL_ec = ABS( ecgroup[0] ); + + if ( useecs ) + ccl2ecl(); + } + + +/* set_up_initial_allocations - allocate memory for internal tables */ + +void set_up_initial_allocations() + { + current_mns = INITIAL_MNS; + firstst = allocate_integer_array( current_mns ); + lastst = allocate_integer_array( current_mns ); + finalst = allocate_integer_array( current_mns ); + transchar = allocate_integer_array( current_mns ); + trans1 = allocate_integer_array( current_mns ); + trans2 = allocate_integer_array( current_mns ); + accptnum = allocate_integer_array( current_mns ); + assoc_rule = allocate_integer_array( current_mns ); + state_type = allocate_integer_array( current_mns ); + + current_max_rules = INITIAL_MAX_RULES; + rule_type = allocate_integer_array( current_max_rules ); + rule_linenum = allocate_integer_array( current_max_rules ); + rule_useful = allocate_integer_array( current_max_rules ); + + current_max_scs = INITIAL_MAX_SCS; + scset = allocate_integer_array( current_max_scs ); + scbol = allocate_integer_array( current_max_scs ); + scxclu = allocate_integer_array( current_max_scs ); + sceof = allocate_integer_array( current_max_scs ); + scname = allocate_char_ptr_array( current_max_scs ); + + current_maxccls = INITIAL_MAX_CCLS; + cclmap = allocate_integer_array( current_maxccls ); + ccllen = allocate_integer_array( current_maxccls ); + cclng = allocate_integer_array( current_maxccls ); + + current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; + ccltbl = allocate_Character_array( current_max_ccl_tbl_size ); + + current_max_dfa_size = INITIAL_MAX_DFA_SIZE; + + current_max_xpairs = INITIAL_MAX_XPAIRS; + nxt = allocate_integer_array( current_max_xpairs ); + chk = allocate_integer_array( current_max_xpairs ); + + current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; + tnxt = allocate_integer_array( current_max_template_xpairs ); + + current_max_dfas = INITIAL_MAX_DFAS; + base = allocate_integer_array( current_max_dfas ); + def = allocate_integer_array( current_max_dfas ); + dfasiz = allocate_integer_array( current_max_dfas ); + accsiz = allocate_integer_array( current_max_dfas ); + dhash = allocate_integer_array( current_max_dfas ); + dss = allocate_int_ptr_array( current_max_dfas ); + dfaacc = allocate_dfaacc_union( current_max_dfas ); + + nultrans = (int *) 0; + } + + +void usage() + { + FILE *f = stdout; + + fprintf( f, +_( "%s [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton]\n" ), + program_name ); + fprintf( f, _( "\t[--help --version] [file ...]\n" ) ); + + fprintf( f, _( "\t-b generate backing-up information to %s\n" ), + backing_name ); + fprintf( f, _( "\t-c do-nothing POSIX option\n" ) ); + fprintf( f, _( "\t-d turn on debug mode in generated scanner\n" ) ); + fprintf( f, _( "\t-f generate fast, large scanner\n" ) ); + fprintf( f, _( "\t-h produce this help message\n" ) ); + fprintf( f, _( "\t-i generate case-insensitive scanner\n" ) ); + fprintf( f, _( "\t-l maximal compatibility with original lex\n" ) ); + fprintf( f, _( "\t-n do-nothing POSIX option\n" ) ); + fprintf( f, _( "\t-p generate performance report to stderr\n" ) ); + fprintf( f, + _( "\t-s suppress default rule to ECHO unmatched text\n" ) ); + + if ( ! did_outfilename ) + { + sprintf( outfile_path, outfile_template, + prefix, C_plus_plus ? "cc" : "c" ); + outfilename = outfile_path; + } + + fprintf( f, + _( "\t-t write generated scanner on stdout instead of %s\n" ), + outfilename ); + + fprintf( f, + _( "\t-v write summary of scanner statistics to f\n" ) ); + fprintf( f, _( "\t-w do not generate warnings\n" ) ); + fprintf( f, _( "\t-B generate batch scanner (opposite of -I)\n" ) ); + fprintf( f, + _( "\t-F use alternative fast scanner representation\n" ) ); + fprintf( f, + _( "\t-I generate interactive scanner (opposite of -B)\n" ) ); + fprintf( f, _( "\t-L suppress #line directives in scanner\n" ) ); + fprintf( f, _( "\t-T %s should run in trace mode\n" ), program_name ); + fprintf( f, _( "\t-V report %s version\n" ), program_name ); + fprintf( f, _( "\t-7 generate 7-bit scanner\n" ) ); + fprintf( f, _( "\t-8 generate 8-bit scanner\n" ) ); + fprintf( f, _( "\t-+ generate C++ scanner class\n" ) ); + fprintf( f, _( "\t-? produce this help message\n" ) ); + fprintf( f, +_( "\t-C specify degree of table compression (default is -Cem):\n" ) ); + fprintf( f, +_( "\t\t-Ca trade off larger tables for better memory alignment\n" ) ); + fprintf( f, _( "\t\t-Ce construct equivalence classes\n" ) ); + fprintf( f, +_( "\t\t-Cf do not compress scanner tables; use -f representation\n" ) ); + fprintf( f, +_( "\t\t-CF do not compress scanner tables; use -F representation\n" ) ); + fprintf( f, _( "\t\t-Cm construct meta-equivalence classes\n" ) ); + fprintf( f, + _( "\t\t-Cr use read() instead of stdio for scanner input\n" ) ); + fprintf( f, _( "\t-o specify output filename\n" ) ); + fprintf( f, _( "\t-P specify scanner prefix other than \"yy\"\n" ) ); + fprintf( f, _( "\t-S specify skeleton file\n" ) ); + fprintf( f, _( "\t--help produce this help message\n" ) ); + fprintf( f, _( "\t--version report %s version\n" ), program_name ); + } diff --git a/commands/flex-2.5.4/misc.c b/commands/flex-2.5.4/misc.c new file mode 100644 index 000000000..7093661e6 --- /dev/null +++ b/commands/flex-2.5.4/misc.c @@ -0,0 +1,886 @@ +/* misc - miscellaneous flex routines */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + +#include "flexdef.h" + + +void action_define( defname, value ) +char *defname; +int value; + { + char buf[MAXLINE]; + + if ( (int) strlen( defname ) > MAXLINE / 2 ) + { + format_pinpoint_message( _( "name \"%s\" ridiculously long" ), + defname ); + return; + } + + sprintf( buf, "#define %s %d\n", defname, value ); + add_action( buf ); + } + + +void add_action( new_text ) +char *new_text; + { + int len = strlen( new_text ); + + while ( len + action_index >= action_size - 10 /* slop */ ) + { + int new_size = action_size * 2; + + if ( new_size <= 0 ) + /* Increase just a little, to try to avoid overflow + * on 16-bit machines. + */ + action_size += action_size / 8; + else + action_size = new_size; + + action_array = + reallocate_character_array( action_array, action_size ); + } + + strcpy( &action_array[action_index], new_text ); + + action_index += len; + } + + +/* allocate_array - allocate memory for an integer array of the given size */ + +void *allocate_array( size, element_size ) +int size; +size_t element_size; + { + register void *mem; + size_t num_bytes = element_size * size; + + mem = flex_alloc( num_bytes ); + if ( ! mem ) + flexfatal( + _( "memory allocation failed in allocate_array()" ) ); + + return mem; + } + + +/* all_lower - true if a string is all lower-case */ + +int all_lower( str ) +register char *str; + { + while ( *str ) + { + if ( ! isascii( (Char) *str ) || ! islower( *str ) ) + return 0; + ++str; + } + + return 1; + } + + +/* all_upper - true if a string is all upper-case */ + +int all_upper( str ) +register char *str; + { + while ( *str ) + { + if ( ! isascii( (Char) *str ) || ! isupper( *str ) ) + return 0; + ++str; + } + + return 1; + } + + +/* bubble - bubble sort an integer array in increasing order + * + * synopsis + * int v[n], n; + * void bubble( v, n ); + * + * description + * sorts the first n elements of array v and replaces them in + * increasing order. + * + * passed + * v - the array to be sorted + * n - the number of elements of 'v' to be sorted + */ + +void bubble( v, n ) +int v[], n; + { + register int i, j, k; + + for ( i = n; i > 1; --i ) + for ( j = 1; j < i; ++j ) + if ( v[j] > v[j + 1] ) /* compare */ + { + k = v[j]; /* exchange */ + v[j] = v[j + 1]; + v[j + 1] = k; + } + } + + +/* check_char - checks a character to make sure it's within the range + * we're expecting. If not, generates fatal error message + * and exits. + */ + +void check_char( c ) +int c; + { + if ( c >= CSIZE ) + lerrsf( _( "bad character '%s' detected in check_char()" ), + readable_form( c ) ); + + if ( c >= csize ) + lerrsf( + _( "scanner requires -8 flag to use the character %s" ), + readable_form( c ) ); + } + + + +/* clower - replace upper-case letter to lower-case */ + +Char clower( c ) +register int c; + { + return (Char) ((isascii( c ) && isupper( c )) ? tolower( c ) : c); + } + + +/* copy_string - returns a dynamically allocated copy of a string */ + +char *copy_string( str ) +register const char *str; + { + register const char *c1; + register char *c2; + char *copy; + unsigned int size; + + /* find length */ + for ( c1 = str; *c1; ++c1 ) + ; + + size = (c1 - str + 1) * sizeof( char ); + copy = (char *) flex_alloc( size ); + + if ( copy == NULL ) + flexfatal( _( "dynamic memory failure in copy_string()" ) ); + + for ( c2 = copy; (*c2++ = *str++) != 0; ) + ; + + return copy; + } + + +/* copy_unsigned_string - + * returns a dynamically allocated copy of a (potentially) unsigned string + */ + +Char *copy_unsigned_string( str ) +register Char *str; + { + register Char *c; + Char *copy; + + /* find length */ + for ( c = str; *c; ++c ) + ; + + copy = allocate_Character_array( c - str + 1 ); + + for ( c = copy; (*c++ = *str++) != 0; ) + ; + + return copy; + } + + +/* cshell - shell sort a character array in increasing order + * + * synopsis + * + * Char v[n]; + * int n, special_case_0; + * cshell( v, n, special_case_0 ); + * + * description + * Does a shell sort of the first n elements of array v. + * If special_case_0 is true, then any element equal to 0 + * is instead assumed to have infinite weight. + * + * passed + * v - array to be sorted + * n - number of elements of v to be sorted + */ + +void cshell( v, n, special_case_0 ) +Char v[]; +int n, special_case_0; + { + int gap, i, j, jg; + Char k; + + for ( gap = n / 2; gap > 0; gap = gap / 2 ) + for ( i = gap; i < n; ++i ) + for ( j = i - gap; j >= 0; j = j - gap ) + { + jg = j + gap; + + if ( special_case_0 ) + { + if ( v[jg] == 0 ) + break; + + else if ( v[j] != 0 && v[j] <= v[jg] ) + break; + } + + else if ( v[j] <= v[jg] ) + break; + + k = v[j]; + v[j] = v[jg]; + v[jg] = k; + } + } + + +/* dataend - finish up a block of data declarations */ + +void dataend() + { + if ( datapos > 0 ) + dataflush(); + + /* add terminator for initialization; { for vi */ + outn( " } ;\n" ); + + dataline = 0; + datapos = 0; + } + + +/* dataflush - flush generated data statements */ + +void dataflush() + { + outc( '\n' ); + + if ( ++dataline >= NUMDATALINES ) + { + /* Put out a blank line so that the table is grouped into + * large blocks that enable the user to find elements easily. + */ + outc( '\n' ); + dataline = 0; + } + + /* Reset the number of characters written on the current line. */ + datapos = 0; + } + + +/* flexerror - report an error message and terminate */ + +void flexerror( msg ) +const char msg[]; + { + fprintf( stderr, "%s: %s\n", program_name, msg ); + flexend( 1 ); + } + + +/* flexfatal - report a fatal error message and terminate */ + +void flexfatal( msg ) +const char msg[]; + { + fprintf( stderr, _( "%s: fatal internal error, %s\n" ), + program_name, msg ); + exit( 1 ); + } + + +/* htoi - convert a hexadecimal digit string to an integer value */ + +int htoi( str ) +Char str[]; + { + unsigned int result; + + (void) sscanf( (char *) str, "%x", &result ); + + return result; + } + + +/* lerrif - report an error message formatted with one integer argument */ + +void lerrif( msg, arg ) +const char msg[]; +int arg; + { + char errmsg[MAXLINE]; + (void) sprintf( errmsg, msg, arg ); + flexerror( errmsg ); + } + + +/* lerrsf - report an error message formatted with one string argument */ + +void lerrsf( msg, arg ) +const char msg[], arg[]; + { + char errmsg[MAXLINE]; + + (void) sprintf( errmsg, msg, arg ); + flexerror( errmsg ); + } + + +/* line_directive_out - spit out a "#line" statement */ + +void line_directive_out( output_file, do_infile ) +FILE *output_file; +int do_infile; + { + char directive[MAXLINE], filename[MAXLINE]; + char *s1, *s2, *s3; + static char line_fmt[] = "#line %d \"%s\"\n"; + + if ( ! gen_line_dirs ) + return; + + if ( (do_infile && ! infilename) || (! do_infile && ! outfilename) ) + /* don't know the filename to use, skip */ + return; + + s1 = do_infile ? infilename : outfilename; + s2 = filename; + s3 = &filename[sizeof( filename ) - 2]; + + while ( s2 < s3 && *s1 ) + { + if ( *s1 == '\\' ) + /* Escape the '\' */ + *s2++ = '\\'; + + *s2++ = *s1++; + } + + *s2 = '\0'; + + if ( do_infile ) + sprintf( directive, line_fmt, linenum, filename ); + else + { + if ( output_file == stdout ) + /* Account for the line directive itself. */ + ++out_linenum; + + sprintf( directive, line_fmt, out_linenum, filename ); + } + + /* If output_file is nil then we should put the directive in + * the accumulated actions. + */ + if ( output_file ) + { + fputs( directive, output_file ); + } + else + add_action( directive ); + } + + +/* mark_defs1 - mark the current position in the action array as + * representing where the user's section 1 definitions end + * and the prolog begins + */ +void mark_defs1() + { + defs1_offset = 0; + action_array[action_index++] = '\0'; + action_offset = prolog_offset = action_index; + action_array[action_index] = '\0'; + } + + +/* mark_prolog - mark the current position in the action array as + * representing the end of the action prolog + */ +void mark_prolog() + { + action_array[action_index++] = '\0'; + action_offset = action_index; + action_array[action_index] = '\0'; + } + + +/* mk2data - generate a data statement for a two-dimensional array + * + * Generates a data statement initializing the current 2-D array to "value". + */ +void mk2data( value ) +int value; + { + if ( datapos >= NUMDATAITEMS ) + { + outc( ',' ); + dataflush(); + } + + if ( datapos == 0 ) + /* Indent. */ + out( " " ); + + else + outc( ',' ); + + ++datapos; + + out_dec( "%5d", value ); + } + + +/* mkdata - generate a data statement + * + * Generates a data statement initializing the current array element to + * "value". + */ +void mkdata( value ) +int value; + { + if ( datapos >= NUMDATAITEMS ) + { + outc( ',' ); + dataflush(); + } + + if ( datapos == 0 ) + /* Indent. */ + out( " " ); + else + outc( ',' ); + + ++datapos; + + out_dec( "%5d", value ); + } + + +/* myctoi - return the integer represented by a string of digits */ + +int myctoi( array ) +char array[]; + { + int val = 0; + + (void) sscanf( array, "%d", &val ); + + return val; + } + + +/* myesc - return character corresponding to escape sequence */ + +Char myesc( array ) +Char array[]; + { + Char c, esc_char; + + switch ( array[1] ) + { + case 'b': return '\b'; + case 'f': return '\f'; + case 'n': return '\n'; + case 'r': return '\r'; + case 't': return '\t'; + +#if __STDC__ + case 'a': return '\a'; + case 'v': return '\v'; +#else + case 'a': return '\007'; + case 'v': return '\013'; +#endif + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { /* \ */ + int sptr = 1; + + while ( isascii( array[sptr] ) && + isdigit( array[sptr] ) ) + /* Don't increment inside loop control + * because if isdigit() is a macro it might + * expand into multiple increments ... + */ + ++sptr; + + c = array[sptr]; + array[sptr] = '\0'; + + esc_char = otoi( array + 1 ); + + array[sptr] = c; + + return esc_char; + } + + case 'x': + { /* \x */ + int sptr = 2; + + while ( isascii( array[sptr] ) && + isxdigit( (char) array[sptr] ) ) + /* Don't increment inside loop control + * because if isdigit() is a macro it might + * expand into multiple increments ... + */ + ++sptr; + + c = array[sptr]; + array[sptr] = '\0'; + + esc_char = htoi( array + 2 ); + + array[sptr] = c; + + return esc_char; + } + + default: + return array[1]; + } + } + + +/* otoi - convert an octal digit string to an integer value */ + +int otoi( str ) +Char str[]; + { + unsigned int result; + + (void) sscanf( (char *) str, "%o", &result ); + return result; + } + + +/* out - various flavors of outputing a (possibly formatted) string for the + * generated scanner, keeping track of the line count. + */ + +void out( str ) +const char str[]; + { + fputs( str, stdout ); + out_line_count( str ); + } + +void out_dec( fmt, n ) +const char fmt[]; +int n; + { + printf( fmt, n ); + out_line_count( fmt ); + } + +void out_dec2( fmt, n1, n2 ) +const char fmt[]; +int n1, n2; + { + printf( fmt, n1, n2 ); + out_line_count( fmt ); + } + +void out_hex( fmt, x ) +const char fmt[]; +unsigned int x; + { + printf( fmt, x ); + out_line_count( fmt ); + } + +void out_line_count( str ) +const char str[]; + { + register int i; + + for ( i = 0; str[i]; ++i ) + if ( str[i] == '\n' ) + ++out_linenum; + } + +void out_str( fmt, str ) +const char fmt[], str[]; + { + printf( fmt, str ); + out_line_count( fmt ); + out_line_count( str ); + } + +void out_str3( fmt, s1, s2, s3 ) +const char fmt[], s1[], s2[], s3[]; + { + printf( fmt, s1, s2, s3 ); + out_line_count( fmt ); + out_line_count( s1 ); + out_line_count( s2 ); + out_line_count( s3 ); + } + +void out_str_dec( fmt, str, n ) +const char fmt[], str[]; +int n; + { + printf( fmt, str, n ); + out_line_count( fmt ); + out_line_count( str ); + } + +void outc( c ) +int c; + { + putc( c, stdout ); + + if ( c == '\n' ) + ++out_linenum; + } + +void outn( str ) +const char str[]; + { + puts( str ); + out_line_count( str ); + ++out_linenum; + } + + +/* readable_form - return the the human-readable form of a character + * + * The returned string is in static storage. + */ + +char *readable_form( c ) +register int c; + { + static char rform[10]; + + if ( (c >= 0 && c < 32) || c >= 127 ) + { + switch ( c ) + { + case '\b': return "\\b"; + case '\f': return "\\f"; + case '\n': return "\\n"; + case '\r': return "\\r"; + case '\t': return "\\t"; + +#if __STDC__ + case '\a': return "\\a"; + case '\v': return "\\v"; +#endif + + default: + (void) sprintf( rform, "\\%.3o", + (unsigned int) c ); + return rform; + } + } + + else if ( c == ' ' ) + return "' '"; + + else + { + rform[0] = c; + rform[1] = '\0'; + + return rform; + } + } + + +/* reallocate_array - increase the size of a dynamic array */ + +void *reallocate_array( array, size, element_size ) +void *array; +int size; +size_t element_size; + { + register void *new_array; + size_t num_bytes = element_size * size; + + new_array = flex_realloc( array, num_bytes ); + if ( ! new_array ) + flexfatal( _( "attempt to increase array size failed" ) ); + + return new_array; + } + + +/* skelout - write out one section of the skeleton file + * + * Description + * Copies skelfile or skel array to stdout until a line beginning with + * "%%" or EOF is found. + */ +void skelout() + { + char buf_storage[MAXLINE]; + char *buf = buf_storage; + int do_copy = 1; + + /* Loop pulling lines either from the skelfile, if we're using + * one, or from the skel[] array. + */ + while ( skelfile ? + (fgets( buf, MAXLINE, skelfile ) != NULL) : + ((buf = (char *) skel[skel_ind++]) != 0) ) + { /* copy from skel array */ + if ( buf[0] == '%' ) + { /* control line */ + switch ( buf[1] ) + { + case '%': + return; + + case '+': + do_copy = C_plus_plus; + break; + + case '-': + do_copy = ! C_plus_plus; + break; + + case '*': + do_copy = 1; + break; + + default: + flexfatal( + _( "bad line in skeleton file" ) ); + } + } + + else if ( do_copy ) + { + if ( skelfile ) + /* Skeleton file reads include final + * newline, skel[] array does not. + */ + out( buf ); + else + outn( buf ); + } + } + } + + +/* transition_struct_out - output a yy_trans_info structure + * + * outputs the yy_trans_info structure with the two elements, element_v and + * element_n. Formats the output with spaces and carriage returns. + */ + +void transition_struct_out( element_v, element_n ) +int element_v, element_n; + { + out_dec2( " {%4d,%4d },", element_v, element_n ); + + datapos += TRANS_STRUCT_PRINT_LENGTH; + + if ( datapos >= 79 - TRANS_STRUCT_PRINT_LENGTH ) + { + outc( '\n' ); + + if ( ++dataline % 10 == 0 ) + outc( '\n' ); + + datapos = 0; + } + } + + +/* The following is only needed when building flex's parser using certain + * broken versions of bison. + */ +void *yy_flex_xmalloc( size ) +int size; + { + void *result = flex_alloc( (size_t) size ); + + if ( ! result ) + flexfatal( + _( "memory allocation failed in yy_flex_xmalloc()" ) ); + + return result; + } + + +/* zero_out - set a region of memory to 0 + * + * Sets region_ptr[0] through region_ptr[size_in_bytes - 1] to zero. + */ + +void zero_out( region_ptr, size_in_bytes ) +char *region_ptr; +size_t size_in_bytes; + { + register char *rp, *rp_end; + + rp = region_ptr; + rp_end = region_ptr + size_in_bytes; + + while ( rp < rp_end ) + *rp++ = 0; + } diff --git a/commands/flex-2.5.4/mkinstalldirs b/commands/flex-2.5.4/mkinstalldirs new file mode 100755 index 000000000..0e2937731 --- /dev/null +++ b/commands/flex-2.5.4/mkinstalldirs @@ -0,0 +1,35 @@ +#!/bin/sh +# Make directory hierarchy. +# Written by Noah Friedman +# Public domain. + +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +errstatus=0 + +for file in ${1+"$@"} ; do + oIFS="${IFS}" + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set - `echo ${file} | sed -e 's@/@%@g' -e 's@^%@/@'` + IFS="${oIFS}" + + pathcomp='' + + for d in ${1+"$@"} ; do + pathcomp="${pathcomp}${d}" + + if test ! -d "${pathcomp}"; then + echo "mkdir $pathcomp" 1>&2 + mkdir "${pathcomp}" || errstatus=$? + fi + + pathcomp="${pathcomp}/" + done +done + +exit $errstatus + +# eof diff --git a/commands/flex-2.5.4/mkskel.sh b/commands/flex-2.5.4/mkskel.sh new file mode 100755 index 000000000..a03a11aba --- /dev/null +++ b/commands/flex-2.5.4/mkskel.sh @@ -0,0 +1,16 @@ +#! /bin/sh + +cat < 0 ) + fprintf( stderr, + _( "Variable trailing context rule at line %d\n" ), + rule_linenum[num_rules] ); + + variable_trailing_context_rules = true; + } + + else + { + rule_type[num_rules] = RULE_NORMAL; + + if ( headcnt > 0 || trailcnt > 0 ) + { + /* Do trailing context magic to not match the trailing + * characters. + */ + char *scanner_cp = "yy_c_buf_p = yy_cp"; + char *scanner_bp = "yy_bp"; + + add_action( + "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" ); + + if ( headcnt > 0 ) + { + sprintf( action_text, "%s = %s + %d;\n", + scanner_cp, scanner_bp, headcnt ); + add_action( action_text ); + } + + else + { + sprintf( action_text, "%s -= %d;\n", + scanner_cp, trailcnt ); + add_action( action_text ); + } + + add_action( + "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" ); + } + } + + /* Okay, in the action code at this point yytext and yyleng have + * their proper final values for this rule, so here's the point + * to do any user action. But don't do it for continued actions, + * as that'll result in multiple YY_RULE_SETUP's. + */ + if ( ! continued_action ) + add_action( "YY_RULE_SETUP\n" ); + + line_directive_out( (FILE *) 0, 1 ); + } + + +/* link_machines - connect two machines together + * + * synopsis + * + * new = link_machines( first, last ); + * + * new - a machine constructed by connecting first to last + * first - the machine whose successor is to be last + * last - the machine whose predecessor is to be first + * + * note: this routine concatenates the machine first with the machine + * last to produce a machine new which will pattern-match first first + * and then last, and will fail if either of the sub-patterns fails. + * FIRST is set to new by the operation. last is unmolested. + */ + +int link_machines( first, last ) +int first, last; + { + if ( first == NIL ) + return last; + + else if ( last == NIL ) + return first; + + else + { + mkxtion( finalst[first], last ); + finalst[first] = finalst[last]; + lastst[first] = MAX( lastst[first], lastst[last] ); + firstst[first] = MIN( firstst[first], firstst[last] ); + + return first; + } + } + + +/* mark_beginning_as_normal - mark each "beginning" state in a machine + * as being a "normal" (i.e., not trailing context- + * associated) states + * + * The "beginning" states are the epsilon closure of the first state + */ + +void mark_beginning_as_normal( mach ) +register int mach; + { + switch ( state_type[mach] ) + { + case STATE_NORMAL: + /* Oh, we've already visited here. */ + return; + + case STATE_TRAILING_CONTEXT: + state_type[mach] = STATE_NORMAL; + + if ( transchar[mach] == SYM_EPSILON ) + { + if ( trans1[mach] != NO_TRANSITION ) + mark_beginning_as_normal( + trans1[mach] ); + + if ( trans2[mach] != NO_TRANSITION ) + mark_beginning_as_normal( + trans2[mach] ); + } + break; + + default: + flexerror( + _( "bad state type in mark_beginning_as_normal()" ) ); + break; + } + } + + +/* mkbranch - make a machine that branches to two machines + * + * synopsis + * + * branch = mkbranch( first, second ); + * + * branch - a machine which matches either first's pattern or second's + * first, second - machines whose patterns are to be or'ed (the | operator) + * + * Note that first and second are NEITHER destroyed by the operation. Also, + * the resulting machine CANNOT be used with any other "mk" operation except + * more mkbranch's. Compare with mkor() + */ + +int mkbranch( first, second ) +int first, second; + { + int eps; + + if ( first == NO_TRANSITION ) + return second; + + else if ( second == NO_TRANSITION ) + return first; + + eps = mkstate( SYM_EPSILON ); + + mkxtion( eps, first ); + mkxtion( eps, second ); + + return eps; + } + + +/* mkclos - convert a machine into a closure + * + * synopsis + * new = mkclos( state ); + * + * new - a new state which matches the closure of "state" + */ + +int mkclos( state ) +int state; + { + return mkopt( mkposcl( state ) ); + } + + +/* mkopt - make a machine optional + * + * synopsis + * + * new = mkopt( mach ); + * + * new - a machine which optionally matches whatever mach matched + * mach - the machine to make optional + * + * notes: + * 1. mach must be the last machine created + * 2. mach is destroyed by the call + */ + +int mkopt( mach ) +int mach; + { + int eps; + + if ( ! SUPER_FREE_EPSILON(finalst[mach]) ) + { + eps = mkstate( SYM_EPSILON ); + mach = link_machines( mach, eps ); + } + + /* Can't skimp on the following if FREE_EPSILON(mach) is true because + * some state interior to "mach" might point back to the beginning + * for a closure. + */ + eps = mkstate( SYM_EPSILON ); + mach = link_machines( eps, mach ); + + mkxtion( mach, finalst[mach] ); + + return mach; + } + + +/* mkor - make a machine that matches either one of two machines + * + * synopsis + * + * new = mkor( first, second ); + * + * new - a machine which matches either first's pattern or second's + * first, second - machines whose patterns are to be or'ed (the | operator) + * + * note that first and second are both destroyed by the operation + * the code is rather convoluted because an attempt is made to minimize + * the number of epsilon states needed + */ + +int mkor( first, second ) +int first, second; + { + int eps, orend; + + if ( first == NIL ) + return second; + + else if ( second == NIL ) + return first; + + else + { + /* See comment in mkopt() about why we can't use the first + * state of "first" or "second" if they satisfy "FREE_EPSILON". + */ + eps = mkstate( SYM_EPSILON ); + + first = link_machines( eps, first ); + + mkxtion( first, second ); + + if ( SUPER_FREE_EPSILON(finalst[first]) && + accptnum[finalst[first]] == NIL ) + { + orend = finalst[first]; + mkxtion( finalst[second], orend ); + } + + else if ( SUPER_FREE_EPSILON(finalst[second]) && + accptnum[finalst[second]] == NIL ) + { + orend = finalst[second]; + mkxtion( finalst[first], orend ); + } + + else + { + eps = mkstate( SYM_EPSILON ); + + first = link_machines( first, eps ); + orend = finalst[first]; + + mkxtion( finalst[second], orend ); + } + } + + finalst[first] = orend; + return first; + } + + +/* mkposcl - convert a machine into a positive closure + * + * synopsis + * new = mkposcl( state ); + * + * new - a machine matching the positive closure of "state" + */ + +int mkposcl( state ) +int state; + { + int eps; + + if ( SUPER_FREE_EPSILON(finalst[state]) ) + { + mkxtion( finalst[state], state ); + return state; + } + + else + { + eps = mkstate( SYM_EPSILON ); + mkxtion( eps, state ); + return link_machines( state, eps ); + } + } + + +/* mkrep - make a replicated machine + * + * synopsis + * new = mkrep( mach, lb, ub ); + * + * new - a machine that matches whatever "mach" matched from "lb" + * number of times to "ub" number of times + * + * note + * if "ub" is INFINITY then "new" matches "lb" or more occurrences of "mach" + */ + +int mkrep( mach, lb, ub ) +int mach, lb, ub; + { + int base_mach, tail, copy, i; + + base_mach = copysingl( mach, lb - 1 ); + + if ( ub == INFINITY ) + { + copy = dupmachine( mach ); + mach = link_machines( mach, + link_machines( base_mach, mkclos( copy ) ) ); + } + + else + { + tail = mkstate( SYM_EPSILON ); + + for ( i = lb; i < ub; ++i ) + { + copy = dupmachine( mach ); + tail = mkopt( link_machines( copy, tail ) ); + } + + mach = link_machines( mach, link_machines( base_mach, tail ) ); + } + + return mach; + } + + +/* mkstate - create a state with a transition on a given symbol + * + * synopsis + * + * state = mkstate( sym ); + * + * state - a new state matching sym + * sym - the symbol the new state is to have an out-transition on + * + * note that this routine makes new states in ascending order through the + * state array (and increments LASTNFA accordingly). The routine DUPMACHINE + * relies on machines being made in ascending order and that they are + * CONTIGUOUS. Change it and you will have to rewrite DUPMACHINE (kludge + * that it admittedly is) + */ + +int mkstate( sym ) +int sym; + { + if ( ++lastnfa >= current_mns ) + { + if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS ) + lerrif( + _( "input rules are too complicated (>= %d NFA states)" ), + current_mns ); + + ++num_reallocs; + + firstst = reallocate_integer_array( firstst, current_mns ); + lastst = reallocate_integer_array( lastst, current_mns ); + finalst = reallocate_integer_array( finalst, current_mns ); + transchar = reallocate_integer_array( transchar, current_mns ); + trans1 = reallocate_integer_array( trans1, current_mns ); + trans2 = reallocate_integer_array( trans2, current_mns ); + accptnum = reallocate_integer_array( accptnum, current_mns ); + assoc_rule = + reallocate_integer_array( assoc_rule, current_mns ); + state_type = + reallocate_integer_array( state_type, current_mns ); + } + + firstst[lastnfa] = lastnfa; + finalst[lastnfa] = lastnfa; + lastst[lastnfa] = lastnfa; + transchar[lastnfa] = sym; + trans1[lastnfa] = NO_TRANSITION; + trans2[lastnfa] = NO_TRANSITION; + accptnum[lastnfa] = NIL; + assoc_rule[lastnfa] = num_rules; + state_type[lastnfa] = current_state_type; + + /* Fix up equivalence classes base on this transition. Note that any + * character which has its own transition gets its own equivalence + * class. Thus only characters which are only in character classes + * have a chance at being in the same equivalence class. E.g. "a|b" + * puts 'a' and 'b' into two different equivalence classes. "[ab]" + * puts them in the same equivalence class (barring other differences + * elsewhere in the input). + */ + + if ( sym < 0 ) + { + /* We don't have to update the equivalence classes since + * that was already done when the ccl was created for the + * first time. + */ + } + + else if ( sym == SYM_EPSILON ) + ++numeps; + + else + { + check_char( sym ); + + if ( useecs ) + /* Map NUL's to csize. */ + mkechar( sym ? sym : csize, nextecm, ecgroup ); + } + + return lastnfa; + } + + +/* mkxtion - make a transition from one state to another + * + * synopsis + * + * mkxtion( statefrom, stateto ); + * + * statefrom - the state from which the transition is to be made + * stateto - the state to which the transition is to be made + */ + +void mkxtion( statefrom, stateto ) +int statefrom, stateto; + { + if ( trans1[statefrom] == NO_TRANSITION ) + trans1[statefrom] = stateto; + + else if ( (transchar[statefrom] != SYM_EPSILON) || + (trans2[statefrom] != NO_TRANSITION) ) + flexfatal( _( "found too many transitions in mkxtion()" ) ); + + else + { /* second out-transition for an epsilon state */ + ++eps2; + trans2[statefrom] = stateto; + } + } + +/* new_rule - initialize for a new rule */ + +void new_rule() + { + if ( ++num_rules >= current_max_rules ) + { + ++num_reallocs; + current_max_rules += MAX_RULES_INCREMENT; + rule_type = reallocate_integer_array( rule_type, + current_max_rules ); + rule_linenum = reallocate_integer_array( rule_linenum, + current_max_rules ); + rule_useful = reallocate_integer_array( rule_useful, + current_max_rules ); + } + + if ( num_rules > MAX_RULE ) + lerrif( _( "too many rules (> %d)!" ), MAX_RULE ); + + rule_linenum[num_rules] = linenum; + rule_useful[num_rules] = false; + } diff --git a/commands/flex-2.5.4/parse.y b/commands/flex-2.5.4/parse.y new file mode 100644 index 000000000..f7efa6ce3 --- /dev/null +++ b/commands/flex-2.5.4/parse.y @@ -0,0 +1,913 @@ +/* parse.y - parser for flex input */ + +%token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP +%token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS + +%token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH +%token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT + +%{ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + + +/* Some versions of bison are broken in that they use alloca() but don't + * declare it properly. The following is the patented (just kidding!) + * #ifdef chud to fix the problem, courtesy of Francois Pinard. + */ +#ifdef YYBISON +/* AIX requires this to be the first thing in the file. What a piece. */ +# ifdef _AIX + #pragma alloca +# endif +#endif + +#include "flexdef.h" + +/* The remainder of the alloca() cruft has to come after including flexdef.h, + * so HAVE_ALLOCA_H is (possibly) defined. + */ +#ifdef YYBISON +# ifdef __GNUC__ +# ifndef alloca +# define alloca __builtin_alloca +# endif +# else +# if HAVE_ALLOCA_H +# include +# else +# ifdef __hpux +void *alloca (); +# else +# ifdef __TURBOC__ +# include +# else +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +/* Bletch, ^^^^ that was ugly! */ + + +int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, rulelen; +int trlcontxt, xcluflg, currccl, cclsorted, varlength, variable_trail_rule; + +int *scon_stk; +int scon_stk_ptr; + +static int madeany = false; /* whether we've made the '.' character class */ +int previous_continued_action; /* whether the previous rule's action was '|' */ + +/* Expand a POSIX character class expression. */ +#define CCL_EXPR(func) \ + { \ + int c; \ + for ( c = 0; c < csize; ++c ) \ + if ( isascii(c) && func(c) ) \ + ccladd( currccl, c ); \ + } + +/* While POSIX defines isblank(), it's not ANSI C. */ +#define IS_BLANK(c) ((c) == ' ' || (c) == '\t') + +/* On some over-ambitious machines, such as DEC Alpha's, the default + * token type is "long" instead of "int"; this leads to problems with + * declaring yylval in flexdef.h. But so far, all the yacc's I've seen + * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the + * following should ensure that the default token type is "int". + */ +#define YYSTYPE int + +%} + +%% +goal : initlex sect1 sect1end sect2 initforrule + { /* add default rule */ + int def_rule; + + pat = cclinit(); + cclnegate( pat ); + + def_rule = mkstate( -pat ); + + /* Remember the number of the default rule so we + * don't generate "can't match" warnings for it. + */ + default_rule = num_rules; + + finish_rule( def_rule, false, 0, 0 ); + + for ( i = 1; i <= lastsc; ++i ) + scset[i] = mkbranch( scset[i], def_rule ); + + if ( spprdflt ) + add_action( + "YY_FATAL_ERROR( \"flex scanner jammed\" )" ); + else + add_action( "ECHO" ); + + add_action( ";\n\tYY_BREAK\n" ); + } + ; + +initlex : + { /* initialize for processing rules */ + + /* Create default DFA start condition. */ + scinstal( "INITIAL", false ); + } + ; + +sect1 : sect1 startconddecl namelist1 + | sect1 options + | + | error + { synerr( "unknown error processing section 1" ); } + ; + +sect1end : SECTEND + { + check_options(); + scon_stk = allocate_integer_array( lastsc + 1 ); + scon_stk_ptr = 0; + } + ; + +startconddecl : SCDECL + { xcluflg = false; } + + | XSCDECL + { xcluflg = true; } + ; + +namelist1 : namelist1 NAME + { scinstal( nmstr, xcluflg ); } + + | NAME + { scinstal( nmstr, xcluflg ); } + + | error + { synerr( "bad start condition list" ); } + ; + +options : OPTION_OP optionlist + ; + +optionlist : optionlist option + | + ; + +option : OPT_OUTFILE '=' NAME + { + outfilename = copy_string( nmstr ); + did_outfilename = 1; + } + | OPT_PREFIX '=' NAME + { prefix = copy_string( nmstr ); } + | OPT_YYCLASS '=' NAME + { yyclass = copy_string( nmstr ); } + ; + +sect2 : sect2 scon initforrule flexrule '\n' + { scon_stk_ptr = $2; } + | sect2 scon '{' sect2 '}' + { scon_stk_ptr = $2; } + | + ; + +initforrule : + { + /* Initialize for a parse of one rule. */ + trlcontxt = variable_trail_rule = varlength = false; + trailcnt = headcnt = rulelen = 0; + current_state_type = STATE_NORMAL; + previous_continued_action = continued_action; + in_rule = true; + + new_rule(); + } + ; + +flexrule : '^' rule + { + pat = $2; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt ); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scbol[scon_stk[i]] = + mkbranch( scbol[scon_stk[i]], + pat ); + } + + else + { + /* Add to all non-exclusive start conditions, + * including the default (0) start condition. + */ + + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scbol[i] = mkbranch( scbol[i], + pat ); + } + + if ( ! bol_needed ) + { + bol_needed = true; + + if ( performance_report > 1 ) + pinpoint_message( + "'^' operator results in sub-optimal performance" ); + } + } + + | rule + { + pat = $1; + finish_rule( pat, variable_trail_rule, + headcnt, trailcnt ); + + if ( scon_stk_ptr > 0 ) + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + scset[scon_stk[i]] = + mkbranch( scset[scon_stk[i]], + pat ); + } + + else + { + for ( i = 1; i <= lastsc; ++i ) + if ( ! scxclu[i] ) + scset[i] = + mkbranch( scset[i], + pat ); + } + } + + | EOF_OP + { + if ( scon_stk_ptr > 0 ) + build_eof_action(); + + else + { + /* This EOF applies to all start conditions + * which don't already have EOF actions. + */ + for ( i = 1; i <= lastsc; ++i ) + if ( ! sceof[i] ) + scon_stk[++scon_stk_ptr] = i; + + if ( scon_stk_ptr == 0 ) + warn( + "all start conditions already have <> rules" ); + + else + build_eof_action(); + } + } + + | error + { synerr( "unrecognized rule" ); } + ; + +scon_stk_ptr : + { $$ = scon_stk_ptr; } + ; + +scon : '<' scon_stk_ptr namelist2 '>' + { $$ = $2; } + + | '<' '*' '>' + { + $$ = scon_stk_ptr; + + for ( i = 1; i <= lastsc; ++i ) + { + int j; + + for ( j = 1; j <= scon_stk_ptr; ++j ) + if ( scon_stk[j] == i ) + break; + + if ( j > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = i; + } + } + + | + { $$ = scon_stk_ptr; } + ; + +namelist2 : namelist2 ',' sconname + + | sconname + + | error + { synerr( "bad start condition list" ); } + ; + +sconname : NAME + { + if ( (scnum = sclookup( nmstr )) == 0 ) + format_pinpoint_message( + "undeclared start condition %s", + nmstr ); + else + { + for ( i = 1; i <= scon_stk_ptr; ++i ) + if ( scon_stk[i] == scnum ) + { + format_warn( + "<%s> specified twice", + scname[scnum] ); + break; + } + + if ( i > scon_stk_ptr ) + scon_stk[++scon_stk_ptr] = scnum; + } + } + ; + +rule : re2 re + { + if ( transchar[lastst[$2]] != SYM_EPSILON ) + /* Provide final transition \now/ so it + * will be marked as a trailing context + * state. + */ + $2 = link_machines( $2, + mkstate( SYM_EPSILON ) ); + + mark_beginning_as_normal( $2 ); + current_state_type = STATE_NORMAL; + + if ( previous_continued_action ) + { + /* We need to treat this as variable trailing + * context so that the backup does not happen + * in the action but before the action switch + * statement. If the backup happens in the + * action, then the rules "falling into" this + * one's action will *also* do the backup, + * erroneously. + */ + if ( ! varlength || headcnt != 0 ) + warn( + "trailing context made variable due to preceding '|' action" ); + + /* Mark as variable. */ + varlength = true; + headcnt = 0; + } + + if ( lex_compat || (varlength && headcnt == 0) ) + { /* variable trailing context rule */ + /* Mark the first part of the rule as the + * accepting "head" part of a trailing + * context rule. + * + * By the way, we didn't do this at the + * beginning of this production because back + * then current_state_type was set up for a + * trail rule, and add_accept() can create + * a new state ... + */ + add_accept( $1, + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + else + trailcnt = rulelen; + + $$ = link_machines( $1, $2 ); + } + + | re2 re '$' + { synerr( "trailing context used twice" ); } + + | re '$' + { + headcnt = 0; + trailcnt = 1; + rulelen = 1; + varlength = false; + + current_state_type = STATE_TRAILING_CONTEXT; + + if ( trlcontxt ) + { + synerr( "trailing context used twice" ); + $$ = mkstate( SYM_EPSILON ); + } + + else if ( previous_continued_action ) + { + /* See the comment in the rule for "re2 re" + * above. + */ + warn( + "trailing context made variable due to preceding '|' action" ); + + varlength = true; + } + + if ( lex_compat || varlength ) + { + /* Again, see the comment in the rule for + * "re2 re" above. + */ + add_accept( $1, + num_rules | YY_TRAILING_HEAD_MASK ); + variable_trail_rule = true; + } + + trlcontxt = true; + + eps = mkstate( SYM_EPSILON ); + $$ = link_machines( $1, + link_machines( eps, mkstate( '\n' ) ) ); + } + + | re + { + $$ = $1; + + if ( trlcontxt ) + { + if ( lex_compat || (varlength && headcnt == 0) ) + /* Both head and trail are + * variable-length. + */ + variable_trail_rule = true; + else + trailcnt = rulelen; + } + } + ; + + +re : re '|' series + { + varlength = true; + $$ = mkor( $1, $3 ); + } + + | series + { $$ = $1; } + ; + + +re2 : re '/' + { + /* This rule is written separately so the + * reduction will occur before the trailing + * series is parsed. + */ + + if ( trlcontxt ) + synerr( "trailing context used twice" ); + else + trlcontxt = true; + + if ( varlength ) + /* We hope the trailing context is + * fixed-length. + */ + varlength = false; + else + headcnt = rulelen; + + rulelen = 0; + + current_state_type = STATE_TRAILING_CONTEXT; + $$ = $1; + } + ; + +series : series singleton + { + /* This is where concatenation of adjacent patterns + * gets done. + */ + $$ = link_machines( $1, $2 ); + } + + | singleton + { $$ = $1; } + ; + +singleton : singleton '*' + { + varlength = true; + + $$ = mkclos( $1 ); + } + + | singleton '+' + { + varlength = true; + $$ = mkposcl( $1 ); + } + + | singleton '?' + { + varlength = true; + $$ = mkopt( $1 ); + } + + | singleton '{' NUMBER ',' NUMBER '}' + { + varlength = true; + + if ( $3 > $5 || $3 < 0 ) + { + synerr( "bad iteration values" ); + $$ = $1; + } + else + { + if ( $3 == 0 ) + { + if ( $5 <= 0 ) + { + synerr( + "bad iteration values" ); + $$ = $1; + } + else + $$ = mkopt( + mkrep( $1, 1, $5 ) ); + } + else + $$ = mkrep( $1, $3, $5 ); + } + } + + | singleton '{' NUMBER ',' '}' + { + varlength = true; + + if ( $3 <= 0 ) + { + synerr( "iteration value must be positive" ); + $$ = $1; + } + + else + $$ = mkrep( $1, $3, INFINITY ); + } + + | singleton '{' NUMBER '}' + { + /* The singleton could be something like "(foo)", + * in which case we have no idea what its length + * is, so we punt here. + */ + varlength = true; + + if ( $3 <= 0 ) + { + synerr( "iteration value must be positive" ); + $$ = $1; + } + + else + $$ = link_machines( $1, + copysingl( $1, $3 - 1 ) ); + } + + | '.' + { + if ( ! madeany ) + { + /* Create the '.' character class. */ + anyccl = cclinit(); + ccladd( anyccl, '\n' ); + cclnegate( anyccl ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[anyccl], + ccllen[anyccl], nextecm, + ecgroup, csize, csize ); + + madeany = true; + } + + ++rulelen; + + $$ = mkstate( -anyccl ); + } + + | fullccl + { + if ( ! cclsorted ) + /* Sort characters for fast searching. We + * use a shell sort since this list could + * be large. + */ + cshell( ccltbl + cclmap[$1], ccllen[$1], true ); + + if ( useecs ) + mkeccl( ccltbl + cclmap[$1], ccllen[$1], + nextecm, ecgroup, csize, csize ); + + ++rulelen; + + $$ = mkstate( -$1 ); + } + + | PREVCCL + { + ++rulelen; + + $$ = mkstate( -$1 ); + } + + | '"' string '"' + { $$ = $2; } + + | '(' re ')' + { $$ = $2; } + + | CHAR + { + ++rulelen; + + if ( caseins && $1 >= 'A' && $1 <= 'Z' ) + $1 = clower( $1 ); + + $$ = mkstate( $1 ); + } + ; + +fullccl : '[' ccl ']' + { $$ = $2; } + + | '[' '^' ccl ']' + { + cclnegate( $3 ); + $$ = $3; + } + ; + +ccl : ccl CHAR '-' CHAR + { + if ( caseins ) + { + if ( $2 >= 'A' && $2 <= 'Z' ) + $2 = clower( $2 ); + if ( $4 >= 'A' && $4 <= 'Z' ) + $4 = clower( $4 ); + } + + if ( $2 > $4 ) + synerr( "negative range in character class" ); + + else + { + for ( i = $2; i <= $4; ++i ) + ccladd( $1, i ); + + /* Keep track if this ccl is staying in + * alphabetical order. + */ + cclsorted = cclsorted && ($2 > lastchar); + lastchar = $4; + } + + $$ = $1; + } + + | ccl CHAR + { + if ( caseins && $2 >= 'A' && $2 <= 'Z' ) + $2 = clower( $2 ); + + ccladd( $1, $2 ); + cclsorted = cclsorted && ($2 > lastchar); + lastchar = $2; + $$ = $1; + } + + | ccl ccl_expr + { + /* Too hard to properly maintain cclsorted. */ + cclsorted = false; + $$ = $1; + } + + | + { + cclsorted = true; + lastchar = 0; + currccl = $$ = cclinit(); + } + ; + +ccl_expr: CCE_ALNUM { CCL_EXPR(isalnum) } + | CCE_ALPHA { CCL_EXPR(isalpha) } + | CCE_BLANK { CCL_EXPR(IS_BLANK) } + | CCE_CNTRL { CCL_EXPR(iscntrl) } + | CCE_DIGIT { CCL_EXPR(isdigit) } + | CCE_GRAPH { CCL_EXPR(isgraph) } + | CCE_LOWER { CCL_EXPR(islower) } + | CCE_PRINT { CCL_EXPR(isprint) } + | CCE_PUNCT { CCL_EXPR(ispunct) } + | CCE_SPACE { CCL_EXPR(isspace) } + | CCE_UPPER { + if ( caseins ) + CCL_EXPR(islower) + else + CCL_EXPR(isupper) + } + | CCE_XDIGIT { CCL_EXPR(isxdigit) } + ; + +string : string CHAR + { + if ( caseins && $2 >= 'A' && $2 <= 'Z' ) + $2 = clower( $2 ); + + ++rulelen; + + $$ = link_machines( $1, mkstate( $2 ) ); + } + + | + { $$ = mkstate( SYM_EPSILON ); } + ; + +%% + + +/* build_eof_action - build the "<>" action for the active start + * conditions + */ + +void build_eof_action() + { + register int i; + char action_text[MAXLINE]; + + for ( i = 1; i <= scon_stk_ptr; ++i ) + { + if ( sceof[scon_stk[i]] ) + format_pinpoint_message( + "multiple <> rules for start condition %s", + scname[scon_stk[i]] ); + + else + { + sceof[scon_stk[i]] = true; + sprintf( action_text, "case YY_STATE_EOF(%s):\n", + scname[scon_stk[i]] ); + add_action( action_text ); + } + } + + line_directive_out( (FILE *) 0, 1 ); + + /* This isn't a normal rule after all - don't count it as + * such, so we don't have any holes in the rule numbering + * (which make generating "rule can never match" warnings + * more difficult. + */ + --num_rules; + ++num_eof_rules; + } + + +/* format_synerr - write out formatted syntax error */ + +void format_synerr( msg, arg ) +char msg[], arg[]; + { + char errmsg[MAXLINE]; + + (void) sprintf( errmsg, msg, arg ); + synerr( errmsg ); + } + + +/* synerr - report a syntax error */ + +void synerr( str ) +char str[]; + { + syntaxerror = true; + pinpoint_message( str ); + } + + +/* format_warn - write out formatted warning */ + +void format_warn( msg, arg ) +char msg[], arg[]; + { + char warn_msg[MAXLINE]; + + (void) sprintf( warn_msg, msg, arg ); + warn( warn_msg ); + } + + +/* warn - report a warning, unless -w was given */ + +void warn( str ) +char str[]; + { + line_warning( str, linenum ); + } + +/* format_pinpoint_message - write out a message formatted with one string, + * pinpointing its location + */ + +void format_pinpoint_message( msg, arg ) +char msg[], arg[]; + { + char errmsg[MAXLINE]; + + (void) sprintf( errmsg, msg, arg ); + pinpoint_message( errmsg ); + } + + +/* pinpoint_message - write out a message, pinpointing its location */ + +void pinpoint_message( str ) +char str[]; + { + line_pinpoint( str, linenum ); + } + + +/* line_warning - report a warning at a given line, unless -w was given */ + +void line_warning( str, line ) +char str[]; +int line; + { + char warning[MAXLINE]; + + if ( ! nowarn ) + { + sprintf( warning, "warning, %s", str ); + line_pinpoint( warning, line ); + } + } + + +/* line_pinpoint - write out a message, pinpointing it at the given line */ + +void line_pinpoint( str, line ) +char str[]; +int line; + { + fprintf( stderr, "\"%s\", line %d: %s\n", infilename, line, str ); + } + + +/* yyerror - eat up an error message from the parser; + * currently, messages are ignore + */ + +void yyerror( msg ) +char msg[]; + { + } diff --git a/commands/flex-2.5.4/scan.l b/commands/flex-2.5.4/scan.l new file mode 100644 index 000000000..fee78ab75 --- /dev/null +++ b/commands/flex-2.5.4/scan.l @@ -0,0 +1,710 @@ +/* scan.l - scanner for flex input */ + +%{ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Vern Paxson. + * + * The United States Government has rights in this work pursuant + * to contract no. DE-AC03-76SF00098 between the United States + * Department of Energy and the University of California. + * + * Redistribution and use in source and binary forms with or without + * modification are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: ``This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* $Header$ */ + +#include "flexdef.h" +#include "parse.h" + +#define ACTION_ECHO add_action( yytext ) +#define ACTION_IFDEF(def, should_define) \ + { \ + if ( should_define ) \ + action_define( def, 1 ); \ + } + +#define MARK_END_OF_PROLOG mark_prolog(); + +#define YY_DECL \ + int flexscan() + +#define RETURNCHAR \ + yylval = (unsigned char) yytext[0]; \ + return CHAR; + +#define RETURNNAME \ + strcpy( nmstr, yytext ); \ + return NAME; + +#define PUT_BACK_STRING(str, start) \ + for ( i = strlen( str ) - 1; i >= start; --i ) \ + unput((str)[i]) + +#define CHECK_REJECT(str) \ + if ( all_upper( str ) ) \ + reject = true; + +#define CHECK_YYMORE(str) \ + if ( all_lower( str ) ) \ + yymore_used = true; +%} + +%option caseless nodefault outfile="scan.c" stack noyy_top_state +%option nostdinit + +%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE +%x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION +%x OPTION LINEDIR + +WS [[:blank:]]+ +OPTWS [[:blank:]]* +NOT_WS [^[:blank:]\n] + +NL \r?\n + +NAME ([[:alpha:]_][[:alnum:]_-]*) +NOT_NAME [^[:alpha:]_*\n]+ + +SCNAME {NAME} + +ESCSEQ (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2})) + +FIRST_CCL_CHAR ([^\\\n]|{ESCSEQ}) +CCL_CHAR ([^\\\n\]]|{ESCSEQ}) +CCL_EXPR ("[:"[[:alpha:]]+":]") + +LEXOPT [aceknopr] + +%% + static int bracelevel, didadef, indented_code; + static int doing_rule_action = false; + static int option_sense; + + int doing_codeblock = false; + int i; + Char nmdef[MAXLINE], myesc(); + + +{ + ^{WS} indented_code = true; BEGIN(CODEBLOCK); + ^"/*" ACTION_ECHO; yy_push_state( COMMENT ); + ^#{OPTWS}line{WS} yy_push_state( LINEDIR ); + ^"%s"{NAME}? return SCDECL; + ^"%x"{NAME}? return XSCDECL; + ^"%{".*{NL} { + ++linenum; + line_directive_out( (FILE *) 0, 1 ); + indented_code = false; + BEGIN(CODEBLOCK); + } + + {WS} /* discard */ + + ^"%%".* { + sectnum = 2; + bracelevel = 0; + mark_defs1(); + line_directive_out( (FILE *) 0, 1 ); + BEGIN(SECT2PROLOG); + return SECTEND; + } + + ^"%pointer".*{NL} yytext_is_array = false; ++linenum; + ^"%array".*{NL} yytext_is_array = true; ++linenum; + + ^"%option" BEGIN(OPTION); return OPTION_OP; + + ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL} ++linenum; /* ignore */ + ^"%"{LEXOPT}{WS}.*{NL} ++linenum; /* ignore */ + + ^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) ); + + ^{NAME} { + strcpy( nmstr, yytext ); + didadef = false; + BEGIN(PICKUPDEF); + } + + {SCNAME} RETURNNAME; + ^{OPTWS}{NL} ++linenum; /* allows blank lines in section 1 */ + {OPTWS}{NL} ACTION_ECHO; ++linenum; /* maybe end of comment line */ +} + + +{ + "*/" ACTION_ECHO; yy_pop_state(); + "*" ACTION_ECHO; + [^*\n]+ ACTION_ECHO; + [^*\n]*{NL} ++linenum; ACTION_ECHO; +} + +{ + \n yy_pop_state(); + [[:digit:]]+ linenum = myctoi( yytext ); + + \"[^"\n]*\" { + flex_free( (void *) infilename ); + infilename = copy_string( yytext + 1 ); + infilename[strlen( infilename ) - 1] = '\0'; + } + . /* ignore spurious characters */ +} + +{ + ^"%}".*{NL} ++linenum; BEGIN(INITIAL); + + {NAME}|{NOT_NAME}|. ACTION_ECHO; + + {NL} { + ++linenum; + ACTION_ECHO; + if ( indented_code ) + BEGIN(INITIAL); + } +} + + +{ + {WS} /* separates name and definition */ + + {NOT_WS}.* { + strcpy( (char *) nmdef, yytext ); + + /* Skip trailing whitespace. */ + for ( i = strlen( (char *) nmdef ) - 1; + i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t'); + --i ) + ; + + nmdef[i + 1] = '\0'; + + ndinstal( nmstr, nmdef ); + didadef = true; + } + + {NL} { + if ( ! didadef ) + synerr( _( "incomplete name definition" ) ); + BEGIN(INITIAL); + ++linenum; + } +} + + +