*** empty log message ***
authorbdemsky <bdemsky>
Fri, 3 Feb 2006 01:15:48 +0000 (01:15 +0000)
committerbdemsky <bdemsky>
Fri, 3 Feb 2006 01:15:48 +0000 (01:15 +0000)
21 files changed:
Robust/JavaGrammar/COPYING [new file with mode: 0644]
Robust/JavaGrammar/Makefile [new file with mode: 0644]
Robust/JavaGrammar/README [new file with mode: 0644]
Robust/cup/java_cup/runtime/Scanner.class [new file with mode: 0644]
Robust/cup/java_cup/runtime/Scanner.java [new file with mode: 0644]
Robust/cup/java_cup/runtime/Symbol.class [new file with mode: 0644]
Robust/cup/java_cup/runtime/Symbol.java [new file with mode: 0644]
Robust/cup/java_cup/runtime/lr_parser.class [new file with mode: 0644]
Robust/cup/java_cup/runtime/lr_parser.java [new file with mode: 0644]
Robust/cup/java_cup/runtime/virtual_parse_stack.class [new file with mode: 0644]
Robust/cup/java_cup/runtime/virtual_parse_stack.java [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/CUP$parser$actions.class [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/Main.class [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/Main.java [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/parser.class [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/parser.cup [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/parser.java [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/scanner.class [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/scanner.java [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/sym.class [new file with mode: 0644]
Robust/cup/java_cup/simple_calc/sym.java [new file with mode: 0644]

diff --git a/Robust/JavaGrammar/COPYING b/Robust/JavaGrammar/COPYING
new file mode 100644 (file)
index 0000000..a43ea21
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+       Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/Robust/JavaGrammar/Makefile b/Robust/JavaGrammar/Makefile
new file mode 100644 (file)
index 0000000..758243e
--- /dev/null
@@ -0,0 +1,89 @@
+# Makefile to create simple test framework for the java parsers.
+# Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
+# Released under the terms of the GPL with NO WARRANTY. See COPYING.
+
+# java environment.
+JAVA=java
+JAVAC=javac
+JFLAGS=-g
+#CUPFLAGS=-dump_states
+
+# list the available java grammar versions
+JAVA_GRAMMARS=10 11 12 14 15
+
+all: $(foreach j,$(JAVA_GRAMMARS),Parse/Grm$(j).class) \
+       Lex/Lex.class Main/Main.class
+
+# Feed the appropriate CUP specification to javaCUP.
+Parse/Grm%.java Parse/Sym%.java: Parse/java%.cup
+       cd Parse && \
+       ${JAVA} java_cup.Main ${CUPFLAGS} -parser Grm$* -symbols Sym$* \
+               < java$*.cup 2>Grm$*.err && tail Grm$*.err
+
+# Compile the java source for the parser.
+Parse/Grm%.class: Parse/Lexer.java Parse/Grm%.java Parse/Sym%.java
+       ${JAVAC} ${JFLAGS} $^
+
+# Make the lexer symbols from the parser symbols.
+Lex/Sym.java: $(foreach j,$(JAVA_GRAMMARS),Parse/Sym$(j).java)
+# verify that these are all identical!
+       @if cat $^ | sed -e 's/Sym[0-9][0-9]/Sym/g' | sort | uniq -c | \
+       egrep -v '^[ ]*[0-9]*[05]       ' | grep -v "^[ ]*[0-9]*[       ]*//"\
+       ; then \
+         echo $^ "are not identical;" ;\
+         echo "we won't be able to build a single lexer for all of these." ;\
+         exit 1;\
+       fi
+# now make a generic version.
+       sed -e "s/package Parse/package Lex/" -e "s/Sym10/Sym/g" \
+               < Parse/Sym10.java > $@
+
+# Compile the java source for the (unified) lexer.
+Lex/Lex.class: Lex/*.java Lex/Sym.java
+       ${JAVAC} ${JFLAGS} Lex/*.java
+
+# Compile the java source for the driver.
+Main/Main.class: Main/Main.java
+       ${JAVAC} ${JFLAGS} Main/*.java
+
+# run some quick tests.
+test: Parse/Lexer.java Parse/Grm14.java all phony
+       for n in 1 2 3 4 5; do \
+       ( ${JAVA} Main.Main Parse/Lexer.java $$n && \
+         ${JAVA} Main.Main Parse/Grm14.java $$n && \
+         ${JAVA} Main.Main tests/Escape.java) || exit 1; \
+       done
+       for n in 2 3 4 5; do \
+         ${JAVA} Main.Main tests/Eric.java $$n || exit 1; \
+       done
+       ${JAVA} Main.Main tests/TestJSR201.java 5
+       ${JAVA} Main.Main tests/Test15.java 5
+       ${JAVA} Main.Main tests/Eric15.java 5
+# always run the test.
+phony:
+
+# target to make the distributed files.
+dist:
+       -$(RM) -rf JavaGrammar javagrm.tar.gz javagrm.zip
+       cvs -d `cat CVS/Root` co -A -P JavaGrammar
+       find JavaGrammar -type d -name CVS | xargs $(RM) -rf
+       tar czvf javagrm.tar.gz JavaGrammar
+       zip -r javagrm.zip JavaGrammar
+       cp javagrm.tar.gz `date +javagrm-%d-%b-%Y.tar.gz`
+       cp README javagrm-README.txt
+       $(RM) -rf JavaGrammar
+upload: dist
+       chmod a+r javagrm*
+       scp javagrm* shades.cs.princeton.edu:/u/appel/public_html/modern/java/CUP
+
+# clean up after ourselves.
+clean:
+       $(RM) Lex/Sym.java \
+               $(foreach j,$(JAVA_GRAMMARS),Parse/Grm$(j).err) \
+               $(foreach j,$(JAVA_GRAMMARS),Parse/Grm$(j).java) \
+               $(foreach j,$(JAVA_GRAMMARS),Parse/Sym$(j).java) \
+               Parse/parser.java Parse/sym.java \
+              */*.class 
+
+veryclean: clean
+       $(RM) *~ */*~ javagrm*
diff --git a/Robust/JavaGrammar/README b/Robust/JavaGrammar/README
new file mode 100644 (file)
index 0000000..62edac6
--- /dev/null
@@ -0,0 +1,146 @@
+This package contains CUP grammars for the Java programming language.
+
+Copyright (C) 2002 C. Scott Ananian
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.  See the file COPYING for more details.
+
+Directory structure:
+ Parse/                contains the Java grammars.
+  java10.cup    contains a Java 1.0 grammar.
+  java11.cup    contains a Java 1.1 grammar.
+  java12.cup    contains a Java 1.2 grammar. [added 11-feb-1999]
+  java14.cup    contains a Java 1.4 grammar. [added 10-apr-2002]
+  java15.cup    contains a Java 1.5 Java grammar. [added 12-apr-2002]
+                [last updated 28-jul-2003; Java 1.5 spec not yet final.]
+  Lexer.java    interface description for a lexer.
+
+ Lex/           contains a simple but complete Java lexer.
+  Lex.java      main class
+  Sym.java      a copy of Parse/Sym.java containing symbolic constants.
+
+ Main/
+  Main.java     a simple testing skeleton for the parser/lexer.
+
+The grammar in Parse/ should be processed by CUP into Grm.java.
+There are much better ways to write lexers for java, but the
+implementation in Lex/ seemed to be the easiest at the time.  The
+lexer implemented here may not be as efficient as a table-driven lexer,
+but adheres to the java specification exactly.
+
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 3-Apr-1998
+                                                [revised 12-apr-2002]
+                                                [revised 28-jul-2003]
+
+UPDATE: Fixed a lexer bug: '5.2' is a double, not a float.  Thanks to
+Ben Walter <bwalter@mit.edu> for spotting this.
+
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 14-Jul-1998
+
+UPDATE: Fixed a couple of minor bugs.
+1) Lex.EscapedUnicodeReader wasn't actually parsing unicode escape sequences
+   properly because we didn't implement read(char[], int, int).
+2) Grammar fixes: int[].class, Object[].class and all array class
+   literals were not being parsed.  Also special void.class literal
+   inadvertantly omitted from the grammar.
+Both these problems have been fixed.
+
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 11-Feb-1999
+
+UPDATE: Fixed another lexer bug: Large integer constants such as
+0xFFFF0000 were being incorrectly flagged as 'too large for an int'.
+Also, by the Java Language Specification, "\477" is a valid string
+literal (it is the same as "\0477": the character '\047' followed by
+the character '7').  The lexer handles this case correctly now.
+
+Created java12.cup with grammar updated to Java 1.2.  Features
+added include the 'strictfp' keyword and the various new inner class
+features at http://java.sun.com/docs/books/jls/nested-class-clarify.html.
+
+Also added slightly better position/error reporting to all parsers.
+
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 11-Feb-1999
+
+UPDATE: fixed some buglets with symbol/error position reporting.
+
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 13-Sep-1999
+
+UPDATE: multi-line comments were causing incorrect character position
+reporting.  If you were using the character-position-to-line-number
+code in Lexer, you would never have noticed this problem.  Thanks to
+William Young <youngwr@rose-hulman.edu> for pointing this out.
+
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 27-Oct-1999
+
+UPDATE: extended grammar to handle the 'assert' statement added in
+Java 1.4.  Also fixed an oversight: a single SEMICOLON is a valid
+ClassBodyDeclaration; this was added to allow trailing semicolons
+uniformly on class declarations.  This wasn't part of the original
+JLS, but was revised in to conform with the actual behavior of the
+javac compiler.  I've added this to all the grammars from 1.0-1.4
+to conform to javac behavior; let me know if you've got a good
+reason why this production shouldn't be in early grammars.
+
+Also futzed with the Makefile some to allow building a 'universal'
+driver which will switch between java 1.0/1.1/1.2/1.4 on demand.
+This helps me test the separate grammars; maybe you'll find a
+use for this behavior too.
+
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 10-Apr-2002
+
+NEW: added a grammar for the JSR-14 "Adding Generics to the Java
+Programming Language" Java variant.  Calling this java15.cup, since
+this JSR currently seems to be destined for inclusion in Java 1.5.
+This grammar is very very tricky!  I need to use a lexer trick to
+handle type casts to parameterized types, which otherwise do not
+seem to be LALR(1).
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 12-Apr-2002
+
+UPDATE: various bug fixes to all grammars, in reponse to bugs reported
+by Eric Blake <ebb9@email.byu.edu> and others.
+ a) TWEAK: added 'String' type to IDENTIFIER terminal to match Number types
+    given to numeric literals. (all grammars)
+ b) BUG FIX: added SEMICOLON production to interface_member_declaration to
+    allow optional trailing semicolons, in accordance with the JLS (for
+    java 1.2-and-later grammars) and Sun practice (for earlier grammars).
+    The 10-Apr-2002 release did not address this problem completely, due
+    to an oversight. (all grammars)
+ c) BUG FIX: '<primary>.this(...);' is not a legal production;
+    '<name>.super(...);' and '<name>.new <identifier>(...' ought to be.
+    In particular, plain identifiers ought to be able to qualify instance
+    creation and explicit constructor invocation.
+    (fix due to Eric Blake; java 1.2 grammar and following)
+ d) BUG FIX: parenthesized variables on the left-hand-side of an assignment
+    ought to be legal, according to JLS2.  For example, this code is
+    legal:
+       class Foo { void m(int i) { (i) = 1; } }
+    (fix due to Eric Blake; java 1.2 grammar and following)
+ e) BUG FIX: array access of anonymous arrays ought to be legal, according
+    to JLS2.  For example, this is legal code:
+       class Foo { int i = new int[]{0}[0]; }
+    (fix due to Eric Blake; java 1.2 grammar and following)
+ f) BUG FIX: nested parameterized types ought to be legal, for example:
+       class A<T> { class B<S> { }  A<String>.B<String> c; }
+    (bug found by Eric Blake; jsr-14 grammar only)
+ g) TWEAK: test cases were added for these issues.
+
+In addition, it should be clarified that the 'java15.cup' grammar is
+really only for java 1.4 + jsr-14; recent developments at Sun indicate
+that "Java 1.5" is likely to include several additional language changes
+in addition to JSR-14 parameterized types; see JSR-201 for more details.
+I will endeavor to add these features to 'java15.cup' as soon as their
+syntax is nailed down.
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 13-Apr-2003
+
+UPDATE: Updated the 'java15.cup' grammar to match the latest specifications
+(and their corrections) for Java 1.5.  This grammar matches the 2.2
+prototype of JSR-14 + JSR-201 capabilities, with some corrections for
+mistakes in the released specification and expected future features of
+Java 1.5 (in particular, arrays of parameterized types bounded by
+wildcards).  Reimplemented java15.cup to use a refactoring originally
+due to Eric Blake which eliminates our previous need for "lexer lookahead"
+(see release notes for 12-April-2002).  Added new 'enum' and '...' tokens
+to the lexer to accomodate Java 1.5.  New test cases added for the
+additional language features.
+  -- C. Scott Ananian <cananian@alumni.princeton.edu> 28-Jul-2003
diff --git a/Robust/cup/java_cup/runtime/Scanner.class b/Robust/cup/java_cup/runtime/Scanner.class
new file mode 100644 (file)
index 0000000..29ef66b
Binary files /dev/null and b/Robust/cup/java_cup/runtime/Scanner.class differ
diff --git a/Robust/cup/java_cup/runtime/Scanner.java b/Robust/cup/java_cup/runtime/Scanner.java
new file mode 100644 (file)
index 0000000..3233551
--- /dev/null
@@ -0,0 +1,25 @@
+package java_cup.runtime;
+
+/**
+ * Defines the Scanner interface, which CUP uses in the default
+ * implementation of <code>lr_parser.scan()</code>.  Integration
+ * of scanners implementing <code>Scanner</code> is facilitated.
+ *
+ * @version last updated 23-Jul-1999
+ * @author David MacMahon <davidm@smartsc.com>
+ */
+
+/* *************************************************
+  Interface Scanner
+  
+  Declares the next_token() method that should be
+  implemented by scanners.  This method is typically
+  called by lr_parser.scan().  End-of-file can be
+  indicated either by returning
+  <code>new Symbol(lr_parser.EOF_sym())</code> or
+  <code>null</code>.
+ ***************************************************/
+public interface Scanner {
+    /** Return the next token, or <code>null</code> on end-of-file. */
+    public Symbol next_token() throws java.lang.Exception;
+}
diff --git a/Robust/cup/java_cup/runtime/Symbol.class b/Robust/cup/java_cup/runtime/Symbol.class
new file mode 100644 (file)
index 0000000..4831d12
Binary files /dev/null and b/Robust/cup/java_cup/runtime/Symbol.class differ
diff --git a/Robust/cup/java_cup/runtime/Symbol.java b/Robust/cup/java_cup/runtime/Symbol.java
new file mode 100644 (file)
index 0000000..eeb6a0b
--- /dev/null
@@ -0,0 +1,105 @@
+package java_cup.runtime;
+
+/**
+ * Defines the Symbol class, which is used to represent all terminals
+ * and nonterminals while parsing.  The lexer should pass CUP Symbols 
+ * and CUP returns a Symbol.
+ *
+ * @version last updated: 7/3/96
+ * @author  Frank Flannery
+ */
+
+/* ****************************************************************
+  Class Symbol
+  what the parser expects to receive from the lexer. 
+  the token is identified as follows:
+  sym:    the symbol type
+  parse_state: the parse state.
+  value:  is the lexical value of type Object
+  left :  is the left position in the original input file
+  right:  is the right position in the original input file
+******************************************************************/
+
+public class Symbol {
+
+/*******************************
+  Constructor for l,r values
+ *******************************/
+
+  public Symbol(int id, int l, int r, Object o) {
+    this(id);
+    left = l;
+    right = r;
+    value = o;
+  }
+
+/*******************************
+  Constructor for no l,r values
+********************************/
+
+  public Symbol(int id, Object o) {
+    this(id, -1, -1, o);
+  }
+
+/*****************************
+  Constructor for no value
+  ***************************/
+
+  public Symbol(int id, int l, int r) {
+    this(id, l, r, null);
+  }
+
+/***********************************
+  Constructor for no value or l,r
+***********************************/
+
+  public Symbol(int sym_num) {
+    this(sym_num, -1);
+    left = -1;
+    right = -1;
+    value = null;
+  }
+
+/***********************************
+  Constructor to give a start state
+***********************************/
+  Symbol(int sym_num, int state)
+    {
+      sym = sym_num;
+      parse_state = state;
+    }
+
+/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The symbol number of the terminal or non terminal being represented */
+  public int sym;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The parse state to be recorded on the parse stack with this symbol.
+   *  This field is for the convenience of the parser and shouldn't be 
+   *  modified except by the parser. 
+   */
+  public int parse_state;
+  /** This allows us to catch some errors caused by scanners recycling
+   *  symbols.  For the use of the parser only. [CSA, 23-Jul-1999] */
+  boolean used_by_parser = false;
+
+/*******************************
+  The data passed to parser
+ *******************************/
+
+  public int left, right;
+  public Object value;
+
+  /*****************************
+    Printing this token out. (Override for pretty-print).
+    ****************************/
+  public String toString() { return "#"+sym; }
+}
+
+
+
+
+
+
diff --git a/Robust/cup/java_cup/runtime/lr_parser.class b/Robust/cup/java_cup/runtime/lr_parser.class
new file mode 100644 (file)
index 0000000..3edd497
Binary files /dev/null and b/Robust/cup/java_cup/runtime/lr_parser.class differ
diff --git a/Robust/cup/java_cup/runtime/lr_parser.java b/Robust/cup/java_cup/runtime/lr_parser.java
new file mode 100644 (file)
index 0000000..3c8335c
--- /dev/null
@@ -0,0 +1,1238 @@
+                                   
+package java_cup.runtime;
+
+import java.util.Stack;
+
+/** This class implements a skeleton table driven LR parser.  In general,
+ *  LR parsers are a form of bottom up shift-reduce parsers.  Shift-reduce
+ *  parsers act by shifting input onto a parse stack until the Symbols 
+ *  matching the right hand side of a production appear on the top of the 
+ *  stack.  Once this occurs, a reduce is performed.  This involves removing
+ *  the Symbols corresponding to the right hand side of the production
+ *  (the so called "handle") and replacing them with the non-terminal from
+ *  the left hand side of the production.  <p>
+ *
+ *  To control the decision of whether to shift or reduce at any given point, 
+ *  the parser uses a state machine (the "viable prefix recognition machine" 
+ *  built by the parser generator).  The current state of the machine is placed
+ *  on top of the parse stack (stored as part of a Symbol object representing
+ *  a terminal or non terminal).  The parse action table is consulted 
+ *  (using the current state and the current lookahead Symbol as indexes) to 
+ *  determine whether to shift or to reduce.  When the parser shifts, it 
+ *  changes to a new state by pushing a new Symbol (containing a new state) 
+ *  onto the stack.  When the parser reduces, it pops the handle (right hand 
+ *  side of a production) off the stack.  This leaves the parser in the state 
+ *  it was in before any of those Symbols were matched.  Next the reduce-goto 
+ *  table is consulted (using the new state and current lookahead Symbol as 
+ *  indexes) to determine a new state to go to.  The parser then shifts to 
+ *  this goto state by pushing the left hand side Symbol of the production 
+ *  (also containing the new state) onto the stack.<p>
+ *
+ *  This class actually provides four LR parsers.  The methods parse() and 
+ *  debug_parse() provide two versions of the main parser (the only difference 
+ *  being that debug_parse() emits debugging trace messages as it parses).  
+ *  In addition to these main parsers, the error recovery mechanism uses two 
+ *  more.  One of these is used to simulate "parsing ahead" in the input 
+ *  without carrying out actions (to verify that a potential error recovery 
+ *  has worked), and the other is used to parse through buffered "parse ahead" 
+ *  input in order to execute all actions and re-synchronize the actual parser 
+ *  configuration.<p>
+ *
+ *  This is an abstract class which is normally filled out by a subclass
+ *  generated by the JavaCup parser generator.  In addition to supplying
+ *  the actual parse tables, generated code also supplies methods which 
+ *  invoke various pieces of user supplied code, provide access to certain
+ *  special Symbols (e.g., EOF and error), etc.  Specifically, the following
+ *  abstract methods are normally supplied by generated code:
+ *  <dl compact>
+ *  <dt> short[][] production_table()
+ *  <dd> Provides a reference to the production table (indicating the index of
+ *       the left hand side non terminal and the length of the right hand side
+ *       for each production in the grammar).
+ *  <dt> short[][] action_table()
+ *  <dd> Provides a reference to the parse action table.
+ *  <dt> short[][] reduce_table()
+ *  <dd> Provides a reference to the reduce-goto table.
+ *  <dt> int start_state()      
+ *  <dd> Indicates the index of the start state.
+ *  <dt> int start_production() 
+ *  <dd> Indicates the index of the starting production.
+ *  <dt> int EOF_sym() 
+ *  <dd> Indicates the index of the EOF Symbol.
+ *  <dt> int error_sym() 
+ *  <dd> Indicates the index of the error Symbol.
+ *  <dt> Symbol do_action() 
+ *  <dd> Executes a piece of user supplied action code.  This always comes at 
+ *       the point of a reduce in the parse, so this code also allocates and 
+ *       fills in the left hand side non terminal Symbol object that is to be 
+ *       pushed onto the stack for the reduce.
+ *  <dt> void init_actions()
+ *  <dd> Code to initialize a special object that encapsulates user supplied
+ *       actions (this object is used by do_action() to actually carry out the 
+ *       actions).
+ *  </dl>
+ *  
+ *  In addition to these routines that <i>must</i> be supplied by the 
+ *  generated subclass there are also a series of routines that <i>may</i> 
+ *  be supplied.  These include:
+ *  <dl>
+ *  <dt> Symbol scan()
+ *  <dd> Used to get the next input Symbol from the scanner.
+ *  <dt> Scanner getScanner()
+ *  <dd> Used to provide a scanner for the default implementation of
+ *       scan().
+ *  <dt> int error_sync_size()
+ *  <dd> This determines how many Symbols past the point of an error 
+ *       must be parsed without error in order to consider a recovery to 
+ *       be valid.  This defaults to 3.  Values less than 2 are not 
+ *       recommended.
+ *  <dt> void report_error(String message, Object info)
+ *  <dd> This method is called to report an error.  The default implementation
+ *       simply prints a message to System.err and where the error occurred.
+ *       This method is often replaced in order to provide a more sophisticated
+ *       error reporting mechanism.
+ *  <dt> void report_fatal_error(String message, Object info)
+ *  <dd> This method is called when a fatal error that cannot be recovered from
+ *       is encountered.  In the default implementation, it calls 
+ *       report_error() to emit a message, then throws an exception.
+ *  <dt> void syntax_error(Symbol cur_token)
+ *  <dd> This method is called as soon as syntax error is detected (but
+ *       before recovery is attempted).  In the default implementation it 
+ *       invokes: report_error("Syntax error", null);
+ *  <dt> void unrecovered_syntax_error(Symbol cur_token)
+ *  <dd> This method is called if syntax error recovery fails.  In the default
+ *       implementation it invokes:<br> 
+ *         report_fatal_error("Couldn't repair and continue parse", null);
+ *  </dl>
+ *
+ * @see     java_cup.runtime.Symbol
+ * @see     java_cup.runtime.Symbol
+ * @see     java_cup.runtime.virtual_parse_stack
+ * @version last updated: 7/3/96
+ * @author  Frank Flannery
+ */
+
+public abstract class lr_parser {
+
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Simple constructor. */
+  public lr_parser()
+    {
+      /* nothing to do here */
+    }
+
+  /** Constructor that sets the default scanner. [CSA/davidm] */
+  public lr_parser(Scanner s) {
+    this(); /* in case default constructor someday does something */
+    setScanner(s);
+  }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Static (Class) Variables ------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** The default number of Symbols after an error we much match to consider 
+   *  it recovered from. 
+   */
+  protected final static int _error_sync_size = 3;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The number of Symbols after an error we much match to consider it 
+   *  recovered from. 
+   */
+  protected int error_sync_size() {return _error_sync_size; }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Table of production information (supplied by generated subclass).
+   *  This table contains one entry per production and is indexed by 
+   *  the negative-encoded values (reduce actions) in the action_table.  
+   *  Each entry has two parts, the index of the non-terminal on the 
+   *  left hand side of the production, and the number of Symbols 
+   *  on the right hand side. 
+   */
+  public abstract short[][] production_table();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The action table (supplied by generated subclass).  This table is
+   *  indexed by state and terminal number indicating what action is to
+   *  be taken when the parser is in the given state (i.e., the given state 
+   *  is on top of the stack) and the given terminal is next on the input.  
+   *  States are indexed using the first dimension, however, the entries for 
+   *  a given state are compacted and stored in adjacent index, value pairs 
+   *  which are searched for rather than accessed directly (see get_action()).  
+   *  The actions stored in the table will be either shifts, reduces, or 
+   *  errors.  Shifts are encoded as positive values (one greater than the 
+   *  state shifted to).  Reduces are encoded as negative values (one less 
+   *  than the production reduced by).  Error entries are denoted by zero. 
+   * 
+   * @see java_cup.runtime.lr_parser#get_action
+   */
+  public abstract short[][] action_table();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The reduce-goto table (supplied by generated subclass).  This
+   *  table is indexed by state and non-terminal number and contains
+   *  state numbers.  States are indexed using the first dimension, however,
+   *  the entries for a given state are compacted and stored in adjacent
+   *  index, value pairs which are searched for rather than accessed 
+   *  directly (see get_reduce()).  When a reduce occurs, the handle 
+   *  (corresponding to the RHS of the matched production) is popped off 
+   *  the stack.  The new top of stack indicates a state.  This table is 
+   *  then indexed by that state and the LHS of the reducing production to 
+   *  indicate where to "shift" to. 
+   *
+   * @see java_cup.runtime.lr_parser#get_reduce
+   */
+  public abstract short[][] reduce_table();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the start state (supplied by generated subclass). */
+  public abstract int start_state();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the start production (supplied by generated subclass). */
+  public abstract int start_production();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the end of file terminal Symbol (supplied by generated 
+   *  subclass). 
+   */
+  public abstract int EOF_sym();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The index of the special error Symbol (supplied by generated subclass). */
+  public abstract int error_sym();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Internal flag to indicate when parser should quit. */
+  protected boolean _done_parsing = false;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method is called to indicate that the parser should quit.  This is 
+   *  normally called by an accept action, but can be used to cancel parsing 
+   *  early in other circumstances if desired. 
+   */
+  public void done_parsing()
+    {
+      _done_parsing = true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+  /* Global parse state shared by parse(), error recovery, and 
+   * debugging routines */
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Indication of the index for top of stack (for use by actions). */
+  protected int tos;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The current lookahead Symbol. */
+  protected Symbol cur_token;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The parse stack itself. */
+  protected Stack stack = new Stack();
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Direct reference to the production table. */ 
+  protected short[][] production_tab;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Direct reference to the action table. */
+  protected short[][] action_tab;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Direct reference to the reduce-goto table. */
+  protected short[][] reduce_tab;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This is the scanner object used by the default implementation
+   *  of scan() to get Symbols.  To avoid name conflicts with existing
+   *  code, this field is private. [CSA/davidm] */
+  private Scanner _scanner;
+
+  /**
+   * Simple accessor method to set the default scanner.
+   */
+  public void setScanner(Scanner s) { _scanner = s; }
+
+  /**
+   * Simple accessor method to get the default scanner.
+   */
+  public Scanner getScanner() { return _scanner; }
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Perform a bit of user supplied action code (supplied by generated 
+   *  subclass).  Actions are indexed by an internal action number assigned
+   *  at parser generation time.
+   *
+   * @param act_num   the internal index of the action to be performed.
+   * @param parser    the parser object we are acting for.
+   * @param stack     the parse stack of that object.
+   * @param top       the index of the top element of the parse stack.
+   */
+  public abstract Symbol do_action(
+    int       act_num, 
+    lr_parser parser, 
+    Stack     stack, 
+    int       top) 
+    throws java.lang.Exception;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** User code for initialization inside the parser.  Typically this 
+   *  initializes the scanner.  This is called before the parser requests
+   *  the first Symbol.  Here this is just a placeholder for subclasses that 
+   *  might need this and we perform no action.   This method is normally
+   *  overridden by the generated code using this contents of the "init with"
+   *  clause as its body.
+   */
+  public void user_init() throws java.lang.Exception { }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Initialize the action object.  This is called before the parser does
+   *  any parse actions. This is filled in by generated code to create
+   *  an object that encapsulates all action code. 
+   */ 
+  protected abstract void init_actions() throws java.lang.Exception;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Get the next Symbol from the input (supplied by generated subclass).
+   *  Once end of file has been reached, all subsequent calls to scan 
+   *  should return an EOF Symbol (which is Symbol number 0).  By default
+   *  this method returns getScanner().next_token(); this implementation
+   *  can be overriden by the generated parser using the code declared in
+   *  the "scan with" clause.  Do not recycle objects; every call to
+   *  scan() should return a fresh object.
+   */
+  public Symbol scan() throws java.lang.Exception {
+    Symbol sym = getScanner().next_token();
+    return (sym!=null) ? sym : new Symbol(EOF_sym());
+  }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Report a fatal error.  This method takes a  message string and an 
+   *  additional object (to be used by specializations implemented in 
+   *  subclasses).  Here in the base class a very simple implementation 
+   *  is provided which reports the error then throws an exception. 
+   *
+   * @param message an error message.
+   * @param info    an extra object reserved for use by specialized subclasses.
+   */
+  public void report_fatal_error(
+    String   message, 
+    Object   info)
+    throws java.lang.Exception
+    {
+      /* stop parsing (not really necessary since we throw an exception, but) */
+      done_parsing();
+
+      /* use the normal error message reporting to put out the message */
+      report_error(message, info);
+
+      /* throw an exception */
+      throw new Exception("Can't recover from previous error(s)");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Report a non fatal error (or warning).  This method takes a message 
+   *  string and an additional object (to be used by specializations 
+   *  implemented in subclasses).  Here in the base class a very simple 
+   *  implementation is provided which simply prints the message to 
+   *  System.err. 
+   *
+   * @param message an error message.
+   * @param info    an extra object reserved for use by specialized subclasses.
+   */
+  public void report_error(String message, Object info)
+    {
+      System.err.print(message);
+      if (info instanceof Symbol)
+       if (((Symbol)info).left != -1)
+       System.err.println(" at character " + ((Symbol)info).left + 
+                          " of input");
+       else System.err.println("");
+      else System.err.println("");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method is called when a syntax error has been detected and recovery 
+   *  is about to be invoked.  Here in the base class we just emit a 
+   *  "Syntax error" error message.  
+   *
+   * @param cur_token the current lookahead Symbol.
+   */
+  public void syntax_error(Symbol cur_token)
+    {
+      report_error("Syntax error", cur_token);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method is called if it is determined that syntax error recovery 
+   *  has been unsuccessful.  Here in the base class we report a fatal error. 
+   *
+   * @param cur_token the current lookahead Symbol.
+   */
+  public void unrecovered_syntax_error(Symbol cur_token)
+    throws java.lang.Exception
+    {
+      report_fatal_error("Couldn't repair and continue parse", cur_token);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Fetch an action from the action table.  The table is broken up into
+   *  rows, one per state (rows are indexed directly by state number).  
+   *  Within each row, a list of index, value pairs are given (as sequential
+   *  entries in the table), and the list is terminated by a default entry 
+   *  (denoted with a Symbol index of -1).  To find the proper entry in a row 
+   *  we do a linear or binary search (depending on the size of the row).  
+   *
+   * @param state the state index of the action being accessed.
+   * @param sym   the Symbol index of the action being accessed.
+   */
+  protected final short get_action(int state, int sym)
+    {
+      short tag;
+      int first, last, probe;
+      short[] row = action_tab[state];
+
+      /* linear search if we are < 10 entries */
+      if (row.length < 20)
+        for (probe = 0; probe < row.length; probe++)
+         {
+           /* is this entry labeled with our Symbol or the default? */
+           tag = row[probe++];
+           if (tag == sym || tag == -1)
+             {
+               /* return the next entry */
+               return row[probe];
+             }
+         }
+      /* otherwise binary search */
+      else
+       {
+         first = 0; 
+         last = (row.length-1)/2 - 1;  /* leave out trailing default entry */
+         while (first <= last)
+           {
+             probe = (first+last)/2;
+             if (sym == row[probe*2])
+               return row[probe*2+1];
+             else if (sym > row[probe*2])
+               first = probe+1;
+             else
+               last = probe-1;
+           }
+
+         /* not found, use the default at the end */
+         return row[row.length-1];
+       }
+
+      /* shouldn't happened, but if we run off the end we return the 
+        default (error == 0) */
+      return 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Fetch a state from the reduce-goto table.  The table is broken up into
+   *  rows, one per state (rows are indexed directly by state number).  
+   *  Within each row, a list of index, value pairs are given (as sequential
+   *  entries in the table), and the list is terminated by a default entry 
+   *  (denoted with a Symbol index of -1).  To find the proper entry in a row 
+   *  we do a linear search.  
+   *
+   * @param state the state index of the entry being accessed.
+   * @param sym   the Symbol index of the entry being accessed.
+   */
+  protected final short get_reduce(int state, int sym)
+    {
+      short tag;
+      short[] row = reduce_tab[state];
+
+      /* if we have a null row we go with the default */
+      if (row == null)
+        return -1;
+
+      for (int probe = 0; probe < row.length; probe++)
+       {
+         /* is this entry labeled with our Symbol or the default? */
+         tag = row[probe++];
+         if (tag == sym || tag == -1)
+           {
+             /* return the next entry */
+             return row[probe];
+           }
+       }
+      /* if we run off the end we return the default (error == -1) */
+      return -1;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** This method provides the main parsing routine.  It returns only when 
+   *  done_parsing() has been called (typically because the parser has 
+   *  accepted, or a fatal error has been reported).  See the header 
+   *  documentation for the class regarding how shift/reduce parsers operate
+   *  and how the various tables are used.
+   */
+  public Symbol parse() throws java.lang.Exception
+    {
+      /* the current action code */
+      int act;
+
+      /* the Symbol/stack element returned by a reduce */
+      Symbol lhs_sym = null;
+
+      /* information about production being reduced with */
+      short handle_size, lhs_sym_num;
+
+      /* set up direct reference to tables to drive the parser */
+
+      production_tab = production_table();
+      action_tab     = action_table();
+      reduce_tab     = reduce_table();
+
+      /* initialize the action encapsulation object */
+      init_actions();
+
+      /* do user initialization */
+      user_init();
+
+      /* get the first token */
+      cur_token = scan(); 
+
+      /* push dummy Symbol with start state to get us underway */
+      stack.removeAllElements();
+      stack.push(new Symbol(0, start_state()));
+      tos = 0;
+
+      /* continue until we are told to stop */
+      for (_done_parsing = false; !_done_parsing; )
+       {
+         /* Check current token for freshness. */
+         if (cur_token.used_by_parser)
+           throw new Error("Symbol recycling detected (fix your scanner).");
+
+         /* current state is always on the top of the stack */
+
+         /* look up action out of the current state with the current input */
+         act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym);
+
+         /* decode the action -- > 0 encodes shift */
+         if (act > 0)
+           {
+             /* shift to the encoded state by pushing it on the stack */
+             cur_token.parse_state = act-1;
+             cur_token.used_by_parser = true;
+             stack.push(cur_token);
+             tos++;
+
+             /* advance to the next Symbol */
+             cur_token = scan();
+           }
+         /* if its less than zero, then it encodes a reduce action */
+         else if (act < 0)
+           {
+             /* perform the action for the reduce */
+             lhs_sym = do_action((-act)-1, this, stack, tos);
+
+             /* look up information about the production */
+             lhs_sym_num = production_tab[(-act)-1][0];
+             handle_size = production_tab[(-act)-1][1];
+
+             /* pop the handle off the stack */
+             for (int i = 0; i < handle_size; i++)
+               {
+                 stack.pop();
+                 tos--;
+               }
+             
+             /* look up the state to go to from the one popped back to */
+             act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
+
+             /* shift to that state */
+             lhs_sym.parse_state = act;
+             lhs_sym.used_by_parser = true;
+             stack.push(lhs_sym);
+             tos++;
+           }
+         /* finally if the entry is zero, we have an error */
+         else if (act == 0)
+           {
+             /* call user syntax error reporting routine */
+             syntax_error(cur_token);
+
+             /* try to error recover */
+             if (!error_recovery(false))
+               {
+                 /* if that fails give up with a fatal syntax error */
+                 unrecovered_syntax_error(cur_token);
+
+                 /* just in case that wasn't fatal enough, end parse */
+                 done_parsing();
+               } else {
+                 lhs_sym = (Symbol)stack.peek();
+               }
+           }
+       }
+      return lhs_sym;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Write a debugging message to System.err for the debugging version 
+   *  of the parser. 
+   *
+   * @param mess the text of the debugging message.
+   */
+  public void debug_message(String mess)
+    {
+      System.err.println(mess);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Dump the parse stack for debugging purposes. */
+  public void dump_stack()
+    {
+      if (stack == null)
+       {
+         debug_message("# Stack dump requested, but stack is null");
+         return;
+       }
+
+      debug_message("============ Parse Stack Dump ============");
+
+      /* dump the stack */
+      for (int i=0; i<stack.size(); i++)
+       {
+         debug_message("Symbol: " + ((Symbol)stack.elementAt(i)).sym +
+                       " State: " + ((Symbol)stack.elementAt(i)).parse_state);
+       }
+      debug_message("==========================================");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do debug output for a reduce. 
+   *
+   * @param prod_num  the production we are reducing with.
+   * @param nt_num    the index of the LHS non terminal.
+   * @param rhs_size  the size of the RHS.
+   */
+  public void debug_reduce(int prod_num, int nt_num, int rhs_size)
+    {
+      debug_message("# Reduce with prod #" + prod_num + " [NT=" + nt_num + 
+                   ", " + "SZ=" + rhs_size + "]");
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do debug output for shift. 
+   *
+   * @param shift_tkn the Symbol being shifted onto the stack.
+   */
+  public void debug_shift(Symbol shift_tkn)
+    {
+      debug_message("# Shift under term #" + shift_tkn.sym + 
+                   " to state #" + shift_tkn.parse_state);
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do debug output for stack state. [CSA]
+   */
+  public void debug_stack() {
+      StringBuffer sb=new StringBuffer("## STACK:");
+      for (int i=0; i<stack.size(); i++) {
+         Symbol s = (Symbol) stack.elementAt(i);
+         sb.append(" <state "+s.parse_state+", sym "+s.sym+">");
+         if ((i%3)==2 || (i==(stack.size()-1))) {
+             debug_message(sb.toString());
+             sb = new StringBuffer("         ");
+         }
+      }
+  }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Perform a parse with debugging output.  This does exactly the
+   *  same things as parse(), except that it calls debug_shift() and
+   *  debug_reduce() when shift and reduce moves are taken by the parser
+   *  and produces various other debugging messages.  
+   */
+  public Symbol debug_parse()
+    throws java.lang.Exception
+    {
+      /* the current action code */
+      int act;
+
+      /* the Symbol/stack element returned by a reduce */
+      Symbol lhs_sym = null;
+
+      /* information about production being reduced with */
+      short handle_size, lhs_sym_num;
+
+      /* set up direct reference to tables to drive the parser */
+      production_tab = production_table();
+      action_tab     = action_table();
+      reduce_tab     = reduce_table();
+
+      debug_message("# Initializing parser");
+
+      /* initialize the action encapsulation object */
+      init_actions();
+
+      /* do user initialization */
+      user_init();
+
+      /* the current Symbol */
+      cur_token = scan(); 
+
+      debug_message("# Current Symbol is #" + cur_token.sym);
+
+      /* push dummy Symbol with start state to get us underway */
+      stack.removeAllElements();
+      stack.push(new Symbol(0, start_state()));
+      tos = 0;
+
+      /* continue until we are told to stop */
+      for (_done_parsing = false; !_done_parsing; )
+       {
+         /* Check current token for freshness. */
+         if (cur_token.used_by_parser)
+           throw new Error("Symbol recycling detected (fix your scanner).");
+
+         /* current state is always on the top of the stack */
+         //debug_stack();
+
+         /* look up action out of the current state with the current input */
+         act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym);
+
+         /* decode the action -- > 0 encodes shift */
+         if (act > 0)
+           {
+             /* shift to the encoded state by pushing it on the stack */
+             cur_token.parse_state = act-1;
+             cur_token.used_by_parser = true;
+             debug_shift(cur_token);
+             stack.push(cur_token);
+             tos++;
+
+             /* advance to the next Symbol */
+             cur_token = scan();
+              debug_message("# Current token is " + cur_token);
+           }
+         /* if its less than zero, then it encodes a reduce action */
+         else if (act < 0)
+           {
+             /* perform the action for the reduce */
+             lhs_sym = do_action((-act)-1, this, stack, tos);
+
+             /* look up information about the production */
+             lhs_sym_num = production_tab[(-act)-1][0];
+             handle_size = production_tab[(-act)-1][1];
+
+             debug_reduce((-act)-1, lhs_sym_num, handle_size);
+
+             /* pop the handle off the stack */
+             for (int i = 0; i < handle_size; i++)
+               {
+                 stack.pop();
+                 tos--;
+               }
+             
+             /* look up the state to go to from the one popped back to */
+             act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
+             debug_message("# Reduce rule: top state " +
+                            ((Symbol)stack.peek()).parse_state +
+                            ", lhs sym " + lhs_sym_num + " -> state " + act); 
+
+             /* shift to that state */
+             lhs_sym.parse_state = act;
+             lhs_sym.used_by_parser = true;
+             stack.push(lhs_sym);
+             tos++;
+
+             debug_message("# Goto state #" + act);
+           }
+         /* finally if the entry is zero, we have an error */
+         else if (act == 0)
+           {
+             /* call user syntax error reporting routine */
+             syntax_error(cur_token);
+
+             /* try to error recover */
+             if (!error_recovery(true))
+               {
+                 /* if that fails give up with a fatal syntax error */
+                 unrecovered_syntax_error(cur_token);
+
+                 /* just in case that wasn't fatal enough, end parse */
+                 done_parsing();
+               } else {
+                 lhs_sym = (Symbol)stack.peek();
+               }
+           }
+       }
+      return lhs_sym;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+  /* Error recovery code */
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Attempt to recover from a syntax error.  This returns false if recovery 
+   *  fails, true if it succeeds.  Recovery happens in 4 steps.  First we
+   *  pop the parse stack down to a point at which we have a shift out
+   *  of the top-most state on the error Symbol.  This represents the
+   *  initial error recovery configuration.  If no such configuration is
+   *  found, then we fail.  Next a small number of "lookahead" or "parse
+   *  ahead" Symbols are read into a buffer.  The size of this buffer is 
+   *  determined by error_sync_size() and determines how many Symbols beyond
+   *  the error must be matched to consider the recovery a success.  Next, 
+   *  we begin to discard Symbols in attempt to get past the point of error
+   *  to a point where we can continue parsing.  After each Symbol, we attempt 
+   *  to "parse ahead" though the buffered lookahead Symbols.  The "parse ahead"
+   *  process simulates that actual parse, but does not modify the real 
+   *  parser's configuration, nor execute any actions. If we can  parse all 
+   *  the stored Symbols without error, then the recovery is considered a 
+   *  success.  Once a successful recovery point is determined, we do an
+   *  actual parse over the stored input -- modifying the real parse 
+   *  configuration and executing all actions.  Finally, we return the the 
+   *  normal parser to continue with the overall parse.
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected boolean error_recovery(boolean debug)
+    throws java.lang.Exception
+    {
+      if (debug) debug_message("# Attempting error recovery");
+
+      /* first pop the stack back into a state that can shift on error and 
+        do that shift (if that fails, we fail) */
+      if (!find_recovery_config(debug))
+       {
+         if (debug) debug_message("# Error recovery fails");
+         return false;
+       }
+
+      /* read ahead to create lookahead we can parse multiple times */
+      read_lookahead();
+
+      /* repeatedly try to parse forward until we make it the required dist */
+      for (;;)
+       {
+         /* try to parse forward, if it makes it, bail out of loop */
+         if (debug) debug_message("# Trying to parse ahead");
+         if (try_parse_ahead(debug))
+           {
+             break;
+           }
+
+         /* if we are now at EOF, we have failed */
+         if (lookahead[0].sym == EOF_sym()) 
+           {
+             if (debug) debug_message("# Error recovery fails at EOF");
+             return false;
+           }
+
+         /* otherwise, we consume another Symbol and try again */
+         // BUG FIX by Bruce Hutton
+         // Computer Science Department, University of Auckland,
+         // Auckland, New Zealand.
+         // It is the first token that is being consumed, not the one 
+         // we were up to parsing
+         if (debug) 
+             debug_message("# Consuming Symbol #" + lookahead[ 0 ].sym);
+         restart_lookahead();
+       }
+
+      /* we have consumed to a point where we can parse forward */
+      if (debug) debug_message("# Parse-ahead ok, going back to normal parse");
+
+      /* do the real parse (including actions) across the lookahead */
+      parse_lookahead(debug);
+
+      /* we have success */
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Determine if we can shift under the special error Symbol out of the 
+   *  state currently on the top of the (real) parse stack. 
+   */
+  protected boolean shift_under_error()
+    {
+      /* is there a shift under error Symbol */
+      return get_action(((Symbol)stack.peek()).parse_state, error_sym()) > 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Put the (real) parse stack into error recovery configuration by 
+   *  popping the stack down to a state that can shift on the special 
+   *  error Symbol, then doing the shift.  If no suitable state exists on 
+   *  the stack we return false 
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected boolean find_recovery_config(boolean debug)
+    {
+      Symbol error_token;
+      int act;
+
+      if (debug) debug_message("# Finding recovery state on stack");
+
+      /* Remember the right-position of the top symbol on the stack */
+      int right_pos = ((Symbol)stack.peek()).right;
+      int left_pos  = ((Symbol)stack.peek()).left;
+
+      /* pop down until we can shift under error Symbol */
+      while (!shift_under_error())
+       {
+         /* pop the stack */
+         if (debug) 
+           debug_message("# Pop stack by one, state was # " +
+                         ((Symbol)stack.peek()).parse_state);
+          left_pos = ((Symbol)stack.pop()).left;       
+         tos--;
+
+         /* if we have hit bottom, we fail */
+         if (stack.empty()) 
+           {
+             if (debug) debug_message("# No recovery state found on stack");
+             return false;
+           }
+       }
+
+      /* state on top of the stack can shift under error, find the shift */
+      act = get_action(((Symbol)stack.peek()).parse_state, error_sym());
+      if (debug) 
+       {
+         debug_message("# Recover state found (#" + 
+                       ((Symbol)stack.peek()).parse_state + ")");
+         debug_message("# Shifting on error to state #" + (act-1));
+       }
+
+      /* build and shift a special error Symbol */
+      error_token = new Symbol(error_sym(), left_pos, right_pos);
+      error_token.parse_state = act-1;
+      error_token.used_by_parser = true;
+      stack.push(error_token);
+      tos++;
+
+      return true;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Lookahead Symbols used for attempting error recovery "parse aheads". */
+  protected Symbol lookahead[];
+
+  /** Position in lookahead input buffer used for "parse ahead". */
+  protected int lookahead_pos;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Read from input to establish our buffer of "parse ahead" lookahead 
+   *  Symbols. 
+   */
+  protected void read_lookahead() throws java.lang.Exception
+    {
+      /* create the lookahead array */
+      lookahead = new Symbol[error_sync_size()];
+
+      /* fill in the array */
+      for (int i = 0; i < error_sync_size(); i++)
+       {
+         lookahead[i] = cur_token;
+         cur_token = scan();
+       }
+
+      /* start at the beginning */
+      lookahead_pos = 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Return the current lookahead in our error "parse ahead" buffer. */
+  protected Symbol cur_err_token() { return lookahead[lookahead_pos]; }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Advance to next "parse ahead" input Symbol. Return true if we have 
+   *  input to advance to, false otherwise. 
+   */
+  protected boolean advance_lookahead()
+    {
+      /* advance the input location */
+      lookahead_pos++;
+
+      /* return true if we didn't go off the end */
+      return lookahead_pos < error_sync_size();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Reset the parse ahead input to one Symbol past where we started error 
+   *  recovery (this consumes one new Symbol from the real input). 
+   */
+  protected void restart_lookahead() throws java.lang.Exception
+    {
+      /* move all the existing input over */
+      for (int i = 1; i < error_sync_size(); i++)
+       lookahead[i-1] = lookahead[i];
+
+      /* read a new Symbol into the last spot */
+      // BUG Fix by Bruce Hutton
+      // Computer Science Department, University of Auckland,
+      // Auckland, New Zealand. [applied 5-sep-1999 by csa]
+      // The following two lines were out of order!!
+      lookahead[error_sync_size()-1] = cur_token;
+      cur_token = scan();
+
+      /* reset our internal position marker */
+      lookahead_pos = 0;
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Do a simulated parse forward (a "parse ahead") from the current 
+   *  stack configuration using stored lookahead input and a virtual parse
+   *  stack.  Return true if we make it all the way through the stored 
+   *  lookahead input without error. This basically simulates the action of 
+   *  parse() using only our saved "parse ahead" input, and not executing any 
+   *  actions.
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected boolean try_parse_ahead(boolean debug)
+    throws java.lang.Exception
+    {
+      int act;
+      short lhs, rhs_size;
+
+      /* create a virtual stack from the real parse stack */
+      virtual_parse_stack vstack = new virtual_parse_stack(stack);
+
+      /* parse until we fail or get past the lookahead input */
+      for (;;)
+       {
+         /* look up the action from the current state (on top of stack) */
+         act = get_action(vstack.top(), cur_err_token().sym);
+
+         /* if its an error, we fail */
+         if (act == 0) return false;
+
+         /* > 0 encodes a shift */
+         if (act > 0)
+           {
+             /* push the new state on the stack */
+             vstack.push(act-1);
+
+             if (debug) debug_message("# Parse-ahead shifts Symbol #" + 
+                      cur_err_token().sym + " into state #" + (act-1));
+
+             /* advance simulated input, if we run off the end, we are done */
+             if (!advance_lookahead()) return true;
+           }
+         /* < 0 encodes a reduce */
+         else
+           {
+             /* if this is a reduce with the start production we are done */
+             if ((-act)-1 == start_production()) 
+               {
+                 if (debug) debug_message("# Parse-ahead accepts");
+                 return true;
+               }
+
+             /* get the lhs Symbol and the rhs size */
+             lhs = production_tab[(-act)-1][0];
+             rhs_size = production_tab[(-act)-1][1];
+
+             /* pop handle off the stack */
+             for (int i = 0; i < rhs_size; i++)
+               vstack.pop();
+
+             if (debug) 
+               debug_message("# Parse-ahead reduces: handle size = " + 
+                 rhs_size + " lhs = #" + lhs + " from state #" + vstack.top());
+
+             /* look up goto and push it onto the stack */
+             vstack.push(get_reduce(vstack.top(), lhs));
+             if (debug) 
+               debug_message("# Goto state #" + vstack.top());
+           }
+       }
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Parse forward using stored lookahead Symbols.  In this case we have
+   *  already verified that parsing will make it through the stored lookahead
+   *  Symbols and we are now getting back to the point at which we can hand
+   *  control back to the normal parser.  Consequently, this version of the
+   *  parser performs all actions and modifies the real parse configuration.  
+   *  This returns once we have consumed all the stored input or we accept.
+   *
+   * @param debug should we produce debugging messages as we parse.
+   */
+  protected void parse_lookahead(boolean debug)
+    throws java.lang.Exception
+    {
+      /* the current action code */
+      int act;
+
+      /* the Symbol/stack element returned by a reduce */
+      Symbol lhs_sym = null;
+
+      /* information about production being reduced with */
+      short handle_size, lhs_sym_num;
+
+      /* restart the saved input at the beginning */
+      lookahead_pos = 0;
+
+      if (debug) 
+       {
+         debug_message("# Reparsing saved input with actions");
+         debug_message("# Current Symbol is #" + cur_err_token().sym);
+         debug_message("# Current state is #" + 
+                       ((Symbol)stack.peek()).parse_state);
+       }
+
+      /* continue until we accept or have read all lookahead input */
+      while(!_done_parsing)
+       {
+         /* current state is always on the top of the stack */
+
+         /* look up action out of the current state with the current input */
+         act = 
+           get_action(((Symbol)stack.peek()).parse_state, cur_err_token().sym);
+
+         /* decode the action -- > 0 encodes shift */
+         if (act > 0)
+           {
+             /* shift to the encoded state by pushing it on the stack */
+             cur_err_token().parse_state = act-1;
+             cur_err_token().used_by_parser = true;
+             if (debug) debug_shift(cur_err_token());
+             stack.push(cur_err_token());
+             tos++;
+
+             /* advance to the next Symbol, if there is none, we are done */
+             if (!advance_lookahead()) 
+               {
+                 if (debug) debug_message("# Completed reparse");
+
+                 /* scan next Symbol so we can continue parse */
+                 // BUGFIX by Chris Harris <ckharris@ucsd.edu>:
+                 //   correct a one-off error by commenting out
+                 //   this next line.
+                 /*cur_token = scan();*/
+
+                 /* go back to normal parser */
+                 return;
+               }
+             
+             if (debug) 
+               debug_message("# Current Symbol is #" + cur_err_token().sym);
+           }
+         /* if its less than zero, then it encodes a reduce action */
+         else if (act < 0)
+           {
+             /* perform the action for the reduce */
+             lhs_sym = do_action((-act)-1, this, stack, tos);
+
+             /* look up information about the production */
+             lhs_sym_num = production_tab[(-act)-1][0];
+             handle_size = production_tab[(-act)-1][1];
+
+             if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size);
+
+             /* pop the handle off the stack */
+             for (int i = 0; i < handle_size; i++)
+               {
+                 stack.pop();
+                 tos--;
+               }
+             
+             /* look up the state to go to from the one popped back to */
+             act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num);
+
+             /* shift to that state */
+             lhs_sym.parse_state = act;
+             lhs_sym.used_by_parser = true;
+             stack.push(lhs_sym);
+             tos++;
+              
+             if (debug) debug_message("# Goto state #" + act);
+
+           }
+         /* finally if the entry is zero, we have an error 
+            (shouldn't happen here, but...)*/
+         else if (act == 0)
+           {
+             report_fatal_error("Syntax error", lhs_sym);
+             return;
+           }
+       }
+
+       
+    }
+
+  /*-----------------------------------------------------------*/
+
+  /** Utility function: unpacks parse tables from strings */
+  protected static short[][] unpackFromStrings(String[] sa)
+    {
+      // Concatanate initialization strings.
+      StringBuffer sb = new StringBuffer(sa[0]);
+      for (int i=1; i<sa.length; i++)
+       sb.append(sa[i]);
+      int n=0; // location in initialization string
+      int size1 = (((int)sb.charAt(n))<<16) | ((int)sb.charAt(n+1)); n+=2;
+      short[][] result = new short[size1][];
+      for (int i=0; i<size1; i++) {
+        int size2 = (((int)sb.charAt(n))<<16) | ((int)sb.charAt(n+1)); n+=2;
+        result[i] = new short[size2];
+        for (int j=0; j<size2; j++)
+          result[i][j] = (short) (sb.charAt(n++)-2);
+      }
+      return result;
+    }
+}
+
diff --git a/Robust/cup/java_cup/runtime/virtual_parse_stack.class b/Robust/cup/java_cup/runtime/virtual_parse_stack.class
new file mode 100644 (file)
index 0000000..1c3435c
Binary files /dev/null and b/Robust/cup/java_cup/runtime/virtual_parse_stack.class differ
diff --git a/Robust/cup/java_cup/runtime/virtual_parse_stack.java b/Robust/cup/java_cup/runtime/virtual_parse_stack.java
new file mode 100644 (file)
index 0000000..a4386aa
--- /dev/null
@@ -0,0 +1,145 @@
+
+package java_cup.runtime;
+
+import java.util.Stack;
+
+/** This class implements a temporary or "virtual" parse stack that 
+ *  replaces the top portion of the actual parse stack (the part that 
+ *  has been changed by some set of operations) while maintaining its
+ *  original contents.  This data structure is used when the parse needs 
+ *  to "parse ahead" to determine if a given error recovery attempt will 
+ *  allow the parse to continue far enough to consider it successful.  Once 
+ *  success or failure of parse ahead is determined the system then 
+ *  reverts to the original parse stack (which has not actually been 
+ *  modified).  Since parse ahead does not execute actions, only parse
+ *  state is maintained on the virtual stack, not full Symbol objects.
+ *
+ * @see     java_cup.runtime.lr_parser
+ * @version last updated: 7/3/96
+ * @author  Frank Flannery
+ */
+
+public class virtual_parse_stack {
+  /*-----------------------------------------------------------*/
+  /*--- Constructor(s) ----------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Constructor to build a virtual stack out of a real stack. */
+  public virtual_parse_stack(Stack shadowing_stack) throws java.lang.Exception
+    {
+      /* sanity check */
+      if (shadowing_stack == null)
+       throw new Exception(
+         "Internal parser error: attempt to create null virtual stack");
+
+      /* set up our internals */
+      real_stack = shadowing_stack;
+      vstack     = new Stack();
+      real_next  = 0;
+
+      /* get one element onto the virtual portion of the stack */
+      get_from_real();
+    }
+
+  /*-----------------------------------------------------------*/
+  /*--- (Access to) Instance Variables ------------------------*/
+  /*-----------------------------------------------------------*/
+       
+  /** The real stack that we shadow.  This is accessed when we move off
+   *  the bottom of the virtual portion of the stack, but is always left
+   *  unmodified.
+   */
+  protected Stack real_stack;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Top of stack indicator for where we leave off in the real stack.
+   *  This is measured from top of stack, so 0 would indicate that no
+   *  elements have been "moved" from the real to virtual stack. 
+   */
+  protected int real_next;
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** The virtual top portion of the stack.  This stack contains Integer
+   *  objects with state numbers.  This stack shadows the top portion
+   *  of the real stack within the area that has been modified (via operations
+   *  on the virtual stack).  When this portion of the stack becomes empty we 
+   *  transfer elements from the underlying stack onto this stack. 
+   */
+  protected Stack vstack;
+
+  /*-----------------------------------------------------------*/
+  /*--- General Methods ---------------------------------------*/
+  /*-----------------------------------------------------------*/
+
+  /** Transfer an element from the real to the virtual stack.  This assumes 
+   *  that the virtual stack is currently empty.  
+   */
+  protected void get_from_real()
+    {
+      Symbol stack_sym;
+
+      /* don't transfer if the real stack is empty */
+      if (real_next >= real_stack.size()) return;
+
+      /* get a copy of the first Symbol we have not transfered */
+      stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next);
+
+      /* record the transfer */
+      real_next++;
+
+      /* put the state number from the Symbol onto the virtual stack */
+      vstack.push(new Integer(stack_sym.parse_state));
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Indicate whether the stack is empty. */
+  public boolean empty()
+    {
+      /* if vstack is empty then we were unable to transfer onto it and 
+        the whole thing is empty. */
+      return vstack.empty();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+      
+  /** Return value on the top of the stack (without popping it). */
+  public int top() throws java.lang.Exception
+    {
+      if (vstack.empty())
+       throw new Exception(
+                 "Internal parser error: top() called on empty virtual stack");
+
+      return ((Integer)vstack.peek()).intValue();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Pop the stack. */
+  public void pop() throws java.lang.Exception
+    {
+      if (vstack.empty())
+       throw new Exception(
+                 "Internal parser error: pop from empty virtual stack");
+
+      /* pop it */
+      vstack.pop();
+
+      /* if we are now empty transfer an element (if there is one) */
+      if (vstack.empty())
+        get_from_real();
+    }
+
+  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
+
+  /** Push a state number onto the stack. */
+  public void push(int state_num)
+    {
+      vstack.push(new Integer(state_num));
+    }
+
+  /*-----------------------------------------------------------*/
+
+}
diff --git a/Robust/cup/java_cup/simple_calc/CUP$parser$actions.class b/Robust/cup/java_cup/simple_calc/CUP$parser$actions.class
new file mode 100644 (file)
index 0000000..5758ef5
Binary files /dev/null and b/Robust/cup/java_cup/simple_calc/CUP$parser$actions.class differ
diff --git a/Robust/cup/java_cup/simple_calc/Main.class b/Robust/cup/java_cup/simple_calc/Main.class
new file mode 100644 (file)
index 0000000..aa2cc95
Binary files /dev/null and b/Robust/cup/java_cup/simple_calc/Main.class differ
diff --git a/Robust/cup/java_cup/simple_calc/Main.java b/Robust/cup/java_cup/simple_calc/Main.java
new file mode 100644 (file)
index 0000000..21ff5aa
--- /dev/null
@@ -0,0 +1,32 @@
+// Driver for parser
+
+package java_cup.simple_calc;
+
+import java_cup.simple_calc.parser;
+import java_cup.runtime.Symbol;
+
+class Main {
+
+  static boolean do_debug_parse = false;
+
+  static public void main(String[] args) throws java.io.IOException {
+
+      /* create a parsing object */
+      parser parser_obj = new parser(new scanner());
+
+      /* open input files, etc. here */
+      Symbol parse_tree = null;
+
+      try {
+        if (do_debug_parse)
+          parse_tree = parser_obj.debug_parse();
+        else
+          parse_tree = parser_obj.parse();
+      } catch (Exception e) {
+        /* do cleanup here -- possibly rethrow e */
+      } finally {
+       /* do close out here */
+      }
+  }
+}
+
diff --git a/Robust/cup/java_cup/simple_calc/parser.class b/Robust/cup/java_cup/simple_calc/parser.class
new file mode 100644 (file)
index 0000000..05da56a
Binary files /dev/null and b/Robust/cup/java_cup/simple_calc/parser.class differ
diff --git a/Robust/cup/java_cup/simple_calc/parser.cup b/Robust/cup/java_cup/simple_calc/parser.cup
new file mode 100644 (file)
index 0000000..a88d900
--- /dev/null
@@ -0,0 +1,55 @@
+// JavaCup specification for a simple expression evaluator (w/ actions)
+
+package java_cup.simple_calc;
+
+import java_cup.runtime.*;
+
+/* Terminals (tokens returned by the scanner). */
+terminal           SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD;
+terminal           UMINUS, LPAREN, RPAREN;
+terminal Integer   NUMBER;
+
+/* Non terminals */
+non terminal Object     expr_list, expr_part;
+non terminal Integer    expr;
+
+/* Precedences */
+precedence left PLUS, MINUS;
+precedence left TIMES, DIVIDE, MOD;
+precedence left UMINUS, LPAREN;
+
+/* The grammar */
+expr_list ::= expr_list expr_part 
+             | 
+              expr_part;
+
+expr_part ::= expr:e 
+             {: System.out.println("= " + e); :} 
+              SEMI              
+             ;
+
+expr      ::= expr:e1 PLUS expr:e2    
+             {: RESULT = new Integer(e1.intValue() + e2.intValue()); :} 
+             | 
+              expr:e1 MINUS expr:e2    
+              {: RESULT = new Integer(e1.intValue() - e2.intValue()); :} 
+             | 
+              expr:e1 TIMES expr:e2 
+             {: RESULT = new Integer(e1.intValue() * e2.intValue()); :} 
+             | 
+              expr:e1 DIVIDE expr:e2 
+             {: RESULT = new Integer(e1.intValue() / e2.intValue()); :} 
+             | 
+              expr:e1 MOD expr:e2 
+             {: RESULT = new Integer(e1.intValue() % e2.intValue()); :} 
+             | 
+              NUMBER:n                 
+             {: RESULT = n; :} 
+             | 
+              MINUS expr:e             
+             {: RESULT = new Integer(0 - e.intValue()); :} 
+             %prec UMINUS
+             | 
+              LPAREN expr:e RPAREN     
+             {: RESULT = e; :} 
+             ;
diff --git a/Robust/cup/java_cup/simple_calc/parser.java b/Robust/cup/java_cup/simple_calc/parser.java
new file mode 100644 (file)
index 0000000..d6003c7
--- /dev/null
@@ -0,0 +1,318 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:36:02 EDT 1999
+//----------------------------------------------------
+
+package java_cup.simple_calc;
+
+import java_cup.runtime.*;
+
+/** CUP v0.10k generated parser.
+  * @version Sun Jul 25 13:36:02 EDT 1999
+  */
+public class parser extends java_cup.runtime.lr_parser {
+
+  /** Default constructor. */
+  public parser() {super();}
+
+  /** Constructor which sets the default scanner. */
+  public parser(java_cup.runtime.Scanner s) {super(s);}
+
+  /** Production table. */
+  protected static final short _production_table[][] = 
+    unpackFromStrings(new String[] {
+    "\000\015\000\002\003\004\000\002\002\004\000\002\003" +
+    "\003\000\002\006\002\000\002\004\005\000\002\005\005" +
+    "\000\002\005\005\000\002\005\005\000\002\005\005\000" +
+    "\002\005\005\000\002\005\003\000\002\005\004\000\002" +
+    "\005\005" });
+
+  /** Access to production table. */
+  public short[][] production_table() {return _production_table;}
+
+  /** Parse-action table. */
+  protected static final short[][] _action_table = 
+    unpackFromStrings(new String[] {
+    "\000\030\000\010\006\004\013\011\015\005\001\002\000" +
+    "\010\006\004\013\011\015\005\001\002\000\020\004\ufff7" +
+    "\005\ufff7\006\ufff7\007\ufff7\010\ufff7\011\ufff7\014\ufff7\001" +
+    "\002\000\012\002\uffff\006\uffff\013\uffff\015\uffff\001\002" +
+    "\000\016\004\ufffe\005\016\006\014\007\020\010\017\011" +
+    "\013\001\002\000\012\002\027\006\004\013\011\015\005" +
+    "\001\002\000\010\006\004\013\011\015\005\001\002\000" +
+    "\016\005\016\006\014\007\020\010\017\011\013\014\015" +
+    "\001\002\000\010\006\004\013\011\015\005\001\002\000" +
+    "\010\006\004\013\011\015\005\001\002\000\020\004\ufff5" +
+    "\005\ufff5\006\ufff5\007\ufff5\010\ufff5\011\ufff5\014\ufff5\001" +
+    "\002\000\010\006\004\013\011\015\005\001\002\000\010" +
+    "\006\004\013\011\015\005\001\002\000\010\006\004\013" +
+    "\011\015\005\001\002\000\020\004\ufffa\005\ufffa\006\ufffa" +
+    "\007\ufffa\010\ufffa\011\ufffa\014\ufffa\001\002\000\020\004" +
+    "\ufff9\005\ufff9\006\ufff9\007\ufff9\010\ufff9\011\ufff9\014\ufff9" +
+    "\001\002\000\020\004\ufffc\005\ufffc\006\ufffc\007\020\010" +
+    "\017\011\013\014\ufffc\001\002\000\020\004\ufffb\005\ufffb" +
+    "\006\ufffb\007\020\010\017\011\013\014\ufffb\001\002\000" +
+    "\020\004\ufff8\005\ufff8\006\ufff8\007\ufff8\010\ufff8\011\ufff8" +
+    "\014\ufff8\001\002\000\012\002\001\006\001\013\001\015" +
+    "\001\001\002\000\004\002\000\001\002\000\004\004\031" +
+    "\001\002\000\012\002\ufffd\006\ufffd\013\ufffd\015\ufffd\001" +
+    "\002\000\020\004\ufff6\005\ufff6\006\ufff6\007\ufff6\010\ufff6" +
+    "\011\ufff6\014\ufff6\001\002" });
+
+  /** Access to parse-action table. */
+  public short[][] action_table() {return _action_table;}
+
+  /** <code>reduce_goto</code> table. */
+  protected static final short[][] _reduce_table = 
+    unpackFromStrings(new String[] {
+    "\000\030\000\010\003\007\004\005\005\006\001\001\000" +
+    "\004\005\031\001\001\000\002\001\001\000\002\001\001" +
+    "\000\004\006\027\001\001\000\006\004\025\005\006\001" +
+    "\001\000\004\005\011\001\001\000\002\001\001\000\004" +
+    "\005\024\001\001\000\004\005\023\001\001\000\002\001" +
+    "\001\000\004\005\022\001\001\000\004\005\021\001\001" +
+    "\000\004\005\020\001\001\000\002\001\001\000\002\001" +
+    "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
+    "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
+    "\002\001\001\000\002\001\001" });
+
+  /** Access to <code>reduce_goto</code> table. */
+  public short[][] reduce_table() {return _reduce_table;}
+
+  /** Instance of action encapsulation class. */
+  protected CUP$parser$actions action_obj;
+
+  /** Action encapsulation object initializer. */
+  protected void init_actions()
+    {
+      action_obj = new CUP$parser$actions(this);
+    }
+
+  /** Invoke a user supplied parse action. */
+  public java_cup.runtime.Symbol do_action(
+    int                        act_num,
+    java_cup.runtime.lr_parser parser,
+    java.util.Stack            stack,
+    int                        top)
+    throws java.lang.Exception
+  {
+    /* call code in generated class */
+    return action_obj.CUP$parser$do_action(act_num, parser, stack, top);
+  }
+
+  /** Indicates start state. */
+  public int start_state() {return 0;}
+  /** Indicates start production. */
+  public int start_production() {return 1;}
+
+  /** <code>EOF</code> Symbol index. */
+  public int EOF_sym() {return 0;}
+
+  /** <code>error</code> Symbol index. */
+  public int error_sym() {return 1;}
+
+}
+
+/** Cup generated class to encapsulate user supplied action code.*/
+class CUP$parser$actions {
+  private final parser parser;
+
+  /** Constructor */
+  CUP$parser$actions(parser parser) {
+    this.parser = parser;
+  }
+
+  /** Method with the actual generated action code. */
+  public final java_cup.runtime.Symbol CUP$parser$do_action(
+    int                        CUP$parser$act_num,
+    java_cup.runtime.lr_parser CUP$parser$parser,
+    java.util.Stack            CUP$parser$stack,
+    int                        CUP$parser$top)
+    throws java.lang.Exception
+    {
+      /* Symbol object for return from actions */
+      java_cup.runtime.Symbol CUP$parser$result;
+
+      /* select the action based on the action number */
+      switch (CUP$parser$act_num)
+        {
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 12: // expr ::= LPAREN expr RPAREN 
+            {
+              Integer RESULT = null;
+               int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+               int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+               Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+                RESULT = e; 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 11: // expr ::= MINUS expr 
+            {
+              Integer RESULT = null;
+               int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+                RESULT = new Integer(0 - e.intValue()); 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 10: // expr ::= NUMBER 
+            {
+              Integer RESULT = null;
+               int nleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int nright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer n = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+                RESULT = n; 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 9: // expr ::= expr MOD expr 
+            {
+              Integer RESULT = null;
+               int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+               int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+               Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+               int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+                RESULT = new Integer(e1.intValue() % e2.intValue()); 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 8: // expr ::= expr DIVIDE expr 
+            {
+              Integer RESULT = null;
+               int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+               int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+               Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+               int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+                RESULT = new Integer(e1.intValue() / e2.intValue()); 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 7: // expr ::= expr TIMES expr 
+            {
+              Integer RESULT = null;
+               int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+               int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+               Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+               int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+                RESULT = new Integer(e1.intValue() * e2.intValue()); 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 6: // expr ::= expr MINUS expr 
+            {
+              Integer RESULT = null;
+               int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+               int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+               Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+               int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+                RESULT = new Integer(e1.intValue() - e2.intValue()); 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 5: // expr ::= expr PLUS expr 
+            {
+              Integer RESULT = null;
+               int e1left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+               int e1right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+               Integer e1 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+               int e2left = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int e2right = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer e2 = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+                RESULT = new Integer(e1.intValue() + e2.intValue()); 
+              CUP$parser$result = new java_cup.runtime.Symbol(3/*expr*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 4: // expr_part ::= expr NT$0 SEMI 
+            {
+              Object RESULT = null;
+              // propagate RESULT from NT$0
+              if ( ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value != null )
+                RESULT = (Object) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+               int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left;
+               int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).right;
+               Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-2)).value;
+
+              CUP$parser$result = new java_cup.runtime.Symbol(2/*expr_part*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-2)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 3: // NT$0 ::= 
+            {
+              Object RESULT = null;
+               int eleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left;
+               int eright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right;
+               Integer e = (Integer)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-0)).value;
+ System.out.println("= " + e); 
+              CUP$parser$result = new java_cup.runtime.Symbol(4/*NT$0*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 2: // expr_list ::= expr_part 
+            {
+              Object RESULT = null;
+
+              CUP$parser$result = new java_cup.runtime.Symbol(1/*expr_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 1: // $START ::= expr_list EOF 
+            {
+              Object RESULT = null;
+               int start_valleft = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left;
+               int start_valright = ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).right;
+               Object start_val = (Object)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-1)).value;
+               RESULT = start_val;
+              CUP$parser$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          /* ACCEPT */
+          CUP$parser$parser.done_parsing();
+          return CUP$parser$result;
+
+          /*. . . . . . . . . . . . . . . . . . . .*/
+          case 0: // expr_list ::= expr_list expr_part 
+            {
+              Object RESULT = null;
+
+              CUP$parser$result = new java_cup.runtime.Symbol(1/*expr_list*/, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-1)).left, ((java_cup.runtime.Symbol)CUP$parser$stack.elementAt(CUP$parser$top-0)).right, RESULT);
+            }
+          return CUP$parser$result;
+
+          /* . . . . . .*/
+          default:
+            throw new Exception(
+               "Invalid action number found in internal parse table");
+
+        }
+    }
+}
+
diff --git a/Robust/cup/java_cup/simple_calc/scanner.class b/Robust/cup/java_cup/simple_calc/scanner.class
new file mode 100644 (file)
index 0000000..b24ff03
Binary files /dev/null and b/Robust/cup/java_cup/simple_calc/scanner.class differ
diff --git a/Robust/cup/java_cup/simple_calc/scanner.java b/Robust/cup/java_cup/simple_calc/scanner.java
new file mode 100644 (file)
index 0000000..f8f850a
--- /dev/null
@@ -0,0 +1,63 @@
+// Simple Example Scanner Class
+
+package java_cup.simple_calc;
+
+import java_cup.runtime.Symbol;
+
+public class scanner implements java_cup.runtime.Scanner {
+  final java.io.InputStream instream;
+
+  public scanner(java.io.InputStream is) throws java.io.IOException {
+    instream = is;
+  }
+  public scanner() throws java.io.IOException { this(System.in); }
+
+  /* single lookahead character */
+  protected int next_char = -2;
+
+  /* advance input by one character */
+  protected void advance()
+    throws java.io.IOException
+    { next_char = instream.read(); }
+
+  /* initialize the scanner */
+  private void init()
+    throws java.io.IOException
+    { advance(); }
+
+  /* recognize and return the next complete token */
+  public Symbol next_token()
+    throws java.io.IOException
+    {
+      if (next_char==-2) init(); // set stuff up first time we are called.
+      for (;;)
+        switch (next_char)
+         {
+           case '0': case '1': case '2': case '3': case '4': 
+           case '5': case '6': case '7': case '8': case '9': 
+             /* parse a decimal integer */
+             int i_val = 0;
+             do {
+               i_val = i_val * 10 + (next_char - '0');
+               advance();
+             } while (next_char >= '0' && next_char <= '9');
+           return new Symbol(sym.NUMBER, new Integer(i_val));
+
+           case ';': advance(); return new Symbol(sym.SEMI);
+           case '+': advance(); return new Symbol(sym.PLUS);
+           case '-': advance(); return new Symbol(sym.MINUS);
+           case '*': advance(); return new Symbol(sym.TIMES);
+           case '/': advance(); return new Symbol(sym.DIVIDE);
+           case '%': advance(); return new Symbol(sym.MOD);
+           case '(': advance(); return new Symbol(sym.LPAREN);
+           case ')': advance(); return new Symbol(sym.RPAREN);
+
+           case -1: return new Symbol(sym.EOF);
+
+           default: 
+             /* in this simple scanner we just ignore everything else */
+             advance();
+           break;
+         }
+    }
+};
diff --git a/Robust/cup/java_cup/simple_calc/sym.class b/Robust/cup/java_cup/simple_calc/sym.class
new file mode 100644 (file)
index 0000000..46aed76
Binary files /dev/null and b/Robust/cup/java_cup/simple_calc/sym.class differ
diff --git a/Robust/cup/java_cup/simple_calc/sym.java b/Robust/cup/java_cup/simple_calc/sym.java
new file mode 100644 (file)
index 0000000..2584f2f
--- /dev/null
@@ -0,0 +1,25 @@
+
+//----------------------------------------------------
+// The following code was generated by CUP v0.10k
+// Sun Jul 25 13:36:02 EDT 1999
+//----------------------------------------------------
+
+package java_cup.simple_calc;
+
+/** CUP generated class containing symbol constants. */
+public class sym {
+  /* terminals */
+  public static final int SEMI = 2;
+  public static final int EOF = 0;
+  public static final int DIVIDE = 6;
+  public static final int NUMBER = 11;
+  public static final int error = 1;
+  public static final int UMINUS = 8;
+  public static final int MINUS = 4;
+  public static final int TIMES = 5;
+  public static final int LPAREN = 9;
+  public static final int RPAREN = 10;
+  public static final int MOD = 7;
+  public static final int PLUS = 3;
+}
+