diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch) | |
tree | acaf47eb0fa12142d3896416a69e74cbf5a72242 /lib/antlr | |
download | tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib/antlr')
89 files changed, 9123 insertions, 0 deletions
diff --git a/lib/antlr/AUTHORS b/lib/antlr/AUTHORS new file mode 100644 index 00000000..7bdc4852 --- /dev/null +++ b/lib/antlr/AUTHORS @@ -0,0 +1,2 @@ +Author: + Peter Wells <pete@yamuna.demon.co.uk> diff --git a/lib/antlr/COPYING b/lib/antlr/COPYING new file mode 100644 index 00000000..ce9ec595 --- /dev/null +++ b/lib/antlr/COPYING @@ -0,0 +1,32 @@ + +SOFTWARE RIGHTS + +ANTLR MageLang Institute, 1989-1999 +http://www.ANTLR.org + +We reserve no legal rights to the ANTLR--it is fully in the +public domain. An individual or company may do whatever +they wish with source code distributed with ANTLR or the +code generated by ANTLR, including the incorporation of +ANTLR, or its output, into commerical software. + +We encourage users to develop software with ANTLR. However, +we do ask that credit is given to us for developing +ANTLR. By "credit", we mean that if you use ANTLR or +incorporate any source code into one of your programs +(commercial product, research project, or otherwise) that +you acknowledge this fact somewhere in the documentation, +research report, etc... If you like ANTLR and have +developed a nice tool with the output, please mention that +you developed it using ANTLR. In addition, we ask that the +headers remain intact in our source code. As long as these +guidelines are kept, we expect to continue enhancing this +system and expect to make other tools available as they are +completed. + +The primary ANTLR guy: + +Terence Parr +MageLang Institute; http://www.MageLang.com +parrt@jguru.com +parrt@magelang.com diff --git a/lib/antlr/ChangeLog b/lib/antlr/ChangeLog new file mode 100644 index 00000000..735046e5 --- /dev/null +++ b/lib/antlr/ChangeLog @@ -0,0 +1,293 @@ +Not 100% complete. Changes from develtree are not listed yet. + +Change 400 on 2000/09/27 by klaren@klaren.hawking.main + + Made little TCL script to pretty print a ChangeLog with C++ stuff. + + +Change 399 on 2000/09/27 by klaren@klaren.hawking.main + + Fixed generating too many ASTNULL checks in wrong places. + + +Change 397 on 2000/09/27 by klaren@klaren.hawking.main + + Some *UGLY* fixes for the last typecasting problems in Cpp codegen. It + now works. In 2.7.2 or later I'll fix this in a nice way. + + +Change 397 on 2000/09/27 by klaren@klaren.hawking.main + + Some *UGLY* fixes for the last typecasting problems in Cpp codegen. It + now works. In 2.7.2 or later I'll fix this in a nice way. + + +Change 394 on 2000/09/26 by klaren@klaren.hawking.main + + Prefixed Unicode optimization checks with a ASTNULL check. + + +Change 393 on 2000/09/25 by klaren@klaren.hawking.main + + Bumped up the version no from 2.7.1a4 to 2.7.1. + + +Change 380 on 2000/09/24 by parrt@parrt.foggy + + integrating ric's stuff into main + + +Change 380 on 2000/09/24 by parrt@parrt.foggy + + integrating ric's stuff into main + + +Change 380 on 2000/09/24 by parrt@parrt.foggy + + integrating ric's stuff into main + + +Change 348 on 2000/09/07 by klaren@klaren.hawking.main + + Small improvement in constructor of CommonAST. + + +Change 344 on 2000/09/06 by klaren@klaren.hawking.main + + Fixed missing namespace in generated TreeParsers as reported by Ross + Bencina. + + +Change 341 on 2000/09/06 by klaren@klaren.hawking.main + + Miniscule fix for Borland C++Builder 4.0/C++ 5.4. (extra parens) + + +Change 317 on 2000/08/22 by klaren@klaren.hawking.main + + Updated changelog for a5 (or was it 2.7.1) release.. + + +Change 316 on 2000/08/22 by klaren@klaren.hawking.main + + All kinds of small Makefile/configure tweaks. All gcc-isms should be + gone now. + + +Change 309 on 2000/08/15 by klaren@klaren.hawking.main + + Integrate bugfixes from klaren.dev to MismatchedChar/TokenException. + + +Change 297 on 2000/08/07 by klaren@klaren.kronecker.main + + Fixes for namespace/namespaceAntlr/namespaceStd/genHashLines options. + + +Change 296 on 2000/08/07 by klaren@klaren.kronecker.main + + Virtualized all functions that someone should want to override. Probably + necessary for heteroAST stuff. + + +Change 291 on 2000/08/07 by klaren@klaren.kronecker.main + + Some tweaks to configure.in and Makefile.am's. Fix for CXXFLAGS being + set incorrectly when not using gcc. + + +Change 290 on 2000/08/05 by klaren@klaren.kronecker.main + + Updated prototype of toLower to definition in cpp file. It seems I + messed them up a while back. + + +Change 289 on 2000/08/05 by klaren@klaren.kronecker.main + + Added namespace macro to out_of_range exception. + + +Change 288 on 2000/07/28 by parrt@parrt.foggy + + re-added toLower return type fix + + +Change 285 on 2000/07/19 by klaren@klaren.kronecker.main + + Fixed thinko. + + +Change 284 on 2000/07/19 by klaren@klaren.kronecker.main + + Dumped output of p4 changes -l into it... + + +Change 283 on 2000/07/19 by klaren@klaren.kronecker.main + + Fix for bug found by Michael Ebner. Bitset size was not increased in add + method. + + +Change 280 on 2000/07/19 by klaren@klaren.kronecker.main + + Made namespaceAntlr, namespaceStd and genHashlines options file-level + options. Removed nameSpace member from Tool class all is now handled in + CppCodegenerator.java. + + +Change 276 on 2000/07/18 by klaren@klaren.kronecker.main + + C++ Changes for the indented traceXXXX output as invented by Monty Zukowski + + +Change 275 on 2000/07/18 by klaren@klaren.kronecker.main + + Added missing initializer in generated code for TreeParser + + +Change 272 on 2000/07/17 by klaren@klaren.kronecker.main + + Another workspace for MSVC6 has support for dll's (for version 2.6.1). + + +Change 271 on 2000/07/17 by klaren@klaren.kronecker.main + + New autoconf/automake stuff for the C++ support library. + + +Change 270 on 2000/07/17 by klaren@klaren.kronecker.main + + Fixed error within the NO_STATIC_CONSTS #ifdef + + +Change 269 on 2000/07/17 by klaren@klaren.kronecker.main + + Move C++ files to lib/cpp/src as first step for autoconf setup + + +Change 268 on 2000/07/17 by klaren@klaren.kronecker.main + + Add contrib dir and Microsoft Visual C++ 6.0 projects supplied by John + Millaway + + +Change 260 on 2000/07/14 by klaren@klaren.kronecker.main + + Fixed crashbugs/typos in constructors of Mismatched[Token|Char]Exception + + +Change 258 on 2000/07/10 by parrt@parrt.foggy + + fixes per klaren + + +Change 258 on 2000/07/10 by parrt@parrt.foggy + + fixes per klaren + + +Change 248 on 2000/07/04 by parrt@parrt.foggy + + Ric Klaren's changes to C++ lib + + +Change 247 on 2000/07/04 by parrt@parrt.foggy + + Ric Klaren's changes for namespaces + + +Change 239 on 2000/06/03 by parrt@parrt.foggy + + adjusted so it works; header actions got converted to Token objects from + Strings; lots of cast problems and then null ptr exceptions. + +Change 235 on 2000/05/31 by pete@pete.linux + + More changes to support #line generation in C++ (from Ric Klaren) + +Change 220 on 2000/05/29 by parrt@parrt.foggy + + changed char to int for toLower + + +Change 219 on 2000/05/28 by pete@pete.linux + + Mirroring Java changes + + +Change 218 on 2000/05/28 by pete@pete.linux + + Cleaned up the #line generator a little. + + +Change 211 on 2000/05/27 by parrt@parrt.foggy + + had same bug as JavaCodeGenerator related to ~(A|B) + + +Change 205 on 2000/05/24 by pete@pete.linux + + Add support for Metrowerks Codewarrior + + +Change 203 on 2000/05/22 by pete@pete.linux + + Fix for multithreading from Jan Mikkelsen + + +Change 202 on 2000/05/21 by pete@pete.linux + + Merged in some fixes from Ric Klaren for tracing TreeParsers, cleaner + namespace code, and #line generation. + + +Change 202 on 2000/05/21 by pete@pete.linux + + Merged in some fixes from Ric Klaren for tracing TreeParsers, cleaner + namespace code, and #line generation. + +Change 201 on 2000/05/21 by pete@pete.linux + + Added destructors with empty throw specs, as suggested by Dan Field. + + +Change 200 on 2000/05/21 by pete@pete.linux + + Various performance improvements, mostly from Eric Dumas. + + +Change 183 on 2000/02/08 by pete@pete.linux + + Added support for Sun CC 5.0 (from Michael Schmitt) + + +Change 182 on 2000/02/08 by pete@pete.linux + + Fix a couple of minor problems with C++ generation (noted by Michael + Schmitt) + +Change 132 on 2000/01/18 by parrt@parrt.foggy + + setting type to ktext for everything + + +Change 132 on 2000/01/18 by parrt@parrt.foggy + + setting type to ktext for everything + + +Change 131 on 2000/01/18 by parrt@parrt.foggy + + from dev back to main + + +Change 131 on 2000/01/18 by parrt@parrt.foggy + + from dev back to main + + +Change 1 on 1999/12/13 by parrt@parrt.foggy + + adding 2.6.0 from antlr site as initial main line + + diff --git a/lib/antlr/INSTALL b/lib/antlr/INSTALL new file mode 100644 index 00000000..30dd4d49 --- /dev/null +++ b/lib/antlr/INSTALL @@ -0,0 +1,183 @@ +Basic Installation +================== + + These are generic installation instructions. Check out the README for +additional info. + + 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, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + 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 at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' 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. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +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 supports 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' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +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 host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +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. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--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. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/lib/antlr/Makefile.am b/lib/antlr/Makefile.am new file mode 100644 index 00000000..2aa39c30 --- /dev/null +++ b/lib/antlr/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src antlr diff --git a/lib/antlr/NEWS b/lib/antlr/NEWS new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/lib/antlr/NEWS diff --git a/lib/antlr/README b/lib/antlr/README new file mode 100644 index 00000000..6ca0913b --- /dev/null +++ b/lib/antlr/README @@ -0,0 +1,72 @@ +C++ support libraries + +Original GNU autconf stuff contributed by Braden N. McDaniel. Slightly +hacked up by me (Ric Klaren (klaren@cs.utwente.nl)) for who it's the first +autoconf/automake/aclocal stuff ever, so suggestions additions welcome. + +HOW TO INSTALL + +In theory do: + +./configure --prefix=<basedirectory where you want it installed> +make +make install + +Now libantlr.a should reside under <basedir>/lib/libantlr.a and the +includes should be at <basedir>/include/antlr. + +NOTE: this only installs the C++ library and header files. + +In the contrib directory a dsp/dsw project for Microsoft Visual C++ can be +found. + +In general this library needs runtime typing information (RTTI) make sure +you enable this in whatever compiler you are using. + +SUPPORTED COMPILERS + +Pasted from the FAQ entry on: http://www.jguru.com/jguru/faq/view.jsp?EID=121 + +Compiler OS Version +------------------ --------------------- ---------- +Sun Workshop 4.2 Solaris 2.6, 7 2.7.1a2 +Sun Workshop 5.0 Solaris 2.7 2.7.1a2 +Sun Workshop 6.0 Solaris 2.7 2.7.1a2 +egcs-1.1.2 Solaris 2.6,7 2.7.1a2 +egcs-1.1.2 Linux 2.2, Solaris 2.6 2.7.1a2 +gcc-2.95.2 Linux 2.2, Solaris 2.6,7 2.7.1a2 +gcc-2.96 (20000527) Solaris 2.6 2.7.1a2 +aCC A.01.21 HP-UX 10.20 2.7.0 no! +Visual C++ 6.0 PC 2.7.1a2 (warnings) +Intel C++ 4.0 NT 4.0 2.7.0 +Borland 5.0 NT 4.0 2.7.0 + +IT DOESN'T WORK!? + +Check out the faq: http://www.jguru.com/jguru/faq/view.jsp?EID=120 + +The text of that entry (by Peter Wells): + +The ANTLR code uses some relatively new features of C++ which not all +compilers support yet (such as namespaces, and new style standard headers). + +There is work currently in progress to provide a compatibility mode for +ANTLR, to enable older compilers to handle this. + +At the moment, you may be able to work around the problem with a few nasty +tricks: + +Try creating some header files like 'iostream' just containing: + +#include <iostream.h> + +and compile with an option to define away the word 'std', such as + +CC .... -Dstd= .... + +Also in the antlr subdirectory there's a file config.hpp. Tweak this one to +enable/disable the different bells and whistles used in the rest of the code. +Don't forget to submit those changes back to us (along with compiler info) +so we can incorporate them in our next release! + +Thanks! diff --git a/lib/antlr/TODO b/lib/antlr/TODO new file mode 100644 index 00000000..51d104c3 --- /dev/null +++ b/lib/antlr/TODO @@ -0,0 +1,34 @@ +* Improve configure scripts => KICK OUT automake! + +* Add allocators to the objects + +* Look more at exception handling + +* TreeParser.cpp around line 76 the MismatchedTokenException here does not + use ttype to improve it's errormessage. Would require changing a bit in + MismatchedTokenException.cpp + +* On Thu, Sep 21, 2000 at 12:33:48AM -0700, John Lambert <JohnL@jBASE.com> wrote: + > 1) The literal EOF is not defined and causes the define of EOF_CHAR in + > CharScanner.hpp to fail. + + ANTLR with STL Port. Changing the EOF define to char_traits<char>::eof() + breaks things for gcc-2.95.2. Fix this in next release portably. + http://www.egroups.com/message/antlr-interest/2520 + +* John Millaway requested some mechanism to add code to the constructor + of the parser/lexer/treewalker. This can be usefull. + http://www.egroups.com/message/antlr-interest/2501 + +* Fix heterogeneous AST stuff. It boils down to adding a method to AST + types that knows how to duplicate the sucker. Atm duptree cannot work + because of this. Knowing one factory is not enough. Also look at having + to set the astfactory by hand (this is not 100% necessary). + http://www.egroups.com/message/antlr-interest/2496 + +* Look at messageLog stuff Ross Bencina proposed. Looks good at first glance. + http://www.egroups.com/message/antlr-interest/2555 + +* Add RW_STL & CC 4.2 patch from Ulrich Teichert: + See my mailbox.. and these comments from Ross Bencina: + http://www.egroups.com/message/antlr-interest/2494 diff --git a/lib/antlr/antlr/ANTLRException.hpp b/lib/antlr/antlr/ANTLRException.hpp new file mode 100644 index 00000000..426595a2 --- /dev/null +++ b/lib/antlr/antlr/ANTLRException.hpp @@ -0,0 +1,59 @@ +#ifndef INC_ANTLRException_hpp__ +#define INC_ANTLRException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API ANTLRException +{ +public: + /// Create ANTLR base exception without error message + ANTLRException() : text("") + { + } + /// Create ANTLR base exception with error message + ANTLRException(const ANTLR_USE_NAMESPACE(std)string& s) + : text(s) + { + } + virtual ~ANTLRException() throw() + { + } + + /** Return complete error message with line/column number info (if present) + * @note for your own exceptions override this one. Call getMessage from + * here to get the 'clean' error message stored in the text attribute. + */ + virtual ANTLR_USE_NAMESPACE(std)string toString() const + { + return text; + } + + /** Return error message without additional info (if present) + * @note when making your own exceptions classes override toString + * and call in toString getMessage which relays the text attribute + * from here. + */ + virtual ANTLR_USE_NAMESPACE(std)string getMessage() const + { + return text; + } +private: + ANTLR_USE_NAMESPACE(std)string text; +}; +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_ANTLRException_hpp__ diff --git a/lib/antlr/antlr/ANTLRUtil.hpp b/lib/antlr/antlr/ANTLRUtil.hpp new file mode 100644 index 00000000..4732588c --- /dev/null +++ b/lib/antlr/antlr/ANTLRUtil.hpp @@ -0,0 +1,53 @@ +#ifndef INC_ANTLRUtil_hpp__ +#define INC_ANTLRUtil_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <iostream> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** Eat whitespace from the input stream + * @param is the stream to read from + */ +ANTLR_USE_NAMESPACE(std)istream& eatwhite( ANTLR_USE_NAMESPACE(std)istream& is ); + +/** Read a string enclosed by '"' from a stream. Also handles escaping of \". + * Skips leading whitespace. + * @param in the istream to read from. + * @returns the string read from file exclusive the '"' + * @throws ios_base::failure if string is badly formatted + */ +ANTLR_USE_NAMESPACE(std)string read_string( ANTLR_USE_NAMESPACE(std)istream& in ); + +/* Read a ([A-Z][0-9][a-z]_)* kindoff thing. Skips leading whitespace. + * @param in the istream to read from. + */ +ANTLR_USE_NAMESPACE(std)string read_identifier( ANTLR_USE_NAMESPACE(std)istream& in ); + +/** Read a attribute="value" thing. Leading whitespace is skipped. + * Between attribute and '=' no whitespace is allowed. After the '=' it is + * permitted. + * @param in the istream to read from. + * @param attribute string the attribute name is put in + * @param value string the value of the attribute is put in + * @throws ios_base::failure if something is fishy. E.g. malformed quoting + * or missing '=' + */ +void read_AttributeNValue( ANTLR_USE_NAMESPACE(std)istream& in, + ANTLR_USE_NAMESPACE(std)string& attribute, + ANTLR_USE_NAMESPACE(std)string& value ); + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif diff --git a/lib/antlr/antlr/AST.hpp b/lib/antlr/antlr/AST.hpp new file mode 100644 index 00000000..b01a60a9 --- /dev/null +++ b/lib/antlr/antlr/AST.hpp @@ -0,0 +1,166 @@ +#ifndef INC_AST_hpp__ +#define INC_AST_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/ASTRefCount.hpp> +#include <antlr/Token.hpp> +#include <vector> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +struct ASTRef; + +class ANTLR_API AST { +public: + AST() : ref(0) {} + AST(const AST&) : ref(0) {} + virtual ~AST() {} + + /// Return the type name for this AST node. (for XML output) + virtual const char* typeName( void ) const = 0; + /// Clone this AST node. + virtual RefAST clone( void ) const = 0; + /// Is node t equal to this in terms of token type and text? + virtual bool equals(RefAST t) const = 0; + /** Is t an exact structural and equals() match of this tree. The + * 'this' reference is considered the start of a sibling list. + */ + virtual bool equalsList(RefAST t) const = 0; + + /** Is 't' a subtree of this list? The siblings of the root are NOT ignored. + */ + virtual bool equalsListPartial(RefAST t) const = 0; + /** Is tree rooted at 'this' equal to 't'? The siblings of 'this' are + * ignored. + */ + virtual bool equalsTree(RefAST t) const = 0; + /** Is 't' a subtree of the tree rooted at 'this'? The siblings of + * 'this' are ignored. + */ + virtual bool equalsTreePartial(RefAST t) const = 0; + + /** Walk the tree looking for all exact subtree matches. Return + * a vector of RefAST that lets the caller walk the list + * of subtree roots found herein. + */ + virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAll(RefAST t) = 0; + + /** Walk the tree looking for all subtrees. Return + * a vector of RefAST that lets the caller walk the list + * of subtree roots found herein. + */ + virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAllPartial(RefAST t) = 0; + + /// Add a node to the end of the child list for this node + virtual void addChild(RefAST c) = 0; + /// Get the number of children. Returns 0 if the node is a leaf + virtual size_t getNumberOfChildren() const = 0; + + /// Get the first child of this node; null if no children + virtual RefAST getFirstChild() const = 0; + /// Get the next sibling in line after this one + virtual RefAST getNextSibling() const = 0; + + /// Get the token text for this node + virtual ANTLR_USE_NAMESPACE(std)string getText() const = 0; + /// Get the token type for this node + virtual int getType() const = 0; + + /** Various initialization routines. Used by several factories to initialize + * an AST element. + */ + virtual void initialize(int t, const ANTLR_USE_NAMESPACE(std)string& txt) = 0; + virtual void initialize(RefAST t) = 0; + virtual void initialize(RefToken t) = 0; + +#ifdef ANTLR_SUPPORT_XML + /** initialize this node from the contents of a stream. + * @param in the stream to read the AST attributes from. + */ + virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in ) = 0; +#endif + + /// Set the first child of a node. + virtual void setFirstChild(RefAST c) = 0; + /// Set the next sibling after this one. + virtual void setNextSibling(RefAST n) = 0; + + /// Set the token text for this node + virtual void setText(const ANTLR_USE_NAMESPACE(std)string& txt) = 0; + /// Set the token type for this node + virtual void setType(int type) = 0; + + /// Return this AST node as a string + virtual ANTLR_USE_NAMESPACE(std)string toString() const = 0; + + /// Print out a child-sibling tree in LISP notation + virtual ANTLR_USE_NAMESPACE(std)string toStringList() const = 0; + virtual ANTLR_USE_NAMESPACE(std)string toStringTree() const = 0; + +#ifdef ANTLR_SUPPORT_XML + /** get attributes of this node to 'out'. Override to customize XML + * output. + * @param out the stream to write the AST attributes to. + * @returns if a explicit closetag should be written + */ + virtual bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const = 0; + + /** Print a symbol over ostream. Overload this one to customize the XML + * output for AST derived AST-types + * @param output stream + */ + virtual void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const = 0; + + /** Dump AST contents in XML format to output stream. + * Works in conjunction with to_stream method. Overload that one is + * derived classes to customize behaviour. + * @param output stream to write to string to put the stuff in. + * @param ast RefAST object to write. + */ + friend ANTLR_USE_NAMESPACE(std)ostream& operator<<( ANTLR_USE_NAMESPACE(std)ostream& output, const RefAST& ast ); +#endif + +private: + friend struct ASTRef; + ASTRef* ref; + + AST(RefAST other); + AST& operator=(const AST& other); + AST& operator=(RefAST other); +}; + +#ifdef ANTLR_SUPPORT_XML +inline ANTLR_USE_NAMESPACE(std)ostream& operator<<( ANTLR_USE_NAMESPACE(std)ostream& output, const RefAST& ast ) +{ + ast->toStream(output); + return output; +} +#endif + +extern ANTLR_API RefAST nullAST; +extern ANTLR_API AST* const nullASTptr; + +#ifdef NEEDS_OPERATOR_LESS_THAN +// RK: apparently needed by MSVC and a SUN CC, up to and including +// 2.7.2 this was undefined ? +inline bool operator<( RefAST l, RefAST r ) +{ + return nullAST == l ? ( nullAST == r ? false : true ) : l->getType() < r->getType(); +} +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_AST_hpp__ diff --git a/lib/antlr/antlr/ASTArray.hpp b/lib/antlr/antlr/ASTArray.hpp new file mode 100644 index 00000000..2d224d32 --- /dev/null +++ b/lib/antlr/antlr/ASTArray.hpp @@ -0,0 +1,45 @@ +#ifndef INC_ASTArray_hpp__ +#define INC_ASTArray_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/AST.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** ASTArray is a class that allows ANTLR to + * generate code that can create and initialize an array + * in one expression, like: + * (new ASTArray(3))->add(x)->add(y)->add(z) + */ +class ANTLR_API ASTArray { +public: + int size; // = 0; + ANTLR_USE_NAMESPACE(std)vector<RefAST> array; + + ASTArray(int capacity) + : size(0) + , array(capacity) + { + } + + ASTArray* add(RefAST node) + { + array[size++] = node; + return this; + } +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_ASTArray_hpp__ diff --git a/lib/antlr/antlr/ASTFactory.hpp b/lib/antlr/antlr/ASTFactory.hpp new file mode 100644 index 00000000..968ab6c5 --- /dev/null +++ b/lib/antlr/antlr/ASTFactory.hpp @@ -0,0 +1,165 @@ +#ifndef INC_ASTFactory_hpp__ +#define INC_ASTFactory_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/AST.hpp> +#include <antlr/ASTArray.hpp> +#include <antlr/ASTPair.hpp> + +#include <istream> +#include <utility> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +// Using these extra types to appease MSVC +typedef RefAST (*factory_type_)(); +typedef ANTLR_USE_NAMESPACE(std)pair< const char*, factory_type_ > factory_descriptor_; +typedef ANTLR_USE_NAMESPACE(std)vector< factory_descriptor_* > factory_descriptor_list_; + +/** AST Super Factory shared by TreeParser and Parser. + * This super factory maintains a map of all AST node types to their respective + * AST factories. One instance should be shared among a parser/treeparser + * chain. + * + * @todo check all this code for possible use of references in + * stead of RefAST's. + */ +class ANTLR_API ASTFactory { +public: + typedef factory_type_ factory_type; + typedef factory_descriptor_ factory_descriptor; + typedef factory_descriptor_list_ factory_descriptor_list; +protected: + /* The mapping of AST node type to factory.. + */ + factory_descriptor default_factory_descriptor; + factory_descriptor_list nodeFactories; +public: + /// Make new factory. Per default (Ref)CommonAST instances are generated. + ASTFactory(); + /** Initialize factory with a non default node type. + * factory_node_name should be the name of the AST node type the factory + * generates. (should exist during the existance of this ASTFactory + * instance) + */ + ASTFactory( const char* factory_node_name, factory_type factory ); + /// Destroy factory + virtual ~ASTFactory(); + + /// Register a node factory for the node type type with name ast_name + void registerFactory( int type, const char* ast_name, factory_type factory ); + /// Set the maximum node (AST) type this factory may encounter + void setMaxNodeType( int type ); + + /// Add a child to the current AST + void addASTChild(ASTPair& currentAST, RefAST child); + /// Create new empty AST node. The right default type shou + virtual RefAST create(); + /// Create AST node of the right type for 'type' + RefAST create(int type); + /// Create AST node of the right type for 'type' and initialize with txt + RefAST create(int type, const ANTLR_USE_NAMESPACE(std)string& txt); + /// Create duplicate of tr + RefAST create(RefAST tr); + /// Create new AST node and initialize contents from a token. + RefAST create(RefToken tok); + /// Create new AST node and initialize contents from a stream. + RefAST create(const ANTLR_USE_NAMESPACE(std)string& txt, ANTLR_USE_NAMESPACE(std)istream& infile ); + /** Deep copy a single node. This function the new clone() methods in the + * AST interface. Returns a new RefAST(nullASTptr) if t is null. + */ + RefAST dup(RefAST t); + /// Duplicate tree including siblings of root. + RefAST dupList(RefAST t); + /** Duplicate a tree, assuming this is a root node of a tree-- + * duplicate that node and what's below; ignore siblings of root node. + */ + RefAST dupTree(RefAST t); + /** Make a tree from a list of nodes. The first element in the + * array is the root. If the root is null, then the tree is + * a simple list not a tree. Handles null children nodes correctly. + * For example, make(a, b, null, c) yields tree (a b c). make(null,a,b) + * yields tree (nil a b). + */ + RefAST make(ANTLR_USE_NAMESPACE(std)vector<RefAST>& nodes); + /** Make a tree from a list of nodes, where the nodes are contained + * in an ASTArray object. The ASTArray is deleted after use. + * @todo FIXME! I have a feeling we can get rid of this ugly ASTArray thing + */ + RefAST make(ASTArray* nodes); + /// Make an AST the root of current AST + void makeASTRoot(ASTPair& currentAST, RefAST root); + + /** Set a new default AST type. + * factory_node_name should be the name of the AST node type the factory + * generates. (should exist during the existance of this ASTFactory + * instance). + * Only change factory between parser runs. You might get unexpected results + * otherwise. + */ + void setASTNodeFactory( const char* factory_node_name, factory_type factory ); + +#ifdef ANTLR_SUPPORT_XML + /** Load a XML AST from stream. Make sure you have all the factories + * registered before use. + * @note this 'XML' stuff is quite rough still. YMMV. + */ + RefAST LoadAST( ANTLR_USE_NAMESPACE(std)istream& infile ); +#endif +protected: + void loadChildren( ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current ); + void loadSiblings( ANTLR_USE_NAMESPACE(std)istream& infile, RefAST current ); + bool checkCloseTag( ANTLR_USE_NAMESPACE(std)istream& infile ); + +#ifdef ANTLR_VECTOR_HAS_AT + /// construct a node of 'type' + inline RefAST getNodeOfType( unsigned int type ) + { + return RefAST(nodeFactories.at(type)->second()); + } + /// get the name of the node 'type' + const char* getASTNodeType( unsigned int type ) + { + return nodeFactories.at(type)->first; + } + /// get the factory used for node 'type' + factory_type getASTNodeFactory( unsigned int type ) + { + return nodeFactories.at(type)->second; + } +#else + inline RefAST getNodeOfType( unsigned int type ) + { + return RefAST(nodeFactories[type]->second()); + } + /// get the name of the node 'type' + const char* getASTNodeType( unsigned int type ) + { + return nodeFactories[type]->first; + } + factory_type getASTNodeFactory( unsigned int type ) + { + return nodeFactories[type]->second; + } +#endif + +private: + // no copying and such.. + ASTFactory( const ASTFactory& ); + ASTFactory& operator=( const ASTFactory& ); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_ASTFactory_hpp__ diff --git a/lib/antlr/antlr/ASTNULLType.hpp b/lib/antlr/antlr/ASTNULLType.hpp new file mode 100644 index 00000000..867f5e5b --- /dev/null +++ b/lib/antlr/antlr/ASTNULLType.hpp @@ -0,0 +1,64 @@ +#ifndef INC_ASTNULLType_hpp__ +#define INC_ASTNULLType_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/AST.hpp> +#include <iostream> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** There is only one instance of this class **/ +class ANTLR_API ASTNULLType : public AST { +public: + const char* typeName( void ) const; + RefAST clone( void ) const; + + void addChild(RefAST c); + size_t getNumberOfChildren() const; + void setFirstChild(RefAST c); + void setNextSibling(RefAST n); + + bool equals(RefAST t) const; + bool equalsList(RefAST t) const; + bool equalsListPartial(RefAST t) const; + bool equalsTree(RefAST t) const; + bool equalsTreePartial(RefAST t) const; + + ANTLR_USE_NAMESPACE(std)vector<RefAST> findAll(RefAST tree); + ANTLR_USE_NAMESPACE(std)vector<RefAST> findAllPartial(RefAST subtree); + + RefAST getFirstChild() const; + RefAST getNextSibling() const; + + ANTLR_USE_NAMESPACE(std)string getText() const; + int getType() const; + + void initialize(int t, const ANTLR_USE_NAMESPACE(std)string& txt); + void initialize(RefAST t); + void initialize(RefToken t); + void initialize(ANTLR_USE_NAMESPACE(std)istream& infile); + + void setText(const ANTLR_USE_NAMESPACE(std)string& text); + void setType(int ttype); + ANTLR_USE_NAMESPACE(std)string toString() const; + ANTLR_USE_NAMESPACE(std)string toStringList() const; + ANTLR_USE_NAMESPACE(std)string toStringTree() const; + + bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const; + void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_ASTNULLType_hpp__ diff --git a/lib/antlr/antlr/ASTPair.hpp b/lib/antlr/antlr/ASTPair.hpp new file mode 100644 index 00000000..d6237902 --- /dev/null +++ b/lib/antlr/antlr/ASTPair.hpp @@ -0,0 +1,57 @@ +#ifndef INC_ASTPair_hpp__ +#define INC_ASTPair_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/AST.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** ASTPair: utility class used for manipulating a pair of ASTs + * representing the current AST root and current AST sibling. + * This exists to compensate for the lack of pointers or 'var' + * arguments in Java. + * + * OK, so we can do those things in C++, but it seems easier + * to stick with the Java way for now. + */ +class ANTLR_API ASTPair { +public: + RefAST root; // current root of tree + RefAST child; // current child to which siblings are added + + /** Make sure that child is the last sibling */ + void advanceChildToEnd() { + if (child) { + while (child->getNextSibling()) { + child = child->getNextSibling(); + } + } + } +// /** Copy an ASTPair. Don't call it clone() because we want type-safety */ +// ASTPair copy() { +// ASTPair tmp = new ASTPair(); +// tmp.root = root; +// tmp.child = child; +// return tmp; +// } + ANTLR_USE_NAMESPACE(std)string toString() const { + ANTLR_USE_NAMESPACE(std)string r = !root ? ANTLR_USE_NAMESPACE(std)string("null") : root->getText(); + ANTLR_USE_NAMESPACE(std)string c = !child ? ANTLR_USE_NAMESPACE(std)string("null") : child->getText(); + return "["+r+","+c+"]"; + } +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_ASTPair_hpp__ diff --git a/lib/antlr/antlr/ASTRefCount.hpp b/lib/antlr/antlr/ASTRefCount.hpp new file mode 100644 index 00000000..f5ef4422 --- /dev/null +++ b/lib/antlr/antlr/ASTRefCount.hpp @@ -0,0 +1,98 @@ +#ifndef INC_ASTRefCount_hpp__ +# define INC_ASTRefCount_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +# include <antlr/config.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + + class AST; + +struct ANTLR_API ASTRef +{ + AST* const ptr; + unsigned int count; + + ASTRef(AST* p); + ~ASTRef(); + ASTRef* increment() + { + ++count; + return this; + } + bool decrement() + { + return (--count==0); + } + + static ASTRef* getRef(const AST* p); +private: + ASTRef( const ASTRef& ); + ASTRef& operator=( const ASTRef& ); +}; + +template<class T> + class ANTLR_API ASTRefCount +{ +private: + ASTRef* ref; + +public: + ASTRefCount(const AST* p=0) + : ref(p ? ASTRef::getRef(p) : 0) + { + } + ASTRefCount(const ASTRefCount<T>& other) + : ref(other.ref ? other.ref->increment() : 0) + { + } + ~ASTRefCount() + { + if (ref && ref->decrement()) + delete ref; + } + ASTRefCount<T>& operator=(AST* other) + { + ASTRef* tmp = ASTRef::getRef(other); + + if (ref && ref->decrement()) + delete ref; + + ref=tmp; + + return *this; + } + ASTRefCount<T>& operator=(const ASTRefCount<T>& other) + { + if( other.ref != ref ) + { + ASTRef* tmp = other.ref ? other.ref->increment() : 0; + + if (ref && ref->decrement()) + delete ref; + + ref=tmp; + } + return *this; + } + + operator T* () const { return ref ? static_cast<T*>(ref->ptr) : 0; } + T* operator->() const { return ref ? static_cast<T*>(ref->ptr) : 0; } + T* get() const { return ref ? static_cast<T*>(ref->ptr) : 0; } +}; + +typedef ASTRefCount<AST> RefAST; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_ASTRefCount_hpp__ diff --git a/lib/antlr/antlr/BaseAST.hpp b/lib/antlr/antlr/BaseAST.hpp new file mode 100644 index 00000000..1bfc4e56 --- /dev/null +++ b/lib/antlr/antlr/BaseAST.hpp @@ -0,0 +1,193 @@ +#ifndef INC_BaseAST_hpp__ +#define INC_BaseAST_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/AST.hpp> + +#include <iostream> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API BaseAST; +typedef ASTRefCount<BaseAST> RefBaseAST; + +class ANTLR_API BaseAST : public AST { +public: + BaseAST() : AST() + { + } + BaseAST(const BaseAST& other) + : AST(other) + { + } + virtual ~BaseAST() + { + } + + /// Return the class name + virtual const char* typeName( void ) const = 0; + + /// Clone this AST node. + virtual RefAST clone( void ) const = 0; + + /// Is node t equal to this in terms of token type and text? + virtual bool equals(RefAST t) const; + + /** Is t an exact structural and equals() match of this tree. The + * 'this' reference is considered the start of a sibling list. + */ + virtual bool equalsList(RefAST t) const; + + /** Is 't' a subtree of this list? The siblings of the root are NOT ignored. + */ + virtual bool equalsListPartial(RefAST t) const; + + /** Is tree rooted at 'this' equal to 't'? The siblings of 'this' are + * ignored. + */ + virtual bool equalsTree(RefAST t) const; + + /** Is 't' a subtree of the tree rooted at 'this'? The siblings of + * 'this' are ignored. + */ + virtual bool equalsTreePartial(RefAST t) const; + + /** Walk the tree looking for all exact subtree matches. Return + * an ASTEnumerator that lets the caller walk the list + * of subtree roots found herein. + */ + virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAll(RefAST t); + + /** Walk the tree looking for all subtrees. Return + * an ASTEnumerator that lets the caller walk the list + * of subtree roots found herein. + */ + virtual ANTLR_USE_NAMESPACE(std)vector<RefAST> findAllPartial(RefAST t); + + /// Add a node to the end of the child list for this node + virtual void addChild(RefAST c) + { + if( !c ) + return; + + RefBaseAST tmp = down; + + if (tmp) + { + while (tmp->right) + tmp = tmp->right; + tmp->right = c; + } + else + down = c; + } + + /** Get the number of child nodes of this node (shallow e.g. not of the + * whole tree it spans). + */ + virtual size_t getNumberOfChildren() const; + + /// Get the first child of this node; null if no children + virtual RefAST getFirstChild() const + { + return RefAST(down); + } + /// Get the next sibling in line after this one + virtual RefAST getNextSibling() const + { + return RefAST(right); + } + + /// Get the token text for this node + virtual ANTLR_USE_NAMESPACE(std)string getText() const + { + return ""; + } + /// Get the token type for this node + virtual int getType() const + { + return 0; + } + + /// Remove all children + virtual void removeChildren() + { + down = static_cast<BaseAST*>(static_cast<AST*>(nullAST)); + } + + /// Set the first child of a node. + virtual void setFirstChild(RefAST c) + { + down = static_cast<BaseAST*>(static_cast<AST*>(c)); + } + + /// Set the next sibling after this one. + virtual void setNextSibling(RefAST n) + { + right = static_cast<BaseAST*>(static_cast<AST*>(n)); + } + + /// Set the token text for this node + virtual void setText(const ANTLR_USE_NAMESPACE(std)string& txt) + { + } + + /// Set the token type for this node + virtual void setType(int type) + { + } + +#ifdef ANTLR_SUPPORT_XML + /** print attributes of this node to 'out'. Override to customize XML + * output. + * @param out the stream to write the AST attributes to. + */ + virtual bool attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const; + /** Write this subtree to a stream. Overload this one to customize the XML + * output for AST derived AST-types + * @param output stream + */ + virtual void toStream( ANTLR_USE_NAMESPACE(std)ostream &out ) const; +#endif + + /// Return string representation for the AST + virtual ANTLR_USE_NAMESPACE(std)string toString() const + { + return getText(); + } + + /// Print out a child sibling tree in LISP notation + virtual ANTLR_USE_NAMESPACE(std)string toStringList() const; + virtual ANTLR_USE_NAMESPACE(std)string toStringTree() const; +protected: + RefBaseAST down; + RefBaseAST right; +private: + void doWorkForFindAll(ANTLR_USE_NAMESPACE(std)vector<RefAST>& v, + RefAST target, + bool partialMatch); +}; + +/** Is node t equal to this in terms of token type and text? + */ +inline bool BaseAST::equals(RefAST t) const +{ + if (!t) + return false; + return ((getType() == t->getType()) && (getText() == t->getText())); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_BaseAST_hpp__ diff --git a/lib/antlr/antlr/BitSet.hpp b/lib/antlr/antlr/BitSet.hpp new file mode 100644 index 00000000..f7619232 --- /dev/null +++ b/lib/antlr/antlr/BitSet.hpp @@ -0,0 +1,60 @@ +#ifndef INC_BitSet_hpp__ +#define INC_BitSet_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <vector> +#include <stdexcept> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** A BitSet to replace java.util.BitSet. + * Primary differences are that most set operators return new sets + * as opposed to oring and anding "in place". Further, a number of + * operations were added. I cannot contain a BitSet because there + * is no way to access the internal bits (which I need for speed) + * and, because it is final, I cannot subclass to add functionality. + * Consider defining set degree. Without access to the bits, I must + * call a method n times to test the ith bit...ack! + * + * Also seems like or() from util is wrong when size of incoming set is bigger + * than this.length. + * + * This is a C++ version of the Java class described above, with only + * a handful of the methods implemented, because we don't need the + * others at runtime. It's really just a wrapper around vector<bool>, + * which should probably be changed to a wrapper around bitset, once + * bitset is more widely available. + * + * @author Terence Parr, MageLang Institute + * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a> + */ +class ANTLR_API BitSet { +private: + ANTLR_USE_NAMESPACE(std)vector<bool> storage; + +public: + BitSet( unsigned int nbits=64 ); + BitSet( const unsigned long* bits_, unsigned int nlongs); + ~BitSet(); + + void add( unsigned int el ); + + bool member( unsigned int el ) const; + + ANTLR_USE_NAMESPACE(std)vector<unsigned int> toArray() const; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_BitSet_hpp__ diff --git a/lib/antlr/antlr/CharBuffer.hpp b/lib/antlr/antlr/CharBuffer.hpp new file mode 100644 index 00000000..fe2b1bc5 --- /dev/null +++ b/lib/antlr/antlr/CharBuffer.hpp @@ -0,0 +1,56 @@ +#ifndef INC_CharBuffer_hpp__ +#define INC_CharBuffer_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> + +#include <istream> + +#include <antlr/InputBuffer.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/**A Stream of characters fed to the lexer from a InputStream that can + * be rewound via mark()/rewind() methods. + * <p> + * A dynamic array is used to buffer up all the input characters. Normally, + * "k" characters are stored in the buffer. More characters may be stored + * during guess mode (testing syntactic predicate), or when LT(i>k) is + * referenced. + * Consumption of characters is deferred. In other words, reading the next + * character is not done by consume(), but deferred until needed by LA or LT. + * <p> + * + * @see antlr.CharQueue + */ + +class ANTLR_API CharBuffer : public InputBuffer { +public: + /// Create a character buffer + CharBuffer( ANTLR_USE_NAMESPACE(std)istream& input ); + /// Get the next character from the stream + int getChar(); + +protected: + // character source + ANTLR_USE_NAMESPACE(std)istream& input; + +private: + // NOTE: Unimplemented + CharBuffer(const CharBuffer& other); + CharBuffer& operator=(const CharBuffer& other); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CharBuffer_hpp__ diff --git a/lib/antlr/antlr/CharInputBuffer.hpp b/lib/antlr/antlr/CharInputBuffer.hpp new file mode 100644 index 00000000..543972a3 --- /dev/null +++ b/lib/antlr/antlr/CharInputBuffer.hpp @@ -0,0 +1,77 @@ +#ifndef INC_CharInputBuffer_hpp__ +# define INC_CharInputBuffer_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +# include <antlr/config.hpp> +# include <antlr/InputBuffer.hpp> + +# ifdef HAS_NOT_CCTYPE_H +# include <ctype.h> +# else +# include <cctype> +# endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** CharInputBuffer.hpp provides an InputBuffer for plain character arrays (buffers). + */ +class CharInputBuffer : public InputBuffer +{ +public: + /** Construct a CharInputBuffer.hpp object with a char* buffer of 'size' + * if 'owner' is true, then the buffer will be delete[]-ed on destruction. + * @note it is assumed the buffer was allocated with new[]! + */ + CharInputBuffer( unsigned char* buf, size_t size, bool owner = false ) + : buffer(buf) + , ptr(buf) + , end(buf + size) + , delete_buffer(owner) + { + } + + /** Destructor + * @note If you're using malloced data, then you probably need to change + * this destructor. Or better use this class as template for your own. + */ + ~CharInputBuffer( void ) + { + if( delete_buffer && buffer ) + delete [] buffer; + } + + /** Reset the CharInputBuffer to initial state + * Called from LexerInputState::reset. + * @see LexerInputState + */ + virtual inline void reset( void ) + { + InputBuffer::reset(); + ptr = buffer; + } + + virtual int getChar( void ) + { + return (ptr < end) ? *ptr++ : EOF; + } + +protected: + unsigned char* buffer; ///< the buffer with data + unsigned char* ptr; ///< position ptr into the buffer + unsigned char* end; ///< end sentry for buffer + bool delete_buffer; ///< flag signifying if we have to delete the buffer +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif diff --git a/lib/antlr/antlr/CharScanner.hpp b/lib/antlr/antlr/CharScanner.hpp new file mode 100644 index 00000000..c426eba2 --- /dev/null +++ b/lib/antlr/antlr/CharScanner.hpp @@ -0,0 +1,575 @@ +#ifndef INC_CharScanner_hpp__ +#define INC_CharScanner_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> + +#include <map> + +#ifdef HAS_NOT_CCTYPE_H +#include <ctype.h> +#else +#include <cctype> +#endif +#include <cstring> + +#if ( _MSC_VER == 1200 ) +// VC6 seems to need this +// note that this is not a standard C++ include file. +# include <stdio.h> +#endif + +#include <antlr/TokenStream.hpp> +#include <antlr/RecognitionException.hpp> +#include <antlr/SemanticException.hpp> +#include <antlr/MismatchedCharException.hpp> +#include <antlr/InputBuffer.hpp> +#include <antlr/BitSet.hpp> +#include <antlr/LexerSharedInputState.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API CharScanner; + +ANTLR_C_USING(tolower) + +#ifdef ANTLR_REALLY_NO_STRCASECMP +// Apparently, neither strcasecmp nor stricmp is standard, and Codewarrior +// on the mac has neither... +inline int strcasecmp(const char *s1, const char *s2) +{ + while (true) + { + char c1 = tolower(*s1++), + c2 = tolower(*s2++); + if (c1 < c2) return -1; + if (c1 > c2) return 1; + if (c1 == 0) return 0; + } +} +#else +#ifdef NO_STRCASECMP +ANTLR_C_USING(stricmp) +#else +ANTLR_C_USING(strcasecmp) +#endif +#endif + +/** Functor for the literals map + */ +class ANTLR_API CharScannerLiteralsLess : public ANTLR_USE_NAMESPACE(std)binary_function<ANTLR_USE_NAMESPACE(std)string,ANTLR_USE_NAMESPACE(std)string,bool> { +private: + const CharScanner* scanner; +public: +#ifdef NO_TEMPLATE_PARTS + CharScannerLiteralsLess() {} // not really used, definition to appease MSVC +#endif + CharScannerLiteralsLess(const CharScanner* theScanner) + : scanner(theScanner) + { + } + bool operator() (const ANTLR_USE_NAMESPACE(std)string& x,const ANTLR_USE_NAMESPACE(std)string& y) const; +// defaults are good enough.. + // CharScannerLiteralsLess(const CharScannerLiteralsLess&); + // CharScannerLiteralsLess& operator=(const CharScannerLiteralsLess&); +}; + +/** Superclass of generated lexers + */ +class ANTLR_API CharScanner : public TokenStream { +protected: + typedef RefToken (*factory_type)(); +public: + CharScanner(InputBuffer& cb, bool case_sensitive ); + CharScanner(InputBuffer* cb, bool case_sensitive ); + CharScanner(const LexerSharedInputState& state, bool case_sensitive ); + + virtual ~CharScanner() + { + } + + virtual int LA(unsigned int i); + + virtual void append(char c) + { + if (saveConsumedInput) + { + size_t l = text.length(); + + if ((l%256) == 0) + text.reserve(l+256); + + text.replace(l,0,&c,1); + } + } + + virtual void append(const ANTLR_USE_NAMESPACE(std)string& s) + { + if( saveConsumedInput ) + text += s; + } + + virtual void commit() + { + inputState->getInput().commit(); + } + + /** called by the generated lexer to do error recovery, override to + * customize the behaviour. + */ + virtual void recover(const RecognitionException& ex, const BitSet& tokenSet) + { + consume(); + consumeUntil(tokenSet); + } + + virtual void consume() + { + if (inputState->guessing == 0) + { + int c = LA(1); + if (caseSensitive) + { + append(c); + } + else + { + // use input.LA(), not LA(), to get original case + // CharScanner.LA() would toLower it. + append(inputState->getInput().LA(1)); + } + + // RK: in a sense I don't like this automatic handling. + if (c == '\t') + tab(); + else + inputState->column++; + } + inputState->getInput().consume(); + } + + /** Consume chars until one matches the given char */ + virtual void consumeUntil(int c) + { + for(;;) + { + int la_1 = LA(1); + if( la_1 == EOF_CHAR || la_1 == c ) + break; + consume(); + } + } + + /** Consume chars until one matches the given set */ + virtual void consumeUntil(const BitSet& set) + { + for(;;) + { + int la_1 = LA(1); + if( la_1 == EOF_CHAR || set.member(la_1) ) + break; + consume(); + } + } + + /// Mark the current position and return a id for it + virtual unsigned int mark() + { + return inputState->getInput().mark(); + } + /// Rewind the scanner to a previously marked position + virtual void rewind(unsigned int pos) + { + inputState->getInput().rewind(pos); + } + + /// See if input contains character 'c' throw MismatchedCharException if not + virtual void match(int c) + { + int la_1 = LA(1); + if ( la_1 != c ) + throw MismatchedCharException(la_1, c, false, this); + consume(); + } + + /** See if input contains element from bitset b + * throw MismatchedCharException if not + */ + virtual void match(const BitSet& b) + { + int la_1 = LA(1); + + if ( !b.member(la_1) ) + throw MismatchedCharException( la_1, b, false, this ); + consume(); + } + + /** See if input contains string 's' throw MismatchedCharException if not + * @note the string cannot match EOF + */ + virtual void match( const char* s ) + { + while( *s != '\0' ) + { + // the & 0xFF is here to prevent sign extension lateron + int la_1 = LA(1), c = (*s++ & 0xFF); + + if ( la_1 != c ) + throw MismatchedCharException(la_1, c, false, this); + + consume(); + } + } + /** See if input contains string 's' throw MismatchedCharException if not + * @note the string cannot match EOF + */ + virtual void match(const ANTLR_USE_NAMESPACE(std)string& s) + { + size_t len = s.length(); + + for (size_t i = 0; i < len; i++) + { + // the & 0xFF is here to prevent sign extension lateron + int la_1 = LA(1), c = (s[i] & 0xFF); + + if ( la_1 != c ) + throw MismatchedCharException(la_1, c, false, this); + + consume(); + } + } + /** See if input does not contain character 'c' + * throw MismatchedCharException if not + */ + virtual void matchNot(int c) + { + int la_1 = LA(1); + + if ( la_1 == c ) + throw MismatchedCharException(la_1, c, true, this); + + consume(); + } + /** See if input contains character in range c1-c2 + * throw MismatchedCharException if not + */ + virtual void matchRange(int c1, int c2) + { + int la_1 = LA(1); + + if ( la_1 < c1 || la_1 > c2 ) + throw MismatchedCharException(la_1, c1, c2, false, this); + + consume(); + } + + virtual bool getCaseSensitive() const + { + return caseSensitive; + } + + virtual void setCaseSensitive(bool t) + { + caseSensitive = t; + } + + virtual bool getCaseSensitiveLiterals() const=0; + + /// Get the line the scanner currently is in (starts at 1) + virtual int getLine() const + { + return inputState->line; + } + + /// set the line number + virtual void setLine(int l) + { + inputState->line = l; + } + + /// Get the column the scanner currently is in (starts at 1) + virtual int getColumn() const + { + return inputState->column; + } + /// set the column number + virtual void setColumn(int c) + { + inputState->column = c; + } + + /// get the filename for the file currently used + virtual const ANTLR_USE_NAMESPACE(std)string& getFilename() const + { + return inputState->filename; + } + /// Set the filename the scanner is using (used in error messages) + virtual void setFilename(const ANTLR_USE_NAMESPACE(std)string& f) + { + inputState->filename = f; + } + + virtual bool getCommitToPath() const + { + return commitToPath; + } + + virtual void setCommitToPath(bool commit) + { + commitToPath = commit; + } + + /** return a copy of the current text buffer */ + virtual const ANTLR_USE_NAMESPACE(std)string& getText() const + { + return text; + } + + virtual void setText(const ANTLR_USE_NAMESPACE(std)string& s) + { + text = s; + } + + virtual void resetText() + { + text = ""; + inputState->tokenStartColumn = inputState->column; + inputState->tokenStartLine = inputState->line; + } + + virtual RefToken getTokenObject() const + { + return _returnToken; + } + + /** Used to keep track of line breaks, needs to be called from + * within generated lexers when a \n \r is encountered. + */ + virtual void newline() + { + ++inputState->line; + inputState->column = 1; + } + + /** Advance the current column number by an appropriate amount according + * to the tabsize. This method needs to be explicitly called from the + * lexer rules encountering tabs. + */ + virtual void tab() + { + int c = getColumn(); + int nc = ( ((c-1)/tabsize) + 1) * tabsize + 1; // calculate tab stop + setColumn( nc ); + } + /// set the tabsize. Returns the old tabsize + int setTabsize( int size ) + { + int oldsize = tabsize; + tabsize = size; + return oldsize; + } + /// Return the tabsize used by the scanner + int getTabSize() const + { + return tabsize; + } + + /** Report exception errors caught in nextToken() */ + virtual void reportError(const RecognitionException& e); + + /** Parser error-reporting function can be overridden in subclass */ + virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s); + + /** Parser warning-reporting function can be overridden in subclass */ + virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s); + + virtual InputBuffer& getInputBuffer() + { + return inputState->getInput(); + } + + virtual LexerSharedInputState getInputState() + { + return inputState; + } + + /** set the input state for the lexer. + * @note state is a reference counted object, hence no reference */ + virtual void setInputState(LexerSharedInputState state) + { + inputState = state; + } + + /// Set the factory for created tokens + virtual void setTokenObjectFactory(factory_type factory) + { + tokenFactory = factory; + } + + /** Test the token text against the literals table + * Override this method to perform a different literals test + */ + virtual int testLiteralsTable(int ttype) const + { + ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess>::const_iterator i = literals.find(text); + if (i != literals.end()) + ttype = (*i).second; + return ttype; + } + + /** Test the text passed in against the literals table + * Override this method to perform a different literals test + * This is used primarily when you want to test a portion of + * a token + */ + virtual int testLiteralsTable(const ANTLR_USE_NAMESPACE(std)string& txt,int ttype) const + { + ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess>::const_iterator i = literals.find(txt); + if (i != literals.end()) + ttype = (*i).second; + return ttype; + } + + /// Override this method to get more specific case handling + virtual int toLower(int c) const + { + // test on EOF_CHAR for buggy (?) STLPort tolower (or HPUX tolower?) + // also VC++ 6.0 does this. (see fix 422 (is reverted by this fix) + // this one is more structural. Maybe make this configurable. + return (c == EOF_CHAR ? EOF_CHAR : tolower(c)); + } + + /** This method is called by YourLexer::nextToken() when the lexer has + * hit EOF condition. EOF is NOT a character. + * This method is not called if EOF is reached during + * syntactic predicate evaluation or during evaluation + * of normal lexical rules, which presumably would be + * an IOException. This traps the "normal" EOF condition. + * + * uponEOF() is called after the complete evaluation of + * the previous token and only if your parser asks + * for another token beyond that last non-EOF token. + * + * You might want to throw token or char stream exceptions + * like: "Heh, premature eof" or a retry stream exception + * ("I found the end of this file, go back to referencing file"). + */ + virtual void uponEOF() + { + } + + /// Methods used to change tracing behavior + virtual void traceIndent(); + virtual void traceIn(const char* rname); + virtual void traceOut(const char* rname); + +#ifndef NO_STATIC_CONSTS + static const int EOF_CHAR = EOF; +#else + enum { + EOF_CHAR = EOF + }; +#endif +protected: + ANTLR_USE_NAMESPACE(std)string text; ///< Text of current token + /// flag indicating wether consume saves characters + bool saveConsumedInput; + factory_type tokenFactory; ///< Factory for tokens + bool caseSensitive; ///< Is this lexer case sensitive + ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,int,CharScannerLiteralsLess> literals; // set by subclass + + RefToken _returnToken; ///< used to return tokens w/o using return val + + /// Input state, gives access to input stream, shared among different lexers + LexerSharedInputState inputState; + + /** Used during filter mode to indicate that path is desired. + * A subsequent scan error will report an error as usual + * if acceptPath=true; + */ + bool commitToPath; + + int tabsize; ///< tab size the scanner uses. + + /// Create a new RefToken of type t + virtual RefToken makeToken(int t) + { + RefToken tok = tokenFactory(); + tok->setType(t); + tok->setColumn(inputState->tokenStartColumn); + tok->setLine(inputState->tokenStartLine); + return tok; + } + + /** Tracer class, used when -traceLexer is passed to antlr + */ + class Tracer { + private: + CharScanner* parser; + const char* text; + + Tracer(const Tracer& other); // undefined + Tracer& operator=(const Tracer& other); // undefined + public: + Tracer( CharScanner* p,const char* t ) + : parser(p), text(t) + { + parser->traceIn(text); + } + ~Tracer() + { + parser->traceOut(text); + } + }; + + int traceDepth; +private: + CharScanner( const CharScanner& other ); // undefined + CharScanner& operator=( const CharScanner& other ); // undefined + +#ifndef NO_STATIC_CONSTS + static const int NO_CHAR = 0; +#else + enum { + NO_CHAR = 0 + }; +#endif +}; + +inline int CharScanner::LA(unsigned int i) +{ + int c = inputState->getInput().LA(i); + + if ( caseSensitive ) + return c; + else + return toLower(c); // VC 6 tolower bug caught in toLower. +} + +inline bool CharScannerLiteralsLess::operator() (const ANTLR_USE_NAMESPACE(std)string& x,const ANTLR_USE_NAMESPACE(std)string& y) const +{ + if (scanner->getCaseSensitiveLiterals()) + return ANTLR_USE_NAMESPACE(std)less<ANTLR_USE_NAMESPACE(std)string>()(x,y); + else + { +#ifdef NO_STRCASECMP + return (stricmp(x.c_str(),y.c_str())<0); +#else + return (strcasecmp(x.c_str(),y.c_str())<0); +#endif + } +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CharScanner_hpp__ diff --git a/lib/antlr/antlr/CharStreamException.hpp b/lib/antlr/antlr/CharStreamException.hpp new file mode 100644 index 00000000..a49e3bbb --- /dev/null +++ b/lib/antlr/antlr/CharStreamException.hpp @@ -0,0 +1,29 @@ +#ifndef INC_CharStreamException_hpp__ +#define INC_CharStreamException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/ANTLRException.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API CharStreamException : public ANTLRException { +public: + CharStreamException(const ANTLR_USE_NAMESPACE(std)string& s) + : ANTLRException(s) {} + ~CharStreamException() throw() {} +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CharStreamException_hpp__ diff --git a/lib/antlr/antlr/CharStreamIOException.hpp b/lib/antlr/antlr/CharStreamIOException.hpp new file mode 100644 index 00000000..e3e3111e --- /dev/null +++ b/lib/antlr/antlr/CharStreamIOException.hpp @@ -0,0 +1,31 @@ +#ifndef INC_CharStreamIOException_hpp__ +#define INC_CharStreamIOException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/CharStreamException.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API CharStreamIOException : public CharStreamException { +public: + ANTLR_USE_NAMESPACE(std)exception io; + + CharStreamIOException(ANTLR_USE_NAMESPACE(std)exception& e) + : CharStreamException(e.what()), io(e) {} + ~CharStreamIOException() throw() {} +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CharStreamIOException_hpp__ diff --git a/lib/antlr/antlr/CircularQueue.hpp b/lib/antlr/antlr/CircularQueue.hpp new file mode 100644 index 00000000..506b4f56 --- /dev/null +++ b/lib/antlr/antlr/CircularQueue.hpp @@ -0,0 +1,100 @@ +#ifndef INC_CircularQueue_hpp__ +#define INC_CircularQueue_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/Token.hpp> +#include <vector> +#include <cassert> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +// Resize every 5000 items +#define OFFSET_MAX_RESIZE 5000 + +template <class T> +class ANTLR_API CircularQueue { +public: + CircularQueue() + : storage() + , m_offset(0) + { + } + ~CircularQueue() + { + } + + /// Clear the queue + inline void clear( void ) + { + m_offset = 0; + storage.clear(); + } + + /// @todo this should use at or should have a check + inline T elementAt( size_t idx ) const + { + return storage[idx+m_offset]; + } + void removeFirst() + { + if (m_offset >= OFFSET_MAX_RESIZE) + { + storage.erase( storage.begin(), storage.begin() + m_offset + 1 ); + m_offset = 0; + } + else + ++m_offset; + } + inline void removeItems( size_t nb ) + { + // it would be nice if we would not get called with nb > entries + // (or to be precise when entries() == 0) + // This case is possible when lexer/parser::recover() calls + // consume+consumeUntil when the queue is empty. + // In recover the consume says to prepare to read another + // character/token. Then in the subsequent consumeUntil the + // LA() call will trigger + // syncConsume which calls this method *before* the same queue + // has been sufficiently filled. + if( nb > entries() ) + nb = entries(); + + if (m_offset >= OFFSET_MAX_RESIZE) + { + storage.erase( storage.begin(), storage.begin() + m_offset + nb ); + m_offset = 0; + } + else + m_offset += nb; + } + inline void append(const T& t) + { + storage.push_back(t); + } + inline size_t entries() const + { + return storage.size() - m_offset; + } + +private: + ANTLR_USE_NAMESPACE(std)vector<T> storage; + size_t m_offset; + + CircularQueue(const CircularQueue&); + const CircularQueue& operator=(const CircularQueue&); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CircularQueue_hpp__ diff --git a/lib/antlr/antlr/CommonAST.hpp b/lib/antlr/antlr/CommonAST.hpp new file mode 100644 index 00000000..091d7b6e --- /dev/null +++ b/lib/antlr/antlr/CommonAST.hpp @@ -0,0 +1,110 @@ +#ifndef INC_CommonAST_hpp__ +#define INC_CommonAST_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/BaseAST.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API CommonAST : public BaseAST { +public: + CommonAST() + : BaseAST() + , ttype( Token::INVALID_TYPE ) + , text() + { + } + + CommonAST( RefToken t ) + : BaseAST() + , ttype( t->getType() ) + , text( t->getText() ) + { + } + + CommonAST( const CommonAST& other ) + : BaseAST(other) + , ttype(other.ttype) + , text(other.text) + { + } + + virtual ~CommonAST() + { + } + + virtual const char* typeName( void ) const + { + return CommonAST::TYPE_NAME; + } + + /// Clone this AST node. + virtual RefAST clone( void ) const + { + CommonAST *ast = new CommonAST( *this ); + return RefAST(ast); + } + + virtual ANTLR_USE_NAMESPACE(std)string getText() const + { + return text; + } + virtual int getType() const + { + return ttype; + } + + virtual void initialize( int t, const ANTLR_USE_NAMESPACE(std)string& txt ) + { + setType(t); + setText(txt); + } + + virtual void initialize( RefAST t ) + { + setType(t->getType()); + setText(t->getText()); + } + virtual void initialize( RefToken t ) + { + setType(t->getType()); + setText(t->getText()); + } + +#ifdef ANTLR_SUPPORT_XML + virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in ); +#endif + + virtual void setText( const ANTLR_USE_NAMESPACE(std)string& txt ) + { + text = txt; + } + virtual void setType( int type ) + { + ttype = type; + } + + static RefAST factory(); + + static const char* const TYPE_NAME; +protected: + int ttype; + ANTLR_USE_NAMESPACE(std)string text; +}; + +typedef ASTRefCount<CommonAST> RefCommonAST; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CommonAST_hpp__ diff --git a/lib/antlr/antlr/CommonASTWithHiddenTokens.hpp b/lib/antlr/antlr/CommonASTWithHiddenTokens.hpp new file mode 100644 index 00000000..cac7c83e --- /dev/null +++ b/lib/antlr/antlr/CommonASTWithHiddenTokens.hpp @@ -0,0 +1,60 @@ +#ifndef INC_CommonASTWithHiddenTokens_hpp__ +#define INC_CommonASTWithHiddenTokens_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/CommonAST.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** A CommonAST whose initialization copies hidden token + * information from the Token used to create a node. + */ +class ANTLR_API CommonASTWithHiddenTokens : public CommonAST { +public: + CommonASTWithHiddenTokens(); + virtual ~CommonASTWithHiddenTokens(); + virtual const char* typeName( void ) const + { + return CommonASTWithHiddenTokens::TYPE_NAME; + } + /// Clone this AST node. + virtual RefAST clone( void ) const; + + // Borland C++ builder seems to need the decl's of the first two... + virtual void initialize(int t,const ANTLR_USE_NAMESPACE(std)string& txt); + virtual void initialize(RefAST t); + virtual void initialize(RefToken t); + + virtual RefToken getHiddenAfter() const + { + return hiddenAfter; + } + + virtual RefToken getHiddenBefore() const + { + return hiddenBefore; + } + + static RefAST factory(); + + static const char* const TYPE_NAME; +protected: + RefToken hiddenBefore,hiddenAfter; // references to hidden tokens +}; + +typedef ASTRefCount<CommonASTWithHiddenTokens> RefCommonASTWithHiddenTokens; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CommonASTWithHiddenTokens_hpp__ diff --git a/lib/antlr/antlr/CommonHiddenStreamToken.hpp b/lib/antlr/antlr/CommonHiddenStreamToken.hpp new file mode 100644 index 00000000..f3b78c44 --- /dev/null +++ b/lib/antlr/antlr/CommonHiddenStreamToken.hpp @@ -0,0 +1,41 @@ +#ifndef INC_CommonHiddenStreamToken_hpp__ +#define INC_CommonHiddenStreamToken_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/CommonToken.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API CommonHiddenStreamToken : public CommonToken { +protected: + RefToken hiddenBefore; + RefToken hiddenAfter; + +public: + CommonHiddenStreamToken(); + CommonHiddenStreamToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt); + CommonHiddenStreamToken(const ANTLR_USE_NAMESPACE(std)string& s); + + RefToken getHiddenAfter(); + RefToken getHiddenBefore(); + + static RefToken factory(); + + void setHiddenAfter(RefToken t); + void setHiddenBefore(RefToken t); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CommonHiddenStreamToken_hpp__ diff --git a/lib/antlr/antlr/CommonToken.hpp b/lib/antlr/antlr/CommonToken.hpp new file mode 100644 index 00000000..51d17b42 --- /dev/null +++ b/lib/antlr/antlr/CommonToken.hpp @@ -0,0 +1,83 @@ +#ifndef INC_CommonToken_hpp__ +#define INC_CommonToken_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/Token.hpp> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API CommonToken : public Token { +public: + CommonToken(); + CommonToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt); + CommonToken(const ANTLR_USE_NAMESPACE(std)string& s); + + /// return contents of token + virtual ANTLR_USE_NAMESPACE(std)string getText() const + { + return text; + } + + /// set contents of token + virtual void setText(const ANTLR_USE_NAMESPACE(std)string& s) + { + text = s; + } + + /** get the line the token is at (starting at 1) + * @see CharScanner::newline() + * @see CharScanner::tab() + */ + virtual int getLine() const + { + return line; + } + /** gt the column the token is at (starting at 1) + * @see CharScanner::newline() + * @see CharScanner::tab() + */ + virtual int getColumn() const + { + return col; + } + + /// set line for token + virtual void setLine(int l) + { + line = l; + } + /// set column for token + virtual void setColumn(int c) + { + col = c; + } + + virtual ANTLR_USE_NAMESPACE(std)string toString() const; + static RefToken factory(); + +protected: + // most tokens will want line and text information + int line; + int col; + ANTLR_USE_NAMESPACE(std)string text; + +private: + CommonToken(const CommonToken&); + const CommonToken& operator=(const CommonToken&); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CommonToken_hpp__ diff --git a/lib/antlr/antlr/IOException.hpp b/lib/antlr/antlr/IOException.hpp new file mode 100644 index 00000000..22566ecc --- /dev/null +++ b/lib/antlr/antlr/IOException.hpp @@ -0,0 +1,45 @@ +#ifndef INC_IOException_hpp__ +#define INC_IOException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/ANTLRException.hpp> +#include <exception> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** Generic IOException used inside support code. (thrown by XML I/O routs) + * basically this is something I'm using since a lot of compilers don't + * support ios_base::failure. + */ +class ANTLR_API IOException : public ANTLRException +{ +public: + ANTLR_USE_NAMESPACE(std)exception io; + + IOException( ANTLR_USE_NAMESPACE(std)exception& e ) + : ANTLRException(e.what()) + { + } + IOException( const ANTLR_USE_NAMESPACE(std)string& mesg ) + : ANTLRException(mesg) + { + } + virtual ~IOException() throw() + { + } +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_IOException_hpp__ diff --git a/lib/antlr/antlr/InputBuffer.hpp b/lib/antlr/antlr/InputBuffer.hpp new file mode 100644 index 00000000..b979ef8c --- /dev/null +++ b/lib/antlr/antlr/InputBuffer.hpp @@ -0,0 +1,146 @@ +#ifndef INC_InputBuffer_hpp__ +#define INC_InputBuffer_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/CircularQueue.hpp> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** A Stream of characters fed to the lexer from a InputStream that can + * be rewound via mark()/rewind() methods. + * <p> + * A dynamic array is used to buffer up all the input characters. Normally, + * "k" characters are stored in the buffer. More characters may be stored during + * guess mode (testing syntactic predicate), or when LT(i>k) is referenced. + * Consumption of characters is deferred. In other words, reading the next + * character is not done by conume(), but deferred until needed by LA or LT. + * <p> + * + * @see antlr.CharQueue + */ +class ANTLR_API InputBuffer { +public: + /** Create a character buffer */ + InputBuffer() + : nMarkers(0) + , markerOffset(0) + , numToConsume(0) + { + } + + virtual ~InputBuffer() + { + } + + /// Reset the input buffer to empty state + virtual inline void reset( void ) + { + nMarkers = 0; + markerOffset = 0; + numToConsume = 0; + queue.clear(); + } + + /** This method updates the state of the input buffer so that + * the text matched since the most recent mark() is no longer + * held by the buffer. So, you either do a mark/rewind for + * failed predicate or mark/commit to keep on parsing without + * rewinding the input. + */ + inline void commit( void ) + { + nMarkers--; + } + + /** Mark another character for deferred consumption */ + virtual inline void consume() + { + numToConsume++; + } + + /** Ensure that the character buffer is sufficiently full */ + virtual void fill(unsigned int amount); + + /** Override this in subclasses to get the next character */ + virtual int getChar()=0; + + /** Get a lookahead character */ + virtual inline int LA(unsigned int i) + { + fill(i); + return queue.elementAt(markerOffset + i - 1); + } + + /** Return an integer marker that can be used to rewind the buffer to + * its current state. + */ + virtual unsigned int mark(); + /// Are there any marks active in the InputBuffer + virtual inline bool isMarked() const + { + return (nMarkers != 0); + } + /** Rewind the character buffer to a marker. + * @param mark Marker returned previously from mark() + */ + virtual void rewind(unsigned int mark); + + /** Get the number of non-consumed characters + */ + virtual unsigned int entries() const; + + ANTLR_USE_NAMESPACE(std)string getLAChars() const; + + ANTLR_USE_NAMESPACE(std)string getMarkedChars() const; + +protected: + // char source + // leave to subclasses + + // Number of active markers + unsigned int nMarkers; // = 0; + + // Additional offset used when markers are active + unsigned int markerOffset; // = 0; + + // Number of calls to consume() since last LA() or LT() call + unsigned int numToConsume; // = 0; + + // Circular queue + CircularQueue<int> queue; + + /** Sync up deferred consumption */ + void syncConsume(); + +private: + InputBuffer(const InputBuffer& other); + InputBuffer& operator=(const InputBuffer& other); +}; + +/** Sync up deferred consumption */ +inline void InputBuffer::syncConsume() { + if (numToConsume > 0) + { + if (nMarkers > 0) + markerOffset += numToConsume; + else + queue.removeItems( numToConsume ); + numToConsume = 0; + } +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_InputBuffer_hpp__ diff --git a/lib/antlr/antlr/LLkParser.hpp b/lib/antlr/antlr/LLkParser.hpp new file mode 100644 index 00000000..32acd3dd --- /dev/null +++ b/lib/antlr/antlr/LLkParser.hpp @@ -0,0 +1,67 @@ +#ifndef INC_LLkParser_hpp__ +#define INC_LLkParser_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/Parser.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/**An LL(k) parser. + * + * @see antlr.Token + * @see antlr.TokenBuffer + * @see antlr.LL1Parser + */ +class ANTLR_API LLkParser : public Parser { +public: + LLkParser(const ParserSharedInputState& lexer, int k_); + + LLkParser(TokenBuffer& tokenBuf, int k_); + + LLkParser(TokenStream& lexer, int k_); + + /** Consume another token from the input stream. Can only write sequentially! + * If you need 3 tokens ahead, you must consume() 3 times. + * <p> + * Note that it is possible to overwrite tokens that have not been matched. + * For example, calling consume() 3 times when k=2, means that the first token + * consumed will be overwritten with the 3rd. + */ + virtual inline void consume() + { + inputState->getInput().consume(); + } + + virtual inline int LA(unsigned int i) + { + return inputState->getInput().LA(i); + } + + virtual inline RefToken LT(unsigned int i) + { + return inputState->getInput().LT(i); + } +protected: + /// the lookahead this LL(k) parser is using. + int k; +private: + void trace(const char* ee, const char* rname); +public: + virtual void traceIn(const char* rname); + virtual void traceOut(const char* rname); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_LLkParser_hpp__ diff --git a/lib/antlr/antlr/LexerSharedInputState.hpp b/lib/antlr/antlr/LexerSharedInputState.hpp new file mode 100644 index 00000000..2571bda3 --- /dev/null +++ b/lib/antlr/antlr/LexerSharedInputState.hpp @@ -0,0 +1,156 @@ +#ifndef INC_LexerSharedInputState_hpp__ +#define INC_LexerSharedInputState_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/InputBuffer.hpp> +#include <antlr/RefCount.hpp> +#include <antlr/CharBuffer.hpp> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** This object contains the data associated with an + * input stream of characters. Multiple lexers + * share a single LexerSharedInputState to lex + * the same input stream. + */ +class ANTLR_API LexerInputState { +public: + /** Construct a new LexerInputState + * @param inbuf the InputBuffer to read from. The object is deleted together + * with the LexerInputState object. + */ + LexerInputState(InputBuffer* inbuf) + : column(1) + , line(1) + , tokenStartColumn(1) + , tokenStartLine(1) + , guessing(0) + , filename("") + , input(inbuf) + , inputResponsible(true) + { + } + + /** Construct a new LexerInputState + * @param inbuf the InputBuffer to read from. + */ + LexerInputState(InputBuffer& inbuf) + : column(1) + , line(1) + , tokenStartColumn(1) + , tokenStartLine(1) + , guessing(0) + , filename("") + , input(&inbuf) + , inputResponsible(false) + { + } + + /** Construct a new LexerInputState + * @param in an istream to read from. + * @see antlr.CharBuffer + */ + LexerInputState(ANTLR_USE_NAMESPACE(std)istream& in) + : column(1) + , line(1) + , tokenStartColumn(1) + , tokenStartLine(1) + , guessing(0) + , filename("") + , input(new CharBuffer(in)) + , inputResponsible(true) + { + } + + /** Reset the LexerInputState with a specified stream and filename. + * This method is a hack, dunno what I was thinking when I added it. + * This should actually be done in a subclass. + * @deprecated + */ + virtual void initialize( ANTLR_USE_NAMESPACE(std)istream& in, const char* file = "" ) + { + column = 1; + line = 1; + tokenStartColumn = 1; + tokenStartLine = 1; + guessing = 0; + filename = file; + + if( input && inputResponsible ) + delete input; + + input = new CharBuffer(in); + inputResponsible = true; + } + + /** Reset the LexerInputState to initial state. + * The underlying InputBuffer is also reset. + */ + virtual void reset( void ) + { + column = 1; + line = 1; + tokenStartColumn = 1; + tokenStartLine = 1; + guessing = 0; + input->reset(); + } + + /** Set the file position of the SharedLexerInputState. + * @param line_ line number to be set + * @param column_ column number to be set + */ + void setPosition( int line_, int column_ ) + { + line = line_; + column = column_; + } + + virtual ~LexerInputState() + { + if (inputResponsible) + delete input; + } + + int column; + int line; + int tokenStartColumn; + int tokenStartLine; + int guessing; + /** What file (if known) caused the problem? */ + ANTLR_USE_NAMESPACE(std)string filename; + InputBuffer& getInput(); +private: + /// Input buffer we use + InputBuffer* input; + /// Who is responsible for cleaning up the InputBuffer? + bool inputResponsible; + + // we don't want these: + LexerInputState(const LexerInputState&); + LexerInputState& operator=(const LexerInputState&); +}; + +inline InputBuffer& LexerInputState::getInput() +{ + return *input; +} + +/// A reference counted LexerInputState object +typedef RefCount<LexerInputState> LexerSharedInputState; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_LexerSharedInputState_hpp__ diff --git a/lib/antlr/antlr/Makefile.am b/lib/antlr/antlr/Makefile.am new file mode 100644 index 00000000..717c43c0 --- /dev/null +++ b/lib/antlr/antlr/Makefile.am @@ -0,0 +1,2 @@ + +noinst_HEADERS = ANTLRException.hpp ANTLRUtil.hpp AST.hpp ASTArray.hpp ASTFactory.hpp ASTNULLType.hpp ASTPair.hpp ASTRefCount.hpp BaseAST.hpp BitSet.hpp CharBuffer.hpp CharInputBuffer.hpp CharScanner.hpp CharStreamException.hpp CharStreamIOException.hpp CircularQueue.hpp CommonAST.hpp CommonASTWithHiddenTokens.hpp CommonHiddenStreamToken.hpp CommonToken.hpp InputBuffer.hpp IOException.hpp LLkParser.hpp LexerSharedInputState.hpp MismatchedCharException.hpp MismatchedTokenException.hpp NoViableAltException.hpp NoViableAltForCharException.hpp Parser.hpp ParserSharedInputState.hpp RecognitionException.hpp RefCount.hpp SemanticException.hpp String.hpp Token.hpp TokenBuffer.hpp TokenStream.hpp TokenStreamBasicFilter.hpp TokenStreamException.hpp TokenStreamHiddenTokenFilter.hpp TokenStreamIOException.hpp TokenStreamRecognitionException.hpp TokenStreamRetryException.hpp TokenStreamSelector.hpp TreeParser.hpp TreeParserSharedInputState.hpp config.hpp diff --git a/lib/antlr/antlr/MismatchedCharException.hpp b/lib/antlr/antlr/MismatchedCharException.hpp new file mode 100644 index 00000000..cc77f9e4 --- /dev/null +++ b/lib/antlr/antlr/MismatchedCharException.hpp @@ -0,0 +1,102 @@ +#ifndef INC_MismatchedCharException_hpp__ +#define INC_MismatchedCharException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/RecognitionException.hpp> +#include <antlr/BitSet.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class CharScanner; + +class ANTLR_API MismatchedCharException : public RecognitionException { +public: + // Types of chars +#ifndef NO_STATIC_CONSTS + static const int CHAR = 1; + static const int NOT_CHAR = 2; + static const int RANGE = 3; + static const int NOT_RANGE = 4; + static const int SET = 5; + static const int NOT_SET = 6; +#else + enum { + CHAR = 1, + NOT_CHAR = 2, + RANGE = 3, + NOT_RANGE = 4, + SET = 5, + NOT_SET = 6 + }; +#endif + +public: + // One of the above + int mismatchType; + + // what was found on the input stream + int foundChar; + + // For CHAR/NOT_CHAR and RANGE/NOT_RANGE + int expecting; + + // For RANGE/NOT_RANGE (expecting is lower bound of range) + int upper; + + // For SET/NOT_SET + BitSet set; + +protected: + // who knows...they may want to ask scanner questions + CharScanner* scanner; + +public: + MismatchedCharException(); + + // Expected range / not range + MismatchedCharException( + int c, + int lower, + int upper_, + bool matchNot, + CharScanner* scanner_ + ); + + // Expected token / not token + MismatchedCharException( + int c, + int expecting_, + bool matchNot, + CharScanner* scanner_ + ); + + // Expected BitSet / not BitSet + MismatchedCharException( + int c, + BitSet set_, + bool matchNot, + CharScanner* scanner_ + ); + + ~MismatchedCharException() throw() {} + + /** + * Returns a clean error message (no line number/column information) + */ + ANTLR_USE_NAMESPACE(std)string getMessage() const; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_MismatchedCharException_hpp__ diff --git a/lib/antlr/antlr/MismatchedTokenException.hpp b/lib/antlr/antlr/MismatchedTokenException.hpp new file mode 100644 index 00000000..47fb44e6 --- /dev/null +++ b/lib/antlr/antlr/MismatchedTokenException.hpp @@ -0,0 +1,144 @@ +#ifndef INC_MismatchedTokenException_hpp__ +#define INC_MismatchedTokenException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/RecognitionException.hpp> +#include <antlr/BitSet.hpp> +#include <antlr/Token.hpp> +#include <antlr/AST.hpp> +#include <vector> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API MismatchedTokenException : public RecognitionException { +public: + MismatchedTokenException(); + + /// Expected range / not range + MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefAST node_, + int lower, + int upper_, + bool matchNot + ); + + // Expected token / not token + MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefAST node_, + int expecting_, + bool matchNot + ); + + // Expected BitSet / not BitSet + MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefAST node_, + BitSet set_, + bool matchNot + ); + + // Expected range / not range + MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefToken token_, + int lower, + int upper_, + bool matchNot, + const ANTLR_USE_NAMESPACE(std)string& fileName_ + ); + + // Expected token / not token + MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefToken token_, + int expecting_, + bool matchNot, + const ANTLR_USE_NAMESPACE(std)string& fileName_ + ); + + // Expected BitSet / not BitSet + MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefToken token_, + BitSet set_, + bool matchNot, + const ANTLR_USE_NAMESPACE(std)string& fileName_ + ); + ~MismatchedTokenException() throw() {} + + /** + * Returns a clean error message (no line number/column information) + */ + ANTLR_USE_NAMESPACE(std)string getMessage() const; + +public: + /// The token that was encountered + const RefToken token; + /// The offending AST node if tree walking + const RefAST node; + /// taken from node or token object + ANTLR_USE_NAMESPACE(std)string tokenText; + + /// Types of tokens +#ifndef NO_STATIC_CONSTS + static const int TOKEN = 1; + static const int NOT_TOKEN = 2; + static const int RANGE = 3; + static const int NOT_RANGE = 4; + static const int SET = 5; + static const int NOT_SET = 6; +#else + enum { + TOKEN = 1, + NOT_TOKEN = 2, + RANGE = 3, + NOT_RANGE = 4, + SET = 5, + NOT_SET = 6 + }; +#endif + +public: + /// One of the above + int mismatchType; + + /// For TOKEN/NOT_TOKEN and RANGE/NOT_RANGE + int expecting; + + /// For RANGE/NOT_RANGE (expecting is lower bound of range) + int upper; + + /// For SET/NOT_SET + BitSet set; + +private: + /// Token names array for formatting + const char* const* tokenNames; + /// Max number of tokens in tokenNames + const int numTokens; + /// Return token name for tokenType + ANTLR_USE_NAMESPACE(std)string tokenName(int tokenType) const; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_MismatchedTokenException_hpp__ diff --git a/lib/antlr/antlr/NoViableAltException.hpp b/lib/antlr/antlr/NoViableAltException.hpp new file mode 100644 index 00000000..22236c90 --- /dev/null +++ b/lib/antlr/antlr/NoViableAltException.hpp @@ -0,0 +1,40 @@ +#ifndef INC_NoViableAltException_hpp__ +#define INC_NoViableAltException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/RecognitionException.hpp> +#include <antlr/Token.hpp> +#include <antlr/AST.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API NoViableAltException : public RecognitionException { +public: + const RefToken token; + const RefAST node; // handles parsing and treeparsing + + NoViableAltException(RefAST t); + NoViableAltException(RefToken t,const ANTLR_USE_NAMESPACE(std)string& fileName_); + + ~NoViableAltException() throw() {} + + /** + * Returns a clean error message (no line number/column information) + */ + ANTLR_USE_NAMESPACE(std)string getMessage() const; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_NoViableAltException_hpp__ diff --git a/lib/antlr/antlr/NoViableAltForCharException.hpp b/lib/antlr/antlr/NoViableAltForCharException.hpp new file mode 100644 index 00000000..0b16a0ea --- /dev/null +++ b/lib/antlr/antlr/NoViableAltForCharException.hpp @@ -0,0 +1,41 @@ +#ifndef INC_NoViableAltForCharException_hpp__ +# define INC_NoViableAltForCharException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +# include <antlr/config.hpp> +# include <antlr/RecognitionException.hpp> +# include <antlr/CharScanner.hpp> + +# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr +{ +# endif + +class ANTLR_API NoViableAltForCharException : public RecognitionException +{ +public: + NoViableAltForCharException(int c, CharScanner* scanner); + NoViableAltForCharException(int c, const ANTLR_USE_NAMESPACE(std)string& fileName_, + int line_, int column_); + + virtual ~NoViableAltForCharException() throw() + { + } + + /// Returns a clean error message (no line number/column information) + ANTLR_USE_NAMESPACE(std)string getMessage() const; +protected: + int foundChar; +}; + +# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +# endif + +#endif //INC_NoViableAltForCharException_hpp__ diff --git a/lib/antlr/antlr/Parser.hpp b/lib/antlr/antlr/Parser.hpp new file mode 100644 index 00000000..f74be2a8 --- /dev/null +++ b/lib/antlr/antlr/Parser.hpp @@ -0,0 +1,319 @@ +#ifndef INC_Parser_hpp__ +#define INC_Parser_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> + +#include <iostream> +#include <exception> + +#include <antlr/BitSet.hpp> +#include <antlr/TokenBuffer.hpp> +#include <antlr/RecognitionException.hpp> +#include <antlr/MismatchedTokenException.hpp> +#include <antlr/ASTFactory.hpp> +#include <antlr/ParserSharedInputState.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +extern bool DEBUG_PARSER; + +/** A generic ANTLR parser (LL(k) for k>=1) containing a bunch of + * utility routines useful at any lookahead depth. We distinguish between + * the LL(1) and LL(k) parsers because of efficiency. This may not be + * necessary in the near future. + * + * Each parser object contains the state of the parse including a lookahead + * cache (the form of which is determined by the subclass), whether or + * not the parser is in guess mode, where tokens come from, etc... + * + * <p> + * During <b>guess</b> mode, the current lookahead token(s) and token type(s) + * cache must be saved because the token stream may not have been informed + * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block. + * Guessing is started by: + * <ol> + * <li>saving the lookahead cache. + * <li>marking the current position in the TokenBuffer. + * <li>increasing the guessing level. + * </ol> + * + * After guessing, the parser state is restored by: + * <ol> + * <li>restoring the lookahead cache. + * <li>rewinding the TokenBuffer. + * <li>decreasing the guessing level. + * </ol> + * + * @see antlr.Token + * @see antlr.TokenBuffer + * @see antlr.TokenStream + * @see antlr.LL1Parser + * @see antlr.LLkParser + * + * @todo add constructors with ASTFactory. + */ +class ANTLR_API Parser { +protected: + Parser(TokenBuffer& input) + : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0) + { + } + Parser(TokenBuffer* input) + : inputState(new ParserInputState(input)), astFactory(0), traceDepth(0) + { + } + Parser(const ParserSharedInputState& state) + : inputState(state), astFactory(0), traceDepth(0) + { + } +public: + virtual ~Parser() + { + } + + /** Return the token type of the ith token of lookahead where i=1 + * is the current token being examined by the parser (i.e., it + * has not been matched yet). + */ + virtual int LA(unsigned int i)=0; + + /// Return the i-th token of lookahead + virtual RefToken LT(unsigned int i)=0; + + /** DEPRECATED! Specify the factory to be used during tree building. (Compulsory) + * Setting the factory is nowadays compulsory. + * @see setASTFactory + */ + virtual void setASTNodeFactory( ASTFactory *factory ) + { + astFactory = factory; + } + /** Specify the factory to be used during tree building. (Compulsory) + * Setting the factory is nowadays compulsory. + */ + virtual void setASTFactory( ASTFactory *factory ) + { + astFactory = factory; + } + /** Return a pointer to the ASTFactory used. + * So you might use it in subsequent treewalkers or to reload AST's + * from disk. + */ + virtual ASTFactory* getASTFactory() + { + return astFactory; + } + /** Get the root AST node of the generated AST. When using a custom AST type + * or heterogenous AST's, you'll have to convert it to the right type + * yourself. + */ + virtual RefAST getAST() = 0; + + /// Return the filename of the input file. + virtual inline ANTLR_USE_NAMESPACE(std)string getFilename() const + { + return inputState->filename; + } + /// Set the filename of the input file (used for error reporting). + virtual void setFilename(const ANTLR_USE_NAMESPACE(std)string& f) + { + inputState->filename = f; + } + + virtual void setInputState(ParserSharedInputState state) + { + inputState = state; + } + virtual inline ParserSharedInputState getInputState() const + { + return inputState; + } + + /// Get another token object from the token stream + virtual void consume()=0; + /// Consume tokens until one matches the given token + virtual void consumeUntil(int tokenType) + { + while (LA(1) != Token::EOF_TYPE && LA(1) != tokenType) + consume(); + } + + /// Consume tokens until one matches the given token set + virtual void consumeUntil(const BitSet& set) + { + while (LA(1) != Token::EOF_TYPE && !set.member(LA(1))) + consume(); + } + + /** Make sure current lookahead symbol matches token type <tt>t</tt>. + * Throw an exception upon mismatch, which is catch by either the + * error handler or by the syntactic predicate. + */ + virtual void match(int t) + { + if ( DEBUG_PARSER ) + { + traceIndent(); + ANTLR_USE_NAMESPACE(std)cout << "enter match(" << t << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; + } + if ( LA(1) != t ) + { + if ( DEBUG_PARSER ) + { + traceIndent(); + ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << "!=" << t << ANTLR_USE_NAMESPACE(std)endl; + } + throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, false, getFilename()); + } + else + { + // mark token as consumed -- fetch next token deferred until LA/LT + consume(); + } + } + + virtual void matchNot(int t) + { + if ( LA(1)==t ) + { + // Throws inverted-sense exception + throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), t, true, getFilename()); + } + else + { + // mark token as consumed -- fetch next token deferred until LA/LT + consume(); + } + } + + /** Make sure current lookahead symbol matches the given set + * Throw an exception upon mismatch, which is catch by either the + * error handler or by the syntactic predicate. + */ + virtual void match(const BitSet& b) + { + if ( DEBUG_PARSER ) + { + traceIndent(); + ANTLR_USE_NAMESPACE(std)cout << "enter match(" << "bitset" /*b.toString()*/ + << ") with LA(1)=" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; + } + if ( !b.member(LA(1)) ) + { + if ( DEBUG_PARSER ) + { + traceIndent(); + ANTLR_USE_NAMESPACE(std)cout << "token mismatch: " << LA(1) << " not member of " + << "bitset" /*b.toString()*/ << ANTLR_USE_NAMESPACE(std)endl; + } + throw MismatchedTokenException(getTokenNames(), getNumTokens(), LT(1), b, false, getFilename()); + } + else + { + // mark token as consumed -- fetch next token deferred until LA/LT + consume(); + } + } + + /** Mark a spot in the input and return the position. + * Forwarded to TokenBuffer. + */ + virtual inline unsigned int mark() + { + return inputState->getInput().mark(); + } + /// rewind to a previously marked position + virtual inline void rewind(unsigned int pos) + { + inputState->getInput().rewind(pos); + } + /** called by the generated parser to do error recovery, override to + * customize the behaviour. + */ + virtual void recover(const RecognitionException& ex, const BitSet& tokenSet) + { + consume(); + consumeUntil(tokenSet); + } + + /// Parser error-reporting function can be overridden in subclass + virtual void reportError(const RecognitionException& ex); + /// Parser error-reporting function can be overridden in subclass + virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s); + /// Parser warning-reporting function can be overridden in subclass + virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s); + + /// get the token name for the token number 'num' + virtual const char* getTokenName(int num) const = 0; + /// get a vector with all token names + virtual const char* const* getTokenNames() const = 0; + /** Get the number of tokens defined. + * This one should be overridden in subclasses. + */ + virtual int getNumTokens(void) const = 0; + + /** Set or change the input token buffer */ +// void setTokenBuffer(TokenBuffer<Token>* t); + + virtual void traceIndent(); + virtual void traceIn(const char* rname); + virtual void traceOut(const char* rname); +protected: +// void setTokenNames(const char** tokenNames_); + + ParserSharedInputState inputState; + +// /// AST return value for a rule is squirreled away here +// RefAST returnAST; + + /// AST support code; parser and treeparser delegate to this object + ASTFactory *astFactory; + + // used to keep track of the indentation for the trace + int traceDepth; + + /** Utility class which allows tracing to work even when exceptions are + * thrown. + */ + class Tracer { /*{{{*/ + private: + Parser* parser; + const char* text; + public: + Tracer(Parser* p,const char * t) + : parser(p), text(t) + { + parser->traceIn(text); + } + ~Tracer() + { +#ifdef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION + // Only give trace if there's no uncaught exception.. + if(!ANTLR_USE_NAMESPACE(std)uncaught_exception()) +#endif + parser->traceOut(text); + } + private: + Tracer(const Tracer&); // undefined + const Tracer& operator=(const Tracer&); // undefined + /*}}}*/ + }; +private: + Parser(const Parser&); // undefined + const Parser& operator=(const Parser&); // undefined +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_Parser_hpp__ diff --git a/lib/antlr/antlr/ParserSharedInputState.hpp b/lib/antlr/antlr/ParserSharedInputState.hpp new file mode 100644 index 00000000..b011bc15 --- /dev/null +++ b/lib/antlr/antlr/ParserSharedInputState.hpp @@ -0,0 +1,92 @@ +#ifndef INC_ParserSharedInputState_hpp__ +#define INC_ParserSharedInputState_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenBuffer.hpp> +#include <antlr/RefCount.hpp> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** This object contains the data associated with an + * input stream of tokens. Multiple parsers + * share a single ParserSharedInputState to parse + * the same stream of tokens. + */ +class ANTLR_API ParserInputState { +public: + /** Construct a new ParserInputState + * @param in the TokenBuffer to read from. The object is deleted together + * with the ParserInputState object. + */ + ParserInputState( TokenBuffer* in ) + : guessing(0) + , filename() + , input(in) + , inputResponsible(true) + { + } + /** Construct a new ParserInputState + * @param in the TokenBuffer to read from. + */ + ParserInputState( TokenBuffer& in ) + : guessing(0) + , filename("") + , input(&in) + , inputResponsible(false) + { + } + + virtual ~ParserInputState() + { + if (inputResponsible) + delete input; + } + + TokenBuffer& getInput( void ) + { + return *input; + } + + /// Reset the ParserInputState and the underlying TokenBuffer + void reset( void ) + { + input->reset(); + guessing = 0; + } + +public: + /** Are we guessing (guessing>0)? */ + int guessing; + /** What file (if known) caused the problem? + * @todo wrap this one.. + */ + ANTLR_USE_NAMESPACE(std)string filename; +private: + /** Where to get token objects */ + TokenBuffer* input; + /// Do we need to free the TokenBuffer or is it owned by another.. + bool inputResponsible; + + // we don't want these: + ParserInputState(const ParserInputState&); + ParserInputState& operator=(const ParserInputState&); +}; + +/// A reference counted ParserInputState +typedef RefCount<ParserInputState> ParserSharedInputState; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_ParserSharedInputState_hpp__ diff --git a/lib/antlr/antlr/RecognitionException.hpp b/lib/antlr/antlr/RecognitionException.hpp new file mode 100644 index 00000000..e61bc620 --- /dev/null +++ b/lib/antlr/antlr/RecognitionException.hpp @@ -0,0 +1,66 @@ +#ifndef INC_RecognitionException_hpp__ +# define INC_RecognitionException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +# include <antlr/config.hpp> +# include <antlr/ANTLRException.hpp> + +# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr +{ +# endif + class ANTLR_API RecognitionException : public ANTLRException + { + public: + RecognitionException(); + RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s); + RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s, + const ANTLR_USE_NAMESPACE(std)string& fileName, + int line, int column ); + + virtual ~RecognitionException() throw() + { + } + + /// Return file where mishap occurred. + virtual ANTLR_USE_NAMESPACE(std)string getFilename() const throw() + { + return fileName; + } + /** + * @return the line number that this exception happened on. + */ + virtual int getLine() const throw() + { + return line; + } + /** + * @return the column number that this exception happened on. + */ + virtual int getColumn() const throw() + { + return column; + } + + /// Return complete error message with line/column number info (if present) + virtual ANTLR_USE_NAMESPACE(std)string toString() const; + + /// See what file/line/column info is present and return it as a string + virtual ANTLR_USE_NAMESPACE(std)string getFileLineColumnString() const; + protected: + ANTLR_USE_NAMESPACE(std)string fileName; // not used by treeparsers + int line; // not used by treeparsers + int column; // not used by treeparsers + }; + +# ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +# endif + +#endif //INC_RecognitionException_hpp__ diff --git a/lib/antlr/antlr/RefCount.hpp b/lib/antlr/antlr/RefCount.hpp new file mode 100644 index 00000000..8546a049 --- /dev/null +++ b/lib/antlr/antlr/RefCount.hpp @@ -0,0 +1,80 @@ +#ifndef INC_RefCount_hpp__ +#define INC_RefCount_hpp__ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +template<class T> +class ANTLR_API RefCount { +private: + struct Ref { + T* const ptr; + unsigned int count; + + Ref(T* p) : ptr(p), count(1) {} + ~Ref() {delete ptr;} + Ref* increment() {++count;return this;} + bool decrement() {return (--count==0);} + private: + Ref(const Ref&); + Ref& operator=(const Ref&); + }* ref; + +public: + explicit RefCount(T* p = 0) + : ref(p ? new Ref(p) : 0) + { + } + RefCount(const RefCount<T>& other) + : ref(other.ref ? other.ref->increment() : 0) + { + } + ~RefCount() + { + if (ref && ref->decrement()) + delete ref; + } + RefCount<T>& operator=(const RefCount<T>& other) + { + Ref* tmp = other.ref ? other.ref->increment() : 0; + if (ref && ref->decrement()) + delete ref; + ref = tmp; + return *this; + } + + operator T* () const + { + return ref ? ref->ptr : 0; + } + + T* operator->() const + { + return ref ? ref->ptr : 0; + } + + T* get() const + { + return ref ? ref->ptr : 0; + } + + template<class newType> operator RefCount<newType>() + { + return RefCount<newType>(ref); + } +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_RefCount_hpp__ diff --git a/lib/antlr/antlr/SemanticException.hpp b/lib/antlr/antlr/SemanticException.hpp new file mode 100644 index 00000000..dc68d5a9 --- /dev/null +++ b/lib/antlr/antlr/SemanticException.hpp @@ -0,0 +1,40 @@ +#ifndef INC_SemanticException_hpp__ +#define INC_SemanticException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/RecognitionException.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API SemanticException : public RecognitionException { +public: + SemanticException(const ANTLR_USE_NAMESPACE(std)string& s) + : RecognitionException(s) + { + } + SemanticException(const ANTLR_USE_NAMESPACE(std)string& s, + const ANTLR_USE_NAMESPACE(std)string& fileName_, + int line_,int column_) + : RecognitionException(s,fileName_,line_,column_) + { + } + + ~SemanticException() throw() + { + } +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_SemanticException_hpp__ diff --git a/lib/antlr/antlr/String.hpp b/lib/antlr/antlr/String.hpp new file mode 100644 index 00000000..7e6dde5a --- /dev/null +++ b/lib/antlr/antlr/String.hpp @@ -0,0 +1,27 @@ +#ifndef INC_String_hpp__ +#define INC_String_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +ANTLR_API ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, const int rhs ); +ANTLR_API ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, size_t rhs ); + +ANTLR_API ANTLR_USE_NAMESPACE(std)string charName( int ch ); + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_String_hpp__ diff --git a/lib/antlr/antlr/Token.hpp b/lib/antlr/antlr/Token.hpp new file mode 100644 index 00000000..cd56fc3c --- /dev/null +++ b/lib/antlr/antlr/Token.hpp @@ -0,0 +1,108 @@ +#ifndef INC_Token_hpp__ +#define INC_Token_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenRefCount.hpp> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +struct TokenRef; + +/** A token is minimally a token type. Subclasses can add the text matched + * for the token and line info. + */ +class ANTLR_API Token +{ +public: + // constants +#ifndef NO_STATIC_CONSTS + static const int MIN_USER_TYPE = 4; + static const int NULL_TREE_LOOKAHEAD = 3; + static const int INVALID_TYPE = 0; + static const int EOF_TYPE = 1; + static const int SKIP = -1; +#else + enum { + MIN_USER_TYPE = 4, + NULL_TREE_LOOKAHEAD = 3, + INVALID_TYPE = 0, + EOF_TYPE = 1, + SKIP = -1 + }; +#endif + + Token() + : ref(0) + , type(INVALID_TYPE) + { + } + Token(int t) + : ref(0) + , type(t) + { + } + Token(int t, const ANTLR_USE_NAMESPACE(std)string& txt) + : ref(0) + , type(t) + { + setText(txt); + } + virtual ~Token() + { + } + + virtual int getColumn() const; + virtual int getLine() const; + virtual ANTLR_USE_NAMESPACE(std)string getText() const; + virtual const ANTLR_USE_NAMESPACE(std)string& getFilename() const; + virtual int getType() const; + + virtual void setColumn(int c); + + virtual void setLine(int l); + virtual void setText(const ANTLR_USE_NAMESPACE(std)string& t); + virtual void setType(int t); + + virtual void setFilename( const std::string& file ); + + virtual ANTLR_USE_NAMESPACE(std)string toString() const; + +private: + friend struct TokenRef; + TokenRef* ref; + + int type; ///< the type of the token + + Token(RefToken other); + Token& operator=(const Token& other); + Token& operator=(RefToken other); + + Token(const Token&); +}; + +extern ANTLR_API RefToken nullToken; + +#ifdef NEEDS_OPERATOR_LESS_THAN +// RK: Added after 2.7.2 previously it was undefined. +// AL: what to return if l and/or r point to nullToken??? +inline bool operator<( RefToken l, RefToken r ) +{ + return nullToken == l ? ( nullToken == r ? false : true ) : l->getType() < r->getType(); +} +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_Token_hpp__ diff --git a/lib/antlr/antlr/TokenBuffer.hpp b/lib/antlr/antlr/TokenBuffer.hpp new file mode 100644 index 00000000..3077eead --- /dev/null +++ b/lib/antlr/antlr/TokenBuffer.hpp @@ -0,0 +1,121 @@ +#ifndef INC_TokenBuffer_hpp__ +#define INC_TokenBuffer_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenStream.hpp> +#include <antlr/CircularQueue.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/**A Stream of Token objects fed to the parser from a TokenStream that can + * be rewound via mark()/rewind() methods. + * <p> + * A dynamic array is used to buffer up all the input tokens. Normally, + * "k" tokens are stored in the buffer. More tokens may be stored during + * guess mode (testing syntactic predicate), or when LT(i>k) is referenced. + * Consumption of tokens is deferred. In other words, reading the next + * token is not done by conume(), but deferred until needed by LA or LT. + * <p> + * + * @todo: see if we can integrate this one with InputBuffer into one template + * or so. + * + * @see antlr.Token + * @see antlr.TokenStream + * @see antlr.TokenQueue + */ +class ANTLR_API TokenBuffer { +public: + /** Create a token buffer */ + TokenBuffer(TokenStream& input_); + virtual ~TokenBuffer(); + + /// Reset the input buffer to empty state + inline void reset( void ) + { + nMarkers = 0; + markerOffset = 0; + numToConsume = 0; + queue.clear(); + } + + /** Get a lookahead token value */ + int LA( unsigned int i ); + + /** Get a lookahead token */ + RefToken LT( unsigned int i ); + + /** Return an integer marker that can be used to rewind the buffer to + * its current state. + */ + unsigned int mark(); + + /**Rewind the token buffer to a marker. + * @param mark Marker returned previously from mark() + */ + void rewind(unsigned int mark); + + /** Mark another token for deferred consumption */ + inline void consume() + { + numToConsume++; + } + + /// Return the number of entries in the TokenBuffer + virtual unsigned int entries() const; + +private: + /** Ensure that the token buffer is sufficiently full */ + void fill(unsigned int amount); + /** Sync up deferred consumption */ + void syncConsume(); + +protected: + /// Token source + TokenStream& input; + + /// Number of active markers + unsigned int nMarkers; + + /// Additional offset used when markers are active + unsigned int markerOffset; + + /// Number of calls to consume() since last LA() or LT() call + unsigned int numToConsume; + + /// Circular queue with Tokens + CircularQueue<RefToken> queue; + +private: + TokenBuffer(const TokenBuffer& other); + const TokenBuffer& operator=(const TokenBuffer& other); +}; + +/** Sync up deferred consumption */ +inline void TokenBuffer::syncConsume() +{ + if (numToConsume > 0) + { + if (nMarkers > 0) + markerOffset += numToConsume; + else + queue.removeItems( numToConsume ); + + numToConsume = 0; + } +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenBuffer_hpp__ diff --git a/lib/antlr/antlr/TokenRefCount.hpp b/lib/antlr/antlr/TokenRefCount.hpp new file mode 100644 index 00000000..9ccbb98c --- /dev/null +++ b/lib/antlr/antlr/TokenRefCount.hpp @@ -0,0 +1,98 @@ +#ifndef INC_TokenRefCount_hpp__ +# define INC_TokenRefCount_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id:$ + */ + +# include <antlr/config.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class Token; + +struct ANTLR_API TokenRef +{ + Token* const ptr; + unsigned int count; + + TokenRef(Token* p); + ~TokenRef(); + TokenRef* increment() + { + ++count; + return this; + } + bool decrement() + { + return (--count==0); + } + + static TokenRef* getRef(const Token* p); +private: + TokenRef( const TokenRef& ); + TokenRef& operator=( const TokenRef& ); +}; + +template<class T> + class ANTLR_API TokenRefCount +{ +private: + TokenRef* ref; + +public: + TokenRefCount(const Token* p=0) + : ref(p ? TokenRef::getRef(p) : 0) + { + } + TokenRefCount(const TokenRefCount<T>& other) + : ref(other.ref ? other.ref->increment() : 0) + { + } + ~TokenRefCount() + { + if (ref && ref->decrement()) + delete ref; + } + TokenRefCount<T>& operator=(Token* other) + { + TokenRef* tmp = TokenRef::getRef(other); + + if (ref && ref->decrement()) + delete ref; + + ref=tmp; + + return *this; + } + TokenRefCount<T>& operator=(const TokenRefCount<T>& other) + { + if( other.ref != ref ) + { + TokenRef* tmp = other.ref ? other.ref->increment() : 0; + + if (ref && ref->decrement()) + delete ref; + + ref=tmp; + } + return *this; + } + + operator T* () const { return ref ? static_cast<T*>(ref->ptr) : 0; } + T* operator->() const { return ref ? static_cast<T*>(ref->ptr) : 0; } + T* get() const { return ref ? static_cast<T*>(ref->ptr) : 0; } +}; + +typedef TokenRefCount<Token> RefToken; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenRefCount_hpp__ diff --git a/lib/antlr/antlr/TokenStream.hpp b/lib/antlr/antlr/TokenStream.hpp new file mode 100644 index 00000000..dbf83a8c --- /dev/null +++ b/lib/antlr/antlr/TokenStream.hpp @@ -0,0 +1,34 @@ +#ifndef INC_TokenStream_hpp__ +#define INC_TokenStream_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/Token.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** This interface allows any object to pretend it is a stream + * of tokens. + * @author Terence Parr, MageLang Institute + */ +class ANTLR_API TokenStream { +public: + virtual RefToken nextToken()=0; + virtual ~TokenStream() + { + } +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStream_hpp__ diff --git a/lib/antlr/antlr/TokenStreamBasicFilter.hpp b/lib/antlr/antlr/TokenStreamBasicFilter.hpp new file mode 100644 index 00000000..bcdb131c --- /dev/null +++ b/lib/antlr/antlr/TokenStreamBasicFilter.hpp @@ -0,0 +1,46 @@ +#ifndef INC_TokenStreamBasicFilter_hpp__ +#define INC_TokenStreamBasicFilter_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/BitSet.hpp> +#include <antlr/TokenStream.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** This object is a TokenStream that passes through all + * tokens except for those that you tell it to discard. + * There is no buffering of the tokens. + */ +class ANTLR_API TokenStreamBasicFilter : public TokenStream { + /** The set of token types to discard */ +protected: + BitSet discardMask; + + /** The input stream */ +protected: + TokenStream* input; + +public: + TokenStreamBasicFilter(TokenStream& input_); + + void discard(int ttype); + + void discard(const BitSet& mask); + + RefToken nextToken(); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStreamBasicFilter_hpp__ diff --git a/lib/antlr/antlr/TokenStreamException.hpp b/lib/antlr/antlr/TokenStreamException.hpp new file mode 100644 index 00000000..dbddb442 --- /dev/null +++ b/lib/antlr/antlr/TokenStreamException.hpp @@ -0,0 +1,41 @@ +#ifndef INC_TokenStreamException_hpp__ +#define INC_TokenStreamException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/ANTLRException.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** Baseclass for exceptions thrown by classes implementing the TokenStream + * interface. + * @see TokenStream + */ +class ANTLR_API TokenStreamException : public ANTLRException { +public: + TokenStreamException() + : ANTLRException() + { + } + TokenStreamException(const ANTLR_USE_NAMESPACE(std)string& s) + : ANTLRException(s) + { + } + virtual ~TokenStreamException() throw() + { + } +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStreamException_hpp__ diff --git a/lib/antlr/antlr/TokenStreamHiddenTokenFilter.hpp b/lib/antlr/antlr/TokenStreamHiddenTokenFilter.hpp new file mode 100644 index 00000000..ed007a7a --- /dev/null +++ b/lib/antlr/antlr/TokenStreamHiddenTokenFilter.hpp @@ -0,0 +1,95 @@ +#ifndef INC_TokenStreamHiddenTokenFilter_hpp__ +#define INC_TokenStreamHiddenTokenFilter_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenStreamBasicFilter.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/**This object filters a token stream coming from a lexer + * or another TokenStream so that only certain token channels + * get transmitted to the parser. + * + * Any of the channels can be filtered off as "hidden" channels whose + * tokens can be accessed from the parser. + */ +class ANTLR_API TokenStreamHiddenTokenFilter : public TokenStreamBasicFilter { + // protected BitSet discardMask; +protected: + BitSet hideMask; + +private: + RefToken nextMonitoredToken; + +protected: + /** track tail of hidden list emanating from previous + * monitored token + */ + RefToken lastHiddenToken; + + RefToken firstHidden; // = null; + +public: + TokenStreamHiddenTokenFilter(TokenStream& input); + +protected: + void consume(); + +private: + void consumeFirst(); + +public: + BitSet getDiscardMask() const; + + /** Return a ptr to the hidden token appearing immediately after + * token t in the input stream. + */ + RefToken getHiddenAfter(RefToken t); + + /** Return a ptr to the hidden token appearing immediately before + * token t in the input stream. + */ + RefToken getHiddenBefore(RefToken t); + + BitSet getHideMask() const; + + /** Return the first hidden token if one appears + * before any monitored token. + */ + RefToken getInitialHiddenToken(); + + void hide(int m); + + void hide(const BitSet& mask); + +protected: + RefToken LA(int i); + +public: +/** Return the next monitored token. + * Test the token following the monitored token. + * If following is another monitored token, save it + * for the next invocation of nextToken (like a single + * lookahead token) and return it then. + * If following is unmonitored, nondiscarded (hidden) + * channel token, add it to the monitored token. + * + * Note: EOF must be a monitored Token. + */ + RefToken nextToken(); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStreamHiddenTokenFilter_hpp__ diff --git a/lib/antlr/antlr/TokenStreamIOException.hpp b/lib/antlr/antlr/TokenStreamIOException.hpp new file mode 100644 index 00000000..fff72ced --- /dev/null +++ b/lib/antlr/antlr/TokenStreamIOException.hpp @@ -0,0 +1,40 @@ +#ifndef INC_TokenStreamIOException_hpp__ +#define INC_TokenStreamIOException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenStreamException.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class TokenStreamIOException : public TokenStreamException { +public: + TokenStreamIOException() + : TokenStreamException() + { + } + TokenStreamIOException(const ANTLR_USE_NAMESPACE(std)exception& e) + : TokenStreamException(e.what()) + , io(e) + { + } + ~TokenStreamIOException() throw() + { + } +private: + ANTLR_USE_NAMESPACE(std)exception io; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStreamIOException_hpp__ diff --git a/lib/antlr/antlr/TokenStreamRecognitionException.hpp b/lib/antlr/antlr/TokenStreamRecognitionException.hpp new file mode 100644 index 00000000..687d7814 --- /dev/null +++ b/lib/antlr/antlr/TokenStreamRecognitionException.hpp @@ -0,0 +1,57 @@ +#ifndef INC_TokenStreamRecognitionException_hpp__ +#define INC_TokenStreamRecognitionException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenStreamException.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** Exception thrown from generated lexers when there's no default error + * handler specified. + * @see TokenStream + */ +class TokenStreamRecognitionException : public TokenStreamException { +public: + TokenStreamRecognitionException(RecognitionException& re) + : TokenStreamException(re.getMessage()) + , recog(re) + { + } + virtual ~TokenStreamRecognitionException() throw() + { + } + virtual ANTLR_USE_NAMESPACE(std)string toString() const + { + return recog.getFileLineColumnString()+getMessage(); + } + + virtual ANTLR_USE_NAMESPACE(std)string getFilename() const throw() + { + return recog.getFilename(); + } + virtual int getLine() const throw() + { + return recog.getLine(); + } + virtual int getColumn() const throw() + { + return recog.getColumn(); + } +private: + RecognitionException recog; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStreamRecognitionException_hpp__ diff --git a/lib/antlr/antlr/TokenStreamRetryException.hpp b/lib/antlr/antlr/TokenStreamRetryException.hpp new file mode 100644 index 00000000..5af21cde --- /dev/null +++ b/lib/antlr/antlr/TokenStreamRetryException.hpp @@ -0,0 +1,28 @@ +#ifndef INC_TokenStreamRetryException_hpp__ +#define INC_TokenStreamRetryException_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenStreamException.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class TokenStreamRetryException : public TokenStreamException { +public: + TokenStreamRetryException() {} + ~TokenStreamRetryException() throw() {} +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStreamRetryException_hpp__ diff --git a/lib/antlr/antlr/TokenStreamRewriteEngine.hpp b/lib/antlr/antlr/TokenStreamRewriteEngine.hpp new file mode 100644 index 00000000..9fab08c2 --- /dev/null +++ b/lib/antlr/antlr/TokenStreamRewriteEngine.hpp @@ -0,0 +1,439 @@ +#ifndef INC_TokenStreamRewriteEngine_hpp__ +#define INC_TokenStreamRewriteEngine_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + */ + +#include <string> +#include <list> +#include <vector> +#include <map> +#include <utility> +#include <iostream> +#include <iterator> +#include <cassert> +#include <algorithm> + +#include <antlr/config.hpp> + +#include <antlr/TokenStream.hpp> +#include <antlr/TokenWithIndex.hpp> +#include <antlr/BitSet.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** This token stream tracks the *entire* token stream coming from + * a lexer, but does not pass on the whitespace (or whatever else + * you want to discard) to the parser. + * + * This class can then be asked for the ith token in the input stream. + * Useful for dumping out the input stream exactly after doing some + * augmentation or other manipulations. Tokens are index from 0..n-1 + * + * You can insert stuff, replace, and delete chunks. Note that the + * operations are done lazily--only if you convert the buffer to a + * String. This is very efficient because you are not moving data around + * all the time. As the buffer of tokens is converted to strings, the + * toString() method(s) check to see if there is an operation at the + * current index. If so, the operation is done and then normal String + * rendering continues on the buffer. This is like having multiple Turing + * machine instruction streams (programs) operating on a single input tape. :) + * + * Since the operations are done lazily at toString-time, operations do not + * screw up the token index values. That is, an insert operation at token + * index i does not change the index values for tokens i+1..n-1. + * + * Because operations never actually alter the buffer, you may always get + * the original token stream back without undoing anything. Since + * the instructions are queued up, you can easily simulate transactions and + * roll back any changes if there is an error just by removing instructions. + * For example, + * + * TokenStreamRewriteEngine rewriteEngine = + * new TokenStreamRewriteEngine(lexer); + * JavaRecognizer parser = new JavaRecognizer(rewriteEngine); + * ... + * rewriteEngine.insertAfter("pass1", t, "foobar");} + * rewriteEngine.insertAfter("pass2", u, "start");} + * System.out.println(rewriteEngine.toString("pass1")); + * System.out.println(rewriteEngine.toString("pass2")); + * + * You can also have multiple "instruction streams" and get multiple + * rewrites from a single pass over the input. Just name the instruction + * streams and use that name again when printing the buffer. This could be + * useful for generating a C file and also its header file--all from the + * same buffer. + * + * If you don't use named rewrite streams, a "default" stream is used. + * + * Terence Parr, parrt@cs.usfca.edu + * University of San Francisco + * February 2004 + */ +class TokenStreamRewriteEngine : public TokenStream +{ +public: + typedef ANTLR_USE_NAMESPACE(std)vector<antlr::RefTokenWithIndex> token_list; + static const char* DEFAULT_PROGRAM_NAME; +#ifndef NO_STATIC_CONSTS + static const size_t MIN_TOKEN_INDEX; + static const int PROGRAM_INIT_SIZE; +#else + enum { + MIN_TOKEN_INDEX = 0, + PROGRAM_INIT_SIZE = 100 + }; +#endif + + struct tokenToStream { + tokenToStream( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {} + template <typename T> void operator() ( const T& t ) { + out << t->getText(); + } + ANTLR_USE_NAMESPACE(std)ostream& out; + }; + + class RewriteOperation { + protected: + RewriteOperation( size_t idx, const ANTLR_USE_NAMESPACE(std)string& txt ) + : index(idx), text(txt) + { + } + public: + virtual ~RewriteOperation() + { + } + /** Execute the rewrite operation by possibly adding to the buffer. + * Return the index of the next token to operate on. + */ + virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& /* out */ ) { + return index; + } + virtual size_t getIndex() const { + return index; + } + virtual const char* type() const { + return "RewriteOperation"; + } + protected: + size_t index; + ANTLR_USE_NAMESPACE(std)string text; + }; + + struct executeOperation { + ANTLR_USE_NAMESPACE(std)ostream& out; + executeOperation( ANTLR_USE_NAMESPACE(std)ostream& s ) : out(s) {} + void operator () ( RewriteOperation* t ) { + t->execute(out); + } + }; + + /// list of rewrite operations + typedef ANTLR_USE_NAMESPACE(std)list<RewriteOperation*> operation_list; + /// map program name to <program counter,program> tuple + typedef ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,operation_list> program_map; + + class InsertBeforeOp : public RewriteOperation + { + public: + InsertBeforeOp( size_t index, const ANTLR_USE_NAMESPACE(std)string& text ) + : RewriteOperation(index, text) + { + } + virtual ~InsertBeforeOp() {} + virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out ) + { + out << text; + return index; + } + virtual const char* type() const { + return "InsertBeforeOp"; + } + }; + + class ReplaceOp : public RewriteOperation + { + public: + ReplaceOp(size_t from, size_t to, ANTLR_USE_NAMESPACE(std)string text) + : RewriteOperation(from,text) + , lastIndex(to) + { + } + virtual ~ReplaceOp() {} + virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out ) { + out << text; + return lastIndex+1; + } + virtual const char* type() const { + return "ReplaceOp"; + } + protected: + size_t lastIndex; + }; + + class DeleteOp : public ReplaceOp { + public: + DeleteOp(size_t from, size_t to) + : ReplaceOp(from,to,"") + { + } + virtual const char* type() const { + return "DeleteOp"; + } + }; + + TokenStreamRewriteEngine(TokenStream& upstream); + + TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize); + + RefToken nextToken( void ); + + void rollback(size_t instructionIndex) { + rollback(DEFAULT_PROGRAM_NAME, instructionIndex); + } + + /** Rollback the instruction stream for a program so that + * the indicated instruction (via instructionIndex) is no + * longer in the stream. UNTESTED! + */ + void rollback(const ANTLR_USE_NAMESPACE(std)string& programName, + size_t instructionIndex ); + + void deleteProgram() { + deleteProgram(DEFAULT_PROGRAM_NAME); + } + + /** Reset the program so that no instructions exist */ + void deleteProgram(const ANTLR_USE_NAMESPACE(std)string& programName) { + rollback(programName, MIN_TOKEN_INDEX); + } + + void insertAfter( RefTokenWithIndex t, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + insertAfter(DEFAULT_PROGRAM_NAME, t, text); + } + + void insertAfter(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) { + insertAfter(DEFAULT_PROGRAM_NAME, index, text); + } + + void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName, + RefTokenWithIndex t, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + insertAfter(programName, t->getIndex(), text); + } + + void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName, + size_t index, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + // to insert after, just insert before next index (even if past end) + insertBefore(programName,index+1, text); + } + + void insertBefore( RefTokenWithIndex t, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + // std::cout << "insertBefore index " << t->getIndex() << " " << text << std::endl; + insertBefore(DEFAULT_PROGRAM_NAME, t, text); + } + + void insertBefore(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) { + insertBefore(DEFAULT_PROGRAM_NAME, index, text); + } + + void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName, + RefTokenWithIndex t, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + insertBefore(programName, t->getIndex(), text); + } + + void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName, + size_t index, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + addToSortedRewriteList(programName, new InsertBeforeOp(index,text)); + } + + void replace(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) + { + replace(DEFAULT_PROGRAM_NAME, index, index, text); + } + + void replace( size_t from, size_t to, + const ANTLR_USE_NAMESPACE(std)string& text) + { + replace(DEFAULT_PROGRAM_NAME, from, to, text); + } + + void replace( RefTokenWithIndex indexT, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + replace(DEFAULT_PROGRAM_NAME, indexT->getIndex(), indexT->getIndex(), text); + } + + void replace( RefTokenWithIndex from, + RefTokenWithIndex to, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + replace(DEFAULT_PROGRAM_NAME, from, to, text); + } + + void replace(const ANTLR_USE_NAMESPACE(std)string& programName, + size_t from, size_t to, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + addToSortedRewriteList(programName,new ReplaceOp(from, to, text)); + } + + void replace( const ANTLR_USE_NAMESPACE(std)string& programName, + RefTokenWithIndex from, + RefTokenWithIndex to, + const ANTLR_USE_NAMESPACE(std)string& text ) + { + replace(programName, + from->getIndex(), + to->getIndex(), + text); + } + + void remove(size_t index) { + remove(DEFAULT_PROGRAM_NAME, index, index); + } + + void remove(size_t from, size_t to) { + remove(DEFAULT_PROGRAM_NAME, from, to); + } + + void remove(RefTokenWithIndex indexT) { + remove(DEFAULT_PROGRAM_NAME, indexT, indexT); + } + + void remove(RefTokenWithIndex from, RefTokenWithIndex to) { + remove(DEFAULT_PROGRAM_NAME, from, to); + } + + void remove( const ANTLR_USE_NAMESPACE(std)string& programName, + size_t from, size_t to) + { + replace(programName,from,to,""); + } + + void remove( const ANTLR_USE_NAMESPACE(std)string& programName, + RefTokenWithIndex from, RefTokenWithIndex to ) + { + replace(programName,from,to,""); + } + + void discard(int ttype) { + discardMask.add(ttype); + } + + RefToken getToken( size_t i ) + { + return RefToken(tokens.at(i)); + } + + size_t getTokenStreamSize() const { + return tokens.size(); + } + + void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { + ANTLR_USE_NAMESPACE(std)for_each( tokens.begin(), tokens.end(), tokenToStream(out) ); + } + + void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out, + size_t start, size_t end ) const; + + void toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { + toStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); + } + + void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, + const ANTLR_USE_NAMESPACE(std)string& programName ) const + { + toStream( out, programName, MIN_TOKEN_INDEX, getTokenStreamSize()); + } + + void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, + size_t start, size_t end ) const + { + toStream(out, DEFAULT_PROGRAM_NAME, start, end); + } + + void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, + const ANTLR_USE_NAMESPACE(std)string& programName, + size_t firstToken, size_t lastToken ) const; + + void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { + toDebugStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); + } + + void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out, + size_t start, size_t end ) const; + + size_t getLastRewriteTokenIndex() const { + return getLastRewriteTokenIndex(DEFAULT_PROGRAM_NAME); + } + + /** Return the last index for the program named programName + * return 0 if the program does not exist or the program is empty. + * (Note this is different from the java implementation that returns -1) + */ + size_t getLastRewriteTokenIndex(const ANTLR_USE_NAMESPACE(std)string& programName) const { + program_map::const_iterator rewrites = programs.find(programName); + + if( rewrites == programs.end() ) + return 0; + + const operation_list& prog = rewrites->second; + if( !prog.empty() ) + { + operation_list::const_iterator last = prog.end(); + --last; + return (*last)->getIndex(); + } + return 0; + } + +protected: + /** If op.index > lastRewriteTokenIndexes, just add to the end. + * Otherwise, do linear */ + void addToSortedRewriteList(RewriteOperation* op) { + addToSortedRewriteList(DEFAULT_PROGRAM_NAME, op); + } + + void addToSortedRewriteList( const ANTLR_USE_NAMESPACE(std)string& programName, + RewriteOperation* op ); + +protected: + /** Who do we suck tokens from? */ + TokenStream& stream; + /** track index of tokens */ + size_t index; + + /** Track the incoming list of tokens */ + token_list tokens; + + /** You may have multiple, named streams of rewrite operations. + * I'm calling these things "programs." + * Maps String (name) -> rewrite (List) + */ + program_map programs; + + /** Which (whitespace) token(s) to throw out */ + BitSet discardMask; +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif diff --git a/lib/antlr/antlr/TokenStreamSelector.hpp b/lib/antlr/antlr/TokenStreamSelector.hpp new file mode 100644 index 00000000..1dab8797 --- /dev/null +++ b/lib/antlr/antlr/TokenStreamSelector.hpp @@ -0,0 +1,87 @@ +#ifndef INC_TokenStreamSelector_hpp__ +#define INC_TokenStreamSelector_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/TokenStream.hpp> +#include <map> +#include <stack> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** A token stream MUX (multiplexor) knows about n token streams + * and can multiplex them onto the same channel for use by token + * stream consumer like a parser. This is a way to have multiple + * lexers break up the same input stream for a single parser. + * Or, you can have multiple instances of the same lexer handle + * multiple input streams; this works great for includes. + */ +class ANTLR_API TokenStreamSelector : public TokenStream { +protected: + /** The set of inputs to the MUX */ +#ifdef OS_NO_ALLOCATOR + typedef ANTLR_USE_NAMESPACE(std)less<ANTLR_USE_NAMESPACE(std)string> lessp; + typedef ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,TokenStream*,lessp> inputStreamNames_coll; +#else + typedef ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,TokenStream*> inputStreamNames_coll; +#endif + inputStreamNames_coll inputStreamNames; + + /** The currently-selected token stream input */ + TokenStream* input; + + /** Used to track stack of input streams */ +#ifdef OS_NO_ALLOCATOR + typedef ANTLR_USE_NAMESPACE(std)stack<TokenStream*, ANTLR_USE_NAMESPACE(std)deque<TokenStream*> > streamStack_coll; +#else + typedef ANTLR_USE_NAMESPACE(std)stack<TokenStream*> streamStack_coll; +#endif + streamStack_coll streamStack; + +public: + TokenStreamSelector(); + ~TokenStreamSelector(); + + void addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key); + + /// Return the stream from which tokens are being pulled at the moment. + TokenStream* getCurrentStream() const; + + TokenStream* getStream(const ANTLR_USE_NAMESPACE(std)string& sname) const; + + RefToken nextToken(); + + TokenStream* pop(); + + void push(TokenStream* stream); + + void push(const ANTLR_USE_NAMESPACE(std)string& sname); + + /** Abort recognition of current Token and try again. + * A stream can push a new stream (for include files + * for example, and then retry(), which will cause + * the current stream to abort back to this.nextToken(). + * this.nextToken() then asks for a token from the + * current stream, which is the new "substream." + */ + void retry(); + + /** Set the stream without pushing old stream */ + void select(TokenStream* stream); + + void select(const ANTLR_USE_NAMESPACE(std)string& sname); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TokenStreamSelector_hpp__ diff --git a/lib/antlr/antlr/TokenWithIndex.hpp b/lib/antlr/antlr/TokenWithIndex.hpp new file mode 100644 index 00000000..e4a3e37e --- /dev/null +++ b/lib/antlr/antlr/TokenWithIndex.hpp @@ -0,0 +1,84 @@ +#ifndef INC_TokenWithIndex_hpp__ +#define INC_TokenWithIndex_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id:$ + */ + +#include <antlr/config.hpp> +#include <antlr/CommonToken.hpp> +#include <antlr/String.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API TokenWithIndex : public ANTLR_USE_NAMESPACE(antlr)CommonToken { +public: + // static size_t count; + TokenWithIndex() : CommonToken(), index(0) + { + // std::cout << __PRETTY_FUNCTION__ << std::endl; + // count++; + } + TokenWithIndex(int t, const ANTLR_USE_NAMESPACE(std)string& txt) + : CommonToken(t,txt) + , index(0) + { + // std::cout << __PRETTY_FUNCTION__ << std::endl; + // count++; + } + TokenWithIndex(const ANTLR_USE_NAMESPACE(std)string& s) + : CommonToken(s) + , index(0) + { + // std::cout << __PRETTY_FUNCTION__ << std::endl; + // count++; + } + ~TokenWithIndex() + { + // count--; + } + void setIndex( size_t idx ) + { + index = idx; + } + size_t getIndex( void ) const + { + return index; + } + + ANTLR_USE_NAMESPACE(std)string toString() const + { + return ANTLR_USE_NAMESPACE(std)string("[")+ + index+ + ":\""+ + getText()+"\",<"+ + getType()+">,line="+ + getLine()+",column="+ + getColumn()+"]"; + } + + static RefToken factory() + { + return RefToken(new TokenWithIndex()); + } + +protected: + size_t index; + +private: + TokenWithIndex(const TokenWithIndex&); + const TokenWithIndex& operator=(const TokenWithIndex&); +}; + +typedef TokenRefCount<TokenWithIndex> RefTokenWithIndex; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_CommonToken_hpp__ diff --git a/lib/antlr/antlr/TreeParser.hpp b/lib/antlr/antlr/TreeParser.hpp new file mode 100644 index 00000000..aeee3f9d --- /dev/null +++ b/lib/antlr/antlr/TreeParser.hpp @@ -0,0 +1,155 @@ +#ifndef INC_TreeParser_hpp__ +#define INC_TreeParser_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/AST.hpp> +#include <antlr/ASTFactory.hpp> +#include <antlr/BitSet.hpp> +#include <antlr/RecognitionException.hpp> +#include <antlr/MismatchedTokenException.hpp> +#include <antlr/TreeParserSharedInputState.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +class ANTLR_API TreeParser { +public: + TreeParser() + : astFactory(0) + , inputState(new TreeParserInputState()) + , traceDepth(0) + { + } + + TreeParser(const TreeParserSharedInputState& state) + : astFactory(0) + , inputState(state) + , traceDepth(0) + { + } + + virtual ~TreeParser() + { + } + + /// Get the AST return value squirreled away in the parser + virtual RefAST getAST() = 0; + + /** Make sure current lookahead symbol matches the given set + * Throw an exception upon mismatch, which is caught by either the + * error handler or by a syntactic predicate. + */ + virtual void match(RefAST t, const BitSet& b) + { + if ( !t || t==ASTNULL || !b.member(t->getType()) ) + throw MismatchedTokenException( getTokenNames(), getNumTokens(), + t, b, false ); + } + + /** Specify the AST factory to be used during tree building. (Compulsory) + * Setting the factory is compulsory (if you intend to modify + * the tree in the treeparser). The AST Factory is shared between + * parser (who builds the initial AST) and treeparser. + * @see Parser::getASTFactory() + */ + virtual void setASTFactory(ASTFactory* factory) + { + astFactory = factory; + } + /// Return pointer to ASTFactory + virtual ASTFactory* getASTFactory() const + { + return astFactory; + } + /// Get the name for token 'num' + virtual const char* getTokenName(int num) const = 0; + /// Return the number of tokens defined + virtual int getNumTokens() const = 0; + /// Return an array of getNumTokens() token names + virtual const char* const* getTokenNames() const = 0; + + /// Parser error-reporting function can be overridden in subclass + virtual void reportError(const RecognitionException& ex); + /// Parser error-reporting function can be overridden in subclass + virtual void reportError(const ANTLR_USE_NAMESPACE(std)string& s); + /// Parser warning-reporting function can be overridden in subclass + virtual void reportWarning(const ANTLR_USE_NAMESPACE(std)string& s); + + /// These are used during when traceTreeParser commandline option is passed. + virtual void traceIndent(); + virtual void traceIn(const char* rname, RefAST t); + virtual void traceOut(const char* rname, RefAST t); + + /** The AST Null object; the parsing cursor is set to this when + * it is found to be null. This way, we can test the + * token type of a node without having to have tests for 0 + * everywhere. + */ + static RefAST ASTNULL; + +protected: + virtual void match(RefAST t, int ttype) + { + if (!t || t == ASTNULL || t->getType() != ttype ) + throw MismatchedTokenException( getTokenNames(), getNumTokens(), + t, ttype, false ); + } + + virtual void matchNot(RefAST t, int ttype) + { + if ( !t || t == ASTNULL || t->getType() == ttype ) + throw MismatchedTokenException( getTokenNames(), getNumTokens(), + t, ttype, true ); + } + + /** AST support code; parser and treeparser delegate to this object */ + ASTFactory* astFactory; + + /// The input state of this tree parser. + TreeParserSharedInputState inputState; + + /** Used to keep track of indent depth with -traceTreeParser */ + int traceDepth; + + /** Utility class which allows tracing to work even when exceptions are + * thrown. + */ + class Tracer { + private: + TreeParser* parser; + const char* text; + RefAST tree; + public: + Tracer(TreeParser* p, const char* t, RefAST a) + : parser(p), text(t), tree(a) + { + parser->traceIn(text,tree); + } + ~Tracer() + { + parser->traceOut(text,tree); + } + private: + Tracer(const Tracer&); // undefined + const Tracer& operator=(const Tracer&); // undefined + }; + +private: + // no copying of treeparser instantiations... + TreeParser(const TreeParser& other); + TreeParser& operator=(const TreeParser& other); +}; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TreeParser_hpp__ diff --git a/lib/antlr/antlr/TreeParserSharedInputState.hpp b/lib/antlr/antlr/TreeParserSharedInputState.hpp new file mode 100644 index 00000000..76ec6840 --- /dev/null +++ b/lib/antlr/antlr/TreeParserSharedInputState.hpp @@ -0,0 +1,45 @@ +#ifndef INC_TreeParserSharedInputState_hpp__ +#define INC_TreeParserSharedInputState_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/RefCount.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** This object contains the data associated with an + * input AST. Multiple parsers + * share a single TreeParserSharedInputState to parse + * the same tree or to have the parser walk multiple + * trees. + */ +class ANTLR_API TreeParserInputState { +public: + TreeParserInputState() : guessing(0) {} + virtual ~TreeParserInputState() {} + +public: + /** Are we guessing (guessing>0)? */ + int guessing; //= 0; + +private: + // we don't want these: + TreeParserInputState(const TreeParserInputState&); + TreeParserInputState& operator=(const TreeParserInputState&); +}; + +typedef RefCount<TreeParserInputState> TreeParserSharedInputState; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +#endif //INC_TreeParserSharedInputState_hpp__ diff --git a/lib/antlr/antlr/config.hpp b/lib/antlr/antlr/config.hpp new file mode 100644 index 00000000..db8fb28a --- /dev/null +++ b/lib/antlr/antlr/config.hpp @@ -0,0 +1,290 @@ +#ifndef INC_config_hpp__ +#define INC_config_hpp__ + +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +/* + * Just a simple configuration file to differentiate between the + * various compilers used and reconfigure stuff for any oddities of the + * compiler in question. + * + * These are the defaults. Per compiler these are amended. + */ +#define ANTLR_USE_NAMESPACE(_x_) _x_:: +#define ANTLR_USING_NAMESPACE(_x_) using namespace _x_; +#define ANTLR_CXX_SUPPORTS_NAMESPACE 1 +#define ANTLR_C_USING(_x_) +#define ANTLR_API +#ifndef CUSTOM_API +# define CUSTOM_API +#endif +#define ANTLR_IOS_BASE ios_base +/** define if cctype functions/macros need a std:: prefix. A lot of compilers + * define these as macros, in which case something barfs. + */ +#define ANTLR_CCTYPE_NEEDS_STD + +/// Define if C++ compiler supports std::uncaught_exception +#define ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION + +#define ANTLR_ATOI_IN_STD + +/******************************************************************************/ +/*{{{ Microsoft Visual C++ */ +// NOTE: If you provide patches for a specific MSVC version guard them for +// the specific version!!!! +// _MSC_VER == 1100 for Microsoft Visual C++ 5.0 +// _MSC_VER == 1200 for Microsoft Visual C++ 6.0 +// _MSC_VER == 1300 for Microsoft Visual C++ 7.0 +#if defined(_MSC_VER) + +# if _MSC_VER < 1300 +# define NOMINMAX +# pragma warning(disable : 4786) +# define min _cpp_min +# endif + +// This warning really gets on my nerves. +// It's the one about symbol longer than 256 chars, and it happens +// all the time with STL. +# pragma warning( disable : 4786 4231 ) +// this shuts up some DLL interface warnings for STL +# pragma warning( disable : 4251 ) + +# ifdef ANTLR_CXX_USE_STLPORT +# undef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION +# endif + +# if ( _MSC_VER < 1300 ) && ( defined(ANTLR_EXPORTS) || defined(ANTLR_IMPORTS) ) +# error "DLL Build not supported on these MSVC versions." +// see comment in lib/cpp/src/dll.cpp +# endif + +// For the DLL support originally contributed by Stephen Naughton +// If you are building statically leave ANTLR_EXPORTS/ANTLR_IMPORTS undefined +// If you are building the DLL define ANTLR_EXPORTS +// If you are compiling code to be used with the DLL define ANTLR_IMPORTS +# ifdef ANTLR_EXPORTS +# undef ANTLR_API +# define ANTLR_API __declspec(dllexport) +# endif + +# ifdef ANTLR_IMPORTS +# undef ANTLR_API +# define ANTLR_API __declspec(dllimport) +# endif + +# if ( _MSC_VER < 1200 ) +// supposedly only for MSVC5 and before... +// Using vector<XXX> requires operator<(X,X) to be defined +# define NEEDS_OPERATOR_LESS_THAN +# endif + +// VC6 +# if ( _MSC_VER == 1200 ) +# undef ANTLR_ATOI_IN_STD +# endif + +# if ( _MSC_VER < 1310 ) +// Supposedly only for MSVC7 and before... +// Not allowed to put 'static const int XXX=20;' in a class definition +# define NO_STATIC_CONSTS +# define NO_TEMPLATE_PARTS +# endif + +// No strcasecmp in the C library (so use stricmp instead) +// - Anyone know which is in which standard? +# define NO_STRCASECMP +# undef ANTLR_CCTYPE_NEEDS_STD +# define NO_STATIC_CONSTS +#endif // End of Microsoft Visual C++ + +/*}}}*/ +/******************************************************************************/ +/*{{{ SunPro Compiler (Using OBJECTSPACE STL) + *****************************************************************************/ +#ifdef __SUNPRO_CC + +# if (__SUNPRO_CC >= 0x500) + +# define NEEDS_OPERATOR_LESS_THAN +# define NO_TEMPLATE_PARTS + +# else + +# undef namespace +# define namespace + +# if (__SUNPRO_CC == 0x420) + +/* This code is specif to SunWspro Compiler 4.2, and will compile with + the objectspace 2.1 toolkit for Solaris2.6 */ +# define HAS_NOT_CASSERT_H +# define HAS_NOT_CSTRING_H +# define HAS_NOT_CCTYPE_H +# define HAS_NOT_CSTDIO_H +# define HAS_OSTREAM_H + +/* #define OS_SOLARIS_2_6 + #define OS_NO_WSTRING + #define OS_NO_ALLOCATORS + #define OS_MULTI_THREADED + #define OS_SOLARIS_NATIVE + #define OS_REALTIME + #define __OSVERSION__=5 + #define SVR4 + */ + +// ObjectSpace + some specific templates constructions with stl. +/* #define OS_NO_ALLOCATOR */ + +// This great compiler does not have the namespace feature. +# undef ANTLR_USE_NAMESPACE +# define ANTLR_USE_NAMESPACE(_x_) +# undef ANTLR_USING_NAMESPACE +# define ANTLR_USING_NAMESPACE(_x_) +# undef ANTLR_CXX_SUPPORTS_NAMESPACE +# endif // End __SUNPRO_CC == 0x420 + +# undef explicit +# define explicit + +# define exception os_exception +# define bad_exception os_bad_exception + +// Not allowed to put 'static const int XXX=20;' in a class definition +# define NO_STATIC_CONSTS +// Using vector<XXX> requires operator<(X,X) to be defined +# define NEEDS_OPERATOR_LESS_THAN + +# endif + +# undef ANTLR_CCTYPE_NEEDS_STD + +#endif // end __SUNPRO_CC +/*}}}*/ +/*****************************************************************************/ +/*{{{ Inprise C++ Builder 3.0 + *****************************************************************************/ +#ifdef __BCPLUSPLUS__ +# define NO_TEMPLATE_PARTS +# define NO_STRCASECMP +# undef ANTLR_CCTYPE_NEEDS_STD +#endif // End of C++ Builder 3.0 +/*}}}*/ +/*****************************************************************************/ +/*{{{ IBM VisualAge C++ ( which includes the Dinkumware C++ Library ) + *****************************************************************************/ +#ifdef __IBMCPP__ + +// No strcasecmp in the C library (so use stricmp instead) +// - Anyone know which is in which standard? +#if (defined(_AIX) && (__IBMCPP__ >= 600)) +# define NO_STATIC_CONSTS +#else +# define NO_STRCASECMP +# undef ANTLR_CCTYPE_NEEDS_STD +#endif + +#endif // end IBM VisualAge C++ +/*}}}*/ +/*****************************************************************************/ +/*{{{ Metrowerks Codewarrior + *****************************************************************************/ +#ifdef __MWERKS__ +# if (__MWERKS__ <= 0x2201) +# define NO_TEMPLATE_PARTS +# endif + +// CW 6.0 and 7.0 still do not have it. +# define ANTLR_REALLY_NO_STRCASECMP + +# undef ANTLR_C_USING +# define ANTLR_C_USING(_x_) using std:: ## _x_; + +# define ANTLR_CCTYPE_NEEDS_STD +# undef ANTLR_CXX_SUPPORTS_UNCAUGHT_EXCEPTION + +#endif // End of Metrowerks Codewarrior +/*}}}*/ +/*****************************************************************************/ +/*{{{ SGI Irix 6.5.10 MIPSPro compiler + *****************************************************************************/ +// (contributed by Anna Winkler) +// Note: you can't compile ANTLR with the MIPSPro compiler on +// anything < 6.5.10 because SGI just fixed a big bug dealing with +// namespaces in that release. +#ifdef __sgi +# define HAS_NOT_CCTYPE_H +# define HAS_NOT_CSTRING_H +# define HAS_NOT_CSTDIO_H +# undef ANTLR_CCTYPE_NEEDS_STD +#endif // End IRIX MIPSPro +/*}}}*/ +/*****************************************************************************/ +/*{{{ G++ in various incarnations + *****************************************************************************/ +// With the gcc-2.95 and 3.0 being in the near future we should start handling +// incompatabilities between the various libstdc++'s. +#if defined(__GNUC__) || defined(__GNUG__) +// gcc 2 branch.. +# if (__GNUC__ == 2 ) +# if (__GNUC_MINOR__ <= 8 ) +# undef ANTLR_USE_NAMESPACE +# define ANTLR_USE_NAMESPACE(_x_) +# undef ANTLR_USING_NAMESPACE +# define ANTLR_USING_NAMESPACE(_x_) +# undef ANTLR_CXX_SUPPORTS_NAMESPACE +# endif +# if (__GNUC_MINOR__ > 8 && __GNUC_MINOR__ <= 95 ) +# undef ANTLR_IOS_BASE +# define ANTLR_IOS_BASE ios +# undef ANTLR_CCTYPE_NEEDS_STD +// compiling with -ansi ? +# ifdef __STRICT_ANSI__ +# undef ANTLR_REALLY_NO_STRCASECMP +# define ANTLR_REALLY_NO_STRCASECMP +# endif +# else +// experimental .96 .97 branches.. +# undef ANTLR_CCTYPE_NEEDS_STD +# endif +# endif +#endif // ! __GNUC__ +/*}}}*/ +/*****************************************************************************/ +/*{{{ Digital CXX (Tru64) + *****************************************************************************/ +#ifdef __DECCXX +#define __USE_STD_IOSTREAM +#endif +/*}}}*/ +/*****************************************************************************/ +#ifdef __BORLANDC__ +# if __BORLANDC__ >= 560 +# include <ctype> +# include <stdlib> +# define ANTLR_CCTYPE_NEEDS_STD +# else +# error "sorry, compiler is too old - consider an update." +# endif +#endif + +// Redefine these for backwards compatability.. +#undef ANTLR_BEGIN_NAMESPACE +#undef ANTLR_END_NAMESPACE + +#if ANTLR_CXX_SUPPORTS_NAMESPACE == 1 +# define ANTLR_BEGIN_NAMESPACE(_x_) namespace _x_ { +# define ANTLR_END_NAMESPACE } +#else +# define ANTLR_BEGIN_NAMESPACE(_x_) +# define ANTLR_END_NAMESPACE +#endif + +#endif //INC_config_hpp__ diff --git a/lib/antlr/src/ANTLRUtil.cpp b/lib/antlr/src/ANTLRUtil.cpp new file mode 100644 index 00000000..30e7ba21 --- /dev/null +++ b/lib/antlr/src/ANTLRUtil.cpp @@ -0,0 +1,163 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <antlr/config.hpp> +#include <antlr/IOException.hpp> + +#include <iostream> +#include <cctype> +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** Eat whitespace from the input stream + * @param is the stream to read from + */ +ANTLR_USE_NAMESPACE(std)istream& eatwhite( ANTLR_USE_NAMESPACE(std)istream& is ) +{ + char c; + while( is.get(c) ) + { +#ifdef ANTLR_CCTYPE_NEEDS_STD + if( !ANTLR_USE_NAMESPACE(std)isspace(c) ) +#else + if( !isspace(c) ) +#endif + { + is.putback(c); + break; + } + } + return is; +} + +/** Read a string enclosed by '"' from a stream. Also handles escaping of \". + * Skips leading whitespace. + * @param in the istream to read from. + * @returns the string read from file exclusive the '"' + * @throws IOException if string is badly formatted + */ +ANTLR_USE_NAMESPACE(std)string read_string( ANTLR_USE_NAMESPACE(std)istream& in ) +{ + char ch; + ANTLR_USE_NAMESPACE(std)string ret(""); + // States for a simple state machine... + enum { START, READING, ESCAPE, FINISHED }; + int state = START; + + eatwhite(in); + + while( state != FINISHED && in.get(ch) ) + { + switch( state ) + { + case START: + // start state: check wether starting with " then switch to READING + if( ch != '"' ) + throw IOException("string must start with '\"'"); + state = READING; + continue; + case READING: + // reading state: look out for escape sequences and closing " + if( ch == '\\' ) // got escape sequence + { + state = ESCAPE; + continue; + } + if( ch == '"' ) // close quote -> stop + { + state = FINISHED; + continue; + } + ret += ch; // else append... + continue; + case ESCAPE: + switch(ch) + { + case '\\': + ret += ch; + state = READING; + continue; + case '"': + ret += ch; + state = READING; + continue; + case '0': + ret += '\0'; + state = READING; + continue; + default: // unrecognized escape is not mapped + ret += '\\'; + ret += ch; + state = READING; + continue; + } + } + } + if( state != FINISHED ) + throw IOException("badly formatted string: "+ret); + + return ret; +} + +/* Read a ([A-Z][0-9][a-z]_)* kindoff thing. Skips leading whitespace. + * @param in the istream to read from. + */ +ANTLR_USE_NAMESPACE(std)string read_identifier( ANTLR_USE_NAMESPACE(std)istream& in ) +{ + char ch; + ANTLR_USE_NAMESPACE(std)string ret(""); + + eatwhite(in); + + while( in.get(ch) ) + { +#ifdef ANTLR_CCTYPE_NEEDS_STD + if( ANTLR_USE_NAMESPACE(std)isupper(ch) || + ANTLR_USE_NAMESPACE(std)islower(ch) || + ANTLR_USE_NAMESPACE(std)isdigit(ch) || + ch == '_' ) +#else + if( isupper(ch) || islower(ch) || isdigit(ch) || ch == '_' ) +#endif + ret += ch; + else + { + in.putback(ch); + break; + } + } + return ret; +} + +/** Read a attribute="value" thing. Leading whitespace is skipped. + * Between attribute and '=' no whitespace is allowed. After the '=' it is + * permitted. + * @param in the istream to read from. + * @param attribute string the attribute name is put in + * @param value string the value of the attribute is put in + * @throws IOException if something is fishy. E.g. malformed quoting + * or missing '=' + */ +void read_AttributeNValue( ANTLR_USE_NAMESPACE(std)istream& in, + ANTLR_USE_NAMESPACE(std)string& attribute, + ANTLR_USE_NAMESPACE(std)string& value ) +{ + attribute = read_identifier(in); + + char ch; + if( in.get(ch) && ch == '=' ) + value = read_string(in); + else + throw IOException("invalid attribute=value thing "+attribute); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/ASTFactory.cpp b/lib/antlr/src/ASTFactory.cpp new file mode 100644 index 00000000..98ce6b7a --- /dev/null +++ b/lib/antlr/src/ASTFactory.cpp @@ -0,0 +1,504 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/CommonAST.hpp" +#include "antlr/ANTLRException.hpp" +#include "antlr/IOException.hpp" +#include "antlr/ASTFactory.hpp" +#include "antlr/ANTLRUtil.hpp" + +#include <iostream> +#include <istream> + +using namespace std; + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** AST Support code shared by TreeParser and Parser. + * We use delegation to share code (and have only one + * bit of code to maintain) rather than subclassing + * or superclassing (forces AST support code to be + * loaded even when you don't want to do AST stuff). + * + * This class collects all factories of AST types used inside the code. + * New AST node types are registered with the registerFactory method. + * On creation of an ASTFactory object a default AST node factory may be + * specified. + * + * When registering types gaps between different types are filled with entries + * for the default factory. + */ + +/// Initialize factory +ASTFactory::ASTFactory() +: default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(CommonAST::TYPE_NAME,&CommonAST::factory)) +{ + nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor ); +} + +/** Initialize factory with a non default node type. + * factory_node_name should be the name of the AST node type the factory + * generates. (should exist during the existance of this ASTFactory instance) + */ +ASTFactory::ASTFactory( const char* factory_node_name, factory_type fact ) +: default_factory_descriptor(ANTLR_USE_NAMESPACE(std)make_pair(factory_node_name, fact)) +{ + nodeFactories.resize( Token::MIN_USER_TYPE, &default_factory_descriptor ); +} + +/// Delete ASTFactory +ASTFactory::~ASTFactory() +{ + factory_descriptor_list::iterator i = nodeFactories.begin(); + + while( i != nodeFactories.end() ) + { + if( *i != &default_factory_descriptor ) + delete *i; + i++; + } +} + +/// Register a factory for a given AST type +void ASTFactory::registerFactory( int type, const char* ast_name, factory_type factory ) +{ + // check validity of arguments... + if( type < Token::MIN_USER_TYPE ) + throw ANTLRException("Internal parser error invalid type passed to RegisterFactory"); + if( factory == 0 ) + throw ANTLRException("Internal parser error 0 factory passed to RegisterFactory"); + + // resize up to and including 'type' and initalize any gaps to default + // factory. + if( nodeFactories.size() < (static_cast<unsigned int>(type)+1) ) + nodeFactories.resize( type+1, &default_factory_descriptor ); + + // And add new thing.. + nodeFactories[type] = new ANTLR_USE_NAMESPACE(std)pair<const char*, factory_type>( ast_name, factory ); +} + +void ASTFactory::setMaxNodeType( int type ) +{ + if( nodeFactories.size() < (static_cast<unsigned int>(type)+1) ) + nodeFactories.resize( type+1, &default_factory_descriptor ); +} + +/** Create a new empty AST node; if the user did not specify + * an AST node type, then create a default one: CommonAST. + */ +RefAST ASTFactory::create() +{ + RefAST node = nodeFactories[0]->second(); + node->setType(Token::INVALID_TYPE); + return node; +} + +RefAST ASTFactory::create(int type) +{ + RefAST t = nodeFactories[type]->second(); + t->initialize(type,""); + return t; +} + +RefAST ASTFactory::create(int type, const ANTLR_USE_NAMESPACE(std)string& txt) +{ + RefAST t = nodeFactories[type]->second(); + t->initialize(type,txt); + return t; +} + +#ifdef ANTLR_SUPPORT_XML +RefAST ASTFactory::create(const ANTLR_USE_NAMESPACE(std)string& type_name, ANTLR_USE_NAMESPACE(std)istream& infile ) +{ + factory_descriptor_list::iterator fact = nodeFactories.begin(); + + while( fact != nodeFactories.end() ) + { + if( type_name == (*fact)->first ) + { + RefAST t = (*fact)->second(); + t->initialize(infile); + return t; + } + fact++; + } + + string error = "ASTFactory::create: Unknown AST type '" + type_name + "'"; + throw ANTLRException(error); +} +#endif + +/** Create a new empty AST node; if the user did not specify + * an AST node type, then create a default one: CommonAST. + */ +RefAST ASTFactory::create(RefAST tr) +{ + if (!tr) + return nullAST; + +// cout << "create(tr)" << endl; + + RefAST t = nodeFactories[tr->getType()]->second(); + t->initialize(tr); + return t; +} + +RefAST ASTFactory::create(RefToken tok) +{ +// cout << "create( tok="<< tok->getType() << ", " << tok->getText() << ")" << nodeFactories.size() << endl; + RefAST t = nodeFactories[tok->getType()]->second(); + t->initialize(tok); + return t; +} + +/** Add a child to the current AST */ +void ASTFactory::addASTChild(ASTPair& currentAST, RefAST child) +{ + if (child) + { + if (!currentAST.root) + { + // Make new child the current root + currentAST.root = child; + } + else + { + if (!currentAST.child) + { + // Add new child to current root + currentAST.root->setFirstChild(child); + } + else + { + currentAST.child->setNextSibling(child); + } + } + // Make new child the current child + currentAST.child = child; + currentAST.advanceChildToEnd(); + } +} + +/** Deep copy a single node. This function the new clone() methods in the AST + * interface. Returns nullAST if t is null. + */ +RefAST ASTFactory::dup(RefAST t) +{ + if( t ) + return t->clone(); + else + return RefAST(nullASTptr); +} + +/** Duplicate tree including siblings of root. */ +RefAST ASTFactory::dupList(RefAST t) +{ + RefAST result = dupTree(t); // if t == null, then result==null + RefAST nt = result; + + while( t ) + { // for each sibling of the root + t = t->getNextSibling(); + nt->setNextSibling(dupTree(t)); // dup each subtree, building new tree + nt = nt->getNextSibling(); + } + return result; +} + +/** Duplicate a tree, assuming this is a root node of a tree + * duplicate that node and what's below; ignore siblings of root node. + */ +RefAST ASTFactory::dupTree(RefAST t) +{ + RefAST result = dup(t); // make copy of root + // copy all children of root. + if( t ) + result->setFirstChild( dupList(t->getFirstChild()) ); + return result; +} + +/** Make a tree from a list of nodes. The first element in the + * array is the root. If the root is null, then the tree is + * a simple list not a tree. Handles null children nodes correctly. + * For example, make(a, b, null, c) yields tree (a b c). make(null,a,b) + * yields tree (nil a b). + */ +RefAST ASTFactory::make(ANTLR_USE_NAMESPACE(std)vector<RefAST>& nodes) +{ + if ( nodes.size() == 0 ) + return RefAST(nullASTptr); + + RefAST root = nodes[0]; + RefAST tail = RefAST(nullASTptr); + + if( root ) + root->setFirstChild(RefAST(nullASTptr)); // don't leave any old pointers set + + // link in children; + for( unsigned int i = 1; i < nodes.size(); i++ ) + { + if ( nodes[i] == 0 ) // ignore null nodes + continue; + + if ( root == 0 ) // Set the root and set it up for a flat list + root = tail = nodes[i]; + else if ( tail == 0 ) + { + root->setFirstChild(nodes[i]); + tail = root->getFirstChild(); + } + else + { + tail->setNextSibling(nodes[i]); + tail = tail->getNextSibling(); + } + + if( tail ) // RK: I cannot fathom why this missing check didn't bite anyone else... + { + // Chase tail to last sibling + while (tail->getNextSibling()) + tail = tail->getNextSibling(); + } + } + + return root; +} + +/** Make a tree from a list of nodes, where the nodes are contained + * in an ASTArray object + */ +RefAST ASTFactory::make(ASTArray* nodes) +{ + RefAST ret = make(nodes->array); + delete nodes; + return ret; +} + +/// Make an AST the root of current AST +void ASTFactory::makeASTRoot( ASTPair& currentAST, RefAST root ) +{ + if (root) + { + // Add the current root as a child of new root + root->addChild(currentAST.root); + // The new current child is the last sibling of the old root + currentAST.child = currentAST.root; + currentAST.advanceChildToEnd(); + // Set the new root + currentAST.root = root; + } +} + +void ASTFactory::setASTNodeFactory( const char* factory_node_name, + factory_type factory ) +{ + default_factory_descriptor.first = factory_node_name; + default_factory_descriptor.second = factory; +} + +#ifdef ANTLR_SUPPORT_XML +bool ASTFactory::checkCloseTag( ANTLR_USE_NAMESPACE(std)istream& in ) +{ + char ch; + + if( in.get(ch) ) + { + if( ch == '<' ) + { + char ch2; + if( in.get(ch2) ) + { + if( ch2 == '/' ) + { + in.putback(ch2); + in.putback(ch); + return true; + } + in.putback(ch2); + in.putback(ch); + return false; + } + } + in.putback(ch); + return false; + } + return false; +} + +void ASTFactory::loadChildren( ANTLR_USE_NAMESPACE(std)istream& infile, + RefAST current ) +{ + char ch; + + for(;;) // for all children of this node.... + { + eatwhite(infile); + + infile.get(ch); // '<' + if( ch != '<' ) + { + string error = "Invalid XML file... no '<' found ("; + error += ch + ")"; + throw IOException(error); + } + + infile.get(ch); // / or text.... + + if( ch == '/' ) // check for close tag... + { + string temp; + + // read until '>' and see if it matches the open tag... if not trouble + temp = read_identifier( infile ); + + if( strcmp(temp.c_str(), current->typeName() ) != 0 ) + { + string error = "Invalid XML file... close tag does not match start tag: "; + error += current->typeName(); + error += " closed by " + temp; + throw IOException(error); + } + + infile.get(ch); // must be a '>' + + if( ch != '>' ) + { + string error = "Invalid XML file... no '>' found ("; + error += ch + ")"; + throw IOException(error); + } + // close tag => exit loop + break; + } + + // put our 'look ahead' back where it came from + infile.putback(ch); + infile.putback('<'); + + // and recurse into the tree... + RefAST child = LoadAST(infile); + + current->addChild( child ); + } +} + +void ASTFactory::loadSiblings(ANTLR_USE_NAMESPACE(std)istream& infile, + RefAST current ) +{ + for(;;) + { + eatwhite(infile); + + if( infile.eof() ) + break; + + if( checkCloseTag(infile) ) + break; + + RefAST sibling = LoadAST(infile); + current->setNextSibling(sibling); + } +} + +RefAST ASTFactory::LoadAST( ANTLR_USE_NAMESPACE(std)istream& infile ) +{ + RefAST current = nullAST; + char ch; + + eatwhite(infile); + + if( !infile.get(ch) ) + return nullAST; + + if( ch != '<' ) + { + string error = "Invalid XML file... no '<' found ("; + error += ch + ")"; + throw IOException(error); + } + + string ast_type = read_identifier(infile); + + // create the ast of type 'ast_type' + current = create( ast_type, infile ); + if( current == nullAST ) + { + string error = "Unsuported AST type: " + ast_type; + throw IOException(error); + } + + eatwhite(infile); + + infile.get(ch); + + // now if we have a '/' here it's a single node. If it's a '>' we get + // a tree with children + + if( ch == '/' ) + { + infile.get(ch); // get the closing '>' + if( ch != '>' ) + { + string error = "Invalid XML file... no '>' found after '/' ("; + error += ch + ")"; + throw IOException(error); + } + + // get the rest on this level + loadSiblings( infile, current ); + + return current; + } + + // and finaly see if we got the close tag... + if( ch != '>' ) + { + string error = "Invalid XML file... no '>' found ("; + error += ch + ")"; + throw IOException(error); + } + + // handle the ones below this level.. + loadChildren( infile, current ); + + // load the rest on this level... + loadSiblings( infile, current ); + + return current; +} +#endif // ANTLR_SUPPORT_XML + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + +/* Heterogeneous AST/XML-I/O ramblings... + * + * So there is some heterogeneous AST support.... + * basically in the code generators a new custom ast is generated without + * going throug the factory. It also expects the RefXAST to be defined. + * + * Is it maybe better to register all AST types with the ASTFactory class + * together with the respective factory methods. + * + * More and more I get the impression that hetero ast was a kindoff hack + * on top of ANTLR's normal AST system. + * + * The heteroast stuff will generate trouble for all astFactory.create( ... ) + * invocations. Most of this is handled via getASTCreateString methods in the + * codegenerator. At the moment getASTCreateString(GrammarAtom, String) has + * slightly to little info to do it's job (ok the hack that is in now + * works, but it's an ugly hack) + * + * An extra caveat is the 'nice' action.g thing. Which also judiciously calls + * getASTCreateString methods because it handles the #( ... ) syntax. + * And converts that to ASTFactory calls. + * + * + */ diff --git a/lib/antlr/src/ASTNULLType.cpp b/lib/antlr/src/ASTNULLType.cpp new file mode 100644 index 00000000..7dd62724 --- /dev/null +++ b/lib/antlr/src/ASTNULLType.cpp @@ -0,0 +1,157 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/config.hpp" +#include "antlr/AST.hpp" +#include "antlr/ASTNULLType.hpp" + +#include <iostream> + +ANTLR_USING_NAMESPACE(std) + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +RefAST ASTNULLType::clone( void ) const +{ + return RefAST(this); +} + +void ASTNULLType::addChild( RefAST ) +{ +} + +size_t ASTNULLType::getNumberOfChildren() const +{ + return 0; +} + +bool ASTNULLType::equals( RefAST ) const +{ + return false; +} + +bool ASTNULLType::equalsList( RefAST ) const +{ + return false; +} + +bool ASTNULLType::equalsListPartial( RefAST ) const +{ + return false; +} + +bool ASTNULLType::equalsTree( RefAST ) const +{ + return false; +} + +bool ASTNULLType::equalsTreePartial( RefAST ) const +{ + return false; +} + +vector<RefAST> ASTNULLType::findAll( RefAST ) +{ + return vector<RefAST>(); +} + +vector<RefAST> ASTNULLType::findAllPartial( RefAST ) +{ + return vector<RefAST>(); +} + +RefAST ASTNULLType::getFirstChild() const +{ + return this; +} + +RefAST ASTNULLType::getNextSibling() const +{ + return this; +} + +string ASTNULLType::getText() const +{ + return "<ASTNULL>"; +} + +int ASTNULLType::getType() const +{ + return Token::NULL_TREE_LOOKAHEAD; +} + +void ASTNULLType::initialize( int, const string& ) +{ +} + +void ASTNULLType::initialize( RefAST ) +{ +} + +void ASTNULLType::initialize( RefToken ) +{ +} + +#ifdef ANTLR_SUPPORT_XML +void ASTNULLType::initialize( istream& ) +{ +} +#endif + +void ASTNULLType::setFirstChild( RefAST ) +{ +} + +void ASTNULLType::setNextSibling( RefAST ) +{ +} + +void ASTNULLType::setText( const string& ) +{ +} + +void ASTNULLType::setType( int ) +{ +} + +string ASTNULLType::toString() const +{ + return getText(); +} + +string ASTNULLType::toStringList() const +{ + return getText(); +} + +string ASTNULLType::toStringTree() const +{ + return getText(); +} + +#ifdef ANTLR_SUPPORT_XML +bool ASTNULLType::attributesToStream( ostream& ) const +{ + return false; +} + +void ASTNULLType::toStream( ostream& out ) const +{ + out << "</ASTNULL>" << endl; +} +#endif + +const char* ASTNULLType::typeName( void ) const +{ + return "ASTNULLType"; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/ASTRefCount.cpp b/lib/antlr/src/ASTRefCount.cpp new file mode 100644 index 00000000..0ca54df0 --- /dev/null +++ b/lib/antlr/src/ASTRefCount.cpp @@ -0,0 +1,41 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/ASTRefCount.hpp" +#include "antlr/AST.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +ASTRef::ASTRef(AST* p) +: ptr(p), count(1) +{ + if (p && !p->ref) + p->ref = this; +} + +ASTRef::~ASTRef() +{ + delete ptr; +} + +ASTRef* ASTRef::getRef(const AST* p) +{ + if (p) { + AST* pp = const_cast<AST*>(p); + if (pp->ref) + return pp->ref->increment(); + else + return new ASTRef(pp); + } else + return 0; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/BaseAST.cpp b/lib/antlr/src/BaseAST.cpp new file mode 100644 index 00000000..f10f1e16 --- /dev/null +++ b/lib/antlr/src/BaseAST.cpp @@ -0,0 +1,281 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/config.hpp" + +#include <iostream> + +#include "antlr/AST.hpp" +#include "antlr/BaseAST.hpp" + +ANTLR_USING_NAMESPACE(std) +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +size_t BaseAST::getNumberOfChildren() const +{ + RefBaseAST t = this->down; + size_t n = 0; + if( t ) + { + n = 1; + while( t->right ) + { + t = t->right; + n++; + } + return n; + } + return n; +} + +void BaseAST::doWorkForFindAll( + ANTLR_USE_NAMESPACE(std)vector<RefAST>& v, + RefAST target,bool partialMatch) +{ + // Start walking sibling lists, looking for matches. + for (RefAST sibling=this; + sibling; + sibling=sibling->getNextSibling()) + { + if ( (partialMatch && sibling->equalsTreePartial(target)) || + (!partialMatch && sibling->equalsTree(target)) ) { + v.push_back(sibling); + } + // regardless of match or not, check any children for matches + if ( sibling->getFirstChild() ) { + RefBaseAST(sibling->getFirstChild())->doWorkForFindAll(v, target, partialMatch); + } + } +} + +/** Is t an exact structural and equals() match of this tree. The + * 'this' reference is considered the start of a sibling list. + */ +bool BaseAST::equalsList(RefAST t) const +{ + // the empty tree is not a match of any non-null tree. + if (!t) + return false; + + // Otherwise, start walking sibling lists. First mismatch, return false. + RefAST sibling=this; + for (;sibling && t; + sibling=sibling->getNextSibling(), t=t->getNextSibling()) { + // as a quick optimization, check roots first. + if (!sibling->equals(t)) + return false; + // if roots match, do full list match test on children. + if (sibling->getFirstChild()) { + if (!sibling->getFirstChild()->equalsList(t->getFirstChild())) + return false; + } + // sibling has no kids, make sure t doesn't either + else if (t->getFirstChild()) + return false; + } + + if (!sibling && !t) + return true; + + // one sibling list has more than the other + return false; +} + +/** Is 'sub' a subtree of this list? + * The siblings of the root are NOT ignored. + */ +bool BaseAST::equalsListPartial(RefAST sub) const +{ + // the empty tree is always a subset of any tree. + if (!sub) + return true; + + // Otherwise, start walking sibling lists. First mismatch, return false. + RefAST sibling=this; + for (;sibling && sub; + sibling=sibling->getNextSibling(), sub=sub->getNextSibling()) { + // as a quick optimization, check roots first. + if (!sibling->equals(sub)) + return false; + // if roots match, do partial list match test on children. + if (sibling->getFirstChild()) + if (!sibling->getFirstChild()->equalsListPartial(sub->getFirstChild())) + return false; + } + + if (!sibling && sub) + // nothing left to match in this tree, but subtree has more + return false; + + // either both are null or sibling has more, but subtree doesn't + return true; +} + +/** Is tree rooted at 'this' equal to 't'? The siblings + * of 'this' are ignored. + */ +bool BaseAST::equalsTree(RefAST t) const +{ + // check roots first + if (!equals(t)) + return false; + // if roots match, do full list match test on children. + if (getFirstChild()) { + if (!getFirstChild()->equalsList(t->getFirstChild())) + return false; + } + // sibling has no kids, make sure t doesn't either + else if (t->getFirstChild()) + return false; + + return true; +} + +/** Is 'sub' a subtree of the tree rooted at 'this'? The siblings + * of 'this' are ignored. + */ +bool BaseAST::equalsTreePartial(RefAST sub) const +{ + // the empty tree is always a subset of any tree. + if (!sub) + return true; + + // check roots first + if (!equals(sub)) + return false; + // if roots match, do full list partial match test on children. + if (getFirstChild()) + if (!getFirstChild()->equalsListPartial(sub->getFirstChild())) + return false; + + return true; +} + +/** Walk the tree looking for all exact subtree matches. Return + * an ASTEnumerator that lets the caller walk the list + * of subtree roots found herein. + */ +ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAll(RefAST target) +{ + ANTLR_USE_NAMESPACE(std)vector<RefAST> roots; + + // the empty tree cannot result in an enumeration + if (target) { + doWorkForFindAll(roots,target,false); // find all matches recursively + } + + return roots; +} + +/** Walk the tree looking for all subtrees. Return + * an ASTEnumerator that lets the caller walk the list + * of subtree roots found herein. + */ +ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAllPartial(RefAST target) +{ + ANTLR_USE_NAMESPACE(std)vector<RefAST> roots; + + // the empty tree cannot result in an enumeration + if (target) + doWorkForFindAll(roots,target,true); // find all matches recursively + + return roots; +} + +ANTLR_USE_NAMESPACE(std)string BaseAST::toStringList() const +{ + ANTLR_USE_NAMESPACE(std)string ts=""; + + if (getFirstChild()) + { + ts+=" ( "; + ts+=toString(); + ts+=getFirstChild()->toStringList(); + ts+=" )"; + } + else + { + ts+=" "; + ts+=toString(); + } + + if (getNextSibling()) + ts+=getNextSibling()->toStringList(); + + return ts; +} + +ANTLR_USE_NAMESPACE(std)string BaseAST::toStringTree() const +{ + ANTLR_USE_NAMESPACE(std)string ts = ""; + + if (getFirstChild()) + { + ts+=" ( "; + ts+=toString(); + ts+=getFirstChild()->toStringList(); + ts+=" )"; + } + else + { + ts+=" "; + ts+=toString(); + } + return ts; +} + +#ifdef ANTLR_SUPPORT_XML +/* This whole XML output stuff needs a little bit more thought + * I'd like to store extra XML data in the node. e.g. for custom ast's + * with for instance symboltable references. This + * should be more pluggable.. + * @returns boolean value indicating wether a closetag should be produced. + */ +bool BaseAST::attributesToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const +{ + out << "text=\"" << this->getText() + << "\" type=\"" << this->getType() << "\""; + + return false; +} + +void BaseAST::toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const +{ + for( RefAST node = this; node != 0; node = node->getNextSibling() ) + { + out << "<" << this->typeName() << " "; + + // Write out attributes and if there is extra data... + bool need_close_tag = node->attributesToStream( out ); + + if( need_close_tag ) + { + // got children so write them... + if( node->getFirstChild() != 0 ) + node->getFirstChild()->toStream( out ); + + // and a closing tag.. + out << "</" << node->typeName() << ">" << endl; + } + } +} +#endif + +// this is nasty, but it makes the code generation easier +ANTLR_API RefAST nullAST; + +#if defined(_MSC_VER) && !defined(__ICL) // Microsoft Visual C++ +extern ANTLR_API AST* const nullASTptr = 0; +#else +ANTLR_API AST* const nullASTptr = 0; +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/BitSet.cpp b/lib/antlr/src/BitSet.cpp new file mode 100644 index 00000000..2a32404a --- /dev/null +++ b/lib/antlr/src/BitSet.cpp @@ -0,0 +1,62 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/BitSet.hpp" +#include <string> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +BitSet::BitSet(unsigned int nbits) +: storage(nbits) +{ + for (unsigned int i = 0; i < nbits ; i++ ) + storage[i] = false; +} + +BitSet::BitSet( const unsigned long* bits_, unsigned int nlongs ) +: storage(nlongs*32) +{ + for ( unsigned int i = 0 ; i < (nlongs * 32); i++) + storage[i] = (bits_[i>>5] & (1UL << (i&31))) ? true : false; +} + +BitSet::~BitSet() +{ +} + +void BitSet::add(unsigned int el) +{ + if( el >= storage.size() ) + storage.resize( el+1, false ); + + storage[el] = true; +} + +bool BitSet::member(unsigned int el) const +{ + if ( el >= storage.size()) + return false; + + return storage[el]; +} + +ANTLR_USE_NAMESPACE(std)vector<unsigned int> BitSet::toArray() const +{ + ANTLR_USE_NAMESPACE(std)vector<unsigned int> elems; + for (unsigned int i = 0; i < storage.size(); i++) + { + if (storage[i]) + elems.push_back(i); + } + + return elems; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/CharBuffer.cpp b/lib/antlr/src/CharBuffer.cpp new file mode 100644 index 00000000..a0e11eae --- /dev/null +++ b/lib/antlr/src/CharBuffer.cpp @@ -0,0 +1,52 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/CharBuffer.hpp" +#include <iostream> + +//#include <ios> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/* RK: Per default istream does not throw exceptions. This can be + * enabled with: + * stream.exceptions(ios_base::badbit|ios_base::failbit|ios_base::eofbit); + * + * We could try catching the bad/fail stuff. But handling eof via this is + * not a good idea. EOF is best handled as a 'normal' character. + * + * So this does not work yet with gcc... Comment it until I get to a platform + * that does.. + */ + +/** Create a character buffer. Enable fail and bad exceptions, if supported + * by platform. */ +CharBuffer::CharBuffer(ANTLR_USE_NAMESPACE(std)istream& input_) +: input(input_) +{ +// input.exceptions(ANTLR_USE_NAMESPACE(std)ios_base::badbit| +// ANTLR_USE_NAMESPACE(std)ios_base::failbit); +} + +/** Get the next character from the stream. May throw CharStreamIOException + * when something bad happens (not EOF) (if supported by platform). + */ +int CharBuffer::getChar() +{ +// try { + return input.get(); +// } +// catch (ANTLR_USE_NAMESPACE(std)ios_base::failure& e) { +// throw CharStreamIOException(e); +// } +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/CharScanner.cpp b/lib/antlr/src/CharScanner.cpp new file mode 100644 index 00000000..d5b1f753 --- /dev/null +++ b/lib/antlr/src/CharScanner.cpp @@ -0,0 +1,108 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include <iostream> + +#include "antlr/CharScanner.hpp" +#include "antlr/CommonToken.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif +ANTLR_C_USING(exit) + +CharScanner::CharScanner(InputBuffer& cb, bool case_sensitive ) + : saveConsumedInput(true) //, caseSensitiveLiterals(true) + , caseSensitive(case_sensitive) + , literals(CharScannerLiteralsLess(this)) + , inputState(new LexerInputState(cb)) + , commitToPath(false) + , tabsize(8) + , traceDepth(0) +{ + setTokenObjectFactory(&CommonToken::factory); +} + +CharScanner::CharScanner(InputBuffer* cb, bool case_sensitive ) + : saveConsumedInput(true) //, caseSensitiveLiterals(true) + , caseSensitive(case_sensitive) + , literals(CharScannerLiteralsLess(this)) + , inputState(new LexerInputState(cb)) + , commitToPath(false) + , tabsize(8) + , traceDepth(0) +{ + setTokenObjectFactory(&CommonToken::factory); +} + +CharScanner::CharScanner( const LexerSharedInputState& state, bool case_sensitive ) + : saveConsumedInput(true) //, caseSensitiveLiterals(true) + , caseSensitive(case_sensitive) + , literals(CharScannerLiteralsLess(this)) + , inputState(state) + , commitToPath(false) + , tabsize(8) + , traceDepth(0) +{ + setTokenObjectFactory(&CommonToken::factory); +} + +/** Report exception errors caught in nextToken() */ +void CharScanner::reportError(const RecognitionException& ex) +{ + ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Parser error-reporting function can be overridden in subclass */ +void CharScanner::reportError(const ANTLR_USE_NAMESPACE(std)string& s) +{ + if (getFilename() == "") + ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; + else + ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Parser warning-reporting function can be overridden in subclass */ +void CharScanner::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) +{ + if (getFilename() == "") + ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; + else + ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +void CharScanner::traceIndent() +{ + for( int i = 0; i < traceDepth; i++ ) + ANTLR_USE_NAMESPACE(std)cout << " "; +} + +void CharScanner::traceIn(const char* rname) +{ + traceDepth++; + traceIndent(); + ANTLR_USE_NAMESPACE(std)cout << "> lexer " << rname + << "; c==" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; +} + +void CharScanner::traceOut(const char* rname) +{ + traceIndent(); + ANTLR_USE_NAMESPACE(std)cout << "< lexer " << rname + << "; c==" << LA(1) << ANTLR_USE_NAMESPACE(std)endl; + traceDepth--; +} + +#ifndef NO_STATIC_CONSTS +const int CharScanner::NO_CHAR; +const int CharScanner::EOF_CHAR; +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/CommonAST.cpp b/lib/antlr/src/CommonAST.cpp new file mode 100644 index 00000000..e132c0aa --- /dev/null +++ b/lib/antlr/src/CommonAST.cpp @@ -0,0 +1,49 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/config.hpp" + +#include <cstdlib> +#include <iostream> + +#include "antlr/CommonAST.hpp" +#include "antlr/ANTLRUtil.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +const char* const CommonAST::TYPE_NAME = "CommonAST"; + +#ifdef ANTLR_SUPPORT_XML +void CommonAST::initialize( ANTLR_USE_NAMESPACE(std)istream& in ) +{ + ANTLR_USE_NAMESPACE(std)string t1, t2, text; + + // text + read_AttributeNValue( in, t1, text ); + + read_AttributeNValue( in, t1, t2 ); +#ifdef ANTLR_ATOI_IN_STD + int type = ANTLR_USE_NAMESPACE(std)atoi(t2.c_str()); +#else + int type = atoi(t2.c_str()); +#endif + + // initialize first part of AST. + this->initialize( type, text ); +} +#endif + +RefAST CommonAST::factory() +{ + return RefAST(new CommonAST); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/CommonASTWithHiddenTokens.cpp b/lib/antlr/src/CommonASTWithHiddenTokens.cpp new file mode 100644 index 00000000..b0e1a3dd --- /dev/null +++ b/lib/antlr/src/CommonASTWithHiddenTokens.cpp @@ -0,0 +1,64 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/config.hpp" +#include "antlr/AST.hpp" +#include "antlr/BaseAST.hpp" +#include "antlr/CommonAST.hpp" +#include "antlr/CommonASTWithHiddenTokens.hpp" +#include "antlr/CommonHiddenStreamToken.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +const char* const CommonASTWithHiddenTokens::TYPE_NAME = "CommonASTWithHiddenTokens"; +// RK: Do not put constructor and destructor into the header file here.. +// this triggers something very obscure in gcc 2.95.3 (and 3.0) +// missing vtables and stuff. +// Although this may be a problem with with binutils. +CommonASTWithHiddenTokens::CommonASTWithHiddenTokens() +: CommonAST() +{ +} + +CommonASTWithHiddenTokens::~CommonASTWithHiddenTokens() +{ +} + +void CommonASTWithHiddenTokens::initialize(int t,const ANTLR_USE_NAMESPACE(std)string& txt) +{ + CommonAST::initialize(t,txt); +} + +void CommonASTWithHiddenTokens::initialize(RefAST t) +{ + CommonAST::initialize(t); + hiddenBefore = RefCommonASTWithHiddenTokens(t)->getHiddenBefore(); + hiddenAfter = RefCommonASTWithHiddenTokens(t)->getHiddenAfter(); +} + +void CommonASTWithHiddenTokens::initialize(RefToken t) +{ + CommonAST::initialize(t); + hiddenBefore = static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenBefore(); + hiddenAfter = static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenAfter(); +} + +RefAST CommonASTWithHiddenTokens::factory() +{ + return RefAST(new CommonASTWithHiddenTokens); +} + +RefAST CommonASTWithHiddenTokens::clone( void ) const +{ + CommonASTWithHiddenTokens *ast = new CommonASTWithHiddenTokens( *this ); + return RefAST(ast); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/CommonHiddenStreamToken.cpp b/lib/antlr/src/CommonHiddenStreamToken.cpp new file mode 100644 index 00000000..9396a43b --- /dev/null +++ b/lib/antlr/src/CommonHiddenStreamToken.cpp @@ -0,0 +1,56 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/CommonHiddenStreamToken.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +CommonHiddenStreamToken::CommonHiddenStreamToken() +: CommonToken() +{ +} + +CommonHiddenStreamToken::CommonHiddenStreamToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt) +: CommonToken(t,txt) +{ +} + +CommonHiddenStreamToken::CommonHiddenStreamToken(const ANTLR_USE_NAMESPACE(std)string& s) +: CommonToken(s) +{ +} + +RefToken CommonHiddenStreamToken::getHiddenAfter() +{ + return hiddenAfter; +} + +RefToken CommonHiddenStreamToken::getHiddenBefore() +{ + return hiddenBefore; +} + +RefToken CommonHiddenStreamToken::factory() +{ + return RefToken(new CommonHiddenStreamToken); +} + +void CommonHiddenStreamToken::setHiddenAfter(RefToken t) +{ + hiddenAfter = t; +} + +void CommonHiddenStreamToken::setHiddenBefore(RefToken t) +{ + hiddenBefore = t; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/CommonToken.cpp b/lib/antlr/src/CommonToken.cpp new file mode 100644 index 00000000..a223b239 --- /dev/null +++ b/lib/antlr/src/CommonToken.cpp @@ -0,0 +1,45 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/CommonToken.hpp" +#include "antlr/String.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +CommonToken::CommonToken() : Token(), line(1), col(1), text("") +{} + +CommonToken::CommonToken(int t, const ANTLR_USE_NAMESPACE(std)string& txt) +: Token(t) +, line(1) +, col(1) +, text(txt) +{} + +CommonToken::CommonToken(const ANTLR_USE_NAMESPACE(std)string& s) +: Token() +, line(1) +, col(1) +, text(s) +{} + +ANTLR_USE_NAMESPACE(std)string CommonToken::toString() const +{ + return "[\""+getText()+"\",<"+getType()+">,line="+getLine()+",column="+getColumn()+"]"; +} + +RefToken CommonToken::factory() +{ + return RefToken(new CommonToken); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/InputBuffer.cpp b/lib/antlr/src/InputBuffer.cpp new file mode 100644 index 00000000..c9eced7d --- /dev/null +++ b/lib/antlr/src/InputBuffer.cpp @@ -0,0 +1,81 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/config.hpp" +#include "antlr/InputBuffer.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** Ensure that the character buffer is sufficiently full */ +void InputBuffer::fill(unsigned int amount) +{ + syncConsume(); + // Fill the buffer sufficiently to hold needed characters + while (queue.entries() < amount + markerOffset) + { + // Append the next character + queue.append(getChar()); + } +} + +/** get the current lookahead characters as a string + * @warning it may treat 0 and EOF values wrong + */ +ANTLR_USE_NAMESPACE(std)string InputBuffer::getLAChars( void ) const +{ + ANTLR_USE_NAMESPACE(std)string ret; + + for(unsigned int i = markerOffset; i < queue.entries(); i++) + ret += queue.elementAt(i); + + return ret; +} + +/** get the current marked characters as a string + * @warning it may treat 0 and EOF values wrong + */ +ANTLR_USE_NAMESPACE(std)string InputBuffer::getMarkedChars( void ) const +{ + ANTLR_USE_NAMESPACE(std)string ret; + + for(unsigned int i = 0; i < markerOffset; i++) + ret += queue.elementAt(i); + + return ret; +} + +/** Return an integer marker that can be used to rewind the buffer to + * its current state. + */ +unsigned int InputBuffer::mark() +{ + syncConsume(); + nMarkers++; + return markerOffset; +} + +/** Rewind the character buffer to a marker. + * @param mark Marker returned previously from mark() + */ +void InputBuffer::rewind(unsigned int mark) +{ + syncConsume(); + markerOffset = mark; + nMarkers--; +} + +unsigned int InputBuffer::entries() const +{ + //assert(queue.entries() >= markerOffset); + return queue.entries() - markerOffset; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/LLkParser.cpp b/lib/antlr/src/LLkParser.cpp new file mode 100644 index 00000000..ab0d672a --- /dev/null +++ b/lib/antlr/src/LLkParser.cpp @@ -0,0 +1,85 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/LLkParser.hpp" +#include <iostream> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +ANTLR_USING_NAMESPACE(std) + +/**An LL(k) parser. + * + * @see antlr.Token + * @see antlr.TokenBuffer + * @see antlr.LL1Parser + */ + +// LLkParser(int k_); + +LLkParser::LLkParser(const ParserSharedInputState& state, int k_) +: Parser(state), k(k_) +{ +} + +LLkParser::LLkParser(TokenBuffer& tokenBuf, int k_) +: Parser(tokenBuf), k(k_) +{ +} + +LLkParser::LLkParser(TokenStream& lexer, int k_) +: Parser(new TokenBuffer(lexer)), k(k_) +{ +} + +void LLkParser::trace(const char* ee, const char* rname) +{ + traceIndent(); + + cout << ee << rname << ((inputState->guessing>0)?"; [guessing]":"; "); + + for (int i = 1; i <= k; i++) + { + if (i != 1) { + cout << ", "; + } + cout << "LA(" << i << ")=="; + + string temp; + + try { + temp = LT(i)->getText().c_str(); + } + catch( ANTLRException& ae ) + { + temp = "[error: "; + temp += ae.toString(); + temp += ']'; + } + cout << temp; + } + + cout << endl; +} + +void LLkParser::traceIn(const char* rname) +{ + traceDepth++; + trace("> ",rname); +} + +void LLkParser::traceOut(const char* rname) +{ + trace("< ",rname); + traceDepth--; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/Makefile.am b/lib/antlr/src/Makefile.am new file mode 100644 index 00000000..b1af9fca --- /dev/null +++ b/lib/antlr/src/Makefile.am @@ -0,0 +1,10 @@ + +# Make #include <antlr/xxx> work.. +INCLUDES = -I$(srcdir)/.. +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +noinst_LTLIBRARIES = libantlr.la + +libantlr_la_LDFLAGS = -no-undefined + +libantlr_la_SOURCES = ANTLRUtil.cpp ASTFactory.cpp ASTNULLType.cpp ASTRefCount.cpp BaseAST.cpp BitSet.cpp CharBuffer.cpp CharScanner.cpp CommonAST.cpp CommonASTWithHiddenTokens.cpp CommonHiddenStreamToken.cpp CommonToken.cpp InputBuffer.cpp LLkParser.cpp MismatchedCharException.cpp MismatchedTokenException.cpp NoViableAltException.cpp NoViableAltForCharException.cpp Parser.cpp RecognitionException.cpp String.cpp Token.cpp TokenBuffer.cpp TokenRefCount.cpp TokenStreamBasicFilter.cpp TokenStreamHiddenTokenFilter.cpp TokenStreamRewriteEngine.cpp TokenStreamSelector.cpp TreeParser.cpp diff --git a/lib/antlr/src/MismatchedCharException.cpp b/lib/antlr/src/MismatchedCharException.cpp new file mode 100644 index 00000000..e73dbf36 --- /dev/null +++ b/lib/antlr/src/MismatchedCharException.cpp @@ -0,0 +1,120 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/CharScanner.hpp" +#include "antlr/MismatchedCharException.hpp" +#include "antlr/String.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +MismatchedCharException::MismatchedCharException() + : RecognitionException("Mismatched char") +{} + +// Expected range / not range +MismatchedCharException::MismatchedCharException( + int c, + int lower, + int upper_, + bool matchNot, + CharScanner* scanner_ +) : RecognitionException("Mismatched char", + scanner_->getFilename(), + scanner_->getLine(), scanner_->getColumn()) + , mismatchType(matchNot ? NOT_RANGE : RANGE) + , foundChar(c) + , expecting(lower) + , upper(upper_) + , scanner(scanner_) +{ +} + +// Expected token / not token +MismatchedCharException::MismatchedCharException( + int c, + int expecting_, + bool matchNot, + CharScanner* scanner_ +) : RecognitionException("Mismatched char", + scanner_->getFilename(), + scanner_->getLine(), scanner_->getColumn()) + , mismatchType(matchNot ? NOT_CHAR : CHAR) + , foundChar(c) + , expecting(expecting_) + , scanner(scanner_) +{ +} + +// Expected BitSet / not BitSet +MismatchedCharException::MismatchedCharException( + int c, + BitSet set_, + bool matchNot, + CharScanner* scanner_ +) : RecognitionException("Mismatched char", + scanner_->getFilename(), + scanner_->getLine(), scanner_->getColumn()) + , mismatchType(matchNot ? NOT_SET : SET) + , foundChar(c) + , set(set_) + , scanner(scanner_) +{ +} + +ANTLR_USE_NAMESPACE(std)string MismatchedCharException::getMessage() const +{ + ANTLR_USE_NAMESPACE(std)string s; + + switch (mismatchType) { + case CHAR : + s += "expecting '" + charName(expecting) + "', found '" + charName(foundChar) + "'"; + break; + case NOT_CHAR : + s += "expecting anything but '" + charName(expecting) + "'; got it anyway"; + break; + case RANGE : + s += "expecting token in range: '" + charName(expecting) + "'..'" + charName(upper) + "', found '" + charName(foundChar) + "'"; + break; + case NOT_RANGE : + s += "expecting token NOT in range: " + charName(expecting) + "'..'" + charName(upper) + "', found '" + charName(foundChar) + "'"; + break; + case SET : + case NOT_SET : + { + s += ANTLR_USE_NAMESPACE(std)string("expecting ") + (mismatchType == NOT_SET ? "NOT " : "") + "one of ("; + ANTLR_USE_NAMESPACE(std)vector<unsigned int> elems = set.toArray(); + for ( unsigned int i = 0; i < elems.size(); i++ ) + { + s += " '"; + s += charName(elems[i]); + s += "'"; + } + s += "), found '" + charName(foundChar) + "'"; + } + break; + default : + s += RecognitionException::getMessage(); + break; + } + + return s; +} + +#ifndef NO_STATIC_CONSTS +const int MismatchedCharException::CHAR; +const int MismatchedCharException::NOT_CHAR; +const int MismatchedCharException::RANGE; +const int MismatchedCharException::NOT_RANGE; +const int MismatchedCharException::SET; +const int MismatchedCharException::NOT_SET; +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/MismatchedTokenException.cpp b/lib/antlr/src/MismatchedTokenException.cpp new file mode 100644 index 00000000..7fc349f7 --- /dev/null +++ b/lib/antlr/src/MismatchedTokenException.cpp @@ -0,0 +1,196 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/MismatchedTokenException.hpp" +#include "antlr/String.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +MismatchedTokenException::MismatchedTokenException() + : RecognitionException("Mismatched Token: expecting any AST node","<AST>",-1,-1) + , token(0) + , node(nullASTptr) + , tokenNames(0) + , numTokens(0) +{ +} + +// Expected range / not range +MismatchedTokenException::MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefAST node_, + int lower, + int upper_, + bool matchNot +) : RecognitionException("Mismatched Token","<AST>",-1,-1) + , token(0) + , node(node_) + , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("<empty tree>")) ) + , mismatchType(matchNot ? NOT_RANGE : RANGE) + , expecting(lower) + , upper(upper_) + , tokenNames(tokenNames_) + , numTokens(numTokens_) +{ +} + +// Expected token / not token +MismatchedTokenException::MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefAST node_, + int expecting_, + bool matchNot +) : RecognitionException("Mismatched Token","<AST>",-1,-1) + , token(0) + , node(node_) + , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("<empty tree>")) ) + , mismatchType(matchNot ? NOT_TOKEN : TOKEN) + , expecting(expecting_) + , tokenNames(tokenNames_) + , numTokens(numTokens_) +{ +} + +// Expected BitSet / not BitSet +MismatchedTokenException::MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefAST node_, + BitSet set_, + bool matchNot +) : RecognitionException("Mismatched Token","<AST>",-1,-1) + , token(0) + , node(node_) + , tokenText( (node_ ? node_->toString(): ANTLR_USE_NAMESPACE(std)string("<empty tree>")) ) + , mismatchType(matchNot ? NOT_SET : SET) + , set(set_) + , tokenNames(tokenNames_) + , numTokens(numTokens_) +{ +} + +// Expected range / not range +MismatchedTokenException::MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefToken token_, + int lower, + int upper_, + bool matchNot, + const ANTLR_USE_NAMESPACE(std)string& fileName_ +) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn()) + , token(token_) + , node(nullASTptr) + , tokenText(token_->getText()) + , mismatchType(matchNot ? NOT_RANGE : RANGE) + , expecting(lower) + , upper(upper_) + , tokenNames(tokenNames_) + , numTokens(numTokens_) +{ +} + +// Expected token / not token +MismatchedTokenException::MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefToken token_, + int expecting_, + bool matchNot, + const ANTLR_USE_NAMESPACE(std)string& fileName_ +) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn()) + , token(token_) + , node(nullASTptr) + , tokenText(token_->getText()) + , mismatchType(matchNot ? NOT_TOKEN : TOKEN) + , expecting(expecting_) + , tokenNames(tokenNames_) + , numTokens(numTokens_) +{ +} + +// Expected BitSet / not BitSet +MismatchedTokenException::MismatchedTokenException( + const char* const* tokenNames_, + const int numTokens_, + RefToken token_, + BitSet set_, + bool matchNot, + const ANTLR_USE_NAMESPACE(std)string& fileName_ +) : RecognitionException("Mismatched Token",fileName_,token_->getLine(),token_->getColumn()) + , token(token_) + , node(nullASTptr) + , tokenText(token_->getText()) + , mismatchType(matchNot ? NOT_SET : SET) + , set(set_) + , tokenNames(tokenNames_) + , numTokens(numTokens_) +{ +} + +ANTLR_USE_NAMESPACE(std)string MismatchedTokenException::getMessage() const +{ + ANTLR_USE_NAMESPACE(std)string s; + switch (mismatchType) { + case TOKEN: + s += "expecting " + tokenName(expecting) + ", found '" + tokenText + "'"; + break; + case NOT_TOKEN: + s += "expecting anything but " + tokenName(expecting) + "; got it anyway"; + break; + case RANGE: + s += "expecting token in range: " + tokenName(expecting) + ".." + tokenName(upper) + ", found '" + tokenText + "'"; + break; + case NOT_RANGE: + s += "expecting token NOT in range: " + tokenName(expecting) + ".." + tokenName(upper) + ", found '" + tokenText + "'"; + break; + case SET: + case NOT_SET: + { + s += ANTLR_USE_NAMESPACE(std)string("expecting ") + (mismatchType == NOT_SET ? "NOT " : "") + "one of ("; + ANTLR_USE_NAMESPACE(std)vector<unsigned int> elems = set.toArray(); + for ( unsigned int i = 0; i < elems.size(); i++ ) + { + s += " "; + s += tokenName(elems[i]); + } + s += "), found '" + tokenText + "'"; + } + break; + default: + s = RecognitionException::getMessage(); + break; + } + return s; +} + +ANTLR_USE_NAMESPACE(std)string MismatchedTokenException::tokenName(int tokenType) const +{ + if (tokenType == Token::INVALID_TYPE) + return "<Set of tokens>"; + else if (tokenType < 0 || tokenType >= numTokens) + return ANTLR_USE_NAMESPACE(std)string("<") + tokenType + ">"; + else + return tokenNames[tokenType]; +} + +#ifndef NO_STATIC_CONSTS +const int MismatchedTokenException::TOKEN; +const int MismatchedTokenException::NOT_TOKEN; +const int MismatchedTokenException::RANGE; +const int MismatchedTokenException::NOT_RANGE; +const int MismatchedTokenException::SET; +const int MismatchedTokenException::NOT_SET; +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/NoViableAltException.cpp b/lib/antlr/src/NoViableAltException.cpp new file mode 100644 index 00000000..94da2cc4 --- /dev/null +++ b/lib/antlr/src/NoViableAltException.cpp @@ -0,0 +1,52 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/NoViableAltException.hpp" +#include "antlr/String.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +ANTLR_USING_NAMESPACE(std) + +NoViableAltException::NoViableAltException(RefAST t) + : RecognitionException("NoViableAlt","<AST>",-1,-1), + token(0), node(t) +{ +} + +NoViableAltException::NoViableAltException( + RefToken t, + const ANTLR_USE_NAMESPACE(std)string& fileName_ +) : RecognitionException("NoViableAlt",fileName_,t->getLine(),t->getColumn()), + token(t), node(nullASTptr) +{ +} + +ANTLR_USE_NAMESPACE(std)string NoViableAltException::getMessage() const +{ + if (token) + { + if( token->getType() == Token::EOF_TYPE ) + return string("unexpected end of file"); + else if( token->getType() == Token::NULL_TREE_LOOKAHEAD ) + return string("unexpected end of tree"); + else + return string("unexpected token: ")+token->getText(); + } + + // must a tree parser error if token==null + if (!node) + return "unexpected end of subtree"; + + return string("unexpected AST node: ")+node->toString(); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/NoViableAltForCharException.cpp b/lib/antlr/src/NoViableAltForCharException.cpp new file mode 100644 index 00000000..10d9447a --- /dev/null +++ b/lib/antlr/src/NoViableAltForCharException.cpp @@ -0,0 +1,39 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/NoViableAltForCharException.hpp" +#include "antlr/String.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +NoViableAltForCharException::NoViableAltForCharException(int c, CharScanner* scanner) + : RecognitionException("NoViableAlt", + scanner->getFilename(), + scanner->getLine(),scanner->getColumn()), + foundChar(c) +{ +} + +NoViableAltForCharException::NoViableAltForCharException( + int c, + const ANTLR_USE_NAMESPACE(std)string& fileName_, + int line_, int column_) + : RecognitionException("NoViableAlt",fileName_,line_,column_), + foundChar(c) +{ +} + +ANTLR_USE_NAMESPACE(std)string NoViableAltForCharException::getMessage() const +{ + return ANTLR_USE_NAMESPACE(std)string("unexpected char: ")+charName(foundChar); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/Parser.cpp b/lib/antlr/src/Parser.cpp new file mode 100644 index 00000000..640da7b6 --- /dev/null +++ b/lib/antlr/src/Parser.cpp @@ -0,0 +1,113 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/Parser.hpp" + +#include <iostream> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** A generic ANTLR parser (LL(k) for k>=1) containing a bunch of + * utility routines useful at any lookahead depth. We distinguish between + * the LL(1) and LL(k) parsers because of efficiency. This may not be + * necessary in the near future. + * + * Each parser object contains the state of the parse including a lookahead + * cache (the form of which is determined by the subclass), whether or + * not the parser is in guess mode, where tokens come from, etc... + * + * <p> + * During <b>guess</b> mode, the current lookahead token(s) and token type(s) + * cache must be saved because the token stream may not have been informed + * to save the token (via <tt>mark</tt>) before the <tt>try</tt> block. + * Guessing is started by: + * <ol> + * <li>saving the lookahead cache. + * <li>marking the current position in the TokenBuffer. + * <li>increasing the guessing level. + * </ol> + * + * After guessing, the parser state is restored by: + * <ol> + * <li>restoring the lookahead cache. + * <li>rewinding the TokenBuffer. + * <li>decreasing the guessing level. + * </ol> + * + * @see antlr.Token + * @see antlr.TokenBuffer + * @see antlr.TokenStream + * @see antlr.LL1Parser + * @see antlr.LLkParser + */ + +bool DEBUG_PARSER = false; + +/** Parser error-reporting function can be overridden in subclass */ +void Parser::reportError(const RecognitionException& ex) +{ + ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Parser error-reporting function can be overridden in subclass */ +void Parser::reportError(const ANTLR_USE_NAMESPACE(std)string& s) +{ + if ( getFilename()=="" ) + ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; + else + ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Parser warning-reporting function can be overridden in subclass */ +void Parser::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) +{ + if ( getFilename()=="" ) + ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; + else + ANTLR_USE_NAMESPACE(std)cerr << getFilename().c_str() << ": warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Set or change the input token buffer */ +// void setTokenBuffer(TokenBuffer<Token>* t); + +void Parser::traceIndent() +{ + for( int i = 0; i < traceDepth; i++ ) + ANTLR_USE_NAMESPACE(std)cout << " "; +} + +void Parser::traceIn(const char* rname) +{ + traceDepth++; + + for( int i = 0; i < traceDepth; i++ ) + ANTLR_USE_NAMESPACE(std)cout << " "; + + ANTLR_USE_NAMESPACE(std)cout << "> " << rname + << "; LA(1)==" << LT(1)->getText().c_str() + << ((inputState->guessing>0)?" [guessing]":"") + << ANTLR_USE_NAMESPACE(std)endl; +} + +void Parser::traceOut(const char* rname) +{ + for( int i = 0; i < traceDepth; i++ ) + ANTLR_USE_NAMESPACE(std)cout << " "; + + ANTLR_USE_NAMESPACE(std)cout << "< " << rname + << "; LA(1)==" << LT(1)->getText().c_str() + << ((inputState->guessing>0)?" [guessing]":"") + << ANTLR_USE_NAMESPACE(std)endl; + + traceDepth--; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/RecognitionException.cpp b/lib/antlr/src/RecognitionException.cpp new file mode 100644 index 00000000..9c185ccc --- /dev/null +++ b/lib/antlr/src/RecognitionException.cpp @@ -0,0 +1,71 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/RecognitionException.hpp" +#include "antlr/String.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +RecognitionException::RecognitionException() +: ANTLRException("parsing error") +, line(-1) +, column(-1) +{ +} + +RecognitionException::RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s) +: ANTLRException(s) +, line(-1) +, column(-1) +{ +} + +RecognitionException::RecognitionException(const ANTLR_USE_NAMESPACE(std)string& s, + const ANTLR_USE_NAMESPACE(std)string& fileName_, + int line_,int column_) +: ANTLRException(s) +, fileName(fileName_) +, line(line_) +, column(column_) +{ +} + +ANTLR_USE_NAMESPACE(std)string RecognitionException::getFileLineColumnString() const +{ + ANTLR_USE_NAMESPACE(std)string fileLineColumnString; + + if ( fileName.length() > 0 ) + fileLineColumnString = fileName + ":"; + + if ( line != -1 ) + { + if ( fileName.length() == 0 ) + fileLineColumnString = fileLineColumnString + "line "; + + fileLineColumnString = fileLineColumnString + line; + + if ( column != -1 ) + fileLineColumnString = fileLineColumnString + ":" + column; + + fileLineColumnString = fileLineColumnString + ":"; + } + + fileLineColumnString = fileLineColumnString + " "; + + return fileLineColumnString; +} + +ANTLR_USE_NAMESPACE(std)string RecognitionException::toString() const +{ + return getFileLineColumnString()+getMessage(); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/String.cpp b/lib/antlr/src/String.cpp new file mode 100644 index 00000000..ae70f479 --- /dev/null +++ b/lib/antlr/src/String.cpp @@ -0,0 +1,90 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/String.hpp" + +#include <cctype> + +#ifdef HAS_NOT_CSTDIO_H +#include <stdio.h> +#else +#include <cstdio> +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +// wh: hack for Borland C++ 5.6 +#if __BORLANDC__ + using std::sprintf; +#endif + + +// RK: should be using snprintf actually... (or stringstream) +ANTLR_C_USING(sprintf) + +ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, const int rhs ) +{ + char tmp[100]; + sprintf(tmp,"%d",rhs); + return lhs+tmp; +} + +ANTLR_USE_NAMESPACE(std)string operator+( const ANTLR_USE_NAMESPACE(std)string& lhs, size_t rhs ) +{ + char tmp[100]; + sprintf(tmp,"%u",rhs); + return lhs+tmp; +} + +/** Convert character to readable string + */ +ANTLR_USE_NAMESPACE(std)string charName(int ch) +{ + if (ch == EOF) + return "EOF"; + else + { + ANTLR_USE_NAMESPACE(std)string s; + + // when you think you've seen it all.. an isprint that crashes... + ch = ch & 0xFF; +#ifdef ANTLR_CCTYPE_NEEDS_STD + if( ANTLR_USE_NAMESPACE(std)isprint( ch ) ) +#else + if( isprint( ch ) ) +#endif + { + s.append("'"); + s += ch; + s.append("'"); +// s += "'"+ch+"'"; + } + else + { + s += "0x"; + + unsigned int t = ch >> 4; + if( t < 10 ) + s += t | 0x30; + else + s += t + 0x37; + t = ch & 0xF; + if( t < 10 ) + s += t | 0x30; + else + s += t + 0x37; + } + return s; + } +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/Token.cpp b/lib/antlr/src/Token.cpp new file mode 100644 index 00000000..f8181634 --- /dev/null +++ b/lib/antlr/src/Token.cpp @@ -0,0 +1,80 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/Token.hpp" +#include "antlr/String.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +int Token::getColumn() const +{ + return 0; +} + +int Token::getLine() const +{ + return 0; +} + +ANTLR_USE_NAMESPACE(std)string Token::getText() const +{ + return "<no text>"; +} + +int Token::getType() const +{ + return type; +} + +void Token::setColumn(int) +{ +} + +void Token::setLine(int) +{ +} + +void Token::setText(const ANTLR_USE_NAMESPACE(std)string&) +{ +} + +void Token::setType(int t) +{ + type = t; +} + +void Token::setFilename(const ANTLR_USE_NAMESPACE(std)string&) +{ +} + +ANTLR_USE_NAMESPACE(std)string emptyString(""); + +const ANTLR_USE_NAMESPACE(std)string& Token::getFilename() const +{ + return emptyString; +} + +ANTLR_USE_NAMESPACE(std)string Token::toString() const +{ + return "[\""+getText()+"\",<"+type+">]"; +} + +ANTLR_API RefToken nullToken; + +#ifndef NO_STATIC_CONSTS +const int Token::MIN_USER_TYPE; +const int Token::NULL_TREE_LOOKAHEAD; +const int Token::INVALID_TYPE; +const int Token::EOF_TYPE; +const int Token::SKIP; +#endif + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/TokenBuffer.cpp b/lib/antlr/src/TokenBuffer.cpp new file mode 100644 index 00000000..ed69d6e0 --- /dev/null +++ b/lib/antlr/src/TokenBuffer.cpp @@ -0,0 +1,96 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/TokenBuffer.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/**A Stream of Token objects fed to the parser from a TokenStream that can + * be rewound via mark()/rewind() methods. + * <p> + * A dynamic array is used to buffer up all the input tokens. Normally, + * "k" tokens are stored in the buffer. More tokens may be stored during + * guess mode (testing syntactic predicate), or when LT(i>k) is referenced. + * Consumption of tokens is deferred. In other words, reading the next + * token is not done by conume(), but deferred until needed by LA or LT. + * <p> + * + * @see antlr.Token + * @see antlr.TokenStream + * @see antlr.TokenQueue + */ + +/** Create a token buffer */ +TokenBuffer::TokenBuffer( TokenStream& inp ) +: input(inp) +, nMarkers(0) +, markerOffset(0) +, numToConsume(0) +{ +} + +TokenBuffer::~TokenBuffer( void ) +{ +} + +/** Ensure that the token buffer is sufficiently full */ +void TokenBuffer::fill(unsigned int amount) +{ + syncConsume(); + // Fill the buffer sufficiently to hold needed tokens + while (queue.entries() < (amount + markerOffset)) + { + // Append the next token + queue.append(input.nextToken()); + } +} + +/** Get a lookahead token value */ +int TokenBuffer::LA(unsigned int i) +{ + fill(i); + return queue.elementAt(markerOffset+i-1)->getType(); +} + +/** Get a lookahead token */ +RefToken TokenBuffer::LT(unsigned int i) +{ + fill(i); + return queue.elementAt(markerOffset+i-1); +} + +/** Return an integer marker that can be used to rewind the buffer to + * its current state. + */ +unsigned int TokenBuffer::mark() +{ + syncConsume(); + nMarkers++; + return markerOffset; +} + +/**Rewind the token buffer to a marker. + * @param mark Marker returned previously from mark() + */ +void TokenBuffer::rewind(unsigned int mark) +{ + syncConsume(); + markerOffset=mark; + nMarkers--; +} + +/// Get number of non-consumed tokens +unsigned int TokenBuffer::entries() const +{ + return queue.entries() - markerOffset; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE + } +#endif diff --git a/lib/antlr/src/TokenRefCount.cpp b/lib/antlr/src/TokenRefCount.cpp new file mode 100644 index 00000000..0afb0f84 --- /dev/null +++ b/lib/antlr/src/TokenRefCount.cpp @@ -0,0 +1,41 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id:$ + */ +#include "antlr/TokenRefCount.hpp" +#include "antlr/Token.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +TokenRef::TokenRef(Token* p) +: ptr(p), count(1) +{ + if (p && !p->ref) + p->ref = this; +} + +TokenRef::~TokenRef() +{ + delete ptr; +} + +TokenRef* TokenRef::getRef(const Token* p) +{ + if (p) { + Token* pp = const_cast<Token*>(p); + if (pp->ref) + return pp->ref->increment(); + else + return new TokenRef(pp); + } else + return 0; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/TokenStreamBasicFilter.cpp b/lib/antlr/src/TokenStreamBasicFilter.cpp new file mode 100644 index 00000000..982e8645 --- /dev/null +++ b/lib/antlr/src/TokenStreamBasicFilter.cpp @@ -0,0 +1,44 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/TokenStreamBasicFilter.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** This object is a TokenStream that passes through all + * tokens except for those that you tell it to discard. + * There is no buffering of the tokens. + */ +TokenStreamBasicFilter::TokenStreamBasicFilter(TokenStream& input_) +: input(&input_) +{ +} + +void TokenStreamBasicFilter::discard(int ttype) +{ + discardMask.add(ttype); +} + +void TokenStreamBasicFilter::discard(const BitSet& mask) +{ + discardMask = mask; +} + +RefToken TokenStreamBasicFilter::nextToken() +{ + RefToken tok = input->nextToken(); + while ( tok && discardMask.member(tok->getType()) ) { + tok = input->nextToken(); + } + return tok; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/TokenStreamHiddenTokenFilter.cpp b/lib/antlr/src/TokenStreamHiddenTokenFilter.cpp new file mode 100644 index 00000000..431df0c3 --- /dev/null +++ b/lib/antlr/src/TokenStreamHiddenTokenFilter.cpp @@ -0,0 +1,156 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/TokenStreamHiddenTokenFilter.hpp" +#include "antlr/CommonHiddenStreamToken.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/**This object filters a token stream coming from a lexer + * or another TokenStream so that only certain token channels + * get transmitted to the parser. + * + * Any of the channels can be filtered off as "hidden" channels whose + * tokens can be accessed from the parser. + */ + +TokenStreamHiddenTokenFilter::TokenStreamHiddenTokenFilter(TokenStream& input) +: TokenStreamBasicFilter(input) +{ +} + +void TokenStreamHiddenTokenFilter::consume() +{ + nextMonitoredToken = input->nextToken(); +} + +void TokenStreamHiddenTokenFilter::consumeFirst() +{ + consume(); + + // Handle situation where hidden or discarded tokens + // appear first in input stream + RefToken p; + // while hidden or discarded scarf tokens + while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) { + if ( hideMask.member(LA(1)->getType()) ) { + if ( !p ) { + p = LA(1); + } + else { + static_cast<CommonHiddenStreamToken*>(p.get())->setHiddenAfter(LA(1)); + static_cast<CommonHiddenStreamToken*>(LA(1).get())->setHiddenBefore(p); // double-link + p = LA(1); + } + lastHiddenToken = p; + if (!firstHidden) + firstHidden = p; // record hidden token if first + } + consume(); + } +} + +BitSet TokenStreamHiddenTokenFilter::getDiscardMask() const +{ + return discardMask; +} + +/** Return a ptr to the hidden token appearing immediately after + * token t in the input stream. + */ +RefToken TokenStreamHiddenTokenFilter::getHiddenAfter(RefToken t) +{ + return static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenAfter(); +} + +/** Return a ptr to the hidden token appearing immediately before + * token t in the input stream. + */ +RefToken TokenStreamHiddenTokenFilter::getHiddenBefore(RefToken t) +{ + return static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenBefore(); +} + +BitSet TokenStreamHiddenTokenFilter::getHideMask() const +{ + return hideMask; +} + +/** Return the first hidden token if one appears + * before any monitored token. + */ +RefToken TokenStreamHiddenTokenFilter::getInitialHiddenToken() +{ + return firstHidden; +} + +void TokenStreamHiddenTokenFilter::hide(int m) +{ + hideMask.add(m); +} + +void TokenStreamHiddenTokenFilter::hide(const BitSet& mask) +{ + hideMask = mask; +} + +RefToken TokenStreamHiddenTokenFilter::LA(int) +{ + return nextMonitoredToken; +} + +/** Return the next monitored token. +* Test the token following the monitored token. +* If following is another monitored token, save it +* for the next invocation of nextToken (like a single +* lookahead token) and return it then. +* If following is unmonitored, nondiscarded (hidden) +* channel token, add it to the monitored token. +* +* Note: EOF must be a monitored Token. +*/ +RefToken TokenStreamHiddenTokenFilter::nextToken() +{ + // handle an initial condition; don't want to get lookahead + // token of this splitter until first call to nextToken + if ( !LA(1) ) { + consumeFirst(); + } + + // we always consume hidden tokens after monitored, thus, + // upon entry LA(1) is a monitored token. + RefToken monitored = LA(1); + // point to hidden tokens found during last invocation + static_cast<CommonHiddenStreamToken*>(monitored.get())->setHiddenBefore(lastHiddenToken); + lastHiddenToken = nullToken; + + // Look for hidden tokens, hook them into list emanating + // from the monitored tokens. + consume(); + RefToken p = monitored; + // while hidden or discarded scarf tokens + while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) { + if ( hideMask.member(LA(1)->getType()) ) { + // attach the hidden token to the monitored in a chain + // link forwards + static_cast<CommonHiddenStreamToken*>(p.get())->setHiddenAfter(LA(1)); + // link backwards + if (p != monitored) { //hidden cannot point to monitored tokens + static_cast<CommonHiddenStreamToken*>(LA(1).get())->setHiddenBefore(p); + } + p = lastHiddenToken = LA(1); + } + consume(); + } + return monitored; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/TokenStreamRewriteEngine.cpp b/lib/antlr/src/TokenStreamRewriteEngine.cpp new file mode 100644 index 00000000..2f171eb6 --- /dev/null +++ b/lib/antlr/src/TokenStreamRewriteEngine.cpp @@ -0,0 +1,214 @@ +#include <antlr/config.hpp> + +#include <string> +#include <list> +#include <vector> +#include <map> +#include <utility> +#include <iostream> +#include <iterator> +#include <sstream> +#include <cassert> + +#include <antlr/TokenStream.hpp> +#include <antlr/TokenWithIndex.hpp> +#include <antlr/BitSet.hpp> +#include <antlr/TokenStreamRewriteEngine.hpp> + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +#ifndef NO_STATIC_CONSTS +const size_t TokenStreamRewriteEngine::MIN_TOKEN_INDEX = 0; +const int TokenStreamRewriteEngine::PROGRAM_INIT_SIZE = 100; +#endif + +const char* TokenStreamRewriteEngine::DEFAULT_PROGRAM_NAME = "default"; + +namespace { + + struct compareOperationIndex { + typedef TokenStreamRewriteEngine::RewriteOperation RewriteOperation; + bool operator() ( const RewriteOperation* a, const RewriteOperation* b ) const + { + return a->getIndex() < b->getIndex(); + } + }; + struct dumpTokenWithIndex { + dumpTokenWithIndex( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {} + void operator() ( const RefTokenWithIndex& t ) { + out << "[txt='" << t->getText() << "' tp=" << t->getType() << " idx=" << t->getIndex() << "]\n"; + } + ANTLR_USE_NAMESPACE(std)ostream& out; + }; +} + +TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream) +: stream(upstream) +, index(MIN_TOKEN_INDEX) +, tokens() +, programs() +, discardMask() +{ +} + +TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize ) +: stream(upstream) +, index(MIN_TOKEN_INDEX) +, tokens(initialSize) +, programs() +, discardMask() +{ +} + +RefToken TokenStreamRewriteEngine::nextToken( void ) +{ + RefTokenWithIndex t; + // suck tokens until end of stream or we find a non-discarded token + do { + t = RefTokenWithIndex(stream.nextToken()); + if ( t ) + { + t->setIndex(index); // what is t's index in list? + if ( t->getType() != Token::EOF_TYPE ) { + tokens.push_back(t); // track all tokens except EOF + } + index++; // move to next position + } + } while ( t && discardMask.member(t->getType()) ); + return RefToken(t); +} + +void TokenStreamRewriteEngine::rollback( const std::string& programName, + size_t instructionIndex ) +{ + program_map::iterator rewrite = programs.find(programName); + if( rewrite != programs.end() ) + { + operation_list& prog = rewrite->second; + operation_list::iterator + j = prog.begin(), + end = prog.end(); + + std::advance(j,instructionIndex); + if( j != end ) + prog.erase(j, end); + } +} + +void TokenStreamRewriteEngine::originalToStream( std::ostream& out, + size_t start, + size_t end ) const +{ + token_list::const_iterator s = tokens.begin(); + std::advance( s, start ); + token_list::const_iterator e = s; + std::advance( e, end-start ); + std::for_each( s, e, tokenToStream(out) ); +} + +void TokenStreamRewriteEngine::toStream( std::ostream& out, + const std::string& programName, + size_t firstToken, + size_t lastToken ) const +{ + if( tokens.size() == 0 ) + return; + + program_map::const_iterator rewriter = programs.find(programName); + + if ( rewriter == programs.end() ) + return; + + // get the prog and some iterators in it... + const operation_list& prog = rewriter->second; + operation_list::const_iterator + rewriteOpIndex = prog.begin(), + rewriteOpEnd = prog.end(); + + size_t tokenCursor = firstToken; + // make sure we don't run out of the tokens we have... + if( lastToken > (tokens.size() - 1) ) + lastToken = tokens.size() - 1; + + while ( tokenCursor <= lastToken ) + { +// std::cout << "tokenCursor = " << tokenCursor << " first prog index = " << (*rewriteOpIndex)->getIndex() << std::endl; + + if( rewriteOpIndex != rewriteOpEnd ) + { + size_t up_to_here = std::min(lastToken,(*rewriteOpIndex)->getIndex()); + while( tokenCursor < up_to_here ) + out << tokens[tokenCursor++]->getText(); + } + while ( rewriteOpIndex != rewriteOpEnd && + tokenCursor == (*rewriteOpIndex)->getIndex() && + tokenCursor <= lastToken ) + { + tokenCursor = (*rewriteOpIndex)->execute(out); + ++rewriteOpIndex; + } + if( tokenCursor <= lastToken ) + out << tokens[tokenCursor++]->getText(); + } + // std::cout << "Handling tail operations # left = " << std::distance(rewriteOpIndex,rewriteOpEnd) << std::endl; + // now see if there are operations (append) beyond last token index + std::for_each( rewriteOpIndex, rewriteOpEnd, executeOperation(out) ); + rewriteOpIndex = rewriteOpEnd; +} + +void TokenStreamRewriteEngine::toDebugStream( std::ostream& out, + size_t start, + size_t end ) const +{ + token_list::const_iterator s = tokens.begin(); + std::advance( s, start ); + token_list::const_iterator e = s; + std::advance( e, end-start ); + std::for_each( s, e, dumpTokenWithIndex(out) ); +} + +void TokenStreamRewriteEngine::addToSortedRewriteList( const std::string& programName, + RewriteOperation* op ) +{ + program_map::iterator rewrites = programs.find(programName); + // check if we got the program already.. + if ( rewrites == programs.end() ) + { + // no prog make a new one... + operation_list ops; + ops.push_back(op); + programs.insert(std::make_pair(programName,ops)); + return; + } + operation_list& prog = rewrites->second; + + if( prog.empty() ) + { + prog.push_back(op); + return; + } + + operation_list::iterator i, end = prog.end(); + i = end; + --i; + // if at or beyond last op's index, just append + if ( op->getIndex() >= (*i)->getIndex() ) { + prog.push_back(op); // append to list of operations + return; + } + i = prog.begin(); + + if( i != end ) + { + operation_list::iterator pos = std::upper_bound( i, end, op, compareOperationIndex() ); + prog.insert(pos,op); + } + else + prog.push_back(op); +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif diff --git a/lib/antlr/src/TokenStreamSelector.cpp b/lib/antlr/src/TokenStreamSelector.cpp new file mode 100644 index 00000000..602e50dc --- /dev/null +++ b/lib/antlr/src/TokenStreamSelector.cpp @@ -0,0 +1,107 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/TokenStreamSelector.hpp" +#include "antlr/TokenStreamRetryException.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** A token stream MUX (multiplexor) knows about n token streams + * and can multiplex them onto the same channel for use by token + * stream consumer like a parser. This is a way to have multiple + * lexers break up the same input stream for a single parser. + * Or, you can have multiple instances of the same lexer handle + * multiple input streams; this works great for includes. + */ + +TokenStreamSelector::TokenStreamSelector() +: input(0) +{ +} + +TokenStreamSelector::~TokenStreamSelector() +{ +} + +void TokenStreamSelector::addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key) +{ + inputStreamNames[key] = stream; +} + +TokenStream* TokenStreamSelector::getCurrentStream() const +{ + return input; +} + +TokenStream* TokenStreamSelector::getStream(const ANTLR_USE_NAMESPACE(std)string& sname) const +{ + inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname); + if (i == inputStreamNames.end()) { + throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found"; + } + return (*i).second; +} + +RefToken TokenStreamSelector::nextToken() +{ + // keep looking for a token until you don't + // get a retry exception + for (;;) { + try { + return input->nextToken(); + } + catch (TokenStreamRetryException&) { + // just retry "forever" + } + } +} + +TokenStream* TokenStreamSelector::pop() +{ + TokenStream* stream = streamStack.top(); + streamStack.pop(); + select(stream); + return stream; +} + +void TokenStreamSelector::push(TokenStream* stream) +{ + streamStack.push(input); + select(stream); +} + +void TokenStreamSelector::push(const ANTLR_USE_NAMESPACE(std)string& sname) +{ + streamStack.push(input); + select(sname); +} + +void TokenStreamSelector::retry() +{ + throw TokenStreamRetryException(); +} + +/** Set the stream without pushing old stream */ +void TokenStreamSelector::select(TokenStream* stream) +{ + input = stream; +} + +void TokenStreamSelector::select(const ANTLR_USE_NAMESPACE(std)string& sname) +{ + inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname); + if (i == inputStreamNames.end()) { + throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found"; + } + input = (*i).second; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + diff --git a/lib/antlr/src/TreeParser.cpp b/lib/antlr/src/TreeParser.cpp new file mode 100644 index 00000000..6b3f2ca1 --- /dev/null +++ b/lib/antlr/src/TreeParser.cpp @@ -0,0 +1,72 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ + +#include "antlr/TreeParser.hpp" +#include "antlr/ASTNULLType.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/** The AST Null object; the parsing cursor is set to this when + * it is found to be null. This way, we can test the + * token type of a node without having to have tests for null + * everywhere. + */ +RefAST TreeParser::ASTNULL(new ASTNULLType); + +/** Parser error-reporting function can be overridden in subclass */ +void TreeParser::reportError(const RecognitionException& ex) +{ + ANTLR_USE_NAMESPACE(std)cerr << ex.toString().c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Parser error-reporting function can be overridden in subclass */ +void TreeParser::reportError(const ANTLR_USE_NAMESPACE(std)string& s) +{ + ANTLR_USE_NAMESPACE(std)cerr << "error: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Parser warning-reporting function can be overridden in subclass */ +void TreeParser::reportWarning(const ANTLR_USE_NAMESPACE(std)string& s) +{ + ANTLR_USE_NAMESPACE(std)cerr << "warning: " << s.c_str() << ANTLR_USE_NAMESPACE(std)endl; +} + +/** Procedure to write out an indent for traceIn and traceOut */ +void TreeParser::traceIndent() +{ + for( int i = 0; i < traceDepth; i++ ) + ANTLR_USE_NAMESPACE(std)cout << " "; +} + +void TreeParser::traceIn(const char* rname, RefAST t) +{ + traceDepth++; + traceIndent(); + + ANTLR_USE_NAMESPACE(std)cout << "> " << rname + << "(" << (t ? t->toString().c_str() : "null") << ")" + << ((inputState->guessing>0)?" [guessing]":"") + << ANTLR_USE_NAMESPACE(std)endl; +} + +void TreeParser::traceOut(const char* rname, RefAST t) +{ + traceIndent(); + + ANTLR_USE_NAMESPACE(std)cout << "< " << rname + << "(" << (t ? t->toString().c_str() : "null") << ")" + << ((inputState->guessing>0)?" [guessing]":"") + << ANTLR_USE_NAMESPACE(std)endl; + + traceDepth--; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif |