Index: contrib/flex-2.5/AUTHORS =================================================================== RCS file: contrib/flex-2.5/AUTHORS diff -N contrib/flex-2.5/AUTHORS --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/AUTHORS 22 Nov 2002 13:20:23 -0000 @@ -0,0 +1,13 @@ +Vern Paxson wrote flex 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. + +In 2001, W. L. Estes took over as maintainer of flex. + +John Millaway is a co-author of the current version of flex. He has +contributed a large number of new features, fixed a large number of +outstanding bugs and has made significant contributions to the flex +documentation. Index: contrib/flex-2.5/COPYING =================================================================== RCS file: contrib/flex-2.5/COPYING diff -N contrib/flex-2.5/COPYING --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/COPYING 15 Jun 2001 20:21:34 -0000 @@ -0,0 +1,42 @@ +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) 2001 by W. L. Estes + +Copyright (c) 1990, 1997 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 the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +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. Index: contrib/flex-2.5/FlexLexer.h =================================================================== RCS file: contrib/flex-2.5/FlexLexer.h diff -N contrib/flex-2.5/FlexLexer.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/FlexLexer.h 25 Mar 2003 16:39:08 -0000 @@ -0,0 +1,204 @@ +// -*-C++-*- +// 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 the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// 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 +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +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( FLEX_STD istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( FLEX_STD istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream* new_in, FLEX_STD 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( FLEX_STD istream* new_in = 0, + FLEX_STD 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 + +extern "C++" { + +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( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( FLEX_STD istream* s ); + + void yypush_buffer_state( struct yy_buffer_state* new_buffer ); + void yypop_buffer_state(void); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD 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, FLEX_STD 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(); + + FLEX_STD istream* yyin; // input source for default LexerInput + FLEX_STD ostream* yyout; // output sink for default LexerOutput + + // 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; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // 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 Index: contrib/flex-2.5/INSTALL =================================================================== RCS file: contrib/flex-2.5/INSTALL diff -N contrib/flex-2.5/INSTALL --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/INSTALL 21 Feb 2006 02:45:12 -0000 @@ -0,0 +1,229 @@ +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. 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. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, 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 +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + Index: contrib/flex-2.5/NEWS =================================================================== RCS file: contrib/flex-2.5/NEWS diff -N contrib/flex-2.5/NEWS --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/NEWS 20 Feb 2006 19:22:25 -0000 @@ -0,0 +1,416 @@ +This is the file NEWS for the flex package. It records user -visible +changes between releases of flex. + +See the file COPYING for copying conditions. + +* version 2.5.33 released 2006-2-20 + +** all flex resources are now to be found from the website at + http://flex.sourceforge.net/ + +** there was no release 2.5.32 published + +** numerous bug and security fixes + +** new nl, vi, sv, ro, po, ga, ca, fr, tr translations from the translation project + +** upgrade to use gettext 0.12 (this now makes the "pdf" and "ps" + targets in the build system able to be run successfully) + +* version 2.5.31 released 2003-4-1 + +** remove --enable-maintainer-mode configure option; none of the + Makefiles were using it and it can be unduely confusing + +* version 2.5.30 released 2003-4-1 + +** yylineno is per-buffer in reentrant scanners + +** added %top directive for placing code at the top of the generated + scanner; see manual for details + +** flex now uses m4 to generate scanners; while this means that + scanners are more readable, it means that flex requires m4 to be + installed; see manual for details + +* version 2.5.29 released 2003-3-5 + +** Automatic stack management for multiple input buffers in C and C++ scanners + +** moved the flex documentation to a new doc/ subdirectory + +** cleanups to the yy namespace + +* version 2.5.28 released 2003-2-12 + +** flex is now hosted at sourceforge + +** Fixed trailing slash bug in YY_INPUT macro def + +** Flex now warns if always-interactive is specified with fast or full + +* version 2.5.27 released 2003-1-21 + +** flex now works with recent bison versions + +** new pt_br translation from the translation project + +* version 2.5.26 released 2003-1-14 + +** Fixed table deserialization bug on big-endian archs. Patch sent from Bryce Nichols + +** yyleng has proper declarations now; this caused flex to generate + unusable scanners for some programs + +** the flex distribution now includes a spec file suitable for use + with rpm + +** some more c++ fixes + +** new es translation from the translation project + +** slight tweeks to the flex_int*_t types + +** flex now warns about pattern ranges that might be ambiguous when + generating a case-insensitive scanner + + +* version 2.5.25 released 2002-12-2 + +** flex now uses flex_int*_t types. For C99 systems, they are just the + int*_t types; for non-C99 systems, we just make some typedefs + +** new pt_br translation from the translation project + +* version 2.5.24 released 2002-11-25 + +* more portability fixes + +** the manual continues to be updated and edited, but it's still got a + ways to go + +** it is possible to have multiple c++ scanners in the same program again + +** new turkish translation from the translation project + +* version 2.5.23 released 2002-10-21 + +** more portability fixes + +** the manual includes a title page and a table-of-contents when printed + +** the test suite can be run with "make check" from the top-level + directory + +** configure now accepts the --enable-maintainer-mode option + +** gettext functionality is now only available externally + +** the constant FLEX_BETA is defined if flex is a beta release + +** the script create-test was not included in the distribution and it + should have been + +* version 2.5.22 released 2002-10-10 + +** more portability fixes around how we get ahold of the integral + types; there is a constant FLEX_NEED_INTEGRAL_TYPE_DEFINITIONS + which you should define if you don't have the header + file (after you complain to your C vendor for not providing a + reasonable C environment) + +** more test suite cleanups; in particular, the test suite should run + correctly when build from a different directory + +** upgraded automake to 1.7 and consequently autoconf to 2.54; this + means, among other things, that there is some support for +formatting the manual in postscript and pdf in the distributed + Makefile.in (and therefore in the Makefile built by configure) + +** the flex.1 manpage is generated by help2man; (this has been true + for quite a while but was not listed here) + +** flex now includes three defined constants to indicate which version + of flex generated a scanner (YY_FLEX_{MAJOR,MINOR,SUBMINOR}_VERSION) + +** flex tries its best to output only the relevant portions of the + skeleton when generating a scanner, thus avoiding as much + conditional compilation as possible + +* version 2.5.21 released 2002-9-17 + +** one of the tests in the test suite broke the dist target + +* version 2.5.20 released 2002-9-16 + +** A flex scanner has the ability to save the DFA tables to a file, + and load them at runtime when needed; see the manual for details + +** Added %option bison-bridge (--bison-bridge) + +** Removed %option reentrant-bison/--reentrant-bison/-Rb + +** yylineno is present in all scanners; Modified nasty performance + penalty warning with yylineno in documentation + +** test-table-opts is now run last in the test suite because it's so fat + +** flex can, to some extent, diagnose where internal problems occur + +** new translations from the translation project: fr, ca, de, ru, sv + +**Flex generates C99 defs now; see YY_TRADITIONAL_FUNC_DEFS in the + manual if that's not a good thing for you + +* version 2.5.19 released 2002-9-5 + +** prevent segfault on input lines which are longer than the allocated + space (problem report from Manoj Srivastava + ) + +** Changed option 'header' to 'header-file' + +* version 2.5.18 released 2002-9-4 + +** portability fixes for integer constants and in the way the test + suite reports its results + +** the test for bison was reporting bison missing when it was, in + fact, found + +** if we don't find GNU indent, we're more careful when we're not + finding it + +* version 2.5.17 released 2002-8-29 + +** more portability fixes + +** updated config.sub and config.guess + +** flex is indented by GNU indent (this was done earlier but not + explicitly documented) + +* version 2.5.16 released 2002-8-28 + +** c++ scanners compile again + +** there is now an indent target in the top-level Makefile; configure + checks for GNU indent which is required for proper operation of the + indent target + +** some more portability fixes were made + +** %options and invocation sections of manual merged + +** a c++ test was added to the test suite + +** we're trying to clean up more files in the test suite's make clean + targets + +* version 2.5.15 released 2002-8-21 + +** reject-state buffer is now dynamically allocated and REJECT buffer + variables are reentrant-safe + +** manual now discusses memory usage + +** skeleton now processed by m4 before mkskel.sh; (this only matters + if you want to change the skeleton or if you're doing flex development) + +** zh_cn translation added from translation project + +** a bug that caused a segfault has now been fixed + +** the test suite now respects the usual CFLAGS, etc. variables + +** removed some warnings which some tests trigggered with the -s option + +** the flex-generated header file now tries to be smarter about + conditionally including start conditions + +** tables code omitted from generated scanner when not used + +* version 2.5.14 released 2002-8-15 + +** the tests using the reentrant c scanner as c++ were reworked + slightly to be sure that the c++ was enforced + +** de translation now included in the distribution + +** various portability fixes regarding nls support, c++ include + headers, etc. + +* version 2.5.13 released 2002-8-15 + +** the header file output with %option header is now much smaller + +** Fixed type mismatch in printf in scanner skeleton + +** yylex_init now reports errors + +* version 2.5.12 released 2002-8-8 + +** updated gettext support to 0.11.5 + +** new fr translation from the translation project + +** bison is no longer needed to build flex; If you are building flex + from a release (i.e., not from a cvs snapshot), then you don't need + to have a pre-built lex around either (unless you modify scan.l, of + course); (This has been true for some time, but was not mentioned + here.) + +* version 2.5.11 released 2002-7-31 + +** Fixed bug where yyless did not consider yylineno + +** the yylineno performance hit is now gone + +** fixed some typos in the manual and we now include texinfo.tex in + the distribution + +** traditional prototypes output for C scanners, controlled by a + preprocessor symbol; see documentation for details + +* version 2.5.10 released 2002-7-24 + +** yy_globals renamed to yyscanner and yy_globals_t renamed to + yy_guts_t + +** added dist-bzip2 option to Makefile.am so we now produce a bzip2'd + archive in addition to the standard gzip archive + +* version 2.5.9 + +** new tests in test suite: test-mem-{nr,r}, test-posix, + test-posixly-correct, test-debug-{nr,r} + +** made changes to work with gcc-3.2 development code + +** ability to choose which memory functions are used in flex + +** new yylex_destroy() function for the non-reentrant scanner + +** new handling of POSIXLY_CORRECT environment variable + +** the test suite now has its copyrights explicitly described + +** new ca, de, fr, ru, sv, tr translations + +* version 2.5.8 + +** a new --posix option generates scanners with posix-style abc{1,3} + compatible parsing, see manual for the screwy details + +* version 2.5.7 + +** configure.in now includes a call to AC_PREREQ to enforce the + requirement for autoconf at least 2.50 (This only effects you if + you're doing flex development.) + +** configure now uses autoconf's versioning information and configure + --help reports the bug-reporting address for flex + +** test suite now only reports success versus failure; reporting + skipped is problematic under the current setup + +** compilation with --disable-nls now works + +** flex can now be built in a separate directory + +* version 2.5.6 + +** gettext support added (from gettext 0.11) + +*** translations for ca, da, de, es, fr, ko, ru, sv, tr included + +** distribution now built under automake 1.6 and autoconf 2.53 + +** command-line option parsing happens differently now: + +*** Added long option parsing + +*** Options -n and -c, previously deprecated, now simply do nothing + +*** Options are now parsed left to right + +** added a number of new options + +*** All positive %options are now accessible from the command line + +*** Added option -D, to define a preprocessor symbol + +*** Added option --header=FILE to specify a C .h file to generate + +*** added option --yywrap to call yywrap on EOF + +*** added option --yylineno to track line count in yylineno + +*** --yyclass=NAME name of C++ class when generating c++ scanners + +*** for long option names which are associated with existing short +options, see accompanying documentation + +*** new %option nounistd or command-line --nounistd added to prevent + flex from generating #include on systems that don't + have that include file + +** Support for reentrant C scanners has been added + +*** Updated the manual with the new reentrant API + +*** Two new options %option reentrant (-R) and +%option reentrant-bison (-Rb) + +*** All globals optionally placed into struct yyglobals_t + +*** All access to globals replaced by macro invocations + +*** All functions optionally take one additional +argument, yy_globals + +*** New style for invoking reentrant scanner: +yylex_init(void** scanner ); +yylex( scanner ); +yylex_destroy( scanner ); + +*** Added get/set functions for members of struct yy_globals_t +e.g., yyget_text, yyget_leng, etc + +*** Prefix substitution added for new functions + +*** Macro shortcuts to the lengthy get/set functions +provided for use in actions, e.g., yytext, yyleng, etc + +*** Arbitrary, user-defined data, "yyextra", may be added to scanner + +** %option nomain no longer implies %option yywrap +But the inverse is still true + +** Developer test suite added + +*** TESTS/ directory has been added. Users can +'make test' in the TESTS directory to execute the test suite + +** Support for bison variables yylval and yylloc added + +** automake support for the build process + +** manual is now in texinfo/info format + +*** flex.1 removed from distribution + +** flex no longer generates C-language scanners with C++-style + comments + +** flex now generates scanners in c++ which are compatible with + recent c++ compilers + +** flex input scanner now recognizes '\r' as an EOL character + +See the file ONEWS for changes in earlier releases. + +Local Variables: +mode: text +mode: outline-minor +end: Index: contrib/flex-2.5/README =================================================================== RCS file: contrib/flex-2.5/README diff -N contrib/flex-2.5/README --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/README 15 Feb 2006 21:08:40 -0000 @@ -0,0 +1,69 @@ +This is flex, the fast lexical analyzer generator. + +flex is a tool for generating scanners: programs which recognize +lexical patterns in text. + +More information about flex as well as the latest official release of +flex can be found at: + +http://flex.sourceforge.net/ + +Of particular interest is the mailing list +flex-announce@lists.sourceforge.net as that is where posts will be made +announcing new releases of flex. + +Note that flex is distributed under a copyright very similar to that of +BSD Unix, and not under the GNU General Public License (GPL). + +This file is part of flex. + +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 the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +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. + +Please send bug reports and feedback to flex-help@lists.sourceforge.net. + +The flex distribution contains the following files which may be of interest: + +README - This file. + +NEWS - current version number and list of user-visible changes. + +INSTALL - basic installation information. + +ABOUT-NLS - description of internationalization support in flex. + +COPYING - flex's copyright and license. + +doc/ - user documentation. + +examples/ - containing examples of some possible flex scanners and a +few other things. See the file examples/README for more details. + +TODO - outstanding bug reports, desired features, etc. + +tests/ - regression tests. See TESTS/README for details. + +po/ - internationalization support files. Index: contrib/flex-2.5/buf.c =================================================================== RCS file: contrib/flex-2.5/buf.c diff -N contrib/flex-2.5/buf.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/buf.c 22 Dec 2005 00:24:19 -0000 @@ -0,0 +1,254 @@ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" + +/* Take note: The buffer object is sometimes used as a String buffer (one + * continuous string), and sometimes used as a list of strings, usually line by + * line. + * + * The type is specified in buf_init by the elt_size. If the elt_size is + * sizeof(char), then the buffer should be treated as string buffer. If the + * elt_size is sizeof(char*), then the buffer should be treated as a list of + * strings. + * + * Certain functions are only appropriate for one type or the other. + */ + +/* global buffers. */ +struct Buf userdef_buf; /**< for user #definitions triggered by cmd-line. */ +struct Buf defs_buf; /**< for #define's autogenerated. List of strings. */ +struct Buf yydmap_buf; /**< string buffer to hold yydmap elements */ +struct Buf m4defs_buf; /**< m4 definitions. List of strings. */ +struct Buf top_buf; /**< contains %top code. String buffer. */ + +struct Buf *buf_print_strings(struct Buf * buf, FILE* out) +{ + int i; + + if(!buf || !out) + return buf; + + for (i=0; i < buf->nelts; i++){ + const char * s = ((char**)buf->elts)[i]; + if(s) + fprintf(out, "%s", s); + } + return buf; +} + +/* Append a "%s" formatted string to a string buffer */ +struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char *s) +{ + char *t; + + t = flex_alloc (strlen (fmt) + strlen (s) + 1); + sprintf (t, fmt, s); + buf = buf_strappend (buf, t); + flex_free (t); + return buf; +} + +/** Append a line directive to the string buffer. + * @param buf A string buffer. + * @param filename file name + * @param lineno line number + * @return buf + */ +struct Buf *buf_linedir (struct Buf *buf, const char* filename, int lineno) +{ + char *t, *fmt = "#line %d \"%s\"\n"; + + t = flex_alloc (strlen (fmt) + strlen (filename) + (int)(1 + log10(lineno>=0?lineno:-lineno)) + 1); + sprintf (t, fmt, lineno, filename); + buf = buf_strappend (buf, t); + flex_free (t); + return buf; +} + + +/** Append the contents of @a src to @a dest. + * @param @a dest the destination buffer + * @param @a dest the source buffer + * @return @a dest + */ +struct Buf *buf_concat(struct Buf* dest, const struct Buf* src) +{ + buf_append(dest, src->elts, src->nelts); + return dest; +} + + +/* Appends n characters in str to buf. */ +struct Buf *buf_strnappend (buf, str, n) + struct Buf *buf; + const char *str; + int n; +{ + buf_append (buf, str, n + 1); + + /* "undo" the '\0' character that buf_append() already copied. */ + buf->nelts--; + + return buf; +} + +/* Appends characters in str to buf. */ +struct Buf *buf_strappend (buf, str) + struct Buf *buf; + const char *str; +{ + return buf_strnappend (buf, str, strlen (str)); +} + +/* appends "#define str def\n" */ +struct Buf *buf_strdefine (buf, str, def) + struct Buf *buf; + const char *str; + const char *def; +{ + buf_strappend (buf, "#define "); + buf_strappend (buf, " "); + buf_strappend (buf, str); + buf_strappend (buf, " "); + buf_strappend (buf, def); + buf_strappend (buf, "\n"); + return buf; +} + +/** Pushes "m4_define( [[def]], [[val]])m4_dnl" to end of buffer. + * @param buf A buffer as a list of strings. + * @param def The m4 symbol to define. + * @param val The definition; may be NULL. + * @return buf + */ +struct Buf *buf_m4_define (struct Buf *buf, const char* def, const char* val) +{ + const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; + char * str; + + val = val?val:""; + str = (char*)flex_alloc(strlen(fmt) + strlen(def) + strlen(val) + 2); + + sprintf(str, fmt, def, val); + buf_append(buf, &str, 1); + return buf; +} + +/** Pushes "m4_undefine([[def]])m4_dnl" to end of buffer. + * @param buf A buffer as a list of strings. + * @param def The m4 symbol to undefine. + * @return buf + */ +struct Buf *buf_m4_undefine (struct Buf *buf, const char* def) +{ + const char * fmt = "m4_undefine( [[%s]])m4_dnl\n"; + char * str; + + str = (char*)flex_alloc(strlen(fmt) + strlen(def) + 2); + + sprintf(str, fmt, def); + buf_append(buf, &str, 1); + return buf; +} + +/* create buf with 0 elements, each of size elem_size. */ +void buf_init (buf, elem_size) + struct Buf *buf; + size_t elem_size; +{ + buf->elts = (void *) 0; + buf->nelts = 0; + buf->elt_size = elem_size; + buf->nmax = 0; +} + +/* frees memory */ +void buf_destroy (buf) + struct Buf *buf; +{ + if (buf && buf->elts) + flex_free (buf->elts); + buf->elts = (void *) 0; +} + + +/* appends ptr[] to buf, grow if necessary. + * n_elem is number of elements in ptr[], NOT bytes. + * returns buf. + * We grow by mod(512) boundaries. + */ + +struct Buf *buf_append (buf, ptr, n_elem) + struct Buf *buf; + const void *ptr; + int n_elem; +{ + int n_alloc = 0; + + if (!ptr || n_elem == 0) + return buf; + + /* May need to alloc more. */ + if (n_elem + buf->nelts > buf->nmax) { + + /* exact amount needed... */ + n_alloc = (n_elem + buf->nelts) * buf->elt_size; + + /* ...plus some extra */ + if (((n_alloc * buf->elt_size) % 512) != 0 + && buf->elt_size < 512) + n_alloc += + (512 - + ((n_alloc * buf->elt_size) % 512)) / + buf->elt_size; + + if (!buf->elts) + buf->elts = + allocate_array (n_alloc, buf->elt_size); + else + buf->elts = + reallocate_array (buf->elts, n_alloc, + buf->elt_size); + + buf->nmax = n_alloc; + } + + memcpy ((char *) buf->elts + buf->nelts * buf->elt_size, ptr, + n_elem * buf->elt_size); + buf->nelts += n_elem; + + return buf; +} + +/* vim:set tabstop=8 softtabstop=4 shiftwidth=4: */ Index: contrib/flex-2.5/ccl.c =================================================================== RCS file: contrib/flex-2.5/ccl.c diff -N contrib/flex-2.5/ccl.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/ccl.c 16 Dec 2002 23:28:23 -0000 @@ -0,0 +1,199 @@ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#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; + + /* mark newlines */ + if (ch == nlch) + ccl_has_nl[cclp] = true; + + 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); + ccl_has_nl = + reallocate_bool_array (ccl_has_nl, + 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 */ + ccl_has_nl[lastccl] = false; + + return lastccl; +} + + +/* cclnegate - negate the given ccl */ + +void cclnegate (cclp) + int cclp; +{ + cclng[cclp] = 1; + ccl_has_nl[cclp] = !ccl_has_nl[cclp]; +} + + +/* 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); +} + +/** Determines if the range [c1-c2] is unambiguous in a case-insensitive + * scanner. Specifically, if a lowercase or uppercase character, x, is in the + * range [c1-c2], then we require that UPPERCASE(x) and LOWERCASE(x) must also + * be in the range. If not, then this range is ambiguous, and the function + * returns false. For example, [@-_] spans [a-z] but not [A-Z]. Beware that + * [a-z] will be labeled ambiguous because it does not include [A-Z]. + * + * @param c1 the lower end of the range + * @param c2 the upper end of the range + * @return true if [c1-c2] is not ambiguous for a caseless scanner. + */ +bool range_covers_case (int c1, int c2) +{ + int i, o; + + for (i = c1; i <= c2; i++) { + if (has_case (i)) { + o = reverse_case (i); + if (o < c1 || c2 < o) + return false; + } + } + return true; +} + +/** Reverse the case of a character, if possible. + * @return c if case-reversal does not apply. + */ +int reverse_case (int c) +{ + return isupper (c) ? tolower (c) : (islower (c) ? toupper (c) : c); +} + +/** Return true if c is uppercase or lowercase. */ +bool has_case (int c) +{ + return (isupper (c) || islower (c)) ? true : false; +} Index: contrib/flex-2.5/dfa.c =================================================================== RCS file: contrib/flex-2.5/dfa.c diff -N contrib/flex-2.5/dfa.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/dfa.c 14 Feb 2006 06:38:28 -0000 @@ -0,0 +1,1118 @@ +/* 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 the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" +#include "tables.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) \ +do{ trans1[state] = trans1[state] - MARKER_DIFFERENCE;} while(0) + +#define IS_MARKED(state) (trans1[state] < 0) + +#define UNMARK_STATE(state) \ +do{ trans1[state] = trans1[state] + MARKER_DIFFERENCE;} while(0) + +#define CHECK_ACCEPT(state) \ +do{ \ +nfaccnum = accptnum[state]; \ +if ( nfaccnum != NIL ) \ +accset[++nacc] = nfaccnum; \ +}while(0) + +#define DO_REALLOCATION() \ +do { \ +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 ); \ +}while(0) \ + +#define PUT_ON_STACK(state) \ +do { \ +if ( ++stkend >= current_max_dfa_size ) \ +DO_REALLOCATION(); \ +stk[stkend] = state; \ +MARK_STATE(state); \ +}while(0) + +#define ADD_STATE(state) \ +do { \ +if ( ++numstates >= current_max_dfa_size ) \ +DO_REALLOCATION(); \ +t[numstates] = state; \ +hashval += state; \ +}while(0) + +#define STACK_STATE(state) \ +do { \ +PUT_ON_STACK(state); \ +CHECK_ACCEPT(state); \ +if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \ +ADD_STATE(state); \ +}while(0) + + + 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=0; /* 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; + + struct yytbl_data *yynxt_tbl = 0; + flex_int32_t *yynxt_data = 0, yynxt_curr = 0; + + /* 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 needs to be large enough to hold all of the rules present + * in the input, *plus* their YY_TRAILING_HEAD_MASK variants. + */ + accset = allocate_integer_array ((num_rules + 1) * 2); + 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; + + /* Begin generating yy_nxt[][] + * This spans the entire LONG function. + * This table is tricky because we don't know how big it will be. + * So we'll have to realloc() on the way... + * we'll wait until we can calculate yynxt_tbl->td_hilen. + */ + yynxt_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct + yytbl_data)); + yytbl_data_init (yynxt_tbl, YYTD_ID_NXT); + yynxt_tbl->td_hilen = 1; + yynxt_tbl->td_lolen = num_full_table_rows; + yynxt_tbl->td_data = yynxt_data = + (flex_int32_t *) calloc (yynxt_tbl->td_lolen * + yynxt_tbl->td_hilen, + sizeof (flex_int32_t)); + yynxt_curr = 0; + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + + /* Unless -Ca, declare it "short" because it's a real + * long-shot that that won't be large enough. + */ + if (gentables) + out_str_dec + ("static yyconst %s yy_nxt[][%d] =\n {\n", + long_align ? "flex_int32_t" : "flex_int16_t", + num_full_table_rows); + else { + out_dec ("#undef YY_NXT_LOLEN\n#define YY_NXT_LOLEN (%d)\n", num_full_table_rows); + out_str ("static yyconst %s *yy_nxt =0;\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + } + + + if (gentables) + outn (" {"); + + /* Generate 0 entries for state #0. */ + for (i = 0; i < num_full_table_rows; ++i) { + mk2data (0); + yynxt_data[yynxt_curr++] = 0; + } + + dataflush (); + if (gentables) + 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) { + + /* Each time we hit here, it's another td_hilen, so we realloc. */ + yynxt_tbl->td_hilen++; + yynxt_tbl->td_data = yynxt_data = + (flex_int32_t *) realloc (yynxt_data, + yynxt_tbl->td_hilen * + yynxt_tbl->td_lolen * + sizeof (flex_int32_t)); + + + if (gentables) + outn (" {"); + + /* Supply array's 0-element. */ + if (ds == end_of_buffer_state) { + mk2data (-end_of_buffer_state); + yynxt_data[yynxt_curr++] = + -end_of_buffer_state; + } + else { + mk2data (end_of_buffer_state); + yynxt_data[yynxt_curr++] = + 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); + yynxt_data[yynxt_curr++] = + state[i] ? state[i] : -ds; + } + + dataflush (); + if (gentables) + 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 (); + if (tablesext) { + yytbl_data_compress (yynxt_tbl); + if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0) + flexerror (_ + ("Could not write yynxt_tbl[][]")); + } + if (yynxt_tbl) { + yytbl_data_destroy (yynxt_tbl); + yynxt_tbl = 0; + } + } + + 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; + } + } + } + } +} Index: contrib/flex-2.5/ecs.c =================================================================== RCS file: contrib/flex-2.5/ecs.c diff -N contrib/flex-2.5/ecs.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/ecs.c 27 Aug 2002 18:07:19 -0000 @@ -0,0 +1,219 @@ +/* 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. */ + +/* This file is part of flex */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + + +#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; +} Index: contrib/flex-2.5/filter.c =================================================================== RCS file: contrib/flex-2.5/filter.c diff -N contrib/flex-2.5/filter.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/filter.c 14 Feb 2006 03:32:28 -0000 @@ -0,0 +1,405 @@ +/* filter - postprocessing of flex output through filters */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" +static const char * check_4_gnu_m4 = + "m4_dnl ifdef(`__gnu__', ," + "`errprint(Flex requires GNU M4. Set the PATH or set the M4 environment variable to its path name.)" + " m4exit(2)')\n"; + + +/** global chain. */ +struct filter *output_chain = NULL; + +/* Allocate and initialize an external filter. + * @param chain the current chain or NULL for new chain + * @param cmd the command to execute. + * @param ... a NULL terminated list of (const char*) arguments to command, + * not including argv[0]. + * @return newest filter in chain + */ +struct filter *filter_create_ext (struct filter *chain, const char *cmd, + ...) +{ + struct filter *f; + int max_args; + const char *s; + va_list ap; + + /* allocate and initialize new filter */ + f = (struct filter *) flex_alloc (sizeof (struct filter)); + memset (f, 0, sizeof (*f)); + f->filter_func = NULL; + f->extra = NULL; + f->next = NULL; + f->argc = 0; + + if (chain != NULL) { + /* append f to end of chain */ + while (chain->next) + chain = chain->next; + chain->next = f; + } + + + /* allocate argv, and populate it with the argument list. */ + max_args = 8; + f->argv = + (const char **) flex_alloc (sizeof (char *) * + (max_args + 1)); + f->argv[f->argc++] = cmd; + + va_start (ap, cmd); + while ((s = va_arg (ap, const char *)) != NULL) { + if (f->argc >= max_args) { + max_args += 8; + f->argv = + (const char **) flex_realloc (f->argv, + sizeof (char + *) * + (max_args + + 1)); + } + f->argv[f->argc++] = s; + } + f->argv[f->argc] = NULL; + + va_end (ap); + return f; +} + +/* Allocate and initialize an internal filter. + * @param chain the current chain or NULL for new chain + * @param filter_func The function that will perform the filtering. + * filter_func should return 0 if successful, and -1 + * if an error occurs -- or it can simply exit(). + * @param extra optional user-defined data to pass to the filter. + * @return newest filter in chain + */ +struct filter *filter_create_int (struct filter *chain, + int (*filter_func) (struct filter *), + void *extra) +{ + struct filter *f; + + /* allocate and initialize new filter */ + f = (struct filter *) flex_alloc (sizeof (struct filter)); + memset (f, 0, sizeof (*f)); + f->next = NULL; + f->argc = 0; + f->argv = NULL; + + f->filter_func = filter_func; + f->extra = extra; + + if (chain != NULL) { + /* append f to end of chain */ + while (chain->next) + chain = chain->next; + chain->next = f; + } + + return f; +} + +/** Fork and exec entire filter chain. + * @param chain The head of the chain. + * @return true on success. + */ +bool filter_apply_chain (struct filter * chain) +{ + int pid, pipes[2]; + + /* Tricky recursion, since we want to begin the chain + * at the END. Why? Because we need all the forked processes + * to be children of the main flex process. + */ + if (chain) + filter_apply_chain (chain->next); + else + return true; + + /* Now we are the right-most unprocessed link in the chain. + */ + + fflush (stdout); + fflush (stderr); + + if (pipe (pipes) == -1) + flexerror (_("pipe failed")); + + if ((pid = fork ()) == -1) + flexerror (_("fork failed")); + + if (pid == 0) { + /* child */ + close (pipes[1]); + if (dup2 (pipes[0], 0) == -1) + flexfatal (_("dup2(pipes[0],0)")); + close (pipes[0]); + + /* run as a filter, either internally or by exec */ + if (chain->filter_func) { + int r; + + /* setup streams again */ + if ( ! fdopen (0, "r")) + flexfatal (_("fdopen(0) failed")); + if (!fdopen (1, "w")) + flexfatal (_("fdopen(1) failed")); + + if ((r = chain->filter_func (chain)) == -1) + flexfatal (_("filter_func failed")); + exit (0); + } + else { + execvp (chain->argv[0], + (char **const) (chain->argv)); + flexfatal (_("exec failed")); + } + + exit (1); + } + + /* Parent */ + close (pipes[0]); + if (dup2 (pipes[1], 1) == -1) + flexfatal (_("dup2(pipes[1],1)")); + close (pipes[1]); + if ( !fdopen (1, "w")) + flexfatal (_("fdopen(1) failed")); + + return true; +} + +/** Truncate the chain to max_len number of filters. + * @param chain the current chain. + * @param max_len the maximum length of the chain. + * @return the resulting length of the chain. + */ +int filter_truncate (struct filter *chain, int max_len) +{ + int len = 1; + + if (!chain) + return 0; + + while (chain->next && len < max_len) { + chain = chain->next; + ++len; + } + + chain->next = NULL; + return len; +} + +/** Splits the chain in order to write to a header file. + * Similar in spirit to the 'tee' program. + * The header file name is in extra. + * @return 0 (zero) on success, and -1 on failure. + */ +int filter_tee_header (struct filter *chain) +{ + /* This function reads from stdin and writes to both the C file and the + * header file at the same time. + */ + + const int readsz = 512; + char *buf; + int to_cfd = -1; + FILE *to_c = NULL, *to_h = NULL; + bool write_header; + + write_header = (chain->extra != NULL); + + /* Store a copy of the stdout pipe, which is already piped to C file + * through the running chain. Then create a new pipe to the H file as + * stdout, and fork the rest of the chain again. + */ + + if ((to_cfd = dup (1)) == -1) + flexfatal (_("dup(1) failed")); + to_c = fdopen (to_cfd, "w"); + + if (write_header) { + if (freopen ((char *) chain->extra, "w", stdout) == NULL) + flexfatal (_("freopen(headerfilename) failed")); + + filter_apply_chain (chain->next); + to_h = stdout; + } + + /* Now to_c is a pipe to the C branch, and to_h is a pipe to the H branch. + */ + + if (write_header) { + fputs (check_4_gnu_m4, to_h); + fputs ("m4_changecom`'m4_dnl\n", to_h); + fputs ("m4_changequote`'m4_dnl\n", to_h); + fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_h); + fputs ("m4_define( [[M4_YY_IN_HEADER]],[[]])m4_dnl\n", + to_h); + fprintf (to_h, "#ifndef %sHEADER_H\n", prefix); + fprintf (to_h, "#define %sHEADER_H 1\n", prefix); + fprintf (to_h, "#define %sIN_HEADER 1\n\n", prefix); + fprintf (to_h, + "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", + headerfilename ? headerfilename : ""); + + } + + fputs (check_4_gnu_m4, to_c); + fputs ("m4_changecom`'m4_dnl\n", to_c); + fputs ("m4_changequote`'m4_dnl\n", to_c); + fputs ("m4_changequote([[,]])[[]]m4_dnl\n", to_c); + fprintf (to_c, "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n", + outfilename ? outfilename : ""); + + buf = (char *) flex_alloc (readsz); + while (fgets (buf, readsz, stdin)) { + fputs (buf, to_c); + if (write_header) + fputs (buf, to_h); + } + + if (write_header) { + fprintf (to_h, "\n"); + + /* write a fake line number. It will get fixed by the linedir filter. */ + fprintf (to_h, "#line 4000 \"M4_YY_OUTFILE_NAME\"\n"); + + fprintf (to_h, "#undef %sIN_HEADER\n", prefix); + fprintf (to_h, "#endif /* %sHEADER_H */\n", prefix); + fputs ("m4_undefine( [[M4_YY_IN_HEADER]])m4_dnl\n", to_h); + + fflush (to_h); + if (ferror (to_h)) + lerrsf (_("error writing output file %s"), + (char *) chain->extra); + + else if (fclose (to_h)) + lerrsf (_("error closing output file %s"), + (char *) chain->extra); + } + + fflush (to_c); + if (ferror (to_c)) + lerrsf (_("error writing output file %s"), + outfilename ? outfilename : ""); + + else if (fclose (to_c)) + lerrsf (_("error closing output file %s"), + outfilename ? outfilename : ""); + + while (wait (0) > 0) ; + + exit (0); + return 0; +} + +/** Adjust the line numbers in the #line directives of the generated scanner. + * After the m4 expansion, the line numbers are incorrect since the m4 macros + * can add or remove lines. This only adjusts line numbers for generated code, + * not user code. This also happens to be a good place to squeeze multiple + * blank lines into a single blank line. + */ +int filter_fix_linedirs (struct filter *chain) +{ + char *buf; + const int readsz = 512; + int lineno = 1; + bool in_gen = true; /* in generated code */ + bool last_was_blank = false; + + if (!chain) + return 0; + + buf = (char *) flex_alloc (readsz); + + while (fgets (buf, readsz, stdin)) { + + regmatch_t m[10]; + + /* Check for #line directive. */ + if (buf[0] == '#' + && regexec (®ex_linedir, buf, 3, m, 0) == 0) { + + int num; + char *fname; + + /* extract the line number and filename */ + num = regmatch_strtol (&m[1], buf, NULL, 0); + fname = regmatch_dup (&m[2], buf); + + if (strcmp + (fname, outfilename ? outfilename : "") + == 0 + || strcmp (fname, + headerfilename ? headerfilename : + "") == 0) { + /* Adjust the line directives. */ + in_gen = true; + sprintf (buf, "#line %d \"%s\"\n", + lineno + 1, fname); + free (fname); + + } + else { + /* it's a #line directive for code we didn't write */ + in_gen = false; + } + + last_was_blank = false; + } + + /* squeeze blank lines from generated code */ + else if (in_gen + && regexec (®ex_blank_line, buf, 0, NULL, + 0) == 0) { + if (last_was_blank) + continue; + else + last_was_blank = true; + } + + else { + /* it's a line of normal, non-empty code. */ + last_was_blank = false; + } + + fputs (buf, stdout); + lineno++; + } + fflush (stdout); + if (ferror (stdout)) + lerrsf (_("error writing output file %s"), + outfilename ? outfilename : ""); + + else if (fclose (stdout)) + lerrsf (_("error closing output file %s"), + outfilename ? outfilename : ""); + + return 0; +} + +/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ Index: contrib/flex-2.5/flexdef.h =================================================================== RCS file: contrib/flex-2.5/flexdef.h diff -N contrib/flex-2.5/flexdef.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/flexdef.h 14 Feb 2006 19:38:11 -0000 @@ -0,0 +1,1182 @@ + +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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 FLEXDEF_H +#define FLEXDEF_H 1 + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef STDC_HEADERS +#include +#include +#include +#include +#include +#include +#include +#endif +#ifdef HAVE_LIMITS_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_SYS_PARAMS_H +#include +#endif +#ifdef HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_STDBOOL_H +#include +#else +#define bool int +#define true 1 +#define false 0 +#endif +#include +#include "flexint.h" + +/* We use gettext. So, when we write strings which should be translated, we mark them with _() */ +#ifdef ENABLE_NLS +#ifdef HAVE_LOCALE_H +#include +#endif /* HAVE_LOCALE_H */ +#include "gettext.h" +#define _(String) gettext (String) +#else +#define _(STRING) STRING +#endif /* ENABLE_NLS */ + +/* 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 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 INFINITE_REPEAT -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 +#define MAXIMUM_MNS_LONG 1999999999 + +/* 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 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 + * posix_compat - if true (-X), maximize compatibility with POSIX 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 + * reentrant - if true (-R), generate a reentrant C scanner. + * bison_bridge_lval - if true (--bison-bridge), bison pure calling convention. + * bison_bridge_lloc - if true (--bison-locations), bison yylloc. + * 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, posix_compat, do_yylineno; +extern int useecs, fulltbl, usemecs, fullspd; +extern int gen_line_dirs, performance_report, backing_up_report; +extern int reentrant, bison_bridge_lval, bison_bridge_lloc; +extern bool ansi_func_defs, ansi_func_protos; +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 + * headerfilename - name of the .h file to generate + * 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, *headerfilename; +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: + * maximum_mns - maximal number of NFA states supported by tables + * 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 + * rule_has_nl - true if rule could possibly match a newline + * ccl_has_nl - true if current ccl could match a newline + * nlch - default eol char + */ + +extern int maximum_mns, 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; +extern bool *rule_has_nl, *ccl_has_nl; +extern int nlch; + +/* 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_bool_array(size) \ + (bool *) allocate_array( size, sizeof( bool ) ) + +#define reallocate_bool_array(array,size) \ + (bool *) reallocate_array( (void *) array, size, sizeof( bool ) ) + +#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 ((const char *, const char *)); + +/* Write out a string + newline at the current indentation level. */ +extern void indent_puts PROTO ((const 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 ((const 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 *)); + +/* Report a fatal error with a pinpoint, and terminate */ +#if HAVE_DECL___FUNC__ +#define flex_die(msg) \ + do{ \ + fprintf (stderr,\ + _("%s: fatal internal error at %s:%d (%s): %s\n"),\ + program_name, __FILE__, (int)__LINE__,\ + __func__,msg);\ + FLEX_EXIT(1);\ + }while(0) +#else /* ! HAVE_DECL___FUNC__ */ +#define flex_die(msg) \ + do{ \ + fprintf (stderr,\ + _("%s: fatal internal error at %s:%d %s\n"),\ + program_name, __FILE__, (int)__LINE__,\ + msg);\ + FLEX_EXIT(1);\ + }while(0) +#endif /* ! HAVE_DECL___func__ */ + +/* 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 ((const 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 *)); +extern void out_m4_define (const char* def, const char* val); + +/* 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, 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 ((const char *, const char *)); + +/* Write out a message, pinpointing its location. */ +extern void pinpoint_message PROTO ((const char *)); + +/* Write out a warning, pinpointing it at the given line. */ +extern void line_warning PROTO ((const char *, int)); + +/* Write out a message, pinpointing it at the given line. */ +extern void line_pinpoint PROTO ((const char *, int)); + +/* Report a formatted syntax error. */ +extern void format_synerr PROTO ((const char *, const char *)); +extern void synerr PROTO ((const char *)); /* report a syntax error */ +extern void format_warn PROTO ((const char *, const char *)); +extern void warn PROTO ((const char *)); /* report a warning */ +extern void yyerror PROTO ((const 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 */ + +/* 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[])); + +extern void ndinstal PROTO ((const char *, Char[])); /* install a name definition */ +extern Char *ndlookup PROTO ((const char *)); /* lookup a name definition */ + +/* Increase maximum number of SC's. */ +extern void scextend PROTO ((void)); +extern void scinstal PROTO ((const char *, int)); /* make a start condition */ + +/* Lookup the number associated with a start condition. */ +extern int sclookup PROTO ((const 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)); + +/* A growable array. See buf.c. */ +struct Buf { + void *elts; /* elements. */ + int nelts; /* number of elements. */ + size_t elt_size; /* in bytes. */ + int nmax; /* max capacity of elements. */ +}; + +extern void buf_init PROTO ((struct Buf * buf, size_t elem_size)); +extern void buf_destroy PROTO ((struct Buf * buf)); +extern struct Buf *buf_append +PROTO ((struct Buf * buf, const void *ptr, int n_elem)); +extern struct Buf *buf_concat PROTO((struct Buf* dest, const struct Buf* src)); +extern struct Buf *buf_strappend PROTO ((struct Buf *, const char *str)); +extern struct Buf *buf_strnappend +PROTO ((struct Buf *, const char *str, int nchars)); +extern struct Buf *buf_strdefine +PROTO ((struct Buf * buf, const char *str, const char *def)); +extern struct Buf *buf_prints PROTO((struct Buf *buf, const char *fmt, const char* s)); +extern struct Buf *buf_m4_define PROTO((struct Buf *buf, const char* def, const char* val)); +extern struct Buf *buf_m4_undefine PROTO((struct Buf *buf, const char* def)); +extern struct Buf *buf_print_strings PROTO((struct Buf * buf, FILE* out)); +extern struct Buf *buf_linedir PROTO((struct Buf *buf, const char* filename, int lineno)); + +extern struct Buf userdef_buf; /* a string buffer for #define's generated by user-options on cmd line. */ +extern struct Buf defs_buf; /* a char* buffer to save #define'd some symbols generated by flex. */ +extern struct Buf yydmap_buf; /* a string buffer to hold yydmap elements */ +extern struct Buf m4defs_buf; /* Holds m4 definitions. */ +extern struct Buf top_buf; /* contains %top code. String buffer. */ + +/* For blocking out code from the header file. */ +#define OUT_BEGIN_CODE() outn("m4_ifdef( [[M4_YY_IN_HEADER]],,[[") +#define OUT_END_CODE() outn("]])") + +/* For setjmp/longjmp (instead of calling exit(2)). Linkage in main.c */ +extern jmp_buf flex_main_jmp_buf; + +#define FLEX_EXIT(status) longjmp(flex_main_jmp_buf,(status)+1) + +/* Removes all \n and \r chars from tail of str. returns str. */ +extern char *chomp (char *str); + +/* ctype functions forced to return boolean */ +#define b_isalnum(c) (isalnum(c)?true:false) +#define b_isalpha(c) (isalpha(c)?true:false) +#define b_isascii(c) (isascii(c)?true:false) +#define b_isblank(c) (isblank(c)?true:false) +#define b_iscntrl(c) (iscntrl(c)?true:false) +#define b_isdigit(c) (isdigit(c)?true:false) +#define b_isgraph(c) (isgraph(c)?true:false) +#define b_islower(c) (islower(c)?true:false) +#define b_isprint(c) (isprint(c)?true:false) +#define b_ispunct(c) (ispunct(c)?true:false) +#define b_isspace(c) (isspace(c)?true:false) +#define b_isupper(c) (isupper(c)?true:false) +#define b_isxdigit(c) (isxdigit(c)?true:false) + +/* return true if char is uppercase or lowercase. */ +bool has_case(int c); + +/* Change case of character if possible. */ +int reverse_case(int c); + +/* return false if [c1-c2] is ambiguous for a caseless scanner. */ +bool range_covers_case (int c1, int c2); + +/* + * From "filter.c" + */ + +/** A single stdio filter to execute. + * The filter may be external, such as "sed", or it + * may be internal, as a function call. + */ +struct filter { + int (*filter_func)(struct filter*); /**< internal filter function */ + void * extra; /**< extra data passed to filter_func */ + int argc; /**< arg count */ + const char ** argv; /**< arg vector, \0-terminated */ + struct filter * next; /**< next filter or NULL */ +}; + +/* output filter chain */ +extern struct filter * output_chain; +extern struct filter *filter_create_ext PROTO((struct filter * chain, const char *cmd, ...)); +struct filter *filter_create_int PROTO((struct filter *chain, + int (*filter_func) (struct filter *), + void *extra)); +extern bool filter_apply_chain PROTO((struct filter * chain)); +extern int filter_truncate (struct filter * chain, int max_len); +extern int filter_tee_header PROTO((struct filter *chain)); +extern int filter_fix_linedirs PROTO((struct filter *chain)); + + +/* + * From "regex.c" + */ + +extern regex_t regex_linedir, regex_blank_line; +bool flex_init_regex(void); +void flex_regcomp(regex_t *preg, const char *regex, int cflags); +char *regmatch_dup (regmatch_t * m, const char *src); +char *regmatch_cpy (regmatch_t * m, char *dest, const char *src); +int regmatch_len (regmatch_t * m); +int regmatch_strtol (regmatch_t * m, const char *src, char **endptr, int base); +bool regmatch_empty (regmatch_t * m); + +#endif /* not defined FLEXDEF_H */ Index: contrib/flex-2.5/flexint.h =================================================================== RCS file: contrib/flex-2.5/flexint.h diff -N contrib/flex-2.5/flexint.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/flexint.h 14 Feb 2006 20:23:47 -0000 @@ -0,0 +1,63 @@ +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + + +#endif /* ! FLEXINT_H */ Index: contrib/flex-2.5/gen.c =================================================================== RCS file: contrib/flex-2.5/gen.c diff -N contrib/flex-2.5/gen.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/gen.c 14 Feb 2006 03:32:29 -0000 @@ -0,0 +1,2175 @@ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" +#include "tables.h" + + +/* declare functions that have forward references */ + +void gen_next_state PROTO ((int)); +void genecs PROTO ((void)); +void indent_put2s PROTO ((const char *, const char *)); +void indent_puts PROTO ((const 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 const char *get_int16_decl (void) +{ + return (gentables) + ? "static yyconst flex_int16_t %s[%d] =\n { 0,\n" + : "static yyconst flex_int16_t * %s = 0;\n"; +} + + +static const char *get_int32_decl (void) +{ + return (gentables) + ? "static yyconst flex_int32_t %s[%d] =\n { 0,\n" + : "static yyconst flex_int32_t * %s = 0;\n"; +} + +static const char *get_state_decl (void) +{ + return (gentables) + ? "static yyconst yy_state_type %s[%d] =\n { 0,\n" + : "static yyconst yy_state_type * %s = 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; + } +} + + +/** Make the table for possible eol matches. + * @return the newly allocated rule_can_match_eol table + */ +static struct yytbl_data *mkeoltbl (void) +{ + int i; + flex_int8_t *tdata = 0; + struct yytbl_data *tbl; + + tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data)); + yytbl_data_init (tbl, YYTD_ID_RULE_CAN_MATCH_EOL); + tbl->td_flags = YYTD_DATA8; + tbl->td_lolen = num_rules + 1; + tbl->td_data = tdata = + (flex_int8_t *) calloc (tbl->td_lolen, sizeof (flex_int8_t)); + + for (i = 1; i <= num_rules; i++) + tdata[i] = rule_has_nl[i] ? 1 : 0; + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_RULE_CAN_MATCH_EOL, (void**)&yy_rule_can_match_eol, sizeof(%s)},\n", + "flex_int32_t"); + return tbl; +} + +/* Generate the table for possible eol matches. */ +static void geneoltbl () +{ + int i; + + outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[["); + outn ("/* Table of booleans, true if rule could match eol. */"); + out_str_dec (get_int32_decl (), "yy_rule_can_match_eol", + num_rules + 1); + + if (gentables) { + for (i = 1; i <= num_rules; i++) { + out_dec ("%d, ", rule_has_nl[i] ? 1 : 0); + /* format nicely, 20 numbers per line. */ + if ((i % 20) == 19) + out ("\n "); + } + out (" };\n"); + } + outn ("]])"); +} + + +/* 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_G(yy_last_accepting_state) = yy_current_state;"); + indent_puts ("YY_G(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_G(yy_hold_char);"); + + if (fullspd || fulltbl) + indent_puts ("yy_cp = YY_G(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_G(yy_last_accepting_cpos);"); + + indent_puts ("yy_current_state = YY_G(yy_last_accepting_state);"); + indent_puts ("goto yy_find_action;"); + outc ('\n'); + + set_indent (0); +} + +/** mkctbl - make full speed compressed transition table + * This is an array of structs; each struct a pair of integers. + * You should call mkssltbl() immediately after this. + * Then, I think, mkecstbl(). Arrrg. + * @return the newly allocated trans table + */ + +static struct yytbl_data *mkctbl (void) +{ + register int i; + struct yytbl_data *tbl = 0; + flex_int32_t *tdata = 0, curr = 0; + int end_of_buffer_action = num_rules + 1; + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_TRANSITION, (void**)&yy_transition, sizeof(%s)},\n", + ((tblend + numecs + 1) >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data)); + yytbl_data_init (tbl, YYTD_ID_TRANSITION); + tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT; + tbl->td_hilen = 0; + tbl->td_lolen = tblend + numecs + 1; /* number of structs */ + + tbl->td_data = tdata = + (flex_int32_t *) calloc (tbl->td_lolen * 2, sizeof (flex_int32_t)); + + /* 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) { + tdata[curr++] = 0; + tdata[curr++] = base[lastdfa + 1] - i; + } + + else if (chk[i] == ACTION_POSITION) { + tdata[curr++] = 0; + tdata[curr++] = nxt[i]; + } + + else if (chk[i] > numecs || chk[i] == 0) { + tdata[curr++] = 0; + tdata[curr++] = 0; + } + else { /* verify, transition */ + + tdata[curr++] = chk[i]; + tdata[curr++] = base[nxt[i]] - (i - chk[i]); + } + } + + + /* Here's the final, end-of-buffer state. */ + tdata[curr++] = chk[tblend + 1]; + tdata[curr++] = nxt[tblend + 1]; + + tdata[curr++] = chk[tblend + 2]; + tdata[curr++] = nxt[tblend + 2]; + + return tbl; +} + + +/** Make start_state_list table. + * @return the newly allocated start_state_list table + */ +static struct yytbl_data *mkssltbl (void) +{ + struct yytbl_data *tbl = 0; + flex_int32_t *tdata = 0; + flex_int32_t i; + + tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data)); + yytbl_data_init (tbl, YYTD_ID_START_STATE_LIST); + tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS; + tbl->td_hilen = 0; + tbl->td_lolen = lastsc * 2 + 1; + + tbl->td_data = tdata = + (flex_int32_t *) calloc (tbl->td_lolen, sizeof (flex_int32_t)); + + for (i = 0; i <= lastsc * 2; ++i) + tdata[i] = base[i]; + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_START_STATE_LIST, (void**)&yy_start_state_list, sizeof(%s)},\n", + "struct yy_trans_info*"); + + return tbl; +} + + + +/* 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. */ + if (gentables) + out_dec ("static yyconst struct yy_trans_info yy_transition[%d] =\n {\n", tblend + numecs + 1); + else + outn ("static yyconst struct yy_trans_info *yy_transition = 0;"); + + /* 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]); + + if (gentables) + outn (" };\n"); + + /* Table of pointers to start states. */ + if (gentables) + out_dec ("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1); + else + outn ("static yyconst struct yy_trans_info **yy_start_state_list =0;"); + + if (gentables) { + outn (" {"); + + for (i = 0; i <= lastsc * 2; ++i) + out_dec (" &yy_transition[%d],\n", base[i]); + + dataend (); + } + + if (useecs) + genecs (); +} + + +/* mkecstbl - Make equivalence-class tables. */ + +struct yytbl_data *mkecstbl (void) +{ + register int i; + struct yytbl_data *tbl = 0; + flex_int32_t *tdata = 0; + + tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data)); + yytbl_data_init (tbl, YYTD_ID_EC); + tbl->td_flags |= YYTD_DATA32; + tbl->td_hilen = 0; + tbl->td_lolen = csize; + + tbl->td_data = tdata = + (flex_int32_t *) calloc (tbl->td_lolen, sizeof (flex_int32_t)); + + for (i = 1; i < csize; ++i) { + if (caseins && isupper (i)) + ecgroup[i] = ecgroup[tolower (i)]; + + ecgroup[i] = ABS (ecgroup[i]); + tdata[i] = ecgroup[i]; + } + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_EC, (void**)&yy_ec, sizeof(%s)},\n", + "flex_int32_t"); + + return tbl; +} + +/* Generate equivalence-class tables. */ + +void genecs () +{ + register int i, j; + int numrows; + + out_str_dec (get_int32_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_G(yy_state_ptr);"); + indent_puts ("YY_G(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_G(yy_lp) && YY_G(yy_lp) < yy_accept[yy_current_state + 1] )"); + indent_up (); + indent_puts ("{"); + indent_puts ("yy_act = yy_acclist[YY_G(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_G(yy_full_match) = yy_cp;"); + indent_puts + ("yy_full_state = YY_G(yy_state_ptr);"); + indent_puts ("yy_full_lp = YY_G(yy_lp);"); + } + + indent_puts ("}"); + indent_down (); + + indent_puts ("else"); + indent_up (); + indent_puts ("{"); + indent_puts ("YY_G(yy_full_match) = yy_cp;"); + indent_puts + ("yy_full_state = YY_G(yy_state_ptr);"); + indent_puts ("yy_full_lp = YY_G(yy_lp);"); + indent_puts ("break;"); + indent_puts ("}"); + indent_down (); + + indent_puts ("++YY_G(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_G(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_G(yy_state_ptr);"); + indent_puts ("YY_G(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_G(yy_last_accepting_cpos);"); + indent_puts + ("yy_current_state = YY_G(yy_last_accepting_state);"); + indent_puts + ("yy_act = yy_accept[yy_current_state];"); + indent_puts ("}"); + indent_down (); + } + } +} + +/* mkftbl - make the full table and return the struct . + * you should call mkecstbl() after this. + */ + +struct yytbl_data *mkftbl (void) +{ + register int i; + int end_of_buffer_action = num_rules + 1; + struct yytbl_data *tbl; + flex_int32_t *tdata = 0; + + tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data)); + yytbl_data_init (tbl, YYTD_ID_ACCEPT); + tbl->td_flags |= YYTD_DATA32; + tbl->td_hilen = 0; /* it's a one-dimensional array */ + tbl->td_lolen = lastdfa + 1; + + tbl->td_data = tdata = + (flex_int32_t *) calloc (tbl->td_lolen, sizeof (flex_int32_t)); + + dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; + + for (i = 1; i <= lastdfa; ++i) { + register int anum = dfaacc[i].dfaacc_state; + + tdata[i] = anum; + + if (trace && anum) + fprintf (stderr, _("state # %d accepts: [%d]\n"), + i, anum); + } + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + return tbl; +} + + +/* genftbl - generate full transition table */ + +void genftbl () +{ + register int i; + int end_of_buffer_action = num_rules + 1; + + out_str_dec (long_align ? get_int32_decl () : get_int16_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) { + if (gentables) + indent_put2s + ("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )", + char_map); + else + indent_put2s + ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s ]) > 0 )", + char_map); + + indent_up (); + + if (num_backing_up > 0) { + indent_puts ("{"); + gen_backing_up (); + outc ('\n'); + } + + indent_puts ("++yy_cp;"); + + if (num_backing_up > 0) + + indent_puts ("}"); + + indent_down (); + + outc ('\n'); + indent_puts ("yy_current_state = -yy_current_state;"); + } + + else if (fullspd) { + indent_puts ("{"); + 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 ("{"); + + indent_puts ("yy_current_state += yy_trans_info->yy_nxt;"); + + if (num_backing_up > 0) { + outc ('\n'); + gen_backing_up (); + indent_puts ("}"); + } + + indent_down (); + indent_puts ("}"); + } + + else { /* compressed */ + indent_puts ("do"); + + indent_up (); + indent_puts ("{"); + + gen_next_state (false); + + indent_puts ("++yy_cp;"); + + + 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_G(yy_last_accepting_cpos);"); + indent_puts + ("yy_current_state = YY_G(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 ("{"); + } + + if (fulltbl) { + if (gentables) + indent_put2s + ("yy_current_state = yy_nxt[yy_current_state][%s];", + char_map); + else + indent_put2s + ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %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) { + + 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_G(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_G(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 (); + if (gentables) + out_dec ("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec); + else + out_dec ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %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_G(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_G(yy_start) + YY_AT_BOL()];"); + } + else + indent_puts + ("yy_current_state = yy_start_state_list[YY_G(yy_start)];"); + } + + else { + indent_puts ("yy_current_state = YY_G(yy_start);"); + + if (bol_needed) + indent_puts ("yy_current_state += YY_AT_BOL();"); + + if (reject) { + /* Set up for storing up states. */ + outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); + indent_puts + ("YY_G(yy_state_ptr) = YY_G(yy_state_buf);"); + indent_puts + ("*YY_G(yy_state_ptr)++ = yy_current_state;"); + outn ("]])"); + } + } +} + + +/* 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; + struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0, + *yydef_tbl = 0, *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl=0; + flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0, + *yynxt_data = 0, *yychk_data = 0, *yyacclist_data=0; + flex_int32_t yybase_curr = 0, yyacclist_curr=0,yyacc_curr=0; + + 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 ? get_int32_decl () : + get_int16_decl (), "yy_acclist", MAX (numas, + 1) + 1); + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + + yyacclist_tbl = (struct yytbl_data*)calloc(1,sizeof(struct yytbl_data)); + yytbl_data_init (yyacclist_tbl, YYTD_ID_ACCLIST); + yyacclist_tbl->td_lolen = MAX(numas,1) + 1; + yyacclist_tbl->td_data = yyacclist_data = + (flex_int32_t *) calloc (yyacclist_tbl->td_lolen, sizeof (flex_int32_t)); + yyacclist_curr = 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); + yyacclist_data[yyacclist_curr++] = 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 (); + if (tablesext) { + yytbl_data_compress (yyacclist_tbl); + if (yytbl_data_fwrite (&tableswr, yyacclist_tbl) < 0) + flexerror (_("Could not write yyacclist_tbl")); + yytbl_data_destroy (yyacclist_tbl); + yyacclist_tbl = NULL; + } + } + + 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; + } + + /* Begin generating yy_accept */ + + /* 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 ? get_int32_decl () : get_int16_decl (), + "yy_accept", k); + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", + long_align ? "flex_int32_t" : "flex_int16_t"); + + yyacc_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct yytbl_data)); + yytbl_data_init (yyacc_tbl, YYTD_ID_ACCEPT); + yyacc_tbl->td_lolen = k; + yyacc_tbl->td_data = yyacc_data = + (flex_int32_t *) calloc (yyacc_tbl->td_lolen, sizeof (flex_int32_t)); + yyacc_curr=1; + + for (i = 1; i <= lastdfa; ++i) { + mkdata (acc_array[i]); + yyacc_data[yyacc_curr++] = 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]); + yyacc_data[yyacc_curr++] = acc_array[i]; + + if (reject) { + /* Add "cap" for the list. */ + mkdata (acc_array[i]); + yyacc_data[yyacc_curr++] = acc_array[i]; + } + + dataend (); + if (tablesext) { + yytbl_data_compress (yyacc_tbl); + if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0) + flexerror (_("Could not write yyacc_tbl")); + yytbl_data_destroy (yyacc_tbl); + yyacc_tbl = NULL; + } + /* End generating yy_accept */ + + if (useecs) { + + genecs (); + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkecstbl (); + yytbl_data_compress (tbl); + if (yytbl_data_fwrite (&tableswr, tbl) < 0) + flexerror (_("Could not write ecstbl")); + yytbl_data_destroy (tbl); + tbl = 0; + } + } + + if (usemecs) { + /* Begin generating yy_meta */ + /* Write out meta-equivalence classes (used to index + * templates with). + */ + flex_int32_t *yymecs_data = 0; + yymeta_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct + yytbl_data)); + yytbl_data_init (yymeta_tbl, YYTD_ID_META); + yymeta_tbl->td_lolen = numecs + 1; + yymeta_tbl->td_data = yymecs_data = + (flex_int32_t *) calloc (yymeta_tbl->td_lolen, + sizeof (flex_int32_t)); + + if (trace) + fputs (_("\n\nMeta-Equivalence Classes:\n"), + stderr); + + out_str_dec (get_int32_decl (), "yy_meta", numecs + 1); + buf_prints (&yydmap_buf, + "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n", + "flex_int32_t"); + + for (i = 1; i <= numecs; ++i) { + if (trace) + fprintf (stderr, "%d = %d\n", + i, ABS (tecbck[i])); + + mkdata (ABS (tecbck[i])); + yymecs_data[i] = ABS (tecbck[i]); + } + + dataend (); + if (tablesext) { + yytbl_data_compress (yymeta_tbl); + if (yytbl_data_fwrite (&tableswr, yymeta_tbl) < 0) + flexerror (_ + ("Could not write yymeta_tbl")); + yytbl_data_destroy (yymeta_tbl); + yymeta_tbl = NULL; + } + /* End generating yy_meta */ + } + + total_states = lastdfa + numtemps; + + /* Begin generating yy_base */ + out_str_dec ((tblend >= INT16_MAX || long_align) ? + get_int32_decl () : get_int16_decl (), + "yy_base", total_states + 1); + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n", + (tblend >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + yybase_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct yytbl_data)); + yytbl_data_init (yybase_tbl, YYTD_ID_BASE); + yybase_tbl->td_lolen = total_states + 1; + yybase_tbl->td_data = yybase_data = + (flex_int32_t *) calloc (yybase_tbl->td_lolen, + sizeof (flex_int32_t)); + yybase_curr = 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]); + yybase_data[yybase_curr++] = base[i]; + } + + /* Generate jam state's base index. */ + mkdata (base[i]); + yybase_data[yybase_curr++] = base[i]; + + for (++i /* skip jam state */ ; i <= total_states; ++i) { + mkdata (base[i]); + yybase_data[yybase_curr++] = base[i]; + def[i] = jamstate; + } + + dataend (); + if (tablesext) { + yytbl_data_compress (yybase_tbl); + if (yytbl_data_fwrite (&tableswr, yybase_tbl) < 0) + flexerror (_("Could not write yybase_tbl")); + yytbl_data_destroy (yybase_tbl); + yybase_tbl = NULL; + } + /* End generating yy_base */ + + + /* Begin generating yy_def */ + out_str_dec ((total_states >= INT16_MAX || long_align) ? + get_int32_decl () : get_int16_decl (), + "yy_def", total_states + 1); + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_DEF, (void**)&yy_def, sizeof(%s)},\n", + (total_states >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + yydef_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct yytbl_data)); + yytbl_data_init (yydef_tbl, YYTD_ID_DEF); + yydef_tbl->td_lolen = total_states + 1; + yydef_tbl->td_data = yydef_data = + (flex_int32_t *) calloc (yydef_tbl->td_lolen, sizeof (flex_int32_t)); + + for (i = 1; i <= total_states; ++i) { + mkdata (def[i]); + yydef_data[i] = def[i]; + } + + dataend (); + if (tablesext) { + yytbl_data_compress (yydef_tbl); + if (yytbl_data_fwrite (&tableswr, yydef_tbl) < 0) + flexerror (_("Could not write yydef_tbl")); + yytbl_data_destroy (yydef_tbl); + yydef_tbl = NULL; + } + /* End generating yy_def */ + + + /* Begin generating yy_nxt */ + out_str_dec ((total_states >= INT16_MAX || long_align) ? + get_int32_decl () : get_int16_decl (), "yy_nxt", + tblend + 1); + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", + (total_states >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + yynxt_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct yytbl_data)); + yytbl_data_init (yynxt_tbl, YYTD_ID_NXT); + yynxt_tbl->td_lolen = tblend + 1; + yynxt_tbl->td_data = yynxt_data = + (flex_int32_t *) calloc (yynxt_tbl->td_lolen, sizeof (flex_int32_t)); + + 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]); + yynxt_data[i] = nxt[i]; + } + + dataend (); + if (tablesext) { + yytbl_data_compress (yynxt_tbl); + if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0) + flexerror (_("Could not write yynxt_tbl")); + yytbl_data_destroy (yynxt_tbl); + yynxt_tbl = NULL; + } + /* End generating yy_nxt */ + + /* Begin generating yy_chk */ + out_str_dec ((total_states >= INT16_MAX || long_align) ? + get_int32_decl () : get_int16_decl (), "yy_chk", + tblend + 1); + + buf_prints (&yydmap_buf, + "\t{YYTD_ID_CHK, (void**)&yy_chk, sizeof(%s)},\n", + (total_states >= INT16_MAX + || long_align) ? "flex_int32_t" : "flex_int16_t"); + + yychk_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct yytbl_data)); + yytbl_data_init (yychk_tbl, YYTD_ID_CHK); + yychk_tbl->td_lolen = tblend + 1; + yychk_tbl->td_data = yychk_data = + (flex_int32_t *) calloc (yychk_tbl->td_lolen, sizeof (flex_int32_t)); + + for (i = 1; i <= tblend; ++i) { + if (chk[i] == 0) + ++nummt; + + mkdata (chk[i]); + yychk_data[i] = chk[i]; + } + + dataend (); + if (tablesext) { + yytbl_data_compress (yychk_tbl); + if (yytbl_data_fwrite (&tableswr, yychk_tbl) < 0) + flexerror (_("Could not write yychk_tbl")); + yytbl_data_destroy (yychk_tbl); + yychk_tbl = NULL; + } + /* End generating yy_chk */ + + flex_free ((void *) acc_array); +} + + +/* Write out a formatted string (with a secondary string argument) at the + * current indentation level, adding a final newline. + */ + +void indent_put2s (fmt, arg) + const 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) + const 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; + struct yytbl_data *yynultrans_tbl; + + + skelout (); /* %% [2.0] - break point in skel */ + + /* First, take care of YY_DO_BEFORE_ACTION depending on yymore + * being used. + */ + set_indent (1); + + if (yymore_used && !yytext_is_array) { + indent_puts ("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\"); + indent_puts + ("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\"); + } + + else + indent_puts ("yyleng = (size_t) (yy_cp - yy_bp); \\"); + + /* Now also deal with copying yytext_ptr to yytext if needed. */ + skelout (); /* %% [3.0] - break point in skel */ + if (yytext_is_array) { + if (yymore_used) + indent_puts + ("if ( yyleng + YY_G(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_G(yy_more_offset)], YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); + indent_puts ("yyleng += YY_G(yy_more_offset); \\"); + indent_puts + ("YY_G(yy_prev_more_offset) = YY_G(yy_more_offset); \\"); + indent_puts ("YY_G(yy_more_offset) = 0; \\"); + } + else { + indent_puts + ("yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); + } + } + + set_indent (0); + + skelout (); /* %% [4.0] - break point in skel */ + + + /* This is where we REALLY begin generating the tables. */ + + 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 >= INT16_MAX || long_align) ? + "flex_int32_t" : "flex_int16_t"; + + set_indent (0); + indent_puts ("struct yy_trans_info"); + indent_up (); + indent_puts ("{"); + + /* We require that yy_verify and yy_nxt must be of the same size int. */ + indent_put2s ("%s yy_verify;", trans_offset_type); + + /* 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 (); + } + else { + /* We generate a bogus 'struct yy_trans_info' data type + * so we can guarantee that it is always declared in the skel. + * This is so we can compile "sizeof(struct yy_trans_info)" + * in any scanner. + */ + indent_puts + ("/* This struct is not used in this scanner,"); + indent_puts (" but its presence is necessary. */"); + indent_puts ("struct yy_trans_info"); + indent_up (); + indent_puts ("{"); + indent_puts ("flex_int32_t yy_verify;"); + indent_puts ("flex_int32_t yy_nxt;"); + indent_puts ("};"); + indent_down (); + } + + if (fullspd) { + genctbl (); + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkctbl (); + yytbl_data_compress (tbl); + if (yytbl_data_fwrite (&tableswr, tbl) < 0) + flexerror (_("Could not write ftbl")); + yytbl_data_destroy (tbl); + + tbl = mkssltbl (); + yytbl_data_compress (tbl); + if (yytbl_data_fwrite (&tableswr, tbl) < 0) + flexerror (_("Could not write ssltbl")); + yytbl_data_destroy (tbl); + tbl = 0; + + if (useecs) { + tbl = mkecstbl (); + yytbl_data_compress (tbl); + if (yytbl_data_fwrite (&tableswr, tbl) < 0) + flexerror (_ + ("Could not write ecstbl")); + yytbl_data_destroy (tbl); + tbl = 0; + } + } + } + else if (fulltbl) { + genftbl (); + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkftbl (); + yytbl_data_compress (tbl); + if (yytbl_data_fwrite (&tableswr, tbl) < 0) + flexerror (_("Could not write ftbl")); + yytbl_data_destroy (tbl); + tbl = 0; + + if (useecs) { + tbl = mkecstbl (); + yytbl_data_compress (tbl); + if (yytbl_data_fwrite (&tableswr, tbl) < 0) + flexerror (_ + ("Could not write ecstbl")); + yytbl_data_destroy (tbl); + tbl = 0; + } + } + } + else + gentabs (); + + if (do_yylineno) { + + geneoltbl (); + + if (tablesext) { + struct yytbl_data *tbl; + + tbl = mkeoltbl (); + yytbl_data_compress (tbl); + if (yytbl_data_fwrite (&tableswr, tbl) < 0) + flexerror (_("Could not write eoltbl")); + yytbl_data_destroy (tbl); + tbl = 0; + } + } + + /* 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 && !reentrant) { + indent_puts + ("static yy_state_type yy_last_accepting_state;"); + indent_puts + ("static char *yy_last_accepting_cpos;\n"); + } + } + + if (nultrans) { + flex_int32_t *yynultrans_data = 0; + + /* Begin generating yy_NUL_trans */ + out_str_dec (get_state_decl (), "yy_NUL_trans", + lastdfa + 1); + buf_prints (&yydmap_buf, + "\t{YYTD_ID_NUL_TRANS, (void**)&yy_NUL_trans, sizeof(%s)},\n", + (fullspd) ? "struct yy_trans_info*" : + "flex_int32_t"); + + yynultrans_tbl = + (struct yytbl_data *) calloc (1, + sizeof (struct + yytbl_data)); + yytbl_data_init (yynultrans_tbl, YYTD_ID_NUL_TRANS); + if (fullspd) + yynultrans_tbl->td_flags |= YYTD_PTRANS; + yynultrans_tbl->td_lolen = lastdfa + 1; + yynultrans_tbl->td_data = yynultrans_data = + (flex_int32_t *) calloc (yynultrans_tbl->td_lolen, + sizeof (flex_int32_t)); + + for (i = 1; i <= lastdfa; ++i) { + if (fullspd) { + out_dec (" &yy_transition[%d],\n", + base[i]); + yynultrans_data[i] = base[i]; + } + else { + mkdata (nultrans[i]); + yynultrans_data[i] = nultrans[i]; + } + } + + dataend (); + if (tablesext) { + yytbl_data_compress (yynultrans_tbl); + if (yytbl_data_fwrite (&tableswr, yynultrans_tbl) < + 0) + flexerror (_ + ("Could not write yynultrans_tbl")); + yytbl_data_destroy (yynultrans_tbl); + yynultrans_tbl = NULL; + } + /* End generating yy_NUL_trans */ + } + + if (!C_plus_plus && !reentrant) { + indent_puts ("extern int yy_flex_debug;"); + indent_put2s ("int yy_flex_debug = %s;\n", + ddebug ? "1" : "0"); + } + + if (ddebug) { /* Spit out table mapping rules to line numbers. */ + out_str_dec (long_align ? get_int32_decl () : + get_int16_decl (), "yy_rule_linenum", + num_rules); + for (i = 1; i < num_rules; ++i) + mkdata (rule_linenum[i]); + dataend (); + } + + if (reject) { + outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); + /* Declare state buffer variables. */ + if (!C_plus_plus && !reentrant) { + outn ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;"); + 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 ("{ \\"); + outn ("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */ \\"); + outn ("yy_cp = YY_G(yy_full_match); /* restore poss. backed-over text */ \\"); + + if (variable_trailing_context_rules) { + outn ("YY_G(yy_lp) = yy_full_lp; /* restore orig. accepting pos. */ \\"); + outn ("YY_G(yy_state_ptr) = yy_full_state; /* restore orig. state */ \\"); + outn ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\"); + } + + outn ("++YY_G(yy_lp); \\"); + outn ("goto find_rule; \\"); + + outn ("}"); + outn ("]])\n"); + } + + 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) { + if (!reentrant){ + indent_puts ("static int yy_more_offset = 0;"); + indent_puts ("static int yy_prev_more_offset = 0;"); + } + } + else if (!reentrant) { + 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_G(yy_more_offset) = yy_flex_strlen( yytext M4_YY_CALL_LAST_ARG))"); + 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_G(yy_more_offset) = YY_G(yy_prev_more_offset); \\"); + indent_puts ("yyleng -= YY_G(yy_more_offset); \\"); + indent_puts ("}"); + indent_down (); + } + else { + indent_puts + ("#define yymore() (YY_G(yy_more_flag) = 1)"); + indent_puts + ("#define YY_MORE_ADJ YY_G(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"); + if (!reentrant){ + outn ("char yytext[YYLMAX];"); + outn ("char *yytext_ptr;"); + } + } + + else { + if(! reentrant) + outn ("char *yytext;"); + } + } + + out (&action_array[defs1_offset]); + + line_directive_out (stdout, 0); + + skelout (); /* %% [5.0] - break point in skel */ + + if (!C_plus_plus) { + if (use_read) { + outn ("\terrno=0; \\"); + outn ("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\"); + outn ("\t{ \\"); + outn ("\t\tif( errno != EINTR) \\"); + outn ("\t\t{ \\"); + outn ("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); + outn ("\t\t\tbreak; \\"); + outn ("\t\t} \\"); + outn ("\t\terrno=0; \\"); + outn ("\t\tclearerr(yyin); \\"); + outn ("\t}\\"); + } + + else { + outn ("\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\"); + outn ("\t\t{ \\"); + outn ("\t\tint c = '*'; \\"); + outn ("\t\tsize_t 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 \\"); + outn ("\t\t{ \\"); + outn ("\t\terrno=0; \\"); + outn ("\t\twhile ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\"); + outn ("\t\t\t{ \\"); + outn ("\t\t\tif( errno != EINTR) \\"); + outn ("\t\t\t\t{ \\"); + outn ("\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); + outn ("\t\t\t\tbreak; \\"); + outn ("\t\t\t\t} \\"); + outn ("\t\t\terrno=0; \\"); + outn ("\t\t\tclearerr(yyin); \\"); + outn ("\t\t\t} \\"); + outn ("\t\t}\\"); + } + } + + skelout (); /* %% [6.0] - break point in skel */ + + indent_puts ("#define YY_RULE_SETUP \\"); + indent_up (); + if (bol_needed) { + indent_puts ("if ( yyleng > 0 ) \\"); + indent_up (); + indent_puts ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \\"); + indent_puts ("\t\t(yytext[yyleng - 1] == '\\n'); \\"); + indent_down (); + } + indent_puts ("YY_USER_ACTION"); + indent_down (); + + skelout (); /* %% [7.0] - break point in skel */ + + /* Copy prolog to output file. */ + out (&action_array[prolog_offset]); + + line_directive_out (stdout, 0); + + skelout (); /* %% [8.0] - break point in skel */ + + set_indent (2); + + if (yymore_used && !yytext_is_array) { + indent_puts ("YY_G(yy_more_len) = 0;"); + indent_puts ("if ( YY_G(yy_more_flag) )"); + indent_up (); + indent_puts ("{"); + indent_puts + ("YY_G(yy_more_len) = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);"); + indent_puts ("YY_G(yy_more_flag) = 0;"); + indent_puts ("}"); + indent_down (); + } + + skelout (); /* %% [9.0] - break point in skel */ + + gen_start_state (); + + /* Note, don't use any indentation. */ + outn ("yy_match:"); + gen_next_match (); + + skelout (); /* %% [10.0] - break point in skel */ + set_indent (2); + gen_find_action (); + + skelout (); /* %% [11.0] - break point in skel */ + outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[["); + indent_puts + ("if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )"); + indent_up (); + indent_puts ("{"); + indent_puts ("int yyl;"); + do_indent (); + out_str ("for ( yyl = %s; yyl < yyleng; ++yyl )\n", + yymore_used ? (yytext_is_array ? "YY_G(yy_prev_more_offset)" : + "YY_G(yy_more_len)") : "0"); + indent_up (); + indent_puts ("if ( yytext[yyl] == '\\n' )"); + indent_up (); + indent_puts ("M4_YY_INCR_LINENO();"); + indent_down (); + indent_down (); + indent_puts ("}"); + indent_down (); + outn ("]])"); + + skelout (); /* %% [12.0] - break point in skel */ + 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 ? + "std::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 + ("std::cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<"); + indent_puts + (" \"(\\\"\" << yytext << \"\\\")\\n\";"); + } + else { + indent_puts + ("fprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\","); + + indent_puts + (" (long)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 + ("std::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 ? + "std::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 + ("std::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 (); /* %% [13.0] - break point in skel */ + 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 (); /* %% [14.0] - break point in skel */ + set_indent (4); + + if (fullspd || fulltbl) + indent_puts ("yy_cp = YY_G(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_G(yy_last_accepting_cpos);"); + indent_puts + ("yy_current_state = YY_G(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_G(yy_c_buf_p);"); + } + + + /* Generate code for yy_get_previous_state(). */ + set_indent (1); + skelout (); /* %% [15.0] - break point in skel */ + + gen_start_state (); + + set_indent (2); + skelout (); /* %% [16.0] - break point in skel */ + gen_next_state (true); + + set_indent (1); + skelout (); /* %% [17.0] - break point in skel */ + gen_NUL_trans (); + + skelout (); /* %% [18.0] - break point in skel */ + skelout (); /* %% [19.0] - break point in skel */ + /* Update BOL and yylineno inside of input(). */ + if (bol_needed) { + indent_puts + ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\\n');"); + if (do_yylineno) { + indent_puts + ("if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )"); + indent_up (); + indent_puts ("M4_YY_INCR_LINENO();"); + indent_down (); + } + } + + else if (do_yylineno) { + indent_puts ("if ( c == '\\n' )"); + indent_up (); + indent_puts ("M4_YY_INCR_LINENO();"); + indent_down (); + } + + skelout (); + + /* Copy remainder of input to output. */ + + line_directive_out (stdout, 1); + + if (sectnum == 3) { + OUT_BEGIN_CODE (); + (void) flexscan (); /* copy remainder of input to output */ + OUT_END_CODE (); + } +} Index: contrib/flex-2.5/gettext.h =================================================================== RCS file: contrib/flex-2.5/gettext.h diff -N contrib/flex-2.5/gettext.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/gettext.h 12 Mar 2002 19:21:03 -0000 @@ -0,0 +1,59 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ Index: contrib/flex-2.5/libmain.c =================================================================== RCS file: contrib/flex-2.5/libmain.c diff -N contrib/flex-2.5/libmain.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/libmain.c 27 Aug 2002 18:07:19 -0000 @@ -0,0 +1,33 @@ +/* libmain - flex run-time support library "main" function */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +extern int yylex (); + +int main (argc, argv) + int argc; + char *argv[]; +{ + while (yylex () != 0) ; + + return 0; +} Index: contrib/flex-2.5/libyywrap.c =================================================================== RCS file: contrib/flex-2.5/libyywrap.c diff -N contrib/flex-2.5/libyywrap.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/libyywrap.c 14 Feb 2006 03:32:29 -0000 @@ -0,0 +1,27 @@ +/* libyywrap - flex run-time support library "yywrap" function */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +int yywrap (void) +{ + return 1; +} Index: contrib/flex-2.5/main.c =================================================================== RCS file: contrib/flex-2.5/main.c diff -N contrib/flex-2.5/main.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/main.c 28 Dec 2006 06:44:43 -0000 @@ -0,0 +1,1843 @@ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + + +#include "flexdef.h" +#include "version.h" +#include "options.h" +#include "tables.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)); +static char *basename2 PROTO ((char *path, int should_strip_ext)); + + +/* these globals are all defined and commented in flexdef.h */ +int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; +int interactive, caseins, lex_compat, posix_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 reentrant, bison_bridge_lval, bison_bridge_lloc; +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, *headerfilename = 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 maximum_mns, 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; +jmp_buf flex_main_jmp_buf; +bool *rule_has_nl, *ccl_has_nl; +int nlch = '\n'; +bool ansi_func_defs, ansi_func_protos; + +bool tablesext, tablesverify, gentables; +char *tablesfilename=0,*tablesname=0; +struct yytbl_writer tableswr; + +/* 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"; +static char *tablesfile_template = "lex.%s.tables"; +#else +static char *outfile_template = "lex%s.%s"; +static char *backing_name = "lex.bck"; +static char *tablesfile_template = "lex%s.tbl"; +#endif + +#ifdef MS_DOS +extern unsigned _stklen = 16384; +#endif + +/* From scan.l */ +extern FILE* yyout; + +static char outfile_path[MAXLINE]; +static int outfile_created = 0; +static char *skelname = NULL; +static int _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ + +/* For debugging. The max number of filters to apply to skeleton. */ +static int preproc_level = 1000; + +int flex_main PROTO ((int argc, char *argv[])); +int main PROTO ((int argc, char *argv[])); + +int flex_main (argc, argv) + int argc; + char *argv[]; +{ + int i, exit_status, child_status; + + /* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The + * return value of setjmp, if non-zero, is the desired exit code PLUS ONE. + * For example, if you want 'main' to return with code '2', then call + * longjmp() with an argument of 3. This is because it is invalid to + * specify a value of 0 to longjmp. FLEX_EXIT(n) should be used instead of + * exit(n); + */ + exit_status = setjmp (flex_main_jmp_buf); + if (exit_status){ + if (stdout && !_stdout_closed && !ferror(stdout)){ + fflush(stdout); + fclose(stdout); + } + while (wait(&child_status) > 0){ + if (!WIFEXITED (child_status) + || WEXITSTATUS (child_status) != 0){ + /* report an error of a child + */ + if( exit_status <= 1 ) + exit_status = 2; + + } + } + return exit_status - 1; + } + + 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 */ +} + +/* Wrapper around flex_main, so flex_main can be built as a library. */ +int main (argc, argv) + int argc; + char *argv[]; +{ +#if ENABLE_NLS +#if HAVE_LOCALE_H + setlocale (LC_MESSAGES, ""); + textdomain (PACKAGE); + bindtextdomain (PACKAGE, LOCALEDIR); +#endif +#endif + + return flex_main (argc, argv); +} + +/* check_options - check user-specified options */ + +void check_options () +{ + int i; + const char * m4 = NULL; + + 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")); + + if (reentrant || bison_bridge_lval) + flexerror (_ + ("Can't use --reentrant or --bison-bridge 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 0 + /* This makes no sense whatsoever. I'm removing it. */ + if (do_yylineno) + /* This should really be "maintain_backup_tables = true" */ + reject_really_used = true; +#endif + + 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 (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 (C_plus_plus && (reentrant)) + flexerror (_("Options -+ and --reentrant are mutually exclusive.")); + + if (C_plus_plus && bison_bridge_lval) + flexerror (_("bison bridge not supported for the C++ scanner.")); + + + 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 (!ansi_func_defs) + buf_m4_define( &m4defs_buf, "M4_YY_NO_ANSI_FUNC_DEFS", NULL); + + if (!ansi_func_protos) + buf_m4_define( &m4defs_buf, "M4_YY_NO_ANSI_FUNC_PROTOS", NULL); + + 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; + } + + + /* Setup the filter chain. */ + output_chain = filter_create_int(NULL, filter_tee_header, headerfilename); + if ( !(m4 = getenv("M4"))) + m4 = M4; + filter_create_ext(output_chain, m4, "-P", 0); + filter_create_int(output_chain, filter_fix_linedirs, NULL); + + /* For debugging, only run the requested number of filters. */ + if (preproc_level > 0) { + filter_truncate(output_chain, preproc_level); + filter_apply_chain(output_chain); + } + yyout = stdout; + + + /* always generate the tablesverify flag. */ + buf_m4_define (&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); + if (tablesext) + gentables = false; + + if (tablesverify) + /* force generation of C tables. */ + gentables = true; + + + if (tablesext) { + FILE *tablesout; + struct yytbl_hdr hdr; + char *pname = 0; + int nbytes = 0; + + buf_m4_define (&m4defs_buf, "M4_YY_TABLES_EXTERNAL", NULL); + + if (!tablesfilename) { + nbytes = strlen (prefix) + + strlen (tablesfile_template) + 2; + tablesfilename = pname = + (char *) calloc (nbytes, 1); + sprintf (pname, tablesfile_template, prefix); + } + + if ((tablesout = fopen (tablesfilename, "w")) == NULL) + lerrsf (_("could not create %s"), tablesfilename); + if (pname) + free (pname); + tablesfilename = 0; + + yytbl_writer_init (&tableswr, tablesout); + + nbytes = strlen (prefix) + strlen ("tables") + 2; + tablesname = (char *) calloc (nbytes, 1); + sprintf (tablesname, "%stables", prefix); + yytbl_hdr_init (&hdr, flex_version, tablesname); + + if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0) + flexerror (_("could not write tables header")); + } + + if (skelname && (skelfile = fopen (skelname, "r")) == NULL) + lerrsf (_("can't open skeleton file %s"), skelname); + + if (reentrant) { + buf_m4_define (&m4defs_buf, "M4_YY_REENTRANT", NULL); + if (yytext_is_array) + buf_m4_define (&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL); + } + + if ( bison_bridge_lval) + buf_m4_define (&m4defs_buf, "M4_YY_BISON_LVAL", NULL); + + if ( bison_bridge_lloc) + buf_m4_define (&m4defs_buf, "", NULL); + + buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix); + + if (did_outfilename) + line_directive_out (stdout, 0); + + if (do_yylineno) + buf_m4_define (&m4defs_buf, "M4_YY_USE_LINENO", NULL); + + /* Create the alignment type. */ + buf_strdefine (&userdef_buf, "YY_INT_ALIGNED", + long_align ? "long int" : "short int"); + + /* Define the start condition macros. */ + { + struct Buf tmpbuf; + buf_init(&tmpbuf, sizeof(char)); + for (i = 1; i <= lastsc; i++) { + char *str, *fmt = "#define %s %d\n"; + + str = (char*)flex_alloc(strlen(fmt) + strlen(scname[i]) + (int)(1 + log10(i)) + 2); + sprintf(str, fmt, scname[i], i - 1); + buf_strappend(&tmpbuf, str); + free(str); + } + buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", tmpbuf.elts); + buf_destroy(&tmpbuf); + } + + /* This is where we begin writing to the file. */ + + /* Dump the %top code. */ + if( top_buf.elts) + outn((char*) top_buf.elts); + + /* Dump the m4 definitions. */ + buf_print_strings(&m4defs_buf, stdout); + m4defs_buf.nelts = 0; /* memory leak here. */ + + /* Place a bogus line directive, it will be fixed in the filter. */ + outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n"); + + /* Dump the user defined preproc directives. */ + if (userdef_buf.elts) + outn ((char *) (userdef_buf.elts)); + + skelout (); + /* %% [1.0] */ +} + +/* flexend - terminate flex + * + * note + * This routine does not return. + */ + +void flexend (exit_status) + int exit_status; + +{ + static int called_before = -1; /* prevent infinite recursion. */ + int tblsiz; + + if (++called_before) + FLEX_EXIT (exit_status); + + 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 0 + fprintf (header_out, + "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n"); + fprintf (header_out, + "/* Beware! Start conditions are not prefixed. */\n"); + + /* Special case for "INITIAL" */ + fprintf (header_out, + "#undef INITIAL\n#define INITIAL 0\n"); + for (i = 2; i <= lastsc; i++) + fprintf (header_out, "#define %s %d\n", scname[i], i - 1); + fprintf (header_out, + "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n"); + + /* Kill ALL flex-related macros. This is so the user + * can #include more than one generated header file. */ + fprintf (header_out, "#ifndef YY_HEADER_NO_UNDEFS\n"); + fprintf (header_out, + "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n"); + + { + const char * undef_list[] = { + + "BEGIN", + "ECHO", + "EOB_ACT_CONTINUE_SCAN", + "EOB_ACT_END_OF_FILE", + "EOB_ACT_LAST_MATCH", + "FLEX_SCANNER", + "FLEX_STD", + "REJECT", + "YYFARGS0", + "YYFARGS1", + "YYFARGS2", + "YYFARGS3", + "YYLMAX", + "YYSTATE", + "YY_AT_BOL", + "YY_BREAK", + "YY_BUFFER_EOF_PENDING", + "YY_BUFFER_NEW", + "YY_BUFFER_NORMAL", + "YY_BUF_SIZE", + "M4_YY_CALL_LAST_ARG", + "M4_YY_CALL_ONLY_ARG", + "YY_CURRENT_BUFFER", + "YY_DECL", + "M4_YY_DECL_LAST_ARG", + "M4_YY_DEF_LAST_ARG", + "M4_YY_DEF_ONLY_ARG", + "YY_DO_BEFORE_ACTION", + "YY_END_OF_BUFFER", + "YY_END_OF_BUFFER_CHAR", + "YY_EXIT_FAILURE", + "YY_EXTRA_TYPE", + "YY_FATAL_ERROR", + "YY_FLEX_DEFINED_ECHO", + "YY_FLEX_LEX_COMPAT", + "YY_FLEX_MAJOR_VERSION", + "YY_FLEX_MINOR_VERSION", + "YY_FLEX_SUBMINOR_VERSION", + "YY_FLUSH_BUFFER", + "YY_G", + "YY_INPUT", + "YY_INTERACTIVE", + "YY_INT_ALIGNED", + "YY_LAST_ARG", + "YY_LESS_LINENO", + "YY_LEX_ARGS", + "YY_LEX_DECLARATION", + "YY_LEX_PROTO", + "YY_MAIN", + "YY_MORE_ADJ", + "YY_NEED_STRLEN", + "YY_NEW_FILE", + "YY_NULL", + "YY_NUM_RULES", + "YY_ONLY_ARG", + "YY_PARAMS", + "YY_PROTO", + "M4_YY_PROTO_LAST_ARG", + "M4_YY_PROTO_ONLY_ARG void", + "YY_READ_BUF_SIZE", + "YY_REENTRANT", + "YY_RESTORE_YY_MORE_OFFSET", + "YY_RULE_SETUP", + "YY_SC_TO_UI", + "YY_SKIP_YYWRAP", + "YY_START", + "YY_START_STACK_INCR", + "YY_STATE_EOF", + "YY_STDINIT", + "YY_TRAILING_HEAD_MASK", + "YY_TRAILING_MASK", + "YY_USER_ACTION", + "YY_USE_CONST", + "YY_USE_PROTOS", + "unput", + "yyTABLES_NAME", + "yy_create_buffer", + "yy_delete_buffer", + "yy_flex_debug", + "yy_flush_buffer", + "yy_init_buffer", + "yy_load_buffer_state", + "yy_new_buffer", + "yy_scan_buffer", + "yy_scan_bytes", + "yy_scan_string", + "yy_set_bol", + "yy_set_interactive", + "yy_switch_to_buffer", + "yypush_buffer_state", + "yypop_buffer_state", + "yyensure_buffer_stack", + "yyalloc", + "yyconst", + "yyextra", + "yyfree", + "yyget_debug", + "yyget_extra", + "yyget_in", + "yyget_leng", + "yyget_lineno", + "yyget_lloc", + "yyget_lval", + "yyget_out", + "yyget_text", + "yyin", + "yyleng", + "yyless", + "yylex", + "yylex_destroy", + "yylex_init", + "yylineno", + "yylloc", + "yylval", + "yymore", + "yyout", + "yyrealloc", + "yyrestart", + "yyset_debug", + "yyset_extra", + "yyset_in", + "yyset_lineno", + "yyset_lloc", + "yyset_lval", + "yyset_out", + "yytables_destroy", + "yytables_fload", + "yyterminate", + "yytext", + "yytext_ptr", + "yywrap", + + /* must be null-terminated */ + NULL}; + + + for (i=0; undef_list[i] != NULL; i++) + fprintf (header_out, "#undef %s\n", undef_list[i]); + } + + /* undef any of the auto-generated symbols. */ + for (i = 0; i < defs_buf.nelts; i++) { + + /* don't undef start conditions */ + if (sclookup (((char **) defs_buf.elts)[i]) > 0) + continue; + fprintf (header_out, "#undef %s\n", + ((char **) defs_buf.elts)[i]); + } + + fprintf (header_out, + "#endif /* !YY_HEADER_NO_UNDEFS */\n"); + fprintf (header_out, "\n"); + fprintf (header_out, "#undef %sIN_HEADER\n", prefix); + fprintf (header_out, "#endif /* %sHEADER_H */\n", prefix); + + if (ferror (header_out)) + lerrsf (_("error creating header file %s"), + headerfilename); + fflush (header_out); + fclose (header_out); +#endif + + if (exit_status != 0 && outfile_created) { + if (ferror (stdout)) + lerrsf (_("error writing output file %s"), + outfilename); + + else if ((_stdout_closed = 1) && 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 (posix_compat) + putc ('X', stderr); + if (performance_report > 0) + putc ('p', stderr); + if (performance_report > 1) + putc ('p', stderr); + if (spprdflt) + putc ('s', stderr); + if (reentrant) + fputs ("--reentrant", stderr); + if (bison_bridge_lval) + fputs ("--bison-bridge", stderr); + if (bison_bridge_lloc) + fputs ("--bison-locations", 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); + } + + FLEX_EXIT (exit_status); +} + + +/* flexinit - initialize flex */ + +void flexinit (argc, argv) + int argc; + char **argv; +{ + int i, sawcmpflag, rv, optind; + char *arg; + scanopt_t sopt; + + printstats = syntaxerror = trace = spprdflt = caseins = false; + lex_compat = posix_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; + reentrant = bison_bridge_lval = bison_bridge_lloc = false; + performance_report = 0; + did_outfilename = 0; + prefix = "yy"; + yyclass = 0; + use_read = use_stdout = false; + tablesext = tablesverify = false; + gentables = true; + tablesfilename = tablesname = NULL; + ansi_func_defs = ansi_func_protos = true; + + 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'; + + /* Initialize any buffers. */ + buf_init (&userdef_buf, sizeof (char)); /* one long string */ + buf_init (&defs_buf, sizeof (char *)); /* list of strings */ + buf_init (&yydmap_buf, sizeof (char)); /* one long string */ + buf_init (&top_buf, sizeof (char)); /* one long string */ + + { + const char * m4defs_init_str[] = {"m4_changequote\n", + "m4_changequote([[, ]])\n"}; + buf_init (&m4defs_buf, sizeof (char *)); + buf_append (&m4defs_buf, &m4defs_init_str, 2); + } + + /* initialize regex lib */ + flex_init_regex(); + + /* Enable C++ if program name ends with '+'. */ + program_name = basename2 (argv[0], 0); + + if (program_name[0] != '\0' && + program_name[strlen (program_name) - 1] == '+') + C_plus_plus = true; + + /* read flags */ + sopt = scanopt_init (flexopts, argc, argv, 0); + if (!sopt) { + /* This will only happen when flexopts array is altered. */ + fprintf (stderr, + _("Internal error. flexopts are malformed.\n")); + FLEX_EXIT (1); + } + + while ((rv = scanopt (sopt, &arg, &optind)) != 0) { + + if (rv < 0) { + /* Scanopt has already printed an option-specific error message. */ + fprintf (stderr, + _ + ("Try `%s --help' for more information.\n"), + program_name); + FLEX_EXIT (1); + } + + switch ((enum flexopt_flag_t) rv) { + case OPT_CPLUSPLUS: + C_plus_plus = true; + break; + + case OPT_BATCH: + interactive = false; + break; + + case OPT_BACKUP: + backing_up_report = true; + break; + + case OPT_DONOTHING: + break; + + case OPT_COMPRESSION: + if (!sawcmpflag) { + useecs = false; + usemecs = false; + fulltbl = false; + sawcmpflag = true; + } + + for (i = 0; arg && 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; + } + break; + + case OPT_DEBUG: + ddebug = true; + break; + + case OPT_NO_DEBUG: + ddebug = false; + break; + + case OPT_FULL: + useecs = usemecs = false; + use_read = fulltbl = true; + break; + + case OPT_FAST: + useecs = usemecs = false; + use_read = fullspd = true; + break; + + case OPT_HELP: + usage (); + FLEX_EXIT (0); + + case OPT_INTERACTIVE: + interactive = true; + break; + + case OPT_CASE_INSENSITIVE: + caseins = true; + break; + + case OPT_LEX_COMPAT: + lex_compat = true; + break; + + case OPT_POSIX_COMPAT: + posix_compat = true; + break; + + case OPT_PREPROC_LEVEL: + preproc_level = strtol(arg,NULL,0); + break; + + case OPT_MAIN: + buf_strdefine (&userdef_buf, "YY_MAIN", "1"); + do_yywrap = false; + break; + + case OPT_NO_MAIN: + buf_strdefine (&userdef_buf, "YY_MAIN", "0"); + break; + + case OPT_NO_LINE: + gen_line_dirs = false; + break; + + case OPT_OUTFILE: + outfilename = arg; + did_outfilename = 1; + break; + + case OPT_PREFIX: + prefix = arg; + break; + + case OPT_PERF_REPORT: + ++performance_report; + break; + + case OPT_BISON_BRIDGE: + bison_bridge_lval = true; + break; + + case OPT_BISON_BRIDGE_LOCATIONS: + bison_bridge_lval = bison_bridge_lloc = true; + break; + + case OPT_REENTRANT: + reentrant = true; + break; + + case OPT_NO_REENTRANT: + reentrant = false; + break; + + case OPT_SKEL: + skelname = arg; + break; + + case OPT_DEFAULT: + spprdflt = false; + break; + + case OPT_NO_DEFAULT: + spprdflt = true; + break; + + case OPT_STDOUT: + use_stdout = true; + break; + + case OPT_NO_UNISTD_H: + //buf_strdefine (&userdef_buf, "YY_NO_UNISTD_H", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_UNISTD_H",0); + break; + + case OPT_TABLES_FILE: + tablesext = true; + tablesfilename = arg; + break; + + case OPT_TABLES_VERIFY: + tablesverify = true; + break; + + case OPT_TRACE: + trace = true; + break; + + case OPT_VERBOSE: + printstats = true; + break; + + case OPT_VERSION: + printf (_("%s %s\n"), program_name, flex_version); + FLEX_EXIT (0); + + case OPT_WARN: + nowarn = false; + break; + + case OPT_NO_WARN: + nowarn = true; + break; + + case OPT_7BIT: + csize = 128; + break; + + case OPT_8BIT: + csize = CSIZE; + break; + + case OPT_ALIGN: + long_align = true; + break; + + case OPT_NO_ALIGN: + long_align = false; + break; + + case OPT_ALWAYS_INTERACTIVE: + buf_m4_define (&m4defs_buf, "M4_YY_ALWAYS_INTERACTIVE", 0); + break; + + case OPT_NEVER_INTERACTIVE: + buf_m4_define( &m4defs_buf, "M4_YY_NEVER_INTERACTIVE", 0); + break; + + case OPT_ARRAY: + yytext_is_array = true; + break; + + case OPT_POINTER: + yytext_is_array = false; + break; + + case OPT_ECS: + useecs = true; + break; + + case OPT_NO_ECS: + useecs = false; + break; + + case OPT_HEADER_FILE: + headerfilename = arg; + break; + + case OPT_META_ECS: + usemecs = true; + break; + + case OPT_NO_META_ECS: + usemecs = false; + break; + + case OPT_PREPROCDEFINE: + { + /* arg is "symbol" or "symbol=definition". */ + char *def; + + for (def = arg; + *def != '\0' && *def != '='; ++def) ; + + buf_strappend (&userdef_buf, "#define "); + if (*def == '\0') { + buf_strappend (&userdef_buf, arg); + buf_strappend (&userdef_buf, + " 1\n"); + } + else { + buf_strnappend (&userdef_buf, arg, + def - arg); + buf_strappend (&userdef_buf, " "); + buf_strappend (&userdef_buf, + def + 1); + buf_strappend (&userdef_buf, "\n"); + } + } + break; + + case OPT_READ: + use_read = true; + break; + + case OPT_STACK: + //buf_strdefine (&userdef_buf, "YY_STACK_USED", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_STACK_USED",0); + break; + + case OPT_STDINIT: + do_stdinit = true; + break; + + case OPT_NO_STDINIT: + do_stdinit = false; + break; + + case OPT_YYCLASS: + yyclass = arg; + break; + + case OPT_YYLINENO: + do_yylineno = true; + break; + + case OPT_NO_YYLINENO: + do_yylineno = false; + break; + + case OPT_YYWRAP: + do_yywrap = true; + break; + + case OPT_NO_YYWRAP: + do_yywrap = false; + break; + + case OPT_YYMORE: + yymore_really_used = true; + break; + + case OPT_NO_YYMORE: + yymore_really_used = false; + break; + + case OPT_REJECT: + reject_really_used = true; + break; + + case OPT_NO_REJECT: + reject_really_used = false; + break; + + case OPT_NO_ANSI_FUNC_DEFS: + ansi_func_defs = false; + break; + + case OPT_NO_ANSI_FUNC_PROTOS: + ansi_func_protos = false; + break; + + case OPT_NO_YY_PUSH_STATE: + //buf_strdefine (&userdef_buf, "YY_NO_PUSH_STATE", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_PUSH_STATE",0); + break; + case OPT_NO_YY_POP_STATE: + //buf_strdefine (&userdef_buf, "YY_NO_POP_STATE", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_POP_STATE",0); + break; + case OPT_NO_YY_TOP_STATE: + //buf_strdefine (&userdef_buf, "YY_NO_TOP_STATE", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_TOP_STATE",0); + break; + case OPT_NO_UNPUT: + //buf_strdefine (&userdef_buf, "YY_NO_UNPUT", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_UNPUT",0); + break; + case OPT_NO_YY_SCAN_BUFFER: + //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BUFFER", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BUFFER",0); + break; + case OPT_NO_YY_SCAN_BYTES: + //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BYTES", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BYTES",0); + break; + case OPT_NO_YY_SCAN_STRING: + //buf_strdefine (&userdef_buf, "YY_NO_SCAN_STRING", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_STRING",0); + break; + case OPT_NO_YYGET_EXTRA: + //buf_strdefine (&userdef_buf, "YY_NO_GET_EXTRA", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_EXTRA",0); + break; + case OPT_NO_YYSET_EXTRA: + //buf_strdefine (&userdef_buf, "YY_NO_SET_EXTRA", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_EXTRA",0); + break; + case OPT_NO_YYGET_LENG: + //buf_strdefine (&userdef_buf, "YY_NO_GET_LENG", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LENG",0); + break; + case OPT_NO_YYGET_TEXT: + //buf_strdefine (&userdef_buf, "YY_NO_GET_TEXT", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_TEXT",0); + break; + case OPT_NO_YYGET_LINENO: + //buf_strdefine (&userdef_buf, "YY_NO_GET_LINENO", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LINENO",0); + break; + case OPT_NO_YYSET_LINENO: + //buf_strdefine (&userdef_buf, "YY_NO_SET_LINENO", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LINENO",0); + break; + case OPT_NO_YYGET_IN: + //buf_strdefine (&userdef_buf, "YY_NO_GET_IN", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_IN",0); + break; + case OPT_NO_YYSET_IN: + //buf_strdefine (&userdef_buf, "YY_NO_SET_IN", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_IN",0); + break; + case OPT_NO_YYGET_OUT: + //buf_strdefine (&userdef_buf, "YY_NO_GET_OUT", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_OUT",0); + break; + case OPT_NO_YYSET_OUT: + //buf_strdefine (&userdef_buf, "YY_NO_SET_OUT", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_OUT",0); + break; + case OPT_NO_YYGET_LVAL: + //buf_strdefine (&userdef_buf, "YY_NO_GET_LVAL", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LVAL",0); + break; + case OPT_NO_YYSET_LVAL: + //buf_strdefine (&userdef_buf, "YY_NO_SET_LVAL", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LVAL",0); + break; + case OPT_NO_YYGET_LLOC: + //buf_strdefine (&userdef_buf, "YY_NO_GET_LLOC", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LLOC",0); + break; + case OPT_NO_YYSET_LLOC: + //buf_strdefine (&userdef_buf, "YY_NO_SET_LLOC", "1"); + buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LLOC",0); + break; + + } /* switch */ + } /* while scanopt() */ + + scanopt_destroy (sopt); + + num_input_files = argc - optind; + input_files = argv + optind; + 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 the user explicitly requested posix compatibility by specifing the + * posix-compat option, then we check for conflicting options. However, if + * the POSIXLY_CORRECT variable is set, then we quietly make flex as + * posix-compatible as possible. This is the recommended behavior + * according to the GNU Coding Standards. + * + * Note: The posix option was added to flex to provide the posix behavior + * of the repeat operator in regular expressions, e.g., `ab{3}' + */ + if (posix_compat) { + /* TODO: This is where we try to make flex behave according to + * posiz, AND check for conflicting options. How far should we go + * with this? Should we disable all the neat-o flex features? + */ + /* Update: Estes says no, since other flex features don't violate posix. */ + } + + if (getenv ("POSIXLY_CORRECT")) { + posix_compat = true; + } + + 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 performance penalty ONLY on rules that can match newline characters\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 REJECT")); + else + flexerror (_ + ("variable trailing context rules cannot be used with -f or -F")); + } + + if (reject){ + out_m4_define( "M4_YY_USES_REJECT", NULL); + //outn ("\n#define YY_USES_REJECT"); + } + + if (!do_yywrap) { + outn ("\n#define yywrap(n) 1"); + outn ("#define YY_SKIP_YYWRAP"); + } + + if (ddebug) + outn ("\n#define FLEX_DEBUG"); + + OUT_BEGIN_CODE (); + if (csize == 256) + outn ("typedef unsigned char YY_CHAR;"); + else + outn ("typedef char YY_CHAR;"); + OUT_END_CODE (); + + if (C_plus_plus) { + outn ("#define yytext_ptr yytext"); + + if (interactive) + outn ("#define YY_INTERACTIVE"); + } + + else { + OUT_BEGIN_CODE (); + /* In reentrant scanner, stdinit is handled in flex.skl. */ + if (do_stdinit) { + if (reentrant){ + outn ("#ifdef VMS"); + outn ("#ifdef __VMS_POSIX"); + outn ("#define YY_STDINIT"); + outn ("#endif"); + outn ("#else"); + outn ("#define YY_STDINIT"); + outn ("#endif"); + } + + 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 { + if(!reentrant) + outn (yy_nostdinit); + } + OUT_END_CODE (); + } + + OUT_BEGIN_CODE (); + if (fullspd) + outn ("typedef yyconst struct yy_trans_info *yy_state_type;"); + else if (!C_plus_plus) + outn ("typedef int yy_state_type;"); + OUT_END_CODE (); + + if (lex_compat) + outn ("#define YY_FLEX_LEX_COMPAT"); + + if (!C_plus_plus && !reentrant) { + outn ("extern int yylineno;"); + OUT_BEGIN_CODE (); + outn ("int yylineno = 1;"); + OUT_END_CODE (); + } + + 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 { + + /* Watch out: yytext_ptr is a variable when yytext is an array, + * but it's a macro when yytext is a pointer. + */ + if (yytext_is_array) { + if (!reentrant) + outn ("extern char yytext[];\n"); + } + else { + if (reentrant) { + outn ("#define yytext_ptr yytext_r"); + } + 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 () +{ + maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS); + 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); + rule_has_nl = allocate_bool_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); + ccl_has_nl = allocate_bool_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; +} + + +/* extracts basename from path, optionally stripping the extension "\.*" + * (same concept as /bin/sh `basename`, but different handling of extension). */ +static char *basename2 (path, strip_ext) + char *path; + int strip_ext; /* boolean */ +{ + char *b, *e = 0; + + b = path; + for (b = path; *path; path++) + if (*path == '/') + b = path + 1; + else if (*path == '.') + e = path; + + if (strip_ext && e && e > b) + *e = '\0'; + return b; +} + +void usage () +{ + FILE *f = stdout; + + if (!did_outfilename) { + sprintf (outfile_path, outfile_template, + prefix, C_plus_plus ? "cc" : "c"); + outfilename = outfile_path; + } + + fprintf (f, _("Usage: %s [OPTIONS] [FILE]...\n"), program_name); + fprintf (f, + _ + ("Generates programs that perform pattern-matching on text.\n" + "\n" "Table Compression:\n" + " -Ca, --align trade off larger tables for better memory alignment\n" + " -Ce, --ecs construct equivalence classes\n" + " -Cf do not compress tables; use -f representation\n" + " -CF do not compress tables; use -F representation\n" + " -Cm, --meta-ecs construct meta-equivalence classes\n" + " -Cr, --read use read() instead of stdio for scanner input\n" + " -f, --full generate fast, large scanner. Same as -Cfr\n" + " -F, --fast use alternate table representation. Same as -CFr\n" + " -Cem default compression (same as --ecs --meta-ecs)\n" + "\n" "Debugging:\n" + " -d, --debug enable debug mode in scanner\n" + " -b, --backup write backing-up information to %s\n" + " -p, --perf-report write performance report to stderr\n" + " -s, --nodefault suppress default rule to ECHO unmatched text\n" + " -T, --trace %s should run in trace mode\n" + " -w, --nowarn do not generate warnings\n" + " -v, --verbose write summary of scanner statistics to stdout\n" + "\n" "Files:\n" + " -o, --outfile=FILE specify output filename\n" + " -S, --skel=FILE specify skeleton file\n" + " -t, --stdout write scanner on stdout instead of %s\n" + " --yyclass=NAME name of C++ class\n" + " --header-file=FILE create a C header file in addition to the scanner\n" + " --tables-file[=FILE] write tables to FILE\n" "\n" + "Scanner behavior:\n" + " -7, --7bit generate 7-bit scanner\n" + " -8, --8bit generate 8-bit scanner\n" + " -B, --batch generate batch scanner (opposite of -I)\n" + " -i, --case-insensitive ignore case in patterns\n" + " -l, --lex-compat maximal compatibility with original lex\n" + " -X, --posix-compat maximal compatibility with POSIX lex\n" + " -I, --interactive generate interactive scanner (opposite of -B)\n" + " --yylineno track line count in yylineno\n" + "\n" "Generated code:\n" + " -+, --c++ generate C++ scanner class\n" + " -Dmacro[=defn] #define macro defn (default defn is '1')\n" + " -L, --noline suppress #line directives in scanner\n" + " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n" + " -R, --reentrant generate a reentrant C scanner\n" + " --bison-bridge scanner for bison pure parser.\n" + " --bison-locations include yylloc support.\n" + " --stdinit initialize yyin/yyout to stdin/stdout\n" + " --noansi-definitions old-style function definitions\n" + " --noansi-prototypes empty parameter list in prototypes\n" + " --nounistd do not include \n" + " --noFUNCTION do not generate a particular FUNCTION\n" + "\n" "Miscellaneous:\n" + " -c do-nothing POSIX option\n" + " -n do-nothing POSIX option\n" + " -?\n" + " -h, --help produce this help message\n" + " -V, --version report %s version\n"), + backing_name, program_name, outfile_path, program_name); + +} Index: contrib/flex-2.5/misc.c =================================================================== RCS file: contrib/flex-2.5/misc.c diff -N contrib/flex-2.5/misc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/misc.c 1 Apr 2003 01:51:38 -0000 @@ -0,0 +1,1095 @@ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" +#include "tables.h" + +#define CMD_IF_TABLES_SER "%if-tables-serialization" +#define CMD_TABLES_YYDMAP "%tables-yydmap" +#define CMD_DEFINE_YYTABLES "%define-yytables" +#define CMD_IF_CPP_ONLY "%if-c++-only" +#define CMD_IF_C_ONLY "%if-c-only" +#define CMD_IF_C_OR_CPP "%if-c-or-c++" +#define CMD_NOT_FOR_HEADER "%not-for-header" +#define CMD_OK_FOR_HEADER "%ok-for-header" +#define CMD_PUSH "%push" +#define CMD_POP "%pop" +#define CMD_IF_REENTRANT "%if-reentrant" +#define CMD_IF_NOT_REENTRANT "%if-not-reentrant" +#define CMD_IF_BISON_BRIDGE "%if-bison-bridge" +#define CMD_IF_NOT_BISON_BRIDGE "%if-not-bison-bridge" +#define CMD_ENDIF "%endif" + +/* we allow the skeleton to push and pop. */ +struct sko_state { + bool dc; /**< do_copy */ +}; +static struct sko_state *sko_stack=0; +static int sko_len=0,sko_sz=0; +static void sko_push(bool dc) +{ + if(!sko_stack){ + sko_sz = 1; + sko_stack = (struct sko_state*)flex_alloc(sizeof(struct sko_state)*sko_sz); + sko_len = 0; + } + if(sko_len >= sko_sz){ + sko_sz *= 2; + sko_stack = (struct sko_state*)flex_realloc(sko_stack,sizeof(struct sko_state)*sko_sz); + } + + /* initialize to zero and push */ + sko_stack[sko_len].dc = dc; + sko_len++; +} +static void sko_peek(bool *dc) +{ + if(sko_len <= 0) + flex_die("peek attempt when sko stack is empty"); + if(dc) + *dc = sko_stack[sko_len-1].dc; +} +static void sko_pop(bool* dc) +{ + sko_peek(dc); + sko_len--; + if(sko_len < 0) + flex_die("popped too many times in skeleton."); +} + +/* Append "#define defname value\n" to the running buffer. */ +void action_define (defname, value) + const char *defname; + int value; +{ + char buf[MAXLINE]; + char *cpy; + + 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); + + /* track #defines so we can undef them when we're done. */ + cpy = copy_string (defname); + buf_append (&defs_buf, &cpy, 1); +} + + +/** Append "m4_define([[defname]],[[value]])m4_dnl\n" to the running buffer. + * @param defname The macro name. + * @param value The macro value, can be NULL, which is the same as the empty string. + */ +void action_m4_define (const char *defname, const char * value) +{ + char buf[MAXLINE]; + + flexfatal ("DO NOT USE THIS FUNCTION!"); + + if ((int) strlen (defname) > MAXLINE / 2) { + format_pinpoint_message (_ + ("name \"%s\" ridiculously long"), + defname); + return; + } + + sprintf (buf, "m4_define([[%s]],[[%s]])m4_dnl\n", defname, value?value:""); + add_action (buf); +} + +/* Append "new_text" to the running buffer. */ +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 () +{ + /* short circuit any output */ + if (gentables) { + + if (datapos > 0) + dataflush (); + + /* add terminator for initialization; { for vi */ + outn (" } ;\n"); + } + dataline = 0; + datapos = 0; +} + + +/* dataflush - flush generated data statements */ + +void dataflush () +{ + /* short circuit any output */ + if (!gentables) + return; + + 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); + FLEX_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 const char *line_fmt = "#line %d \"%s\"\n"; + + if (!gen_line_dirs) + return; + + s1 = do_infile ? infilename : "M4_YY_OUTFILE_NAME"; + + if (do_infile && !s1) + s1 = ""; + + 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; +{ + /* short circuit any output */ + if (!gentables) + return; + + 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; +{ + /* short circuit any output */ + if (!gentables) + return; + + 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) + const 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; +{ + fprintf (stdout, fmt, n); + out_line_count (fmt); +} + +void out_dec2 (fmt, n1, n2) + const char *fmt; + int n1, n2; +{ + fprintf (stdout, fmt, n1, n2); + out_line_count (fmt); +} + +void out_hex (fmt, x) + const char *fmt; + unsigned int x; +{ + fprintf (stdout, 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[]; +{ + fprintf (stdout,fmt, str); + out_line_count (fmt); + out_line_count (str); +} + +void out_str3 (fmt, s1, s2, s3) + const char *fmt, s1[], s2[], s3[]; +{ + fprintf (stdout,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; +{ + fprintf (stdout,fmt, str, n); + out_line_count (fmt); + out_line_count (str); +} + +void outc (c) + int c; +{ + fputc (c, stdout); + + if (c == '\n') + ++out_linenum; +} + +void outn (str) + const char *str; +{ + fputs (str,stdout); + fputc('\n',stdout); + out_line_count (str); + ++out_linenum; +} + +/** Print "m4_define( [[def]], [[val]])m4_dnl\n". + * @param def The m4 symbol to define. + * @param val The definition; may be NULL. + * @return buf + */ +void out_m4_define (const char* def, const char* val) +{ + const char * fmt = "m4_define( [[%s]], [[%s]])m4_dnl\n"; + fprintf(stdout, fmt, def, val?val:""); +} + + +/* 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; + bool do_copy = true; + + /* "reset" the state by clearing the buffer and pushing a '1' */ + if(sko_len > 0) + sko_peek(&do_copy); + sko_len = 0; + sko_push(do_copy=true); + + + /* 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)) { + + if (skelfile) + chomp (buf); + + /* copy from skel array */ + if (buf[0] == '%') { /* control line */ + /* print the control line as a comment. */ + if (ddebug && buf[1] != '#') { + if (buf[strlen (buf) - 1] == '\\') + out_str ("/* %s */\\\n", buf); + else + out_str ("/* %s */\n", buf); + } + + /* We've been accused of using cryptic markers in the skel. + * So we'll use emacs-style-hyphenated-commands. + * We might consider a hash if this if-else-if-else + * chain gets too large. + */ +#define cmd_match(s) (strncmp(buf,(s),strlen(s))==0) + + if (buf[1] == '%') { + /* %% is a break point for skelout() */ + return; + } + else if (cmd_match (CMD_PUSH)){ + sko_push(do_copy); + if(ddebug){ + out_str("/*(state = (%s) */",do_copy?"true":"false"); + } + out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : ""); + } + else if (cmd_match (CMD_POP)){ + sko_pop(&do_copy); + if(ddebug){ + out_str("/*(state = (%s) */",do_copy?"true":"false"); + } + out_str("%s\n", buf[strlen (buf) - 1] =='\\' ? "\\" : ""); + } + else if (cmd_match (CMD_IF_REENTRANT)){ + sko_push(do_copy); + do_copy = reentrant && do_copy; + } + else if (cmd_match (CMD_IF_NOT_REENTRANT)){ + sko_push(do_copy); + do_copy = !reentrant && do_copy; + } + else if (cmd_match(CMD_IF_BISON_BRIDGE)){ + sko_push(do_copy); + do_copy = bison_bridge_lval && do_copy; + } + else if (cmd_match(CMD_IF_NOT_BISON_BRIDGE)){ + sko_push(do_copy); + do_copy = !bison_bridge_lval && do_copy; + } + else if (cmd_match (CMD_ENDIF)){ + sko_pop(&do_copy); + } + else if (cmd_match (CMD_IF_TABLES_SER)) { + do_copy = do_copy && tablesext; + } + else if (cmd_match (CMD_TABLES_YYDMAP)) { + if (tablesext && yydmap_buf.elts) + outn ((char *) (yydmap_buf.elts)); + } + else if (cmd_match (CMD_DEFINE_YYTABLES)) { + out_str("#define YYTABLES_NAME \"%s\"\n", + tablesname?tablesname:"yytables"); + } + else if (cmd_match (CMD_IF_CPP_ONLY)) { + /* only for C++ */ + sko_push(do_copy); + do_copy = C_plus_plus; + } + else if (cmd_match (CMD_IF_C_ONLY)) { + /* %- only for C */ + sko_push(do_copy); + do_copy = !C_plus_plus; + } + else if (cmd_match (CMD_IF_C_OR_CPP)) { + /* %* for C and C++ */ + sko_push(do_copy); + do_copy = true; + } + else if (cmd_match (CMD_NOT_FOR_HEADER)) { + /* %c begin linkage-only (non-header) code. */ + OUT_BEGIN_CODE (); + } + else if (cmd_match (CMD_OK_FOR_HEADER)) { + /* %e end linkage-only code. */ + OUT_END_CODE (); + } + else if (buf[1] == '#') { + /* %# a comment in the skel. ignore. */ + } + else { + flexfatal (_("bad line in skeleton file")); + } + } + + else if (do_copy) + outn (buf); + } /* end while */ +} + + +/* 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; +{ + + /* short circuit any output */ + if (!gentables) + return; + + 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; +} + +/* Remove all '\n' and '\r' characters, if any, from the end of str. + * str can be any null-terminated string, or NULL. + * returns str. */ +char *chomp (str) + char *str; +{ + char *p = str; + + if (!str || !*str) /* s is null or empty string */ + return str; + + /* find end of string minus one */ + while (*p) + ++p; + --p; + + /* eat newlines */ + while (p >= str && (*p == '\r' || *p == '\n')) + *p-- = 0; + return str; +} Index: contrib/flex-2.5/nfa.c =================================================================== RCS file: contrib/flex-2.5/nfa.c diff -N contrib/flex-2.5/nfa.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/nfa.c 14 Feb 2006 19:38:11 -0000 @@ -0,0 +1,708 @@ +/* nfa - NFA 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" + + +/* declare functions that have forward references */ + +int dupmachine PROTO ((int)); +void mkxtion PROTO ((int, int)); + + +/* add_accept - add an accepting state to a machine + * + * accepting_number becomes mach's accepting number. + */ + +void add_accept (mach, accepting_number) + int mach, accepting_number; +{ + /* Hang the accepting number off an epsilon state. if it is associated + * with a state that has a non-epsilon out-transition, then the state + * will accept BEFORE it makes that transition, i.e., one character + * too soon. + */ + + if (transchar[finalst[mach]] == SYM_EPSILON) + accptnum[finalst[mach]] = accepting_number; + + else { + int astate = mkstate (SYM_EPSILON); + + accptnum[astate] = accepting_number; + (void) link_machines (mach, astate); + } +} + + +/* copysingl - make a given number of copies of a singleton machine + * + * synopsis + * + * newsng = copysingl( singl, num ); + * + * newsng - a new singleton composed of num copies of singl + * singl - a singleton machine + * num - the number of copies of singl to be present in newsng + */ + +int copysingl (singl, num) + int singl, num; +{ + int copy, i; + + copy = mkstate (SYM_EPSILON); + + for (i = 1; i <= num; ++i) + copy = link_machines (copy, dupmachine (singl)); + + return copy; +} + + +/* dumpnfa - debugging routine to write out an nfa */ + +void dumpnfa (state1) + int state1; + +{ + 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 + * lastst[state1], but they're not maintained properly when we "or" + * all of the rules together. So we use our knowledge that the machine + * starts at state 1 and ends at lastnfa. + */ + + /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */ + for (ns = 1; ns <= lastnfa; ++ns) { + fprintf (stderr, _("state # %4d\t"), ns); + + sym = transchar[ns]; + tsp1 = trans1[ns]; + tsp2 = trans2[ns]; + anum = accptnum[ns]; + + fprintf (stderr, "%3d: %4d, %4d", sym, tsp1, tsp2); + + if (anum != NIL) + fprintf (stderr, " [%d]", anum); + + fprintf (stderr, "\n"); + } + + fprintf (stderr, _("********** end of dump\n")); +} + + +/* dupmachine - make a duplicate of a given machine + * + * synopsis + * + * copy = dupmachine( mach ); + * + * copy - holds duplicate of mach + * mach - machine to be duplicated + * + * note that the copy of mach is NOT an exact duplicate; rather, all the + * transition states values are adjusted so that the copy is self-contained, + * as the original should have been. + * + * also note that the original MUST be contiguous, with its low and high + * states accessible by the arrays firstst and lastst + */ + +int dupmachine (mach) + int mach; +{ + int i, init, state_offset; + int state = 0; + int last = lastst[mach]; + + for (i = firstst[mach]; i <= last; ++i) { + state = mkstate (transchar[i]); + + if (trans1[i] != NO_TRANSITION) { + mkxtion (finalst[state], trans1[i] + state - i); + + if (transchar[i] == SYM_EPSILON && + trans2[i] != NO_TRANSITION) + mkxtion (finalst[state], + trans2[i] + state - i); + } + + accptnum[state] = accptnum[i]; + } + + if (state == 0) + flexfatal (_("empty machine in dupmachine()")); + + state_offset = state - i + 1; + + init = mach + state_offset; + firstst[init] = firstst[mach] + state_offset; + finalst[init] = finalst[mach] + state_offset; + lastst[init] = lastst[mach] + state_offset; + + return init; +} + + +/* finish_rule - finish up the processing for a rule + * + * An accepting number is added to the given machine. If variable_trail_rule + * is true then the rule has trailing context and both the head and trail + * are variable size. Otherwise if headcnt or trailcnt is non-zero then + * the machine recognizes a pattern with trailing context and headcnt is + * the number of characters in the matched part of the pattern, or zero + * if the matched part has variable length. trailcnt is the number of + * trailing context characters in the pattern, or zero if the trailing + * context has variable length. + */ + +void finish_rule (mach, variable_trail_rule, headcnt, trailcnt, + pcont_act) + int mach, variable_trail_rule, headcnt, trailcnt, pcont_act; +{ + char action_text[MAXLINE]; + + add_accept (mach, num_rules); + + /* We did this in new_rule(), but it often gets the wrong + * number because we do it before we start parsing the current rule. + */ + rule_linenum[num_rules] = linenum; + + /* If this is a continued action, then the line-number has already + * been updated, giving us the wrong number. + */ + if (continued_action) + --rule_linenum[num_rules]; + + + /* If the previous rule was continued action, then we inherit the + * previous newline flag, possibly overriding the current one. + */ + if (pcont_act && rule_has_nl[num_rules - 1]) + rule_has_nl[num_rules] = true; + + sprintf (action_text, "case %d:\n", num_rules); + add_action (action_text); + if (rule_has_nl[num_rules]) { + sprintf (action_text, "/* rule %d can match eol */\n", + num_rules); + add_action (action_text); + } + + + if (variable_trail_rule) { + rule_type[num_rules] = RULE_VARIABLE; + + if (performance_report > 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_G(yy_c_buf_p) = yy_cp"; + char *scanner_bp = "yy_bp"; + + add_action + ("*yy_cp = YY_G(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 INFINITE_REPEAT 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 == INFINITE_REPEAT) { + 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); + rule_has_nl = reallocate_bool_array (rule_has_nl, + 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; + rule_has_nl[num_rules] = false; +} Index: contrib/flex-2.5/options.c =================================================================== RCS file: contrib/flex-2.5/options.c diff -N contrib/flex-2.5/options.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/options.c 25 Mar 2003 16:39:08 -0000 @@ -0,0 +1,280 @@ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "options.h" + +/* Be sure to synchronize these options with those defined in "options.h", + * the giant switch() statement in "main.c", and the %option processing in + * "scan.l". + */ + + +/* The command-line options, passed to scanopt_init() */ +optspec_t flexopts[] = { + + {"-7", OPT_7BIT, 0} + , + {"--7bit", OPT_7BIT, 0} + , /* Generate 7-bit scanner. */ + {"-8", OPT_8BIT, 0} + , + {"--8bit", OPT_8BIT, 0} + , /* Generate 8-bit scanner. */ + {"--align", OPT_ALIGN, 0} + , /* Trade off larger tables for better memory alignment. */ + {"--noalign", OPT_NO_ALIGN, 0} + , + {"--always-interactive", OPT_ALWAYS_INTERACTIVE, 0} + , + {"--array", OPT_ARRAY, 0} + , + {"-b", OPT_BACKUP, 0} + , + {"--backup", OPT_BACKUP, 0} + , /* Generate backing-up information to lex.backup. */ + {"-B", OPT_BATCH, 0} + , + {"--batch", OPT_BATCH, 0} + , /* Generate batch scanner (opposite of -I). */ + {"--bison-bridge", OPT_BISON_BRIDGE, 0} + , /* Scanner to be called by a bison pure parser. */ + {"--bison-locations", OPT_BISON_BRIDGE_LOCATIONS, 0} + , /* Scanner to be called by a bison pure parser. */ + {"-i", OPT_CASE_INSENSITIVE, 0} + , + {"--case-insensitive", OPT_CASE_INSENSITIVE, 0} + , /* Generate case-insensitive scanner. */ + + {"-C[aefFmr]", OPT_COMPRESSION, + "Specify degree of table compression (default is -Cem)"}, + {"-+", OPT_CPLUSPLUS, 0} + , + {"--c++", OPT_CPLUSPLUS, 0} + , /* Generate C++ scanner class. */ + {"-d", OPT_DEBUG, 0} + , + {"--debug", OPT_DEBUG, 0} + , /* Turn on debug mode in generated scanner. */ + {"--nodebug", OPT_NO_DEBUG, 0} + , + {"-s", OPT_NO_DEFAULT, 0} + , + {"--nodefault", OPT_NO_DEFAULT, 0} + , /* Suppress default rule to ECHO unmatched text. */ + {"--default", OPT_DEFAULT, 0} + , + {"-c", OPT_DONOTHING, 0} + , /* For POSIX lex compatibility. */ + {"-n", OPT_DONOTHING, 0} + , /* For POSIX lex compatibility. */ + {"--ecs", OPT_ECS, 0} + , /* Construct equivalence classes. */ + {"--noecs", OPT_NO_ECS, 0} + , + {"-F", OPT_FAST, 0} + , + {"--fast", OPT_FAST, 0} + , /* Same as -CFr. */ + {"-f", OPT_FULL, 0} + , + {"--full", OPT_FULL, 0} + , /* Same as -Cfr. */ + {"--header-file[=FILE]", OPT_HEADER_FILE, 0} + , + {"-?", OPT_HELP, 0} + , + {"-h", OPT_HELP, 0} + , + {"--help", OPT_HELP, 0} + , /* Produce this help message. */ + {"-I", OPT_INTERACTIVE, 0} + , + {"--interactive", OPT_INTERACTIVE, 0} + , /* Generate interactive scanner (opposite of -B). */ + {"-l", OPT_LEX_COMPAT, 0} + , + {"--lex-compat", OPT_LEX_COMPAT, 0} + , /* Maximal compatibility with original lex. */ + {"-X", OPT_POSIX_COMPAT, 0} + , + {"--posix-compat", OPT_POSIX_COMPAT, 0} + , /* Maximal compatibility with POSIX lex. */ + {"--preproc=NUM", OPT_PREPROC_LEVEL, 0} + , + {"-L", OPT_NO_LINE, 0} + , /* Suppress #line directives in scanner. */ + {"--noline", OPT_NO_LINE, 0} + , /* Suppress #line directives in scanner. */ + {"--main", OPT_MAIN, 0} + , /* use built-in main() function. */ + {"--nomain", OPT_NO_MAIN, 0} + , + {"--meta-ecs", OPT_META_ECS, 0} + , /* Construct meta-equivalence classes. */ + {"--nometa-ecs", OPT_NO_META_ECS, 0} + , + {"--never-interactive", OPT_NEVER_INTERACTIVE, 0} + , + {"-o FILE", OPT_OUTFILE, 0} + , + {"--outfile=FILE", OPT_OUTFILE, 0} + , /* Write to FILE (default is lex.yy.c) */ + {"-p", OPT_PERF_REPORT, 0} + , + {"--perf-report", OPT_PERF_REPORT, 0} + , /* Generate performance report to stderr. */ + {"--pointer", OPT_POINTER, 0} + , + {"-P PREFIX", OPT_PREFIX, 0} + , + {"--prefix=PREFIX", OPT_PREFIX, 0} + , /* Use PREFIX (default is yy) */ + {"-Dmacro", OPT_PREPROCDEFINE, 0} + , /* Define a preprocessor symbol. */ + {"--read", OPT_READ, 0} + , /* Use read(2) instead of stdio. */ + {"-R", OPT_REENTRANT, 0} + , + {"--reentrant", OPT_REENTRANT, 0} + , /* Generate a reentrant C scanner. */ + {"--noreentrant", OPT_NO_REENTRANT, 0} + , + {"--reject", OPT_REJECT, 0} + , + {"--noreject", OPT_NO_REJECT, 0} + , + {"-S FILE", OPT_SKEL, 0} + , + {"--skel=FILE", OPT_SKEL, 0} + , /* Use skeleton from FILE */ + {"--stack", OPT_STACK, 0} + , + {"--stdinit", OPT_STDINIT, 0} + , + {"--nostdinit", OPT_NO_STDINIT, 0} + , + {"-t", OPT_STDOUT, 0} + , + {"--stdout", OPT_STDOUT, 0} + , /* Write generated scanner to stdout. */ + {"-T", OPT_TRACE, 0} + , + {"--trace", OPT_TRACE, 0} + , /* Flex should run in trace mode. */ + {"--tables-file[=FILE]", OPT_TABLES_FILE, 0} + , /* Save tables to FILE */ + {"--tables-verify", OPT_TABLES_VERIFY, 0} + , /* Tables integrity check */ + {"--nounistd", OPT_NO_UNISTD_H, 0} + , /* Do not include unistd.h */ + {"-v", OPT_VERBOSE, 0} + , + {"--verbose", OPT_VERBOSE, 0} + , /* Write summary of scanner statistics to stdout. */ + {"-V", OPT_VERSION, 0} + , + {"--version", OPT_VERSION, 0} + , /* Report flex version. */ + {"--warn", OPT_WARN, 0} + , + {"-w", OPT_NO_WARN, 0} + , + {"--nowarn", OPT_NO_WARN, 0} + , /* Suppress warning messages. */ + {"--noansi-definitions", OPT_NO_ANSI_FUNC_DEFS, 0} + , + {"--noansi-prototypes", OPT_NO_ANSI_FUNC_PROTOS, 0} + , + {"--yyclass=NAME", OPT_YYCLASS, 0} + , + {"--yylineno", OPT_YYLINENO, 0} + , + {"--noyylineno", OPT_NO_YYLINENO, 0} + , + + {"--yymore", OPT_YYMORE, 0} + , + {"--noyymore", OPT_NO_YYMORE, 0} + , + {"--noyywrap", OPT_NO_YYWRAP, 0} + , + {"--yywrap", OPT_YYWRAP, 0} + , + + {"--nounput", OPT_NO_UNPUT, 0} + , + {"--noyy_push_state", OPT_NO_YY_PUSH_STATE, 0} + , + {"--noyy_pop_state", OPT_NO_YY_POP_STATE, 0} + , + {"--noyy_top_state", OPT_NO_YY_TOP_STATE, 0} + , + {"--noyy_scan_buffer", OPT_NO_YY_SCAN_BUFFER, 0} + , + {"--noyy_scan_bytes", OPT_NO_YY_SCAN_BYTES, 0} + , + {"--noyy_scan_string", OPT_NO_YY_SCAN_STRING, 0} + , + {"--noyyget_extra", OPT_NO_YYGET_EXTRA, 0} + , + {"--noyyset_extra", OPT_NO_YYSET_EXTRA, 0} + , + {"--noyyget_leng", OPT_NO_YYGET_LENG, 0} + , + {"--noyyget_text", OPT_NO_YYGET_TEXT, 0} + , + {"--noyyget_lineno", OPT_NO_YYGET_LINENO, 0} + , + {"--noyyset_lineno", OPT_NO_YYSET_LINENO, 0} + , + {"--noyyget_in", OPT_NO_YYGET_IN, 0} + , + {"--noyyset_in", OPT_NO_YYSET_IN, 0} + , + {"--noyyget_out", OPT_NO_YYGET_OUT, 0} + , + {"--noyyset_out", OPT_NO_YYSET_OUT, 0} + , + {"--noyyget_lval", OPT_NO_YYGET_LVAL, 0} + , + {"--noyyset_lval", OPT_NO_YYSET_LVAL, 0} + , + {"--noyyget_lloc", OPT_NO_YYGET_LLOC, 0} + , + {"--noyyset_lloc", OPT_NO_YYSET_LLOC, 0} + , + + {0, 0, 0} /* required final NULL entry. */ +}; + +/* vim:set tabstop=8 softtabstop=4 shiftwidth=4: */ Index: contrib/flex-2.5/options.h =================================================================== RCS file: contrib/flex-2.5/options.h diff -N contrib/flex-2.5/options.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/options.h 25 Mar 2003 16:39:08 -0000 @@ -0,0 +1,134 @@ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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 OPTIONS_H +#define OPTIONS_H +#include "scanopt.h" + +extern optspec_t flexopts[]; + +enum flexopt_flag_t { + /* Use positive integers only, since they are return codes for scanopt. + * Order is not important. */ + OPT_7BIT = 1, + OPT_8BIT, + OPT_ALIGN, + OPT_ALWAYS_INTERACTIVE, + OPT_ARRAY, + OPT_BACKUP, + OPT_BATCH, + OPT_BISON_BRIDGE, + OPT_BISON_BRIDGE_LOCATIONS, + OPT_CASE_INSENSITIVE, + OPT_COMPRESSION, + OPT_CPLUSPLUS, + OPT_DEBUG, + OPT_DEFAULT, + OPT_DONOTHING, + OPT_ECS, + OPT_FAST, + OPT_FULL, + OPT_HEADER_FILE, + OPT_HELP, + OPT_INTERACTIVE, + OPT_LEX_COMPAT, + OPT_POSIX_COMPAT, + OPT_MAIN, + OPT_META_ECS, + OPT_NEVER_INTERACTIVE, + OPT_NO_ALIGN, + OPT_NO_ANSI_FUNC_DEFS, + OPT_NO_ANSI_FUNC_PROTOS, + OPT_NO_DEBUG, + OPT_NO_DEFAULT, + OPT_NO_ECS, + OPT_NO_LINE, + OPT_NO_MAIN, + OPT_NO_META_ECS, + OPT_NO_REENTRANT, + OPT_NO_REJECT, + OPT_NO_STDINIT, + OPT_NO_UNPUT, + OPT_NO_WARN, + OPT_NO_YYGET_EXTRA, + OPT_NO_YYGET_IN, + OPT_NO_YYGET_LENG, + OPT_NO_YYGET_LINENO, + OPT_NO_YYGET_LLOC, + OPT_NO_YYGET_LVAL, + OPT_NO_YYGET_OUT, + OPT_NO_YYGET_TEXT, + OPT_NO_YYLINENO, + OPT_NO_YYMORE, + OPT_NO_YYSET_EXTRA, + OPT_NO_YYSET_IN, + OPT_NO_YYSET_LINENO, + OPT_NO_YYSET_LLOC, + OPT_NO_YYSET_LVAL, + OPT_NO_YYSET_OUT, + OPT_NO_YYWRAP, + OPT_NO_YY_POP_STATE, + OPT_NO_YY_PUSH_STATE, + OPT_NO_YY_SCAN_BUFFER, + OPT_NO_YY_SCAN_BYTES, + OPT_NO_YY_SCAN_STRING, + OPT_NO_YY_TOP_STATE, + OPT_OUTFILE, + OPT_PERF_REPORT, + OPT_POINTER, + OPT_PREFIX, + OPT_PREPROCDEFINE, + OPT_PREPROC_LEVEL, + OPT_READ, + OPT_REENTRANT, + OPT_REJECT, + OPT_SKEL, + OPT_STACK, + OPT_STDINIT, + OPT_STDOUT, + OPT_TABLES_FILE, + OPT_TABLES_VERIFY, + OPT_TRACE, + OPT_NO_UNISTD_H, + OPT_VERBOSE, + OPT_VERSION, + OPT_WARN, + OPT_YYCLASS, + OPT_YYLINENO, + OPT_YYMORE, + OPT_YYWRAP +}; + +#endif + +/* vim:set tabstop=8 softtabstop=4 shiftwidth=4 textwidth=0: */ Index: contrib/flex-2.5/parse.h =================================================================== RCS file: contrib/flex-2.5/parse.h diff -N contrib/flex-2.5/parse.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/parse.h 21 Feb 2006 02:45:50 -0000 @@ -0,0 +1,36 @@ +#ifndef YYSTYPE +#define YYSTYPE int +#endif +#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 OPT_HEADER 269 +#define OPT_TABLES 270 +#define CCE_ALNUM 271 +#define CCE_ALPHA 272 +#define CCE_BLANK 273 +#define CCE_CNTRL 274 +#define CCE_DIGIT 275 +#define CCE_GRAPH 276 +#define CCE_LOWER 277 +#define CCE_PRINT 278 +#define CCE_PUNCT 279 +#define CCE_SPACE 280 +#define CCE_UPPER 281 +#define CCE_XDIGIT 282 +#define BEGIN_REPEAT_POSIX 283 +#define END_REPEAT_POSIX 284 +#define BEGIN_REPEAT_FLEX 285 +#define END_REPEAT_FLEX 286 + + +extern YYSTYPE yylval; Index: contrib/flex-2.5/parse.y =================================================================== RCS file: contrib/flex-2.5/parse.y diff -N contrib/flex-2.5/parse.y --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/parse.y 14 Feb 2006 19:38:11 -0000 @@ -0,0 +1,1049 @@ +/* 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 OPT_HEADER +%token OPT_TABLES + +%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 + +/* + *POSIX and AT&T lex place the + * precedence of the repeat operator, {}, below that of concatenation. + * Thus, ab{3} is ababab. Most other POSIX utilities use an Extended + * Regular Expression (ERE) precedence that has the repeat operator + * higher than concatenation. This causes ab{3} to yield abbb. + * + * In order to support the POSIX and AT&T precedence and the flex + * precedence we define two token sets for the begin and end tokens of + * the repeat operator, '{' and '}'. The lexical scanner chooses + * which tokens to return based on whether posix_compat or lex_compat + * are specified. Specifying either posix_compat or lex_compat will + * cause flex to parse scanner files as per the AT&T and + * POSIX-mandated behavior. + */ + +%token BEGIN_REPEAT_POSIX END_REPEAT_POSIX BEGIN_REPEAT_FLEX END_REPEAT_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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +/* 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" +#include "tables.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 '|' */ + +#define format_warn3(fmt, a1, a2) \ + do{ \ + char fw3_msg[MAXLINE];\ + snprintf( fw3_msg, MAXLINE,(fmt), (a1), (a2) );\ + warn( fw3_msg );\ + }while(0) + +/* Expand a POSIX character class expression. */ +#define CCL_EXPR(func) \ + do{ \ + int c; \ + for ( c = 0; c < csize; ++c ) \ + if ( isascii(c) && func(c) ) \ + ccladd( currccl, c ); \ + }while(0) + +/* 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, 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 ); } + | OPT_HEADER '=' NAME + { headerfilename = copy_string( nmstr ); } + | OPT_TABLES '=' NAME + { tablesext = true; tablesfilename = 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 , previous_continued_action); + + 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 , previous_continued_action); + + 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; } + + | series BEGIN_REPEAT_POSIX NUMBER ',' NUMBER END_REPEAT_POSIX + { + 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 ); + } + } + + | series BEGIN_REPEAT_POSIX NUMBER ',' END_REPEAT_POSIX + { + varlength = true; + + if ( $3 <= 0 ) + { + synerr( _("iteration value must be positive") ); + $$ = $1; + } + + else + $$ = mkrep( $1, $3, INFINITE_REPEAT ); + } + + | series BEGIN_REPEAT_POSIX NUMBER END_REPEAT_POSIX + { + /* The series 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 ) ); + } + + ; + +singleton : singleton '*' + { + varlength = true; + + $$ = mkclos( $1 ); + } + + | singleton '+' + { + varlength = true; + $$ = mkposcl( $1 ); + } + + | singleton '?' + { + varlength = true; + $$ = mkopt( $1 ); + } + + | singleton BEGIN_REPEAT_FLEX NUMBER ',' NUMBER END_REPEAT_FLEX + { + 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 BEGIN_REPEAT_FLEX NUMBER ',' END_REPEAT_FLEX + { + varlength = true; + + if ( $3 <= 0 ) + { + synerr( _("iteration value must be positive") ); + $$ = $1; + } + + else + $$ = mkrep( $1, $3, INFINITE_REPEAT ); + } + + | singleton BEGIN_REPEAT_FLEX NUMBER END_REPEAT_FLEX + { + /* 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; + + if (ccl_has_nl[$1]) + rule_has_nl[num_rules] = true; + + $$ = mkstate( -$1 ); + } + + | PREVCCL + { + ++rulelen; + + if (ccl_has_nl[$1]) + rule_has_nl[num_rules] = true; + + $$ = mkstate( -$1 ); + } + + | '"' string '"' + { $$ = $2; } + + | '(' re ')' + { $$ = $2; } + + | CHAR + { + ++rulelen; + + if ( caseins && $1 >= 'A' && $1 <= 'Z' ) + $1 = clower( $1 ); + + if ($1 == nlch) + rule_has_nl[num_rules] = true; + + $$ = mkstate( $1 ); + } + ; + +fullccl : '[' ccl ']' + { $$ = $2; } + + | '[' '^' ccl ']' + { + cclnegate( $3 ); + $$ = $3; + } + ; + +ccl : ccl CHAR '-' CHAR + { + + if (caseins) + { + /* Squish the character range to lowercase only if BOTH + * ends of the range are uppercase. + */ + if (isupper ($2) && isupper ($4)) + { + $2 = tolower ($2); + $4 = tolower ($4); + } + + /* If one end of the range has case and the other + * does not, or the cases are different, then we're not + * sure what range the user is trying to express. + * Examples: [@-z] or [S-t] + */ + else if (has_case ($2) != has_case ($4) + || (has_case ($2) && (b_islower ($2) != b_islower ($4)))) + format_warn3 ( + _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"), + $2, $4); + + /* If the range spans uppercase characters but not + * lowercase (or vice-versa), then should we automatically + * include lowercase characters in the range? + * Example: [@-_] spans [a-z] but not [A-Z] + */ + else if (!has_case ($2) && !has_case ($4) && !range_covers_case ($2, $4)) + format_warn3 ( + _("the character range [%c-%c] is ambiguous in a case-insensitive scanner"), + $2, $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 ); + + if ( $2 == nlch ) + rule_has_nl[num_rules] = true; + + ++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 ) +const char *msg, arg[]; + { + char errmsg[MAXLINE]; + + (void) sprintf( errmsg, msg, arg ); + synerr( errmsg ); + } + + +/* synerr - report a syntax error */ + +void synerr( str ) +const char *str; + { + syntaxerror = true; + pinpoint_message( str ); + } + + +/* format_warn - write out formatted warning */ + +void format_warn( msg, arg ) +const 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 ) +const 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 ) +const 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 ) +const char *str; + { + line_pinpoint( str, linenum ); + } + + +/* line_warning - report a warning at a given line, unless -w was given */ + +void line_warning( str, line ) +const 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 ) +const char *str; +int line; + { + fprintf( stderr, "%s:%d: %s\n", infilename, line, str ); + } + + +/* yyerror - eat up an error message from the parser; + * currently, messages are ignore + */ + +void yyerror( msg ) +const char *msg; + { + } Index: contrib/flex-2.5/regex.c =================================================================== RCS file: contrib/flex-2.5/regex.c diff -N contrib/flex-2.5/regex.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/regex.c 25 Mar 2003 16:39:08 -0000 @@ -0,0 +1,164 @@ +/** regex - regular expression functions related to POSIX regex lib. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" + + +static const char* REGEXP_LINEDIR = "^#line ([[:digit:]]+) \"(.*)\""; +static const char* REGEXP_BLANK_LINE = "^[[:space:]]*$"; + +regex_t regex_linedir; /**< matches line directives */ +regex_t regex_blank_line; /**< matches blank lines */ + + +/** Initialize the regular expressions. + * @return true upon success. + */ +bool flex_init_regex(void) +{ + flex_regcomp(®ex_linedir, REGEXP_LINEDIR, REG_EXTENDED); + flex_regcomp(®ex_blank_line, REGEXP_BLANK_LINE, REG_EXTENDED); + + return true; +} + +/** Compiles a regular expression or dies trying. + * @param preg Same as for regcomp(). + * @param regex Same as for regcomp(). + * @param cflags Same as for regcomp(). + */ +void flex_regcomp(regex_t *preg, const char *regex, int cflags) +{ + int err; + + memset (preg, 0, sizeof (regex_t)); + + if ((err = regcomp (preg, regex, cflags)) != 0) { + const int errbuf_sz = 200; + char * errbuf=0; + + errbuf = (char*)flex_alloc(errbuf_sz *sizeof(char)); + regerror (err, preg, errbuf, errbuf_sz); + sprintf (errbuf, "regcomp failed: %s\n", errbuf); + + flexfatal (errbuf); + free(errbuf); + } +} + +/** Extract a copy of the match, or NULL if no match. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @return The allocated string. + */ +char *regmatch_dup (regmatch_t * m, const char *src) +{ + char *str; + int len; + + if (m == NULL || m->rm_so < 0) + return NULL; + len = m->rm_eo - m->rm_so; + str = (char *) flex_alloc ((len + 1) * sizeof (char)); + strncpy (str, src + m->rm_so, len); + str[len] = 0; + return str; +} + +/** Copy the match. + * @param m A match as returned by regexec(). + * @param dest The destination buffer. + * @param src The source string that was passed to regexec(). + * @return dest + */ +char *regmatch_cpy (regmatch_t * m, char *dest, const char *src) +{ + if (m == NULL || m->rm_so < 0) { + if (dest) + dest[0] = '\0'; + return dest; + } + + snprintf (dest, regmatch_len(m), "%s", src + m->rm_so); + return dest; +} + +/** Get the length in characters of the match. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @return The length of the match. + */ +int regmatch_len (regmatch_t * m) +{ + if (m == NULL || m->rm_so < 0) { + return 0; + } + + return m->rm_eo - m->rm_so; +} + + + +/** Convert a regmatch_t object to an integer using the strtol() function. + * @param m A match as returned by regexec(). + * @param src The source string that was passed to regexec(). + * @param endptr Same as the second argument to strtol(). + * @param base Same as the third argument to strtol(). + * @return The converted integer or error (Return value is the same as for strtol()). + */ +int regmatch_strtol (regmatch_t * m, const char *src, char **endptr, + int base) +{ + int n = 0; + +#define bufsz 20 + char buf[bufsz]; + char *s; + + if (m == NULL || m->rm_so < 0) + return 0; + + if (regmatch_len (m) < bufsz) + s = regmatch_cpy (m, buf, src); + else + s = regmatch_dup (m, src); + + n = strtol (s, endptr, base); + + if (s != buf) + free (s); + + return n; +} + +/** Check for empty or non-existent match. + * @param m A match as returned by regexec(). + * @return false if match length is non-zero. + * Note that reg_empty returns true even if match did not occur at all. + */ +bool regmatch_empty (regmatch_t * m) +{ + return (m == NULL || m->rm_so < 0 || m->rm_so == m->rm_eo); +} + +/* vim:set expandtab cindent tabstop=4 softtabstop=4 shiftwidth=4 textwidth=0: */ Index: contrib/flex-2.5/scan.l =================================================================== RCS file: contrib/flex-2.5/scan.l diff -N contrib/flex-2.5/scan.l --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/flex-2.5/scan.l 14 Feb 2006 19:28:53 -0000 @@ -0,0 +1,882 @@ +/* scan.l - scanner for flex input -*-C-*- */ + +%{ +/* 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. */ + +/* This file is part of flex. */ + +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions */ +/* are met: */ + +/* 1. Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 2. Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ + +/* 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. */ + +#include "flexdef.h" +#include "parse.h" +extern bool tablesverify, tablesext; +extern int trlcontxt; /* Set in parse.y for each rule. */ + +#define ACTION_ECHO add_action( yytext ) +#define ACTION_IFDEF(def, should_define) \ + { \ + if ( should_define ) \ + action_define( def, 1 ); \ + } + +#define ACTION_M4_IFDEF(def, should_define) \ + do{ \ + if ( should_define ) \ + buf_m4_define( &m4defs_buf, def, NULL);\ + else \ + buf_m4_undefine( &m4defs_buf, def);\ + } while(0) + +#define MARK_END_OF_PROLOG mark_prolog(); + +#define YY_DECL \ + int flexscan() + +#define RETURNCHAR \ + yylval = (unsigned char) yytext[0]; \ + return CHAR; + +#define RETURNNAME \ + if(yyleng < MAXLINE) \ + { \ + strcpy( nmstr, yytext ); \ + } \ + else \ + { \ + synerr(_("Input line too long\n")); \ + FLEX_EXIT(EXIT_FAILURE); \ + } \ + 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_USER_INIT \ + if ( getenv("POSIXLY_CORRECT") ) \ + posix_compat = true; + +%} + +%option caseless nodefault 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 CODEBLOCK_MATCH_BRACE + +WS [[:blank:]]+ +OPTWS [[:blank:]]* +NOT_WS [^[:blank:]\r\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, brace_depth=0, brace_start_line=0; + Char nmdef[MAXLINE]; + + +{ + ^{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); + } + ^"%top"[[:blank:]]*"{"[[:blank:]]*{NL} { + brace_start_line = linenum; + ++linenum; + buf_linedir( &top_buf, infilename?infilename:"", linenum); + brace_depth = 1; + yy_push_state(CODEBLOCK_MATCH_BRACE); + } + + ^"%top".* synerr( _("malformed '%top' directive") ); + + {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 */ + + /* xgettext: no-c-format */ + ^"%"[^sxaceknopr{}].* synerr( _( "unrecognized '%' directive" ) ); + + ^{NAME} { + if(yyleng < MAXLINE) + { + strcpy( nmstr, yytext ); + } + else + { + synerr( _("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } + + 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); + } +} + +{ + "}" { + if( --brace_depth == 0){ + /* TODO: Matched. */ + yy_pop_state(); + }else + buf_strnappend(&top_buf, yytext, yyleng); + } + + "{" { + brace_depth++; + buf_strnappend(&top_buf, yytext, yyleng); + } + + {NL} { + ++linenum; + buf_strnappend(&top_buf, yytext, yyleng); + } + + [^{}\r\n]+ { + buf_strnappend(&top_buf, yytext, yyleng); + } + + <> { + linenum = brace_start_line; + synerr(_("Unmatched '{'")); + yyterminate(); + } +} + + +{ + {WS} /* separates name and definition */ + + {NOT_WS}[^\r\n]* { + if(yyleng < MAXLINE) + { + strcpy( (char *) nmdef, yytext ); + } + else + { + synerr( _("Input line too long\n")); + FLEX_EXIT(EXIT_FAILURE); + } + /* 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; + } +} + + +