diff --git a/tools/re2c/CHANGELOG b/tools/re2c/CHANGELOG
index c371edbe1..02a523c27 100644
--- a/tools/re2c/CHANGELOG
+++ b/tools/re2c/CHANGELOG
@@ -1,3 +1,202 @@
+Version 0.16 (2016-01-21)
+---------------------------
+- Fixed bug #127 "code generation error with wide chars and bitmaps (omitted 'goto' statement)"
+- Added DFA minimization and option '--dfa-minimization
'
+- Fixed bug #128 "very slow DFA construction (resulting in a very large DFA)"
+- Fixed bug #132 "test failure on big endian archs with 0.15.3"
+
+Version 0.15.3 (2015-12-02)
+---------------------------
+- Fixed bugs and applied patches:
+ #122 "clang does not compile re2c 0.15.x" (reported and fixed by Oleksii Taran).
+ #124 "Get rid of UINT32_MAX and friends" (patch by Sergei Trofimovich, fixes FreeBSD builds).
+ #125 "[OS X] git reports changes not staged for commit in newly cloned repository" (by Oleksii Taran, this fix also applies to Windows).
+- Added option --no-version that allows to omit version information.
+- Reduced memory and time consumed with -Wundefined-control-flow.
+- Improved coverage of input data generated with -S --skeleton.
+
+Version 0.15.2 (2015-11-23)
+---------------------------
+- Fixed build system: lexer depends on bison-generated parser
+ (Gentoo bug: https://bugs.gentoo.org/show_bug.cgi?id=566620)
+
+Version 0.15.1 (2015-11-22)
+---------------------------
+- Fixed test failures caused by locale-sensitive 'sort'.
+
+Version 0.15 (2015-11-22)
+-------------------------
+- Updated website http://re2c.org:
+ added examples
+ updated docs
+ added news
+ added web feed (Atom 1.0)
+- Added options:
+ -S, --skeleton
+ --empty-class
+- Added warnings:
+ -W
+ -Werror
+ -W
+ -Wno-
+ -Werror-
+ -Wno-error-
+- Added individual warnings:
+ -Wundefined-control-flow
+ -Wunreachable-rules
+ -Wcondition-order
+ -Wuseless-escape
+ -Wempty-character-class
+ -Wswapped-range
+ -Wmatch-empty-string
+- Fixed options:
+ -- (interpret remaining arguments as non-options)
+- Deprecated options:
+ -1 --single-pass (single pass is by default now)
+- Reduced size of the generated .dot files.
+- Fixed bugs:
+ #27 re2c crashes reading files containing %{ %} (patch by Rui)
+ #51 default rule doesn't work in reuse mode
+ #52 eliminate multiple passes
+ #59 bogus yyaccept in -c mode
+ #60 redundant use of YYMARKER
+ #61 empty character class [] matches empty string
+ #115 flex-style named definitions cause ambiguity in re2c grammar
+ #119 -f with -b/-g generates incorrect dispatch on fill labels
+ #116 empty string with non-empty trailing context consumes code units
+- Added test options:
+ -j, -j (run tests in N threads, defaults to the number of CPUs)
+ --wine (test windows builds using wine)
+ --skeleton (generate skeleton programs, compile and execute them)
+ --keep-tmp-files (don't delete intermediate files for successful tests)
+- Updated build system:
+ support out of source builds
+ support `make distcheck`
+ added `make bootstrap` (rebuild re2c after building with precomplied .re files)
+ added `make tests` (run tests with -j)
+ added `make vtests` (run tests with --valgrind -j)
+ added `make wtests` (run tests with --wine -j 1)
+ added Autoconf tests for CXXFLAGS. By default try the following options:
+ -W -Wall -Wextra -Weffc++ -pedantic -Wformat=2 -Wredundant-decls
+ -Wsuggest-attribute=format -Wconversion -Wsign-conversion -O2 -Weverything),
+ respect user-defined CXXFLAGS
+ support Mingw builds: `configure -host i686-w64-mingw32`
+ structured source files
+ removed old MSVC files
+- Moved development to github (https://github.com/skvadrik/re2c), keep a mirror on sourceforge.
+
+Version 0.14.3 (2015-05-20)
+-----------------------------
+- applied patch '#27 re2c crashes reading files containing %{ %}' by Rui
+- dropped distfiles for MSVC (they are broken anyway)
+
+Version 0.14.2 (2015-03-25)
+-----------------------------
+- fixed #57 Wrong result only if another rule is present
+
+Version 0.14.1 (2015-02-27)
+-----------------------------
+- fixed #55 re2c-0.14: re2c -V outputs null byte
+
+Version 0.14 (2015-02-23)
+-----------------------------
+- Added generic input API 21 (#21 Support to configure how re2c code interfaced with the symbol buffer?)
+- fixed #46 re2c generates an infinite loop, depends on existence of previous parser
+- fixed #47 Dot output label escaped characters
+
+Version 0.13.7.5 (2014-08-22)
+-----------------------------
+- Fixed Gentoo bug: https://bugs.gentoo.org/show_bug.cgi?id=518904 (PHP lexer)
+
+Version 0.13.7.4 (2014-07-29)
+-----------------------------
+- Enabled 'make docs' only if configured with '--enable-docs'
+- Disallowed to use yacc/byacc instead of bison to build parser
+- Removed non-portable sed feature in script that runs tests
+
+Version 0.13.7.3 (2014-07-28)
+-----------------------------
+- Fixed CXX warning
+- Got rid of asciidoc build-time dependency
+
+Version 0.13.7.2 (2014-07-27)
+-----------------------------
+- Included man page into dist, respect users CXXFLAGS.
+
+Version 0.13.7.1 (2014-07-26)
+-----------------------------
+- Added missing files to tarball
+
+Version 0.13.7 (2014-07-25)
+---------------------------
+- Added UTF-8 support
+- Added UTF-16 support
+- Added default rule
+- Added option to control ill-formed Unicode
+
+Version 0.13.6 (2013-07-04)
+---------------------------
+- Fixed #2535084 uint problem with Sun C 5.8
+- #3308400: allow Yacc-style %{code brackets}%
+- #2506253: allow C++ // comments
+- Fixed inplace configuration in -e mode.
+- Applied #2482572 Typos in error messages.
+- Applied #2482561 Error in manual section on -r mode.
+- Fixed #2478216 Wrong start_label in -c mode.
+- Fixed #2186718 Unescaped backslash in file name of #line directive.
+- Fixed #2102138 Duplicate case labels on EBCDIC.
+- Fixed #2088583 Compile problem on AIX.
+- Fixed #2038610 Ebcdic problem.
+- improve dot support: make char intervals (e.g. [A-Z]) instead of one edge per char
+
+Version 0.13.5 (2008-05-25)
+---------------------------
+- Fixed #1952896 Segfault in re2c::Scanner::scan.
+- Fixed #1952842 Regression.
+
+Version 0.13.4 (2008-04-05)
+---------------------------
+- Added transparent handling of #line directives in input files.
+- Added re2c:yyfill:check inplace configuration.
+- Added re2c:define:YYSETSTATE:naked inplace configuration.
+- Added re2c:flags:w and re2c:flags:u inplace configurations.
+- Added the ability to add rules in 'use:re2c' blocks.
+- Changed -r flag to accept only 'rules:re2c' and 'use:re2c' blocks.
+
+Version 0.13.3 (2008-03-14)
+---------------------------
+- Added -r flag to allow reuse of scanner definitions.
+- Added -F flag to support flex syntax in rules.
+- Fixed SEGV in scanner that occurs with very large blocks.
+- Fixed issue with unused yybm.
+- Partial support for flex syntax.
+- Changed to allow /* comments with -c switch.
+- Added flag -D/--emit-dot.
+
+Version 0.13.2 (2008-02-14)
+---------------------------
+- Added flag --case-inverted.
+- Added flag --case-insensitive.
+- Added support for '' to enable rule setup.
+- Added support for '=>' style rules.
+- Added support for ':=' style rules.
+- Added support for ':=>' style rules.
+- Added re2c:cond:divider and re2c:con:goto inplace configuration.
+- Fixed code generation to emit space after 'if'.
+
+Version 0.13.1 (2007-08-24)
+---------------------------
+- Added custom build rules for Visual Studio 2005 (re2c.rules). (William Swanson)
+- Fixed issue with some compilers.
+- Fixed #1776177 Build on AIX.
+- Fixed #1743180 fwrite with 0 length crashes on OS X.
+
+Version 0.13.0 (2007-06-24)
+---------------------------
+- Added -c and -t to generate scanners with (f)lex-like condition support.
+- Fixed issue with short form of switches and parameter if not first switch.
+- Fixed #1708378 segfault in actions.cc.
+
Version 0.12.3 (2007-08-24)
---------------------------
- Fixed issue with some compilers.
diff --git a/tools/re2c/CMakeLists.txt b/tools/re2c/CMakeLists.txt
index ffc7a56e9..78742ef99 100644
--- a/tools/re2c/CMakeLists.txt
+++ b/tools/re2c/CMakeLists.txt
@@ -7,32 +7,92 @@ include( CheckTypeSize )
set( PACKAGE_NAME re2c )
set( PACKAGE_TARNAME re2c )
-set( PACKAGE_VERSION 0.12.3 )
-set( PACKAGE_STRING "re2c 0.12.3" )
+set( PACKAGE_VERSION 0.16 )
+set( PACKAGE_STRING "re2c 0.16" )
set( PACKAGE_BUGREPORT "re2c-general@lists.sourceforge.net" )
CHECK_FUNCTION_EXISTS( strdup HAVE_STRDUP )
CHECK_FUNCTION_EXISTS( strndup HAVE_STRNDUP )
+CHECK_TYPE_SIZE( "0i8" SIZEOF_0I8 )
+CHECK_TYPE_SIZE( "0l" SIZEOF_0L )
+CHECK_TYPE_SIZE( "0ll" SIZEOF_0LL )
CHECK_TYPE_SIZE( char SIZEOF_CHAR )
CHECK_TYPE_SIZE( short SIZEOF_SHORT )
CHECK_TYPE_SIZE( int SIZEOF_INT )
CHECK_TYPE_SIZE( long SIZEOF_LONG )
+CHECK_TYPE_SIZE( "long long" SIZEOF_LONG_LONG )
+CHECK_TYPE_SIZE( "void *" SIZEOF_VOID_P )
+CHECK_TYPE_SIZE( __int64 SIZEOF___INT_64 )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h )
-include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
+include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} )
add_definitions( -DHAVE_CONFIG_H )
+file( GLOB SRC_HDR
+ src/codegen/*.h
+ src/conf/*.h
+ src/ir/*.h
+ src/*.h
+ src/parse/*.h
+ src/util/*.h )
+
add_executable( re2c
- actions.cc
- code.cc
- dfa.cc
- main.cc
- mbo_getopt.cc
- parser.cc
- scanner.cc
- substr.cc
- translate.cc )
+ ${SRC_HDR}
+ src/codegen/bitmap.cc
+ src/codegen/emit_action.cc
+ src/codegen/emit_dfa.cc
+ src/codegen/label.cc
+ src/codegen/go_construct.cc
+ src/codegen/go_destruct.cc
+ src/codegen/go_emit.cc
+ src/codegen/go_used_labels.cc
+ src/codegen/input_api.cc
+ src/codegen/output.cc
+ src/codegen/print.cc
+ src/conf/msg.cc
+ src/conf/opt.cc
+ src/conf/parse_opts.cc
+ src/conf/warn.cc
+ src/ir/nfa/calc_size.cc
+ src/ir/nfa/nfa.cc
+ src/ir/nfa/split.cc
+ src/ir/adfa/adfa.cc
+ src/ir/adfa/prepare.cc
+ src/ir/dfa/determinization.cc
+ src/ir/dfa/fillpoints.cc
+ src/ir/dfa/minimization.cc
+ src/ir/regexp/display.cc
+ src/ir/regexp/encoding/enc.cc
+ src/ir/regexp/encoding/range_suffix.cc
+ src/ir/regexp/encoding/utf8/utf8_regexp.cc
+ src/ir/regexp/encoding/utf8/utf8_range.cc
+ src/ir/regexp/encoding/utf8/utf8.cc
+ src/ir/regexp/encoding/utf16/utf16_regexp.cc
+ src/ir/regexp/encoding/utf16/utf16.cc
+ src/ir/regexp/encoding/utf16/utf16_range.cc
+ src/ir/regexp/fixed_length.cc
+ src/ir/regexp/regexp.cc
+ src/ir/compile.cc
+ src/ir/rule_rank.cc
+ src/ir/skeleton/control_flow.cc
+ src/ir/skeleton/generate_code.cc
+ src/ir/skeleton/generate_data.cc
+ src/ir/skeleton/match_empty.cc
+ src/ir/skeleton/maxlen.cc
+ src/ir/skeleton/skeleton.cc
+ src/ir/skeleton/unreachable.cc
+ src/ir/skeleton/way.cc
+ src/main.cc
+ src/parse/code.cc
+ src/parse/input.cc
+ src/parse/lex.cc
+ src/parse/lex_conf.cc
+ src/parse/parser.cc
+ src/parse/scanner.cc
+ src/parse/unescape.cc
+ src/util/s_to_n32_unsafe.cc
+ src/util/range.cc )
set( CROSS_EXPORTS ${CROSS_EXPORTS} re2c PARENT_SCOPE )
diff --git a/tools/re2c/NO_WARRANTY b/tools/re2c/NO_WARRANTY
new file mode 100644
index 000000000..885a13d06
--- /dev/null
+++ b/tools/re2c/NO_WARRANTY
@@ -0,0 +1,2 @@
+re2c is distributed with no warranty whatever. The author and any other
+contributors take no responsibility for the consequences of its use.
diff --git a/tools/re2c/README b/tools/re2c/README
index 84c2f4fdb..29d97b674 100644
--- a/tools/re2c/README
+++ b/tools/re2c/README
@@ -1,188 +1,159 @@
-re2c Version 0.12.3
-------------------
+re2c
+--------------------------------------------------------------------------------
-Originally written by Peter Bumbulis (peter@csg.uwaterloo.ca)
-Currently maintained by:
- Dan Nuffer
- Marcus Boerger
- Hartmut Kaiser
+DESCRIPTION
+--------------------------------------------------------------------------------
+re2c is a tool for generating C-based recognizers from regular expressions.
+re2c-based scanners are efficient: for programming languages, given similar
+specifications, a re2c-based scanner is typically almost twice as fast as a
+flex-based scanner with little or no increase in size (possibly a decrease
+on cisc architectures). Indeed, re2c-based scanners are quite competitive with
+hand-crafted ones.
+Unlike flex, re2c does not generate complete scanners: the user must supply some
+interface code. While this code is not bulky (about 50-100 lines for a
+flex-like scanner; see the man page and examples in the distribution) careful
+coding is required for efficiency (and correctness). One advantage of this
+arrangement is that the generated code is not tied to any particular input
+model.
+--------------------------------------------------------------------------------
+
+
+DOWNLOAD
+--------------------------------------------------------------------------------
The re2c distribution can be found at:
+ https://sourceforge.net/projects/re2c/
- http://sourceforge.net/projects/re2c/
+Download the latest tarball:
+ https://sourceforge.net/projects/re2c/files/latest/download
-re2c has been developed and tested with the following compilers on various
-platforms in 32 bit and 64 bit mode:
-- GCC 3.3 ... 4.1
-- Microsoft VC 7, 7.1, 8
-- Intel 9.0
-- Sun C++ 5.8 (CXXFLAGS='-library=stlport4')
-- MIPSpro Compilers: Version 7.4.4m
+Clone git repo:
+ git clone git://git.code.sf.net/p/re2c/code-git
+--------------------------------------------------------------------------------
-GCC 2.x and Microsoft VC 6 are not capable of compiling re2c.
-Building re2c on unix like platforms requires autoconf 2.57 and bison (tested
-with 1.875 and later). Under windows you don't need autoconf or bison
-and can use the pregenerated files.
+BUILD
+--------------------------------------------------------------------------------
+Contents:
+ 1. simple build
+ 2. bootstrap
+ 3. out-of-source build
+ 4. testing
+ 5. rebuild documentation
+ 6. build for windows with mingw
+ 7. build from git
-You can build this software by simply typing the following commands:
- ./configure
- make
+1. Simplest possible build:
+ $ ./configure [--prefix=]
+ $ make
+ $ make install
+This will build re2c and install it (binary and man page) to (defaults
+to /usr/local).
-The above version will be based on the pregenerated scanner.cc file.
-If you want to build that file yourself (recommended when installing
-re2c) you need the following steps:
- ./configure
- make
- rm -f scanner.cc
- make install
+2. Bootstrap and rebuild:
+ $ ./configure [--prefix=]
+ $ make bootstrap
+ $ make install
+Usual bootstrap procedure: re2c uses re2c to compile its lexer.
+1. build lexer (if make finds re2c binary in build directory, it will build lexer
+ from source, otherwize it will use prebuilt lexer)
+2. build re2c
+3. build lexer from source using re2c binary in build directory
+4. rebuild re2c
-Or you can create a rpm package and install it by the following commands:
- ./configure
- make rpm
- rpm -Uhv /re2c-0.12.3-1.rpm
+3. Out-of-source build:
+ $ mkdir
+ $ cd
+ $ /configure [--prefix=]
+ $ make
+ $ make install
-If you want to build from CVS then the first thing you should do is
-regenerating all build files using the following command:
- ./autogen.sh
-and then continue with one of the above described build methods. Or if you
-need to generate RPM packages for cvs builds use these commands:
- ./autogen.sh
- ./configure
- ./makerpm
- rpm -Uhv /re2c-0.12.3-.rpm
+4. Testing:
+ $ make check
+This will redirect test script output to file. If you want to see progress:
+ $ make tests
+Testing under valgrind (takes a long time):
+ $ make vtests
-Here should be a number like 1. And must equal
-the directory where the makerpm step has written the generated rpm to.
+5. Rebuild documentation (requires rst2man.py):
+ $ ./configure --enable-docs [--prefix=]
+ $ make docs
+ $ make install
-If you are on a debian system you can use the tool 'alien' to convert rpms
-to debian packages.
+6. Build for windows using mingw:
+ $ ../configure --host i686-w64-mingw32 [--prefix=]
+ $ make
+This will result into an executable re2c.exe, which can be tested with wine:
+ $ make wtests
-When building with native SUN compilers you need to set the following compiler
-flags: CXXFLAGS='-g -compat5 -library=stlport4'.
+7. If you want to build from git, you'll first need to generate autotools files:
+ $ ./autogen.sh
+--------------------------------------------------------------------------------
-If you want to build re2c on a windows system you can either use cygwin and one
-of the methods described above or use Microsoft Visual C .NET 2002 or later
-with the solution files provided (re2c.sln for 2002/2003 and re2c-2005.sln for
-version 2005). re2c cannot be built with Microsoft Visual C 6.0 or earlier.
-re2c is a great tool for writing fast and flexible lexers. It has
-served many people well for many years. re2c is on the order of 2-3
-times faster than a flex based scanner, and its input model is much
-more flexible.
+INFO
+--------------------------------------------------------------------------------
+ $ man re2c
-For an introduction to re2c refer to the lessons sub directory.
+re2c home page:
+ re2c.org
-Peter's original version 0.5 ANNOUNCE and README follows.
+re2c manual:
+ re2c.org/manual.html
---
+Ulya Trofimovich's blog on re2c:
+ skvadrik.github.io/aleph_null/re2c.html
-re2c is a tool for generating C-based recognizers from regular
-expressions. re2c-based scanners are efficient: for programming
-languages, given similar specifications, an re2c-based scanner is
-typically almost twice as fast as a flex-based scanner with little or no
-increase in size (possibly a decrease on cisc architectures). Indeed,
-re2c-based scanners are quite competitive with hand-crafted ones.
+Original paper on re2c: "RE2C: a More Versatile Parser Generator" (1994, Peter
+Bumbulis and Donald D. Cowan).
-Unlike flex, re2c does not generate complete scanners: the user must
-supply some interface code. While this code is not bulky (about 50-100
-lines for a flex-like scanner; see the man page and examples in the
-distribution) careful coding is required for efficiency (and
-correctness). One advantage of this arrangement is that the generated
-code is not tied to any particular input model. For example, re2c
-generated code can be used to scan data from a null-byte terminated
-buffer as illustrated below.
+Examples can be found in 'examples' directory.
+--------------------------------------------------------------------------------
-Given the following source
- #define NULL ((char*) 0)
- char *scan(char *p)
- {
- #define YYCTYPE char
- #define YYCURSOR p
- #define YYLIMIT p
- #define YYFILL(n)
- /*!re2c
- [0-9]+ {return YYCURSOR;}
- [\000-\377] {return NULL;}
- */
- }
+MAILING LISTS
+--------------------------------------------------------------------------------
+re2c-general:
+ re2c-general@lists.sourceforge.net
+re2c-devel:
+ re2c-devel@lists.sourceforge.net
-re2c will generate
+You are welcome to ask for help or share your thoughts and ideas about re2c :)
+--------------------------------------------------------------------------------
- /* Generated by re2c on Sat Apr 16 11:40:58 1994 */
- #line 1 "simple.re"
- #define NULL ((char*) 0)
- char *scan(char *p)
- {
- #define YYCTYPE char
- #define YYCURSOR p
- #define YYLIMIT p
- #define YYFILL(n)
- {
- YYCTYPE yych;
- unsigned int yyaccept;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if(yych <= '/') goto yy4;
- if(yych >= ':') goto yy4;
- yy2: yych = *++YYCURSOR;
- goto yy7;
- yy3:
- #line 9
- {return YYCURSOR;}
- yy4: yych = *++YYCURSOR;
- yy5:
- #line 10
- {return NULL;}
- yy6: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- yy7: if(yych <= '/') goto yy3;
- if(yych <= '9') goto yy6;
- goto yy3;
- }
- #line 11
+BUGS
+--------------------------------------------------------------------------------
+Please report any bugs and send feature requests to:
+ https://sourceforge.net/p/re2c/_list/tickets
+--------------------------------------------------------------------------------
- }
-Note that most compilers will perform dead-code elimination to remove
-all YYCURSOR, YYLIMIT comparisions.
+AUTHORS
+--------------------------------------------------------------------------------
+Originally written by Peter Bumbulis (peter@csg.uwaterloo.ca)
+Currently maintained by:
+ Ulya Trofimovich
+ Dan Nuffer
+ Marcus Boerger
+ Hartmut Kaiser
+--------------------------------------------------------------------------------
-re2c was developed for a particular project (constructing a fast REXX
-scanner of all things!) and so while it has some rough edges, it should
-be quite usable. More information about re2c can be found in the
-(admittedly skimpy) man page; the algorithms and heuristics used are
-described in an upcoming LOPLAS article (included in the distribution).
-Probably the best way to find out more about re2c is to try the supplied
-examples. re2c is written in C++, and is currently being developed
-under Linux using gcc 2.5.8.
-Peter
+LICENSE
+--------------------------------------------------------------------------------
+re2c is distributed with no warranty whatever. The code is certain to contain
+errors. Neither the author nor any contributor takes responsibility for any
+consequences of its use.
---
-
-re2c is distributed with no warranty whatever. The code is certain to
-contain errors. Neither the author nor any contributor takes
-responsibility for any consequences of its use.
-
-re2c is in the public domain. The data structures and algorithms used
-in re2c are all either taken from documents available to the general
-public or are inventions of the author. Programs generated by re2c may
-be distributed freely. re2c itself may be distributed freely, in source
-or binary, unchanged or modified. Distributors may charge whatever fees
-they can obtain for re2c.
+re2c is in the public domain. The data structures and algorithms used in re2c
+are all either taken from documents available to the general public or are
+inventions of the authors. Programs generated by re2c may be distributed freely.
+re2c itself may be distributed freely, in source or binary, unchanged or
+modified. Distributors may charge whatever fees they can obtain for re2c.
If you do make use of re2c, or incorporate it into a larger project an
-acknowledgement somewhere (documentation, research report, etc.) would
-be appreciated.
-
-Please send bug reports and feedback (including suggestions for
-improving the distribution) to
-
- peter@csg.uwaterloo.ca
-
-Include a small example and the banner from parser.y with bug reports.
-
+acknowledgement somewhere (documentation, research report, etc.) would be
+appreciated.
+--------------------------------------------------------------------------------
diff --git a/tools/re2c/actions.cc b/tools/re2c/actions.cc
deleted file mode 100644
index b90584827..000000000
--- a/tools/re2c/actions.cc
+++ /dev/null
@@ -1,1062 +0,0 @@
-/* $Id: actions.cc 608 2006-11-05 00:48:30Z helly $ */
-#include
-#include
-#include
-#include
-#include
-
-#include "globals.h"
-#include "parser.h"
-#include "dfa.h"
-
-namespace re2c
-{
-
-void Symbol::ClearTable()
-{
- for (SymbolTable::iterator it = symbol_table.begin(); it != symbol_table.end(); ++it)
- {
- delete it->second;
- }
-
- symbol_table.clear();
-}
-
-Symbol::SymbolTable Symbol::symbol_table;
-
-Symbol *Symbol::find(const SubStr &str)
-{
- const std::string ss(str.to_string());
- SymbolTable::const_iterator it = symbol_table.find(ss);
-
- if (it == symbol_table.end())
- {
- return (*symbol_table.insert(SymbolTable::value_type(ss, new Symbol(str))).first).second;
- }
-
- return (*it).second;
-}
-
-void showIns(std::ostream &o, const Ins &i, const Ins &base)
-{
- o.width(3);
- o << &i - &base << ": ";
-
- switch (i.i.tag)
- {
-
- case CHAR:
- {
- o << "match ";
-
- for (const Ins *j = &(&i)[1]; j < (Ins*) i.i.link; ++j)
- prtCh(o, j->c.value);
-
- break;
- }
-
- case GOTO:
- o << "goto " << ((Ins*) i.i.link - &base);
- break;
-
- case FORK:
- o << "fork " << ((Ins*) i.i.link - &base);
- break;
-
- case CTXT:
- o << "ctxt";
- break;
-
- case TERM:
- o << "term " << ((RuleOp*) i.i.link)->accept;
- break;
- }
-
- o << "\n";
-}
-
-uint RegExp::fixedLength()
-{
- return ~0;
-}
-
-const char *NullOp::type = "NullOp";
-
-void NullOp::calcSize(Char*)
-{
- size = 0;
-}
-
-uint NullOp::fixedLength()
-{
- return 0;
-}
-
-void NullOp::compile(Char*, Ins*)
-{
- ;
-}
-
-void NullOp::split(CharSet&)
-{
- ;
-}
-
-std::ostream& operator<<(std::ostream &o, const Range &r)
-{
- if ((r.ub - r.lb) == 1)
- {
- prtCh(o, r.lb);
- }
- else
- {
- prtCh(o, r.lb);
- o << "-";
- prtCh(o, r.ub - 1);
- }
-
- return o << r.next;
-}
-
-Range *doUnion(Range *r1, Range *r2)
-{
- Range *r, **rP = &r;
-
- for (;;)
- {
- Range *s;
-
- if (r1->lb <= r2->lb)
- {
- s = new Range(*r1);
- }
- else
- {
- s = new Range(*r2);
- }
-
- *rP = s;
- rP = &s->next;
-
- for (;;)
- {
- if (r1->lb <= r2->lb)
- {
- if (r1->lb > s->ub)
- break;
-
- if (r1->ub > s->ub)
- s->ub = r1->ub;
-
- if (!(r1 = r1->next))
- {
- uint ub = 0;
-
- for (; r2 && r2->lb <= s->ub; r2 = r2->next)
- ub = r2->ub;
-
- if (ub > s->ub)
- s->ub = ub;
-
- *rP = r2;
-
- return r;
- }
- }
- else
- {
- if (r2->lb > s->ub)
- break;
-
- if (r2->ub > s->ub)
- s->ub = r2->ub;
-
- if (!(r2 = r2->next))
- {
- uint ub = 0;
-
- for (; r1 && r1->lb <= s->ub; r1 = r1->next)
- ub = r1->ub;
-
- if (ub > s->ub)
- s->ub = ub;
-
- *rP = r1;
-
- return r;
- }
- }
- }
- }
-
- *rP = NULL;
- return r;
-}
-
-Range *doDiff(Range *r1, Range *r2)
-{
- Range *r, *s, **rP = &r;
-
- for (; r1; r1 = r1->next)
- {
- uint lb = r1->lb;
-
- for (; r2 && r2->ub <= r1->lb; r2 = r2->next)
-
- ;
- for (; r2 && r2->lb < r1->ub; r2 = r2->next)
- {
- if (lb < r2->lb)
- {
- *rP = s = new Range(lb, r2->lb);
- rP = &s->next;
- }
-
- if ((lb = r2->ub) >= r1->ub)
- goto noMore;
- }
-
- *rP = s = new Range(lb, r1->ub);
- rP = &s->next;
-
-noMore:
- ;
- }
-
- *rP = NULL;
- return r;
-}
-
-MatchOp *merge(MatchOp *m1, MatchOp *m2)
-{
- if (!m1)
- return m2;
-
- if (!m2)
- return m1;
-
- return new MatchOp(doUnion(m1->match, m2->match));
-}
-
-const char *MatchOp::type = "MatchOp";
-
-void MatchOp::display(std::ostream &o) const
-{
- o << match;
-}
-
-void MatchOp::calcSize(Char *rep)
-{
- size = 1;
-
- for (Range *r = match; r; r = r->next)
- for (uint c = r->lb; c < r->ub; ++c)
- if (rep[c] == c)
- ++size;
-}
-
-uint MatchOp::fixedLength()
-{
- return 1;
-}
-
-void MatchOp::compile(Char *rep, Ins *i)
-{
- i->i.tag = CHAR;
- i->i.link = &i[size];
- Ins *j = &i[1];
- uint bump = size;
-
- for (Range *r = match; r; r = r->next)
- {
- for (uint c = r->lb; c < r->ub; ++c)
- {
- if (rep[c] == c)
- {
- j->c.value = c;
- j->c.bump = --bump;
- j++;
- }
- }
- }
-}
-
-void MatchOp::split(CharSet &s)
-{
- for (Range *r = match; r; r = r->next)
- {
- for (uint c = r->lb; c < r->ub; ++c)
- {
- CharPtn *x = s.rep[c], *a = x->nxt;
-
- if (!a)
- {
- if (x->card == 1)
- continue;
-
- x->nxt = a = s.freeHead;
-
- if (!(s.freeHead = s.freeHead->nxt))
- s.freeTail = &s.freeHead;
-
- a->nxt = NULL;
-
- x->fix = s.fix;
-
- s.fix = x;
- }
-
- if (--(x->card) == 0)
- {
- *s.freeTail = x;
- *(s.freeTail = &x->nxt) = NULL;
- }
-
- s.rep[c] = a;
- ++(a->card);
- }
- }
-
- for (; s.fix; s.fix = s.fix->fix)
- if (s.fix->card)
- s.fix->nxt = NULL;
-}
-
-RegExp * mkDiff(RegExp *e1, RegExp *e2)
-{
- MatchOp *m1, *m2;
-
- if (!(m1 = (MatchOp*) e1->isA(MatchOp::type)))
- return NULL;
-
- if (!(m2 = (MatchOp*) e2->isA(MatchOp::type)))
- return NULL;
-
- Range *r = doDiff(m1->match, m2->match);
-
- return r ? (RegExp*) new MatchOp(r) : (RegExp*) new NullOp;
-}
-
-RegExp *doAlt(RegExp *e1, RegExp *e2)
-{
- if (!e1)
- return e2;
-
- if (!e2)
- return e1;
-
- return new AltOp(e1, e2);
-}
-
-RegExp *mkAlt(RegExp *e1, RegExp *e2)
-{
- AltOp *a;
- MatchOp *m1, *m2;
-
- if ((a = (AltOp*) e1->isA(AltOp::type)))
- {
- if ((m1 = (MatchOp*) a->exp1->isA(MatchOp::type)))
- e1 = a->exp2;
- }
- else if ((m1 = (MatchOp*) e1->isA(MatchOp::type)))
- {
- e1 = NULL;
- }
-
- if ((a = (AltOp*) e2->isA(AltOp::type)))
- {
- if ((m2 = (MatchOp*) a->exp1->isA(MatchOp::type)))
- e2 = a->exp2;
- }
- else if ((m2 = (MatchOp*) e2->isA(MatchOp::type)))
- {
- e2 = NULL;
- }
-
- return doAlt(merge(m1, m2), doAlt(e1, e2));
-}
-
-const char *AltOp::type = "AltOp";
-
-void AltOp::calcSize(Char *rep)
-{
- exp1->calcSize(rep);
- exp2->calcSize(rep);
- size = exp1->size + exp2->size + 2;
-}
-
-uint AltOp::fixedLength()
-{
- uint l1 = exp1->fixedLength();
- uint l2 = exp1->fixedLength();
-
- if (l1 != l2 || l1 == ~0u)
- return ~0;
-
- return l1;
-}
-
-void AltOp::compile(Char *rep, Ins *i)
-{
- i->i.tag = FORK;
- Ins *j = &i[exp1->size + 1];
- i->i.link = &j[1];
- exp1->compile(rep, &i[1]);
- j->i.tag = GOTO;
- j->i.link = &j[exp2->size + 1];
- exp2->compile(rep, &j[1]);
-}
-
-void AltOp::split(CharSet &s)
-{
- exp1->split(s);
- exp2->split(s);
-}
-
-const char *CatOp::type = "CatOp";
-
-void CatOp::calcSize(Char *rep)
-{
- exp1->calcSize(rep);
- exp2->calcSize(rep);
- size = exp1->size + exp2->size;
-}
-
-uint CatOp::fixedLength()
-{
- uint l1, l2;
-
- if ((l1 = exp1->fixedLength()) != ~0u )
- if ((l2 = exp2->fixedLength()) != ~0u)
- return l1 + l2;
-
- return ~0u;
-}
-
-void CatOp::compile(Char *rep, Ins *i)
-{
- exp1->compile(rep, &i[0]);
- exp2->compile(rep, &i[exp1->size]);
-}
-
-void CatOp::split(CharSet &s)
-{
- exp1->split(s);
- exp2->split(s);
-}
-
-const char *CloseOp::type = "CloseOp";
-
-void CloseOp::calcSize(Char *rep)
-{
- exp->calcSize(rep);
- size = exp->size + 1;
-}
-
-void CloseOp::compile(Char *rep, Ins *i)
-{
- exp->compile(rep, &i[0]);
- i += exp->size;
- i->i.tag = FORK;
- i->i.link = i - exp->size;
-}
-
-void CloseOp::split(CharSet &s)
-{
- exp->split(s);
-}
-
-const char *CloseVOp::type = "CloseVOp";
-
-void CloseVOp::calcSize(Char *rep)
-{
- exp->calcSize(rep);
-
- if (max >= 0)
- {
- size = (exp->size * min) + ((1 + exp->size) * (max - min));
- }
- else
- {
- size = (exp->size * min) + 1;
- }
-}
-
-void CloseVOp::compile(Char *rep, Ins *i)
-{
- Ins *jumppoint;
- int st;
- jumppoint = i + ((1 + exp->size) * (max - min));
-
- for (st = min; st < max; st++)
- {
- i->i.tag = FORK;
- i->i.link = jumppoint;
- i++;
- exp->compile(rep, &i[0]);
- i += exp->size;
- }
-
- for (st = 0; st < min; st++)
- {
- exp->compile(rep, &i[0]);
- i += exp->size;
-
- if (max < 0 && st == 0)
- {
- i->i.tag = FORK;
- i->i.link = i - exp->size;
- i++;
- }
- }
-}
-
-void CloseVOp::split(CharSet &s)
-{
- exp->split(s);
-}
-
-RegExp *expr(Scanner &);
-
-uint Scanner::unescape(SubStr &s) const
-{
- static const char * hex = "0123456789abcdef";
- static const char * oct = "01234567";
-
- s.len--;
- uint c, ucb = 0;
-
- if ((c = *s.str++) != '\\' || s.len == 0)
- {
- return xlat(c);
- }
-
- s.len--;
-
- switch (c = *s.str++)
- {
- case 'n': return xlat('\n');
- case 't': return xlat('\t');
- case 'v': return xlat('\v');
- case 'b': return xlat('\b');
- case 'r': return xlat('\r');
- case 'f': return xlat('\f');
- case 'a': return xlat('\a');
-
- case 'x':
- {
- if (s.len < 2)
- {
- fatal(s.ofs()+s.len, "Illegal hexadecimal character code, two hexadecimal digits are required");
- return ~0;
- }
-
- const char *p1 = strchr(hex, tolower(s.str[0]));
- const char *p2 = strchr(hex, tolower(s.str[1]));
-
- if (!p1 || !p2)
- {
- fatal(s.ofs()+(p1?1:0), "Illegal hexadecimal character code");
- return ~0;
- }
- else
- {
- s.len -= 2;
- s.str += 2;
-
- uint v = (uint)((p1 - hex) << 4)
- + (uint)((p2 - hex));
-
- return v;
- }
- }
-
- case 'U':
- {
- if (s.len < 8)
- {
- fatal(s.ofs()+s.len, "Illegal unicode character, eight hexadecimal digits are required");
- return ~0;
- }
-
- uint l = 0;
-
- if (s.str[0] == '0')
- {
- l++;
- if (s.str[1] == '0')
- {
- l++;
- if (s.str[2] == '0' || (s.str[2] == '1' && uFlag))
- {
- l++;
- if (uFlag) {
- const char *u3 = strchr(hex, tolower(s.str[2]));
- const char *u4 = strchr(hex, tolower(s.str[3]));
- if (u3 && u4)
- {
- ucb = (uint)((u3 - hex) << 20)
- + (uint)((u4 - hex) << 16);
- l++;
- }
- }
- else if (s.str[3] == '0')
- {
- l++;
- }
- }
- }
- }
-
- if (l != 4)
- {
- fatal(s.ofs()+l, "Illegal unicode character, eight hexadecimal digits are required");
- }
-
- s.len -= 4;
- s.str += 4;
-
- // no break;
- }
- case 'X':
- case 'u':
- {
- if (s.len < 4)
- {
- fatal(s.ofs()+s.len,
- c == 'X'
- ? "Illegal hexadecimal character code, four hexadecimal digits are required"
- : "Illegal unicode character, four hexadecimal digits are required");
- return ~0;
- }
-
- const char *p1 = strchr(hex, tolower(s.str[0]));
- const char *p2 = strchr(hex, tolower(s.str[1]));
- const char *p3 = strchr(hex, tolower(s.str[2]));
- const char *p4 = strchr(hex, tolower(s.str[3]));
-
- if (!p1 || !p2 || !p3 || !p4)
- {
- fatal(s.ofs()+(p1?1:0)+(p2?1:0)+(p3?1:0),
- c == 'X'
- ? "Illegal hexadecimal character code, non hexxdecimal digit found"
- : "Illegal unicode character, non hexadecimal digit found");
- return ~0;
- }
- else
- {
- s.len -= 4;
- s.str += 4;
-
- uint v = (uint)((p1 - hex) << 12)
- + (uint)((p2 - hex) << 8)
- + (uint)((p3 - hex) << 4)
- + (uint)((p4 - hex))
- + ucb;
-
- if (v >= nRealChars)
- {
- fatal(s.ofs(),
- c == 'X'
- ? "Illegal hexadecimal character code, out of range"
- : "Illegal unicode character, out of range");
- }
-
- return v;
- }
- }
-
- case '4':
- case '5':
- case '6':
- case '7':
- {
- fatal(s.ofs()-1, "Illegal octal character code, first digit must be 0 thru 3");
- return ~0;
- }
-
- case '0':
- case '1':
- case '2':
- case '3':
- {
- if (s.len < 2)
- {
- fatal(s.ofs()+s.len, "Illegal octal character code, three octal digits are required");
- return ~0;
- }
-
- const char *p0 = strchr(oct, c);
- const char *p1 = strchr(oct, s.str[0]);
- const char *p2 = strchr(oct, s.str[1]);
-
- if (!p0 || !p1 || !p2)
- {
- fatal(s.ofs()+(p1?1:0), "Illegal octal character code, non octal digit found");
- return ~0;
- }
- else
- {
- s.len -= 2;
- s.str += 2;
-
- uint v = (uint)((p0 - oct) << 6) + (uint)((p1 - oct) << 3) + (uint)(p2 - oct);
-
- return v;
- }
- }
-
- default:
- return xlat(c);
- }
-}
-
-std::string& Scanner::unescape(SubStr& str_in, std::string& str_out) const
-{
- str_out.clear();
-
- while(str_in.len)
- {
- uint c = unescape(str_in);
-
- if (c > 0xFF)
- {
- fatal(str_in.ofs(), "Illegal character");
- }
-
- str_out += static_cast(c);
- }
-
- return str_out;
-}
-
-Range * Scanner::getRange(SubStr &s) const
-{
- uint lb = unescape(s), ub, xlb, xub, c;
-
- if (s.len < 2 || *s.str != '-')
- {
- ub = lb;
- }
- else
- {
- s.len--;
- s.str++;
- ub = unescape(s);
-
- if (ub < lb)
- {
- uint tmp = lb;
- lb = ub;
- ub = tmp;
- }
-
- xlb = xlat(lb);
- xub = xlat(ub);
-
- for(c = lb; c <= ub; c++)
- {
- if (!(xlb <= xlat(c) && xlat(c) <= ub))
- {
- /* range doesn't work */
- Range * r = new Range(xlb, xlb + 1);
- for (c = lb + 1; c <= ub; c++)
- {
- r = doUnion(r, new Range(xlat(c), xlat(c) + 1));
- }
- return r;
- }
- }
-
- lb = xlb;
- ub = xub;
- }
-
- return new Range(lb, ub + 1);
-}
-
-RegExp * Scanner::matchChar(uint c) const
-{
- return new MatchOp(new Range(c, c + 1));
-}
-
-RegExp * Scanner::strToRE(SubStr s) const
-{
- s.len -= 2;
- s.str += 1;
-
- if (s.len == 0)
- return new NullOp;
-
- RegExp *re = matchChar(unescape(s));
-
- while (s.len > 0)
- re = new CatOp(re, matchChar(unescape(s)));
-
- return re;
-}
-
-RegExp * Scanner::strToCaseInsensitiveRE(SubStr s) const
-{
- s.len -= 2;
- s.str += 1;
-
- if (s.len == 0)
- return new NullOp;
-
- uint c = unescape(s);
-
- RegExp *re, *reL, *reU;
-
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
- {
- reL = matchChar(xlat(tolower(c)));
- reU = matchChar(xlat(toupper(c)));
- re = mkAlt(reL, reU);
- }
- else
- {
- re = matchChar(c);
- }
-
- while (s.len > 0)
- {
- uint c = unescape(s);
-
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
- {
- reL = matchChar(xlat(tolower(c)));
- reU = matchChar(xlat(toupper(c)));
- re = new CatOp(re, mkAlt(reL, reU));
- }
- else
- {
- re = new CatOp(re, matchChar(c));
- }
- }
-
- return re;
-}
-
-RegExp * Scanner::ranToRE(SubStr s) const
-{
- s.len -= 2;
- s.str += 1;
-
- if (s.len == 0)
- return new NullOp;
-
- Range *r = getRange(s);
-
- while (s.len > 0)
- r = doUnion(r, getRange(s));
-
- return new MatchOp(r);
-}
-
-RegExp * Scanner::invToRE(SubStr s) const
-{
- s.len--;
- s.str++;
-
- RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]"));
-
- if (s.len <= 2)
- {
- return any;
- }
-
- RegExp * ran = ranToRE(s);
- RegExp * inv = mkDiff(any, ran);
-
- delete ran;
- delete any;
-
- return inv;
-}
-
-RegExp * Scanner::mkDot() const
-{
- RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]"));
- RegExp * ran = matchChar(xlat('\n'));
- RegExp * inv = mkDiff(any, ran);
-
- delete ran;
- delete any;
-
- return inv;
-}
-
-const char *RuleOp::type = "RuleOp";
-
-RuleOp::RuleOp(RegExp *e, RegExp *c, Token *t, uint a)
- : exp(e)
- , ctx(c)
- , ins(NULL)
- , accept(a)
- , code(t)
- , line(0)
-{
- ;
-}
-
-void RuleOp::calcSize(Char *rep)
-{
- exp->calcSize(rep);
- ctx->calcSize(rep);
- size = exp->size + (ctx->size ? ctx->size + 2 : 1);
-}
-
-void RuleOp::compile(Char *rep, Ins *i)
-{
- ins = i;
- exp->compile(rep, &i[0]);
- i += exp->size;
- if (ctx->size)
- {
- i->i.tag = CTXT;
- i->i.link = &i[1];
- i++;
- ctx->compile(rep, &i[0]);
- i += ctx->size;
- }
- i->i.tag = TERM;
- i->i.link = this;
-}
-
-void RuleOp::split(CharSet &s)
-{
- exp->split(s);
- ctx->split(s);
-}
-
-void optimize(Ins *i)
-{
- while (!isMarked(i))
- {
- mark(i);
-
- if (i->i.tag == CHAR)
- {
- i = (Ins*) i->i.link;
- }
- else if (i->i.tag == GOTO || i->i.tag == FORK)
- {
- Ins *target = (Ins*) i->i.link;
- optimize(target);
-
- if (target->i.tag == GOTO)
- i->i.link = target->i.link == target ? i : target;
-
- if (i->i.tag == FORK)
- {
- Ins *follow = (Ins*) & i[1];
- optimize(follow);
-
- if (follow->i.tag == GOTO && follow->i.link == follow)
- {
- i->i.tag = GOTO;
- }
- else if (i->i.link == i)
- {
- i->i.tag = GOTO;
- i->i.link = follow;
- }
- }
-
- return ;
- }
- else
- {
- ++i;
- }
- }
-}
-
-void genCode(std::ostream& o, RegExp *re)
-{
- genCode(o, 0, re);
-}
-
-CharSet::CharSet()
- : fix(0)
- , freeHead(0)
- , freeTail(0)
- , rep(new CharPtr[nRealChars])
- , ptn(new CharPtn[nRealChars])
-{
- for (uint j = 0; j < nRealChars; ++j)
- {
- rep[j] = &ptn[0];
- ptn[j].nxt = &ptn[j + 1]; /* wrong for j=nRealChars but will be corrected below */
- ptn[j].card = 0;
- }
-
- freeHead = &ptn[1];
- *(freeTail = &ptn[nRealChars - 1].nxt) = NULL;
- ptn[0].card = nRealChars;
- ptn[0].nxt = NULL;
-}
-
-CharSet::~CharSet()
-{
- delete[] rep;
- delete[] ptn;
-}
-
-void genCode(std::ostream& o, uint ind, RegExp *re)
-{
- CharSet cs;
- uint j;
-
- re->split(cs);
- /*
- for(uint k = 0; k < nChars;){
- for(j = k; ++k < nRealChars && cs.rep[k] == cs.rep[j];);
- printSpan(cerr, j, k);
- cerr << "\t" << cs.rep[j] - &cs.ptn[0] << endl;
- }
- */
- Char *rep = new Char[nRealChars];
-
- for (j = 0; j < nRealChars; ++j)
- {
- if (!cs.rep[j]->nxt)
- cs.rep[j]->nxt = &cs.ptn[j];
-
- rep[j] = (Char) (cs.rep[j]->nxt - &cs.ptn[0]);
- }
-
- re->calcSize(rep);
- Ins *ins = new Ins[re->size + 1];
- memset(ins, 0, (re->size + 1)*sizeof(Ins));
- re->compile(rep, ins);
- Ins *eoi = &ins[re->size];
- eoi->i.tag = GOTO;
- eoi->i.link = eoi;
-
- optimize(ins);
-
- for (j = 0; j < re->size;)
- {
- unmark(&ins[j]);
-
- if (ins[j].i.tag == CHAR)
- {
- j = (Ins*) ins[j].i.link - ins;
- }
- else
- {
- j++;
- }
- }
-
- DFA *dfa = new DFA(ins, re->size, 0, nRealChars, rep);
- dfa->emit(o, ind);
- delete dfa;
- delete [] ins;
- delete [] rep;
-}
-
-} // end namespace re2c
-
diff --git a/tools/re2c/basics.h b/tools/re2c/basics.h
deleted file mode 100644
index c9ddb6276..000000000
--- a/tools/re2c/basics.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* $Id: basics.h 520 2006-05-25 13:31:06Z helly $ */
-#ifndef _basics_h
-#define _basics_h
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#elif defined(_WIN32)
-#include "config_w32.h"
-#endif
-
-namespace re2c
-{
-
-#if SIZEOF_CHAR == 1
-typedef unsigned char byte;
-#elif SIZEOF_SHORT == 1
-typedef unsigned short byte;
-#elif SIZEOF_INT == 1
-typedef unsigned int byte;
-#elif SIZEOF_LONG == 1
-typedef unsigned long byte;
-#else
-typedef unsigned char byte;
-#endif
-
-#if SIZEOF_CHAR == 2
-typedef unsigned char word;
-#elif SIZEOF_SHORT == 2
-typedef unsigned short word;
-#elif SIZEOF_INT == 2
-typedef unsigned int word;
-#elif SIZEOF_LONG == 2
-typedef unsigned long word;
-#else
-typedef unsigned short word;
-#endif
-
-#if SIZEOF_CHAR == 4
-typedef unsigned char dword;
-#elif SIZEOF_SHORT == 4
-typedef unsigned short dword;
-#elif SIZEOF_INT == 4
-typedef unsigned int dword;
-#elif SIZEOF_LONG == 4
-typedef unsigned long dword;
-#else
-typedef unsigned long dword;
-#endif
-
-typedef unsigned int uint;
-typedef unsigned char uchar;
-typedef unsigned short ushort;
-typedef unsigned long ulong;
-
-} // end namespace re2c
-
-#endif
diff --git a/tools/re2c/code.cc b/tools/re2c/code.cc
deleted file mode 100644
index f6eea4d0b..000000000
--- a/tools/re2c/code.cc
+++ /dev/null
@@ -1,1806 +0,0 @@
-/* $Id: code.cc 717 2007-04-29 22:29:59Z helly $ */
-#include
-#include
-#include
-#include
-#include
-#include "substr.h"
-#include "globals.h"
-#include "dfa.h"
-#include "parser.h"
-#include "code.h"
-
-namespace re2c
-{
-
-// there must be at least one span in list; all spans must cover
-// same range
-
-std::string indent(uint ind)
-{
- std::string str;
-
- while (ind-- > 0)
- {
- str += indString;
- }
- return str;
-}
-
-static std::string space(uint this_label)
-{
- int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0;
- int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0;
-
- return std::string(std::max(1, nl - tl + 1), ' ');
-}
-
-void Go::compact()
-{
- // arrange so that adjacent spans have different targets
- uint i = 0;
-
- for (uint j = 1; j < nSpans; ++j)
- {
- if (span[j].to != span[i].to)
- {
- ++i;
- span[i].to = span[j].to;
- }
-
- span[i].ub = span[j].ub;
- }
-
- nSpans = i + 1;
-}
-
-void Go::unmap(Go *base, const State *x)
-{
- Span *s = span, *b = base->span, *e = &b[base->nSpans];
- uint lb = 0;
- s->ub = 0;
- s->to = NULL;
-
- for (; b != e; ++b)
- {
- if (b->to == x)
- {
- if ((s->ub - lb) > 1)
- {
- s->ub = b->ub;
- }
- }
- else
- {
- if (b->to != s->to)
- {
- if (s->ub)
- {
- lb = s->ub;
- ++s;
- }
-
- s->to = b->to;
- }
-
- s->ub = b->ub;
- }
- }
-
- s->ub = e[ -1].ub;
- ++s;
- nSpans = s - span;
-}
-
-void doGen(const Go *g, const State *s, uint *bm, uint f, uint m)
-{
- Span *b = g->span, *e = &b[g->nSpans];
- uint lb = 0;
-
- for (; b < e; ++b)
- {
- if (b->to == s)
- {
- for (; lb < b->ub && lb < 256; ++lb)
- {
- bm[lb-f] |= m;
- }
- }
-
- lb = b->ub;
- }
-}
-
-void prt(std::ostream& o, const Go *g, const State *s)
-{
- Span *b = g->span, *e = &b[g->nSpans];
- uint lb = 0;
-
- for (; b < e; ++b)
- {
- if (b->to == s)
- {
- printSpan(o, lb, b->ub);
- }
-
- lb = b->ub;
- }
-}
-
-bool matches(const Go *g1, const State *s1, const Go *g2, const State *s2)
-{
- Span *b1 = g1->span, *e1 = &b1[g1->nSpans];
- uint lb1 = 0;
- Span *b2 = g2->span, *e2 = &b2[g2->nSpans];
- uint lb2 = 0;
-
- for (;;)
- {
- for (; b1 < e1 && b1->to != s1; ++b1)
- {
- lb1 = b1->ub;
- }
-
- for (; b2 < e2 && b2->to != s2; ++b2)
- {
- lb2 = b2->ub;
- }
-
- if (b1 == e1)
- {
- return b2 == e2;
- }
-
- if (b2 == e2)
- {
- return false;
- }
-
- if (lb1 != lb2 || b1->ub != b2->ub)
- {
- return false;
- }
-
- ++b1;
- ++b2;
- }
-}
-
-BitMap *BitMap::first = NULL;
-
-BitMap::BitMap(const Go *g, const State *x)
- : go(g)
- , on(x)
- , next(first)
- , i(0)
- , m(0)
-{
- first = this;
-}
-
-BitMap::~BitMap()
-{
- delete next;
-}
-
-const BitMap *BitMap::find(const Go *g, const State *x)
-{
- for (const BitMap *b = first; b; b = b->next)
- {
- if (matches(b->go, b->on, g, x))
- {
- return b;
- }
- }
-
- return new BitMap(g, x);
-}
-
-const BitMap *BitMap::find(const State *x)
-{
- for (const BitMap *b = first; b; b = b->next)
- {
- if (b->on == x)
- {
- return b;
- }
- }
-
- return NULL;
-}
-
-void BitMap::gen(std::ostream &o, uint ind, uint lb, uint ub)
-{
- if (first && bLastPass)
- {
- o << indent(ind) << "static const unsigned char " << mapCodeName["yybm"] << "[] = {";
-
- uint c = 1, n = ub - lb;
- const BitMap *cb = first;
-
- while((cb = cb->next) != NULL) {
- ++c;
- }
- BitMap *b = first;
-
- uint *bm = new uint[n];
-
- for (uint i = 0, t = 1; b; i += n, t += 8)
- {
- memset(bm, 0, n * sizeof(uint));
-
- for (uint m = 0x80; b && m; m >>= 1)
- {
- b->i = i;
- b->m = m;
- doGen(b->go, b->on, bm, lb, m);
- b = const_cast(b->next);
- }
-
- if (c > 8)
- {
- o << "\n" << indent(ind+1) << "/* table " << t << " .. " << std::min(c, t+7) << ": " << i << " */";
- }
-
- for (uint j = 0; j < n; ++j)
- {
- if (j % 8 == 0)
- {
- o << "\n" << indent(ind+1);
- }
-
- if (yybmHexTable)
- {
- prtHex(o, bm[j], false);
- }
- else
- {
- o << std::setw(3) << (uint)bm[j];
- }
- o << ", ";
- }
- }
-
- o << "\n" << indent(ind) << "};\n";
- /* stats(); */
-
- delete[] bm;
- }
-}
-
-void BitMap::stats()
-{
- uint n = 0;
-
- for (const BitMap *b = first; b; b = b->next)
- {
- prt(std::cerr, b->go, b->on);
- std::cerr << std::endl;
- ++n;
- }
-
- std::cerr << n << " bitmaps\n";
- first = NULL;
-}
-
-void genGoTo(std::ostream &o, uint ind, const State *from, const State *to, bool & readCh)
-{
- if (readCh && from->label + 1 != to->label)
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = false;
- }
-
- o << indent(ind) << "goto " << labelPrefix << to->label << ";\n";
- vUsedLabels.insert(to->label);
-}
-
-void genIf(std::ostream &o, uint ind, const char *cmp, uint v, bool &readCh)
-{
- o << indent(ind) << "if(";
- if (readCh)
- {
- o << "(" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")";
- readCh = false;
- }
- else
- {
- o << mapCodeName["yych"];
- }
-
- o << " " << cmp << " ";
- prtChOrHex(o, v);
- o << ") ";
-}
-
-static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMarker)
-{
- uint fillIndex = next_fill_index;
-
- if (fFlag)
- {
- next_fill_index++;
- o << indent(ind) << mapCodeName["YYSETSTATE"] << "(" << fillIndex << ");\n";
- }
-
- if (bUseYYFill)
- {
- if (n == 1)
- {
- o << indent(ind) << "if(" << mapCodeName["YYLIMIT"] << " == " << mapCodeName["YYCURSOR"] << ") " << mapCodeName["YYFILL"];
- }
- else
- {
- o << indent(ind) << "if((" << mapCodeName["YYLIMIT"] << " - " << mapCodeName["YYCURSOR"] << ") < " << n << ") " << mapCodeName["YYFILL"];
- }
- if (bUseYYFillParam)
- {
- o << "(" << n << ")";
- }
- o << ";\n";
- }
-
- if (fFlag)
- {
- o << mapCodeName["yyFillLabel"] << fillIndex << ":\n";
- }
-
- if (bSetMarker)
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ");\n";
- }
- else
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
- }
- readCh = false;
-}
-
-void Match::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (state->link)
- {
- o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- else if (!readAhead())
- {
- /* do not read next char if match */
- o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = true;
- }
- else
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = false;
- }
-
- if (state->link)
- {
- need(o, ind, state->depth, readCh, false);
- }
-}
-
-void Enter::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (state->link)
- {
- o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- if (vUsedLabels.count(label))
- {
- o << labelPrefix << label << ":\n";
- }
- need(o, ind, state->depth, readCh, false);
- }
- else
- {
- /* we shouldn't need 'rule-following' protection here */
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- if (vUsedLabels.count(label))
- {
- o << labelPrefix << label << ":\n";
- }
- readCh = false;
- }
-}
-
-void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (!startLabelName.empty())
- {
- o << startLabelName << ":\n";
- }
-
- if (vUsedLabels.count(1))
- {
- if (state->link)
- {
- o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- else
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- }
-
- if (vUsedLabels.count(label))
- {
- o << labelPrefix << label << ":\n";
- }
- else if (!label)
- {
- o << "\n";
- }
-
- if (dFlag)
- {
- o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
- }
-
- if (state->link)
- {
- need(o, ind, state->depth, readCh, setMarker && bUsedYYMarker);
- }
- else
- {
- if (setMarker && bUsedYYMarker)
- {
- o << indent(ind) << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ";\n";
- }
- readCh = false;
- }
-}
-
-void Save::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (bUsedYYAccept)
- {
- o << indent(ind) << mapCodeName["yyaccept"] << " = " << selector << ";\n";
- }
-
- if (state->link)
- {
- if (bUsedYYMarker)
- {
- o << indent(ind) << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- need(o, ind, state->depth, readCh, false);
- }
- else
- {
- if (bUsedYYMarker)
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ");\n";
- }
- else
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- readCh = false;
- }
-}
-
-Move::Move(State *s) : Action(s)
-{
- ;
-}
-
-void Move::emit(std::ostream &, uint, bool &) const
-{
- ;
-}
-
-Accept::Accept(State *x, uint n, uint *s, State **r)
- : Action(x), nRules(n), saves(s), rules(r)
-{
- ;
-}
-
-void Accept::genRuleMap()
-{
- for (uint i = 0; i < nRules; ++i)
- {
- if (saves[i] != ~0u)
- {
- mapRules[saves[i]] = rules[i];
- }
- }
-}
-
-void Accept::emitBinary(std::ostream &o, uint ind, uint l, uint r, bool &readCh) const
-{
- if (l < r)
- {
- uint m = (l + r) >> 1;
-
- o << indent(ind) << "if(" << mapCodeName["yyaccept"] << " <= " << m << ") {\n";
- emitBinary(o, ++ind, l, m, readCh);
- o << indent(--ind) << "} else {\n";
- emitBinary(o, ++ind, m + 1, r, readCh);
- o << indent(--ind) << "}\n";
- }
- else
- {
- genGoTo(o, ind, state, mapRules.find(l)->second, readCh);
- }
-}
-
-void Accept::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (mapRules.size() > 0)
- {
- bUsedYYMarker = true;
- o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYMARKER"] << ";\n";
-
- if (readCh) // shouldn't be necessary, but might become at some point
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = false;
- }
-
- if (mapRules.size() > 1)
- {
- bUsedYYAccept = true;
-
- if (gFlag && mapRules.size() >= cGotoThreshold)
- {
- o << indent(ind++) << "{\n";
- o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[" << mapRules.size() << "] = {\n";
- for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
- {
- o << indent(ind) << "&&" << labelPrefix << it->second->label << ",\n";
- vUsedLabels.insert(it->second->label);
- }
- o << indent(--ind) << "};\n";
- o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << mapCodeName["yyaccept"] << "];\n";
- o << indent(--ind) << "}\n";
- }
- else if (sFlag)
- {
- emitBinary(o, ind, 0, mapRules.size() - 1, readCh);
- }
- else
- {
- o << indent(ind) << "switch(" << mapCodeName["yyaccept"] << ") {\n";
-
- for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
- {
- o << indent(ind) << "case " << it->first << ": \t";
- genGoTo(o, 0, state, it->second, readCh);
- }
-
- o << indent(ind) << "}\n";
- }
- }
- else
- {
- // no need to write if statement here since there is only case 0.
- genGoTo(o, ind, state, mapRules.find(0)->second, readCh);
- }
- }
-}
-
-Rule::Rule(State *s, RuleOp *r) : Action(s), rule(r)
-{
- ;
-}
-
-void Rule::emit(std::ostream &o, uint ind, bool &) const
-{
- uint back = rule->ctx->fixedLength();
-
- if (back != 0u)
- {
- o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYCTXMARKER"] << ";\n";
- }
-
- RuleLine rl(*rule);
-
- o << file_info(sourceFileInfo, &rl);
- o << indent(ind);
- o << rule->code->text;
- o << "\n";
- o << outputFileInfo;
-}
-
-void doLinear(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask)
-{
- for (;;)
- {
- State *bg = s[0].to;
-
- while (n >= 3 && s[2].to == bg && (s[1].ub - s[0].ub) == 1)
- {
- if (s[1].to == next && n == 3)
- {
- if (!mask || (s[0].ub > 0x00FF))
- {
- genIf(o, ind, "!=", s[0].ub, readCh);
- genGoTo(o, 0, from, bg, readCh);
- }
- if (next->label != from->label + 1)
- {
- genGoTo(o, ind, from, next, readCh);
- }
- return ;
- }
- else
- {
- if (!mask || (s[0].ub > 0x00FF))
- {
- genIf(o, ind, "==", s[0].ub, readCh);
- genGoTo(o, 0, from, s[1].to, readCh);
- }
- }
-
- n -= 2;
- s += 2;
- }
-
- if (n == 1)
- {
- // if(bg != next){
- if (s[0].to->label != from->label + 1)
- {
- genGoTo(o, ind, from, s[0].to, readCh);
- }
- // }
- return ;
- }
- else if (n == 2 && bg == next)
- {
- if (!mask || (s[0].ub > 0x00FF))
- {
- genIf(o, ind, ">=", s[0].ub, readCh);
- genGoTo(o, 0, from, s[1].to, readCh);
- }
- if (next->label != from->label + 1)
- {
- genGoTo(o, ind, from, next, readCh);
- }
- return ;
- }
- else
- {
- if (!mask || ((s[0].ub - 1) > 0x00FF))
- {
- genIf(o, ind, "<=", s[0].ub - 1, readCh);
- genGoTo(o, 0, from, bg, readCh);
- }
- n -= 1;
- s += 1;
- }
- }
-
- if (next->label != from->label + 1)
- {
- genGoTo(o, ind, from, next, readCh);
- }
-}
-
-void Go::genLinear(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- doLinear(o, ind, span, nSpans, from, next, readCh, mask);
-}
-
-bool genCases(std::ostream &o, uint ind, uint lb, Span *s, bool &newLine, uint mask)
-{
- bool used = false;
-
- if (!newLine)
- {
- o << "\n";
- }
- newLine = true;
- if (lb < s->ub)
- {
- for (;;)
- {
- if (!mask || lb > 0x00FF)
- {
- o << indent(ind) << "case ";
- prtChOrHex(o, lb);
- o << ":";
- newLine = false;
- used = true;
- }
-
- if (++lb == s->ub)
- {
- break;
- }
-
- o << "\n";
- newLine = true;
- }
- }
- return used;
-}
-
-void Go::genSwitch(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- bool newLine = true;
-
- if ((mask ? wSpans : nSpans) <= 2)
- {
- genLinear(o, ind, from, next, readCh, mask);
- }
- else
- {
- State *def = span[nSpans - 1].to;
- Span **sP = new Span * [nSpans - 1], **r, **s, **t;
-
- t = &sP[0];
-
- for (uint i = 0; i < nSpans; ++i)
- {
- if (span[i].to != def)
- {
- *(t++) = &span[i];
- }
- }
-
- if (dFlag)
- {
- o << indent(ind) << mapCodeName["YYDEBUG"] << "(-1, " << mapCodeName["yych"] << ");\n";
- }
-
- if (readCh)
- {
- o << indent(ind) << "switch((" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")) {\n";
- readCh = false;
- }
- else
- {
- o << indent(ind) << "switch(" << mapCodeName["yych"] << ") {\n";
- }
-
- while (t != &sP[0])
- {
- bool used = false;
-
- r = s = &sP[0];
-
- if (*s == &span[0])
- {
- used |= genCases(o, ind, 0, *s, newLine, mask);
- }
- else
- {
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
- }
-
- State *to = (*s)->to;
-
- while (++s < t)
- {
- if ((*s)->to == to)
- {
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
- }
- else
- {
- *(r++) = *s;
- }
- }
-
- if (used)
- {
- genGoTo(o, newLine ? ind+1 : 1, from, to, readCh);
- newLine = true;
- }
- t = r;
- }
-
- o << indent(ind) << "default:";
- genGoTo(o, 1, from, def, readCh);
- o << indent(ind) << "}\n";
-
- delete [] sP;
- }
-}
-
-void doBinary(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask)
-{
- if (n <= 4)
- {
- doLinear(o, ind, s, n, from, next, readCh, mask);
- }
- else
- {
- uint h = n / 2;
-
- genIf(o, ind, "<=", s[h - 1].ub - 1, readCh);
- o << "{\n";
- doBinary(o, ind+1, &s[0], h, from, next, readCh, mask);
- o << indent(ind) << "} else {\n";
- doBinary(o, ind+1, &s[h], n - h, from, next, readCh, mask);
- o << indent(ind) << "}\n";
- }
-}
-
-void Go::genBinary(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- if (mask)
- {
- Span * sc = new Span[wSpans];
-
- for (uint i = 0, j = 0; i < nSpans; i++)
- {
- if (span[i].ub > 0xFF)
- {
- sc[j++] = span[i];
- }
- }
-
- doBinary(o, ind, sc, wSpans, from, next, readCh, mask);
-
- delete[] sc;
- }
- else
- {
- doBinary(o, ind, span, nSpans, from, next, readCh, mask);
- }
-}
-
-void Go::genBase(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- if ((mask ? wSpans : nSpans) == 0)
- {
- return ;
- }
-
- if (!sFlag)
- {
- genSwitch(o, ind, from, next, readCh, mask);
- return ;
- }
-
- if ((mask ? wSpans : nSpans) > 8)
- {
- Span *bot = &span[0], *top = &span[nSpans - 1];
- uint util;
-
- if (bot[0].to == top[0].to)
- {
- util = (top[ -1].ub - bot[0].ub) / (nSpans - 2);
- }
- else
- {
- if (bot[0].ub > (top[0].ub - top[ -1].ub))
- {
- util = (top[0].ub - bot[0].ub) / (nSpans - 1);
- }
- else
- {
- util = top[ -1].ub / (nSpans - 1);
- }
- }
-
- if (util <= 2)
- {
- genSwitch(o, ind, from, next, readCh, mask);
- return ;
- }
- }
-
- if ((mask ? wSpans : nSpans) > 5)
- {
- genBinary(o, ind, from, next, readCh, mask);
- }
- else
- {
- genLinear(o, ind, from, next, readCh, mask);
- }
-}
-
-void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) const
-{
- std::string sYych;
-
- if (readCh)
- {
- sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")";
- }
- else
- {
- sYych = mapCodeName["yych"];
- }
-
- readCh = false;
- if (wFlag)
- {
- o << indent(ind) << "if(" << sYych <<" & ~0xFF) {\n";
- genBase(o, ind+1, from, next, readCh, 1);
- o << indent(ind++) << "} else {\n";
- sYych = mapCodeName["yych"];
- }
- else
- {
- o << indent(ind++) << "{\n";
- }
- o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[256] = {\n";
- o << indent(ind);
-
- uint ch = 0;
- for (uint i = 0; i < lSpans; ++i)
- {
- vUsedLabels.insert(span[i].to->label);
- for(; ch < span[i].ub; ++ch)
- {
- o << "&&" << labelPrefix << span[i].to->label;
- if (ch == 255)
- {
- o << "\n";
- i = lSpans;
- break;
- }
- else if (ch % 8 == 7)
- {
- o << ",\n" << indent(ind);
- }
- else
- {
- o << "," << space(span[i].to->label);
- }
- }
- }
- o << indent(--ind) << "};\n";
- o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << sYych << "];\n";
- o << indent(--ind) << "}\n";
-}
-
-void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh)
-{
- if ((gFlag || wFlag) && wSpans == ~0u)
- {
- uint nBitmaps = 0;
- std::set vTargets;
- wSpans = 0;
- lSpans = 1;
- dSpans = 0;
- for (uint i = 0; i < nSpans; ++i)
- {
- if (span[i].ub > 0xFF)
- {
- wSpans++;
- }
- if (span[i].ub < 0x100 || !wFlag)
- {
- lSpans++;
-
- State *to = span[i].to;
-
- if (to && to->isBase)
- {
- const BitMap *b = BitMap::find(to);
-
- if (b && matches(b->go, b->on, this, to))
- {
- nBitmaps++;
- }
- else
- {
- dSpans++;
- vTargets.insert(to->label);
- }
- }
- else
- {
- dSpans++;
- vTargets.insert(to->label);
- }
- }
- }
- lTargets = vTargets.size() >> nBitmaps;
- }
-
- if (gFlag && (lTargets >= cGotoThreshold || dSpans >= cGotoThreshold))
- {
- genCpGoto(o, ind, from, next, readCh);
- return;
- }
- else if (bFlag)
- {
- for (uint i = 0; i < nSpans; ++i)
- {
- State *to = span[i].to;
-
- if (to && to->isBase)
- {
- const BitMap *b = BitMap::find(to);
- std::string sYych;
-
- if (b && matches(b->go, b->on, this, to))
- {
- Go go;
- go.span = new Span[nSpans];
- go.unmap(this, to);
- if (readCh)
- {
- sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")";
- }
- else
- {
- sYych = mapCodeName["yych"];
- }
- readCh = false;
- if (wFlag)
- {
- o << indent(ind) << "if(" << sYych << " & ~0xFF) {\n";
- sYych = mapCodeName["yych"];
- genBase(o, ind+1, from, next, readCh, 1);
- o << indent(ind) << "} else ";
- }
- else
- {
- o << indent(ind);
- }
- o << "if(" << mapCodeName["yybm"] << "[" << b->i << "+" << sYych << "] & ";
- if (yybmHexTable)
- {
- prtHex(o, b->m, false);
- }
- else
- {
- o << (uint) b->m;
- }
- o << ") {\n";
- genGoTo(o, ind+1, from, to, readCh);
- o << indent(ind) << "}\n";
- go.genBase(o, ind, from, next, readCh, 0);
- delete [] go.span;
- return ;
- }
- }
- }
- }
-
- genBase(o, ind, from, next, readCh, 0);
-}
-
-void State::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (vUsedLabels.count(label))
- {
- o << labelPrefix << label << ":\n";
- }
- if (dFlag && !action->isInitial())
- {
- o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
- }
- if (isPreCtxt)
- {
- o << indent(ind) << mapCodeName["YYCTXMARKER"] << " = " << mapCodeName["YYCURSOR"] << " + 1;\n";
- }
- action->emit(o, ind, readCh);
-}
-
-uint merge(Span *x0, State *fg, State *bg)
-{
- Span *x = x0, *f = fg->go.span, *b = bg->go.span;
- uint nf = fg->go.nSpans, nb = bg->go.nSpans;
- State *prev = NULL, *to;
- // NB: we assume both spans are for same range
-
- for (;;)
- {
- if (f->ub == b->ub)
- {
- to = f->to == b->to ? bg : f->to;
-
- if (to == prev)
- {
- --x;
- }
- else
- {
- x->to = prev = to;
- }
-
- x->ub = f->ub;
- ++x;
- ++f;
- --nf;
- ++b;
- --nb;
-
- if (nf == 0 && nb == 0)
- {
- return x - x0;
- }
- }
-
- while (f->ub < b->ub)
- {
- to = f->to == b->to ? bg : f->to;
-
- if (to == prev)
- {
- --x;
- }
- else
- {
- x->to = prev = to;
- }
-
- x->ub = f->ub;
- ++x;
- ++f;
- --nf;
- }
-
- while (b->ub < f->ub)
- {
- to = b->to == f->to ? bg : f->to;
-
- if (to == prev)
- {
- --x;
- }
- else
- {
- x->to = prev = to;
- }
-
- x->ub = b->ub;
- ++x;
- ++b;
- --nb;
- }
- }
-}
-
-const uint cInfinity = ~0;
-
-class SCC
-{
-
-public:
- State **top, **stk;
-
-public:
- SCC(uint);
- ~SCC();
- void traverse(State*);
-
-#ifdef PEDANTIC
-private:
- SCC(const SCC& oth)
- : top(oth.top)
- , stk(oth.stk)
- {
- }
- SCC& operator = (const SCC& oth)
- {
- new(this) SCC(oth);
- return *this;
- }
-#endif
-};
-
-SCC::SCC(uint size)
- : top(new State * [size])
- , stk(top)
-{
-}
-
-SCC::~SCC()
-{
- delete [] stk;
-}
-
-void SCC::traverse(State *x)
-{
- *top = x;
- uint k = ++top - stk;
- x->depth = k;
-
- for (uint i = 0; i < x->go.nSpans; ++i)
- {
- State *y = x->go.span[i].to;
-
- if (y)
- {
- if (y->depth == 0)
- {
- traverse(y);
- }
-
- if (y->depth < x->depth)
- {
- x->depth = y->depth;
- }
- }
- }
-
- if (x->depth == k)
- {
- do
- {
- (*--top)->depth = cInfinity;
- (*top)->link = x;
- }
- while (*top != x);
- }
-}
-
-static bool state_is_in_non_trivial_SCC(const State* s)
-{
-
- // does not link to self
- if (s->link != s)
- {
- return true;
- }
-
- // or exists i: (s->go.spans[i].to->link == s)
- //
- // Note: (s->go.spans[i].to == s) is allowed, corresponds to s
- // looping back to itself.
- //
- for (uint i = 0; i < s->go.nSpans; ++i)
- {
- const State* t = s->go.span[i].to;
-
- if (t && t->link == s)
- {
- return true;
- }
- }
- // otherwise no
- return false;
-}
-
-uint maxDist(State *s)
-{
- if (s->depth != cInfinity)
- {
- // Already calculated, just return result.
- return s->depth;
- }
- uint mm = 0;
-
- for (uint i = 0; i < s->go.nSpans; ++i)
- {
- State *t = s->go.span[i].to;
-
- if (t)
- {
- uint m = 1;
-
- if (!t->link) // marked as non-key state
- {
- if (t->depth == cInfinity)
- {
- t->depth = maxDist(t);
- }
- m += t->depth;
- }
-
- if (m > mm)
- {
- mm = m;
- }
- }
- }
-
- s->depth = mm;
- return mm;
-}
-
-void calcDepth(State *head)
-{
- State* s;
-
- // mark non-key states by s->link = NULL ;
- for (s = head; s; s = s->next)
- {
- if (s != head && !state_is_in_non_trivial_SCC(s))
- {
- s->link = NULL;
- }
- //else: key state, leave alone
- }
-
- for (s = head; s; s = s->next)
- {
- s->depth = cInfinity;
- }
-
- // calculate max number of transitions before guarantied to reach
- // a key state.
- for (s = head; s; s = s->next)
- {
- maxDist(s);
- }
-}
-
-void DFA::findSCCs()
-{
- SCC scc(nStates);
- State *s;
-
- for (s = head; s; s = s->next)
- {
- s->depth = 0;
- s->link = NULL;
- }
-
- for (s = head; s; s = s->next)
- {
- if (!s->depth)
- {
- scc.traverse(s);
- }
- }
-
- calcDepth(head);
-}
-
-void DFA::split(State *s)
-{
- State *move = new State;
- (void) new Move(move);
- addState(&s->next, move);
- move->link = s->link;
- move->rule = s->rule;
- move->go = s->go;
- s->rule = NULL;
- s->go.nSpans = 1;
- s->go.span = new Span[1];
- s->go.span[0].ub = ubChar;
- s->go.span[0].to = move;
-}
-
-void DFA::findBaseState()
-{
- Span *span = new Span[ubChar - lbChar];
-
- for (State *s = head; s; s = s->next)
- {
- if (!s->link)
- {
- for (uint i = 0; i < s->go.nSpans; ++i)
- {
- State *to = s->go.span[i].to;
-
- if (to && to->isBase)
- {
- to = to->go.span[0].to;
- uint nSpans = merge(span, s, to);
-
- if (nSpans < s->go.nSpans)
- {
- delete [] s->go.span;
- s->go.nSpans = nSpans;
- s->go.span = new Span[nSpans];
- memcpy(s->go.span, span, nSpans*sizeof(Span));
- }
-
- break;
- }
- }
- }
- }
-
- delete [] span;
-}
-
-void DFA::emit(std::ostream &o, uint ind)
-{
- State *s;
- uint i, bitmap_brace = 0;
-
- findSCCs();
- head->link = head;
-
- uint nRules = 0;
-
- for (s = head; s; s = s->next)
- {
- s->depth = maxDist(s);
- if (maxFill < s->depth)
- {
- maxFill = s->depth;
- }
- if (s->rule && s->rule->accept >= nRules)
- {
- nRules = s->rule->accept + 1;
- }
- }
-
- uint nSaves = 0;
- uint *saves = new uint[nRules];
- memset(saves, ~0, (nRules)*sizeof(*saves));
-
- // mark backtracking points
- bool bSaveOnHead = false;
-
- for (s = head; s; s = s->next)
- {
- if (s->rule)
- {
- for (i = 0; i < s->go.nSpans; ++i)
- {
- if (s->go.span[i].to && !s->go.span[i].to->rule)
- {
- delete s->action;
- s->action = NULL;
-
- if (saves[s->rule->accept] == ~0u)
- {
- saves[s->rule->accept] = nSaves++;
- }
-
- bSaveOnHead |= s == head;
- (void) new Save(s, saves[s->rule->accept]); // sets s->action
- }
- }
- }
- }
-
- // insert actions
- State **rules = new State * [nRules];
-
- memset(rules, 0, (nRules)*sizeof(*rules));
-
- State *accept = NULL;
- Accept *accfixup = NULL;
-
- for (s = head; s; s = s->next)
- {
- State * ow;
-
- if (!s->rule)
- {
- ow = accept;
- }
- else
- {
- if (!rules[s->rule->accept])
- {
- State *n = new State;
- (void) new Rule(n, s->rule);
- rules[s->rule->accept] = n;
- addState(&s->next, n);
- }
-
- ow = rules[s->rule->accept];
- }
-
- for (i = 0; i < s->go.nSpans; ++i)
- {
- if (!s->go.span[i].to)
- {
- if (!ow)
- {
- ow = accept = new State;
- accfixup = new Accept(accept, nRules, saves, rules);
- addState(&s->next, accept);
- }
-
- s->go.span[i].to = ow;
- }
- }
- }
-
- if (accfixup)
- {
- accfixup->genRuleMap();
- }
-
- // split ``base'' states into two parts
- for (s = head; s; s = s->next)
- {
- s->isBase = false;
-
- if (s->link)
- {
- for (i = 0; i < s->go.nSpans; ++i)
- {
- if (s->go.span[i].to == s)
- {
- s->isBase = true;
- split(s);
-
- if (bFlag)
- {
- BitMap::find(&s->next->go, s);
- }
-
- s = s->next;
- break;
- }
- }
- }
- }
-
- // find ``base'' state, if possible
- findBaseState();
-
- delete head->action;
- head->action = NULL;
-
- if (bFlag)
- {
- o << indent(ind++) << "{\n";
- bitmap_brace = 1;
- BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
- }
-
- bUsedYYAccept = false;
-
- uint start_label = next_label;
-
- (void) new Initial(head, next_label++, bSaveOnHead);
-
- if (bUseStartLabel)
- {
- if (startLabelName.empty())
- {
- vUsedLabels.insert(start_label);
- }
- }
-
- for (s = head; s; s = s->next)
- {
- s->label = next_label++;
- }
-
- // Save 'next_fill_index' and compute information about code generation
- // while writing to null device.
- uint save_fill_index = next_fill_index;
- null_stream null_dev;
-
- for (s = head; s; s = s->next)
- {
- bool readCh = false;
- s->emit(null_dev, ind, readCh);
- s->go.genGoto(null_dev, ind, s, s->next, readCh);
- }
- if (last_fill_index < next_fill_index)
- {
- last_fill_index = next_fill_index;
- }
- next_fill_index = save_fill_index;
-
- // Generate prolog
- o << "\n" << outputFileInfo;
- o << indent(ind++) << "{\n";
-
- if (!fFlag)
- {
- o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
- if (bUsedYYAccept)
- {
- o << indent(ind) << "unsigned int "<< mapCodeName["yyaccept"] << " = 0;\n";
- }
- }
- else
- {
- o << "\n";
- }
-
- genGetState(o, ind, start_label);
-
- if (vUsedLabels.count(1))
- {
- vUsedLabels.insert(0);
- o << indent(ind) << "goto " << labelPrefix << "0;\n";
- }
-
- // Generate code
- for (s = head; s; s = s->next)
- {
- bool readCh = false;
- s->emit(o, ind, readCh);
- s->go.genGoto(o, ind, s, s->next, readCh);
- }
-
- // Generate epilog
- o << indent(--ind) << "}\n";
- if (bitmap_brace)
- {
- o << indent(--ind) << "}\n";
- }
-
- // Cleanup
- if (BitMap::first)
- {
- delete BitMap::first;
- BitMap::first = NULL;
- }
-
- delete [] saves;
- delete [] rules;
-
- bUseStartLabel = false;
-}
-
-void genGetState(std::ostream &o, uint& ind, uint start_label)
-{
- if (fFlag && !bWroteGetState)
- {
- vUsedLabels.insert(start_label);
- o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"] << "()) {\n";
- if (bUseStateAbort)
- {
- o << indent(ind) << "default: abort();\n";
- o << indent(ind) << "case -1: goto " << labelPrefix << start_label << ";\n";
- }
- else
- {
- o << indent(ind) << "default: goto " << labelPrefix << start_label << ";\n";
- }
-
- for (size_t i=0; iget_line() << " \"" << li.fname << "\"\n";
- }
- return o;
-}
-
-uint Scanner::get_line() const
-{
- return cline;
-}
-
-void Scanner::config(const Str& cfg, int num)
-{
- if (cfg.to_string() == "indent:top")
- {
- if (num < 0)
- {
- fatal("configuration 'indent:top' must be a positive integer");
- }
- topIndent = num;
- }
- else if (cfg.to_string() == "yybm:hex")
- {
- yybmHexTable = num != 0;
- }
- else if (cfg.to_string() == "startlabel")
- {
- bUseStartLabel = num != 0;
- startLabelName = "";
- }
- else if (cfg.to_string() == "state:abort")
- {
- bUseStateAbort = num != 0;
- }
- else if (cfg.to_string() == "state:nextlabel")
- {
- bUseStateNext = num != 0;
- }
- else if (cfg.to_string() == "yyfill:enable")
- {
- bUseYYFill = num != 0;
- }
- else if (cfg.to_string() == "yyfill:parameter")
- {
- bUseYYFillParam = num != 0;
- }
- else if (cfg.to_string() == "cgoto:threshold")
- {
- cGotoThreshold = num;
- }
- else if (cfg.to_string() == "yych:conversion")
- {
- if (num)
- {
- yychConversion = "(";
- yychConversion += mapCodeName["YYCTYPE"];
- yychConversion += ")";
- }
- else
- {
- yychConversion = "";
- }
- }
- else
- {
- fatal("unrecognized configuration name or illegal integer value");
- }
-}
-
-static std::set mapVariableKeys;
-static std::set mapDefineKeys;
-static std::set mapLabelKeys;
-
-void Scanner::config(const Str& cfg, const Str& val)
-{
- if (mapDefineKeys.empty())
- {
- mapVariableKeys.insert("variable:yyaccept");
- mapVariableKeys.insert("variable:yybm");
- mapVariableKeys.insert("variable:yych");
- mapVariableKeys.insert("variable:yytarget");
- mapDefineKeys.insert("define:YYCTXMARKER");
- mapDefineKeys.insert("define:YYCTYPE");
- mapDefineKeys.insert("define:YYCURSOR");
- mapDefineKeys.insert("define:YYDEBUG");
- mapDefineKeys.insert("define:YYFILL");
- mapDefineKeys.insert("define:YYGETSTATE");
- mapDefineKeys.insert("define:YYLIMIT");
- mapDefineKeys.insert("define:YYMARKER");
- mapDefineKeys.insert("define:YYSETSTATE");
- mapLabelKeys.insert("label:yyFillLabel");
- mapLabelKeys.insert("label:yyNext");
- }
-
- std::string strVal;
-
- if (val.len >= 2 && val.str[0] == val.str[val.len-1]
- && (val.str[0] == '"' || val.str[0] == '\''))
- {
- SubStr tmp(val.str + 1, val.len - 2);
- unescape(tmp, strVal);
- }
- else
- {
- strVal = val.to_string();
- }
-
- if (cfg.to_string() == "indent:string")
- {
- indString = strVal;
- }
- else if (cfg.to_string() == "startlabel")
- {
- startLabelName = strVal;
- bUseStartLabel = !startLabelName.empty();
- }
- else if (cfg.to_string() == "labelprefix")
- {
- labelPrefix = strVal;
- }
- else if (mapVariableKeys.find(cfg.to_string()) != mapVariableKeys.end())
- {
- if (bFirstPass && !mapCodeName.insert(
- std::make_pair(cfg.to_string().substr(sizeof("variable:") - 1), strVal)
- ).second)
- {
- fatal("variable already being used and cannot be changed");
- }
- }
- else if (mapDefineKeys.find(cfg.to_string()) != mapDefineKeys.end())
- {
- if (bFirstPass && !mapCodeName.insert(
- std::make_pair(cfg.to_string().substr(sizeof("define:") - 1), strVal)
- ).second)
- {
- fatal("define already being used and cannot be changed");
- }
- }
- else if (mapLabelKeys.find(cfg.to_string()) != mapLabelKeys.end())
- {
- if (bFirstPass && !mapCodeName.insert(
- std::make_pair(cfg.to_string().substr(sizeof("label:") - 1), strVal)
- ).second)
- {
- fatal("label already being used and cannot be changed");
- }
- }
- else
- {
- fatal("unrecognized configuration name or illegal string value");
- }
-}
-
-} // end namespace re2c
diff --git a/tools/re2c/code.h b/tools/re2c/code.h
deleted file mode 100644
index ed9df0dde..000000000
--- a/tools/re2c/code.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $Id: code.h 525 2006-05-25 13:32:49Z helly $ */
-#ifndef _code_h
-#define _code_h
-
-#include "re.h"
-#include "dfa.h"
-
-namespace re2c
-{
-
-class BitMap
-{
-public:
- static BitMap *first;
-
- const Go *go;
- const State *on;
- const BitMap *next;
- uint i;
- uint m;
-
-public:
- static const BitMap *find(const Go*, const State*);
- static const BitMap *find(const State*);
- static void gen(std::ostream&, uint ind, uint, uint);
- static void stats();
- BitMap(const Go*, const State*);
- ~BitMap();
-
-#if PEDANTIC
- BitMap(const BitMap& oth)
- : go(oth.go)
- , on(oth.on)
- , next(oth.next)
- , i(oth.i)
- , m(oth.m)
- {
- }
- BitMap& operator = (const BitMap& oth)
- {
- new(this) BitMap(oth);
- return *this;
- }
-#endif
-};
-
-#ifdef _MSC_VER
-# pragma warning(disable: 4355) /* 'this' : used in base member initializer list */
-#endif
-
-} // end namespace re2c
-
-#endif
diff --git a/tools/re2c/code_names.h b/tools/re2c/code_names.h
deleted file mode 100644
index 4622e20e0..000000000
--- a/tools/re2c/code_names.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* $Id: token.h 547 2006-05-25 13:40:35Z helly $ */
-#ifndef _code_names_h
-#define _code_names_h
-
-#include
-#include