[Git][java-team/cup][upstream] Import Upstream version 0.11b-20160615

Markus Koschany gitlab at salsa.debian.org
Sun Sep 30 23:15:41 BST 2018


Markus Koschany pushed to branch upstream at Debian Java Maintainers / cup


Commits:
7f3969ef by Markus Koschany at 2018-09-30T22:13:12Z
Import Upstream version 0.11b-20160615
- - - - -


26 changed files:

- + .classpath
- + .project
- build.xml
- changelog.txt
- cup/parser.cup
- flex/Lexer.jflex
- + licence.txt
- manual.html
- src/java_cup/Main.java
- src/java_cup/anttask/CUPTask.java
- src/java_cup/emit.java
- src/java_cup/lalr_state.java
- src/java_cup/production.java
- src/java_cup/runtime/ComplexSymbolFactory.java
- src/java_cup/runtime/DefaultSymbolFactory.java
- + src/java_cup/runtime/ScannerBuffer.java
- src/java_cup/runtime/Symbol.java
- src/java_cup/runtime/SymbolFactory.java
- + src/java_cup/runtime/SyntaxTreeDFS.java
- + src/java_cup/runtime/SyntaxTreeTransform.java
- + src/java_cup/runtime/SyntaxTreeXPath.java
- + src/java_cup/runtime/XMLElement.java
- src/java_cup/runtime/lr_parser.java
- src/java_cup/terminal_set.java
- src/java_cup/version.java
- + version.txt


Changes:

=====================================
.classpath
=====================================
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="/usr/share/ant/lib/ant.jar"/>
+	<classpathentry kind="output" path="classes"/>
+</classpath>


=====================================
.project
=====================================
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>CUP</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>


=====================================
build.xml
=====================================
@@ -1,4 +1,4 @@
-<project name="emugen" default ="dist" basedir=".">
+<project name="cup" default ="dist" basedir="." xmlns:if="ant:if" xmlns:unless="ant:unless">
   <property name="etc"       location="etc"       />
   <property name="bin"       location="bin"       />
   <property name="lib"       location="lib"       />
@@ -13,10 +13,34 @@
   <!-- initialize the workspace -->
   <target name="init">
     <tstamp />
+    <available file="version.txt" property="version.present" />
+    <touch unless:set="version.present" file="version.txt" />
     <mkdir dir="${src}" />
     <mkdir dir="${java}" />
     <mkdir dir="${classes}" />
-    <mkdir dir="${dist}" />    
+    <mkdir dir="${dist}" />
+    <loadfile property="cupversion" srcFile="version.txt" failonerror="false" />
+    <property name="cupversion" value="custombuild" unless:set="cupversion"/>
+    <exec executable="git" outputproperty="gitversion">
+      <arg value="log"/>
+      <arg value="-1"/>
+      <arg value="--format=%h"/>
+    </exec>
+    <exec executable="git" outputproperty="changed">
+      <arg value="status"/>
+      <arg value="--porcelain"/>
+      <redirector>
+	<outputfilterchain>
+	<linecontainsregexp>
+	  <regexp pattern='^M.*'/>
+	</linecontainsregexp>
+	<tokenfilter>
+	  <replaceregex pattern=".*" replace="modifications based on "/>
+	</tokenfilter>
+	</outputfilterchain>
+	</redirector>
+    </exec>
+    <property name="svnversion">${changed}${gitversion}</property>
   </target>
 
   <property environment="env" />
@@ -53,27 +77,82 @@
 
   <target name="compile" depends="jflex">
     <copy todir="${java}"><fileset dir="${src}"></fileset></copy>
-    <javac srcdir="${java}" destdir="${classes}" verbose="off" listfiles="off" debug="on" source="1.2" target="1.2">
+    <replace file="${java}/java_cup/version.java"
+       token="+ version_str"
+       value='+ "v0.11b ${cupversion} (GIT ${svnversion})"'>
+    </replace>
+    <javac srcdir="${java}" destdir="${classes}" verbose="off" listfiles="off" debug="on" source="1.8" target="1.8">
       <classpath refid="libraries"/>
     </javac>
   </target>
 
   <target name="dist" depends="compile">
-   <jar jarfile="${dist}/java-cup-11a.jar" basedir="${classes}">
+   <jar jarfile="${dist}/java-cup-11b.jar" basedir="${classes}">
       <manifest>
         <attribute name="Main-Class" value="java_cup/Main" />
-	<attribute name="Class-Path" value="java-cup-11a-runtime.jar" />
+	<attribute name="Class-Path" value="java-cup-11b-runtime.jar" />
       </manifest>
     </jar>
-    <jar jarfile="${dist}/java-cup-11a-runtime.jar" basedir="${classes}" includes="java_cup/runtime/*">
+    <jar jarfile="${dist}/java-cup-11b-runtime.jar" basedir="${classes}" includes="java_cup/runtime/*">
     </jar>
+   <tar longfile="gnu"  destfile="${dist}/java-cup-bin-11b-${cupversion}.tar.gz" compression="gzip">
+     <tarfileset dir="${dist}" username="ant" group="ant">
+       <depth max="0"/>
+       <include name="*.jar"/>
+     </tarfileset>
+   </tar>
+  </target>
+
+ <target name="src-dist" depends="dist">
+   <tar longfile="gnu"  destfile="${dist}/java-cup-src-11b-${cupversion}.tar.gz" compression="gzip">
+     <tarfileset dir="${src}" username="ant" group="ant" prefix="src/">
+       <include name="**"/>
+     </tarfileset>
+     <tarfileset dir="${cup}" username="ant" group="ant" prefix="cup/">
+       <include name="**"/>
+     </tarfileset>
+     <tarfileset dir="${flex}" username="ant" group="ant" prefix="flex/">
+       <include name="**"/>
+     </tarfileset>
+     <tarfileset dir="${bin}" username="ant" group="ant" prefix="bin/">
+       <include name="**"/>
+     </tarfileset>
+     <tarfileset dir="${lib}" username="ant" group="ant" prefix="lib/">
+       <include name="**"/>
+     </tarfileset>
+     <tarfileset dir="${src}/.." username="ant" group="ant">
+       <depth max="0"/>
+       <include name="*"/>
+     </tarfileset>
+   </tar>
   </target>
 
   <target name="test" depends="dist">
-    <java jar="${dist}/java-cup-11a.jar" fork="true">
+    <java jar="${dist}/java-cup-11b.jar" fork="true">
         <arg value="-interface" />
         <arg value="${cup}/parser.cup" />
     </java>  
-    
   </target>
+
+  <target name="versionbump" depends="init">
+    <echo message="${DSTAMP}" file="version.txt" />
+  </target>  
+
+  <target name="scp" depends="src-dist">
+    <exec executable="scp">
+      <arg value="${dist}/java-cup-src-11b-${cupversion}.tar.gz" />
+      <arg value="${dist}/java-cup-bin-11b-${cupversion}.tar.gz" />
+      <arg value="${dist}/../manual.html" />
+      <arg value="petter at www2.in.tum.de:/srv/www/htdocs/projects/cup/releases" />
+    </exec>
+  </target>
+  
+  <target name="help" depends="init">
+    <echo message="Targets:" />
+    <echo message="  dist           to create CUP jars" />
+    <echo message="  src-dist       to create release packages" />
+    <echo message="  scp            to deploy relase to homepage" />
+    <echo message="  versionbump    to inc release" />
+  </target>
+
 </project>


=====================================
changelog.txt
=====================================
@@ -1,3 +1,59 @@
+CUP version 0.11b 20151001 is a feature release.
+
+Implemented a generic pre-/post DFS search with visitor support
+Also added fragments of XPath 1.0 query support on parse trees
+Fixed the visibility of children and the variant attribute of XMLElement
+
+M. Petter
+Technische Universität München
+2015/10/01
+------------------------------------------------------------------------
+CUP version 0.11b 20150326 is a bugfix release.
+
+Fixed an issue with empty productions having non-empty location information
+Fixed an issue with deprecation of constructors
+
+M. Petter
+Technische Universität München
+2015/02/26
+------------------------------------------------------------------------
+CUP version 0.11b 20150226 is a feature release.
+
+added the means to move Locations
+
+M. Petter
+Technische Universität München
+2015/02/26
+------------------------------------------------------------------------
+CUP version 0.11b 20140808 is a feature/bugfix release.
+
+added expected symbols to the report_error(...) method
+added an expected_token_ids() to inform about valid continuations
+added parameters and code to enable automatic creation of XML parse trees
+fixed a bug in the lookahead computation
+
+M. Petter
+Technische Universität München
+2014/02/26
+------------------------------------------------------------------------
+CUP version 0.11b beta 20140226 is a feature release.
+
+Command line flag -locations now triggers the generation of the identifiers
+xleft and xright in the actions section instead of left and right.
+Both are of type ComplexSymbolFactory.Location instead of plain ints.
+
+M. Petter
+Technische Universität München
+2014/02/26
+------------------------------------------------------------------------
+CUP version 0.11b beta 20140220 is a feature release.
+
+Main switch statement now splits the action code in bundles of 300 productions
+on several different method bodies. Should fix the 65k size boundary problem
+
+M. Petter
+Technische Universität München
+2014/02/20
 ------------------------------------------------------------------------
 CUP version 0.11a beta 20060608 is a bugfix release.
 


=====================================
cup/parser.cup
=====================================
@@ -185,14 +185,28 @@ action code {:
       }
     }
   }
+  
+  private int cur_debug_id = 0;
+  public int get_new_debug_id() {
+   	return cur_debug_id++;
+  }
+   
+  public String attach_debug_symbol(int id, String code) {
+ 	if (!parser.debugSymbols)
+ 		return code;
+ 	return "//@@CUPDBG" + id + "\n" + code;
+  }
 :};
 
 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */ 
 
 parser code {:
-
  /* override error routines */
   protected Lexer lexer;
+  public boolean debugSymbols;
+  public void setDebugSymbols(boolean debugSymbols){
+  	this.debugSymbols = debugSymbols;
+  }
   public void report_fatal_error(
     String   message,
     Object   info)
@@ -230,7 +244,7 @@ terminal
   PACKAGE, IMPORT, CODE, ACTION, PARSER, TERMINAL, NON, INIT, SCAN, WITH, 
   START, SEMI, COMMA, STAR, DOT, COLON, COLON_COLON_EQUALS, BAR, PRECEDENCE,
   LEFT, RIGHT, NONASSOC, PERCENT_PREC, LBRACK, RBRACK, NONTERMINAL, GT, LT,
-  QUESTION, SUPER, EXTENDS;
+  QUESTION, SUPER, EXTENDS, CLASS;
 
 terminal String  ID, CODE_STRING;
 
@@ -242,7 +256,7 @@ non terminal
   type_id, term_name_list, non_term_name_list, production, prod_part_list, 
   prod_part, new_term_id, new_non_term_id, rhs_list, rhs, empty,
   precedence_list, preced, terminal_list, precedence_l, declares_term, 
-  declares_non_term;
+  declares_non_term, class_name;
 
 non terminal String  nt_id, symbol_id, label_id, opt_label, terminal_id,
                      term_id, robust_id, typearglist, typearguement, wildcard;
@@ -263,6 +277,7 @@ spec ::=
 	:}
 	package_spec
 	import_list
+	class_name
 	code_parts
 	symbol_list
 	precedence_list
@@ -322,6 +337,15 @@ import_spec ::=
 	SEMI
 	;
 
+class_name ::=
+    empty |
+    CLASS ID:id SEMI
+    {:
+     emit.parser_class_name = id;
+     emit.symbol_const_class_name = id + "Sym";
+    :}
+    ;
+
 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */ 
 
 // allow any order; all parts are optional. [CSA, 23-Jul-1999]
@@ -339,7 +363,7 @@ action_code_part ::=
 	  if (emit.action_code!=null)
 	    ErrorManager.getManager().emit_warning("Redundant action code (skipping)");
 	  else /* save the user included code string */
-	    emit.action_code = user_code;
+	    emit.action_code = attach_debug_symbol(get_new_debug_id(),user_code);
 	:}
 	;
 
@@ -351,7 +375,7 @@ parser_code_part ::=
 	  if (emit.parser_code!=null)
 	    ErrorManager.getManager().emit_warning("Redundant parser code (skipping)");
 	  else /* save the user included code string */
-	    emit.parser_code = user_code;
+	    emit.parser_code = attach_debug_symbol(get_new_debug_id(),user_code);
 	:}
 	;
 
@@ -363,7 +387,7 @@ init_code ::=
 	  if (emit.init_code!=null)
 	    ErrorManager.getManager().emit_warning("Redundant init code (skipping)");
 	  else /* save the user code */
-	    emit.init_code = user_code;
+	    emit.init_code = attach_debug_symbol(get_new_debug_id(),user_code);
 	:}
 	;
 
@@ -375,7 +399,7 @@ scan_code ::=
 	  if (emit.scan_code!=null)
 	    ErrorManager.getManager().emit_warning("Redundant scan code (skipping)");
 	  else /* save the user code */
-	    emit.scan_code = user_code;
+	    emit.scan_code = attach_debug_symbol(get_new_debug_id(),user_code);
 	:}
 	;
 
@@ -534,7 +558,7 @@ start_spec ::=
 	      new_rhs();
 	      add_rhs_part(add_lab(new symbol_part(start_nt), "start_val"));
 	      add_rhs_part(new symbol_part(terminal.EOF));
-	      add_rhs_part(new action_part("RESULT = start_val;"));
+	      if (!emit._xmlactions) add_rhs_part(new action_part("RESULT = start_val;"));
 	      emit.start_production = 
 		     new production(non_terminal.START_nt, rhs_parts, rhs_pos);
 	      new_rhs();
@@ -621,7 +645,7 @@ rhs ::=
 	          new_rhs();
 	          add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
 	          add_rhs_part(new symbol_part(terminal.EOF));
-		  add_rhs_part(new action_part("RESULT = start_val;"));
+		  if (!emit._xmlactions) add_rhs_part(new action_part("RESULT = start_val;"));
 		  if ((sym!=null) && (sym instanceof terminal)) {
 		    emit.start_production = 
 		      new production(non_terminal.START_nt, rhs_parts, 
@@ -657,7 +681,7 @@ rhs ::=
 	          new_rhs();
 	          add_rhs_part(add_lab(new symbol_part(start_nt),"start_val"));
 	          add_rhs_part(new symbol_part(terminal.EOF));
-		  add_rhs_part(new action_part("RESULT = start_val;"));
+		  if (!emit._xmlactions) add_rhs_part(new action_part("RESULT = start_val;"));
 	          emit.start_production = 
 		     new production(non_terminal.START_nt, rhs_parts, rhs_pos);
 
@@ -699,7 +723,7 @@ prod_part ::=
 	CODE_STRING:code_str
 	{: 
 	  /* add a new production part */
-	  add_rhs_part(new action_part(code_str));
+	  add_rhs_part(new action_part(attach_debug_symbol(get_new_debug_id(),code_str)));
 	:}
 	;
 


=====================================
flex/Lexer.jflex
=====================================
@@ -23,11 +23,9 @@ import java.io.InputStreamReader;
     private ComplexSymbolFactory symbolFactory;
     private int csline,cscolumn;
     public Symbol symbol(String name, int code){
-//	System.out.println("code:"+code+" "+yytext());
 	return symbolFactory.newSymbol(name, code,new Location(yyline+1,yycolumn+1-yylength()),new Location(yyline+1,yycolumn+1));
     }
     public Symbol symbol(String name, int code, String lexem){
-//	System.out.println("code:"+code+", lexem :"+lexem);
 	return symbolFactory.newSymbol(name, code, new Location(yyline+1, yycolumn +1), new Location(yyline+1,yycolumn+yylength()), lexem);
     }
     protected void emit_warning(String message){
@@ -78,6 +76,7 @@ ident = ([:jletter:] | "_" ) ([:jletterdigit:] | [:jletter:] | "_" )*
   "{:"          { sb = new StringBuffer(); csline=yyline+1; cscolumn=yycolumn+1; yybegin(CODESEG);    }
   "package"     { return symbol("PACKAGE",PACKAGE);            } 
   "import"      { return symbol("IMPORT",IMPORT);	       }
+  "class"       { return symbol("CLASS",CLASS); 	       }
   "code"        { return symbol("CODE",CODE);		       }
   "action"      { return symbol("ACTION",ACTION);	       }
   "parser"      { return symbol("PARSER",PARSER);	       }


=====================================
licence.txt
=====================================
@@ -0,0 +1,9 @@
+CUP Parser Generator Copyright Notice, License, and Disclaimer
+Copyright 1996-2015 by Scott Hudson, Frank Flannery, C. Scott Ananian, Michael Petter
+
+Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both the copyright notice and this permission notice and warranty disclaimer appear in supporting documentation, and that the names of the authors or their employers not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.
+
+The authors and their employers disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the authors or their employers be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software.
+This is an open source license. It is also GPL-Compatible (see entry for "Standard ML of New Jersey"). The portions of CUP output which are hard-coded into the CUP source code are (naturally) covered by this same license, as is the CUP runtime code linked with the generated parser.
+
+Java is a trademark of Sun Microsystems, Inc. References to the Java programming language in relation to JLex are not meant to imply that Sun endorses this product. 


=====================================
manual.html
=====================================
@@ -1,11 +1,10 @@
 <html><head>
 <title>CUP User's Manual</title></head><body>
-
-<hr>
-<img src="manual_dateien/cup_logo.gif" alt="[CUP Logo Image]">
+<div class="container">
 <hr>
 <h1>CUP User's Manual</h1>
-<h3><a href="http://www.cc.gatech.edu/gvu/people/Faculty/Scott.E.Hudson.html">
+<h3><a href="http://www2.in.tum.de">Michael Petter, Technische Universität München</a><br />
+<a href="http://www.cc.gatech.edu/gvu/people/Faculty/Scott.E.Hudson.html">
 Scott E. Hudson</a><br> 
 <a href="http://www.cc.gatech.edu/gvu/gvutop.html">
 Graphics Visualization and Usability Center</a><br> 
@@ -13,36 +12,53 @@ Graphics Visualization and Usability Center</a><br>
 Georgia Institute of Technology</a></h3>
 Modified by <a href="http://www.princeton.edu/%7Efrankf">Frank
 Flannery</a>, <a href="http://www.pdos.lcs.mit.edu/%7Ecananian/">C. Scott Ananian</a>, 
-<a href="http://www.cs.princeton.edu/%7Edanwang">Dan Wang</a> with advice from 
+<a href="http://www.cs.princeton.edu/%7Edanwang">Dan Wang</a>, <a href="http://www2.cs.tum.edu/%7Epetter">Michael Petter</a> with advice from 
 <a href="http://www.cs.princeton.edu/%7Eappel">Andrew W. Appel</a><br>
-Now actualized by <a href="http://www2.cs.tum.edu/%7Epetter">Michael Petter</a><br>
-Last updated March 2006 (v0.11a)
+<br>
+Last updated  06/2014 (v0.11b)
 <hr>
 
 <h3>Table of Contents</h3>
-<dl compact="compact">
-  <dt> i.  </dt><dd> <a href="#about">About CUP Version 0.10</a>
-  </dd><dt> 1.  </dt><dd> <a href="#intro">Introduction and Example</a>
-  </dd><dt> 2.  </dt><dd> <a href="#spec">Specification Syntax</a>
-  </dd><dt> 3.1 </dt><dd> <a href="#running">Running CUP</a>
-  </dd><dt> 3.2 </dt><dd> <a href="#ant">CUP and ANT</a>
-  </dd><dt> 4.  </dt><dd> <a href="#parser">Customizing the Parser</a>
-  </dd><dt> 5.  </dt><dd> <a href="#scanner">Scanner interface</a>
-  </dd><dt> 5.1 </dt><dd> <a href="#basic-symbols">Basic Symbol management</a>
-  </dd><dt> 5.2 </dt><dd> <a href="#advanced-symbols">Advanced Symbol management</a>
-  </dd><dt> 6.  </dt><dd> <a href="#errors">Error Recovery</a>
-  </dd><dt> 7.  </dt><dd> <a href="#conclusion">Conclusion</a>
-  </dd><dt>     </dt><dd> <a href="#refs">References</a>
-  </dd><dt> A.  </dt><dd> <a href="#appendixa">Grammar for CUP Specification Files</a>
-  </dd><dt> B.  </dt><dd> <a href="#appendixb">A Very Simple Example Scanner</a>
-  </dd><dt> C.  </dt><dd> <a href="#changes">Incompatibilites between CUP 0.9 and CUP 0.10</a>
-  </dd><dt> D.  </dt><dd> <a href="#bugs">Bugs</a>
-  </dd><dt> E.  </dt><dd> <a href="#version">Change log</a>
-</dd></dl>
-
-<a name="about">
+<ol type="i">
+       <li> <a href="#about">About CUP Version 0.10</a>
+  </li><li> <a href="#about11">About CUP Version 0.11</a>
+  </li>
+</ol>
+<ol>
+       <li> <a href="#intro">Introduction and Example</a>
+  </li><li> <a href="#spec">Specification Syntax</a>
+        <ol><li><a href="#package_spec">Package and import specification</a>
+  </li><li> <a href="#code_part">User code componentes</a>
+  </li><li> <a href="#symbol_list">Symbol lists</a>
+  </li><li> <a href="#precedence">Precedence and associativity declarations</a>
+  </li><li>         <a href="#production_list">The grammar</a></li></ol>
+  </li><li> Running CUP 
+        <ol><li><a href="#running">Command line interface</a>
+  </li><li>         <a href="#ant">CUP and ANT</a></li></ol>
+  </li><li> <a href="#parser">Customizing the Parser</a>
+  </li><li> <a href="#scanner">Scanner interface</a>
+       <ol><li> <a href="#basic-symbols">Basic Symbol management</a>
+  </li><li>  <a href="#advanced-symbols">Advanced Symbol management</a>
+  </li><li>  <a href="#symbolstream-caching">Symbol Stream caching</a></li></ol>
+  </li><li> <a href="#errors">Error Recovery</a>
+        <ol><li><a href="#error_sym">The error symbol</a>
+  </li><li>         <a href="#continuation_symbols">Viable continuations</a></li></ol>
+  </li><li> <a href="#conclusion">Conclusion</a>
+  </li>
+</ol>
+<a href="#refs">References</a>
+<ol type="A">
+       <li> <a href="#appendixa">Grammar for CUP Specification Files</a>
+  </li><li> <a href="#appendixb">A Very Simple Example Scanner</a>
+  </li><li> <a href="#changes">Incompatibilites between CUP 0.9 and CUP 0.10</a>
+  </li><li> <a href="#bugs">Bugs</a>
+  </li><li> <a href="#version">Change log</a>
+  </li>
+</ol>
+
+<a name="about"></a> 
 <h3>i. About CUP Version 0.10</h3>
-</a> Version
+Version
 0.10 of CUP adds many new changes and features over the previous releases
 of version 0.9.  These changes attempt to make CUP more like its
 predecessor, YACC.  As a result, the old 0.9 parser specifications for CUP are
@@ -50,7 +66,7 @@ not compatible and a reading of <a href="#changes">appendix C</a> of the new
 manual will be necessary to write new specifications.  The new version,
 however, gives the user more power and options, making parser specifications
 easier to write.
-<h3>ii. About CUP Version 0.11</h3>
+<a name="about11"></a><h3>ii. About CUP Version 0.11</h3>
 in version 0.11 the TUM team tries to continue the success story of CUP 0.10, 
 beginning with the introduction of generic data types for non-terminal symbols
 as well as a modernisation of the user interface with a comfortable ANT plugin 
@@ -180,7 +196,7 @@ part of the specification contains the grammar.<p>
 To produce a parser from this specification we use the CUP generator.
 If this specification were stored in a file <tt>parser.cup</tt>, then 
 (on a Unix system at least) we might invoke CUP using a command like:
-</p><pre><tt> java -jar java-cup-11a.jar parser.cup</tt> </pre>
+</p><pre><tt> java -jar java-cup-11b.jar parser.cup</tt> </pre>
 In this case, the system will produce two Java source files containing 
 parts of the generated parser: <tt>sym.java</tt> and <tt>parser.java</tt>.  
 As you might expect, these two files contain declarations for the classes 
@@ -269,12 +285,12 @@ symbols in the right hand side of productions.  For example in:<br>
 <pre>  expr:e1 PLUS expr:e2    
 	{: RESULT = new Integer(e1.intValue() + e2.intValue()); :} 
 </pre>
-<a name="RES_part">
+<a name="RES_part"></a>
 the first non-terminal <tt>expr</tt> has been labeled with <tt>e1</tt>, and 
 the second with <tt>e2</tt>.  The left hand side value 
-of each production is always implicitly labeled as <tt>RESULT</tt>.</a><p>
+of each production is always implicitly labeled as <tt>RESULT</tt>.<p>
 
-<a name="RES_part">Each symbol appearing in a production is represented at runtime by an
+Each symbol appearing in a production is represented at runtime by an
 object of type <tt>Symbol</tt> on the parse stack.  The labels refer to
 the instance variable <tt>value</tt> in those objects.  In the
 expression <tt>expr:e1 PLUS expr:e2</tt>, <tt>e1</tt> and <tt>e2</tt>
@@ -283,7 +299,7 @@ of the objects of type <tt>Symbol</tt> representing those non-terminals
 on the parse stack.  <tt>RESULT</tt> is of type <tt>Integer</tt> as
 well, since the resulting non-terminal <tt>expr</tt> was declared as of 
 type <tt>Integer</tt>.  This object becomes the <tt>value</tt> instance
-variable of a new <tt>Symbol</tt> object.</a></p><p><a name="RES_part">  
+variable of a new <tt>Symbol</tt> object.</a></p><p>
 
 For each label, two more variables accessible to the user are declared.
 A left and right value labels are passed to the code string, so that the
@@ -293,9 +309,9 @@ label name, plus <tt>left</tt> or <tt>right</tt>.  for example, given
 the right hand side of a production <tt>expr:e1 PLUS expr:e2</tt> the
 user could not only access variables <tt>e1</tt> and <tt>e2</tt>, but
 also <tt>e1left, e1right, e2left</tt> and <tt>e2right</tt>.  these
-variables are of type <tt>int</tt>.</a></p><p><a name="RES_part">    
+variables are of type <tt>int</tt>.</p><p>
 
-</a><a name="lex_part">
+<a name="lex_part"></a>
 
 The final step in creating a working parser is to create a <i>scanner</i> (also
 known as a <i>lexical analyzer</i> or simply a <i>lexer</i>).  This routine is 
@@ -319,7 +335,8 @@ filled with an object of type <tt>Integer</tt>.  <code>Symbol</code>
 objects corresponding to terminals and non-terminals with no value
 have a null value field.</a></p><p>
 
-<a name="lex_part">The code contained in the <tt>init with</tt> clause of the specification 
+
+The code contained in the <tt>init with</tt> clause of the specification 
 will be executed before any tokens are requested.  Each token will be 
 requested using whatever code is found in the <tt>scan with</tt> clause.
 Beyond this, the exact form the scanner takes is up to you; however
@@ -331,7 +348,8 @@ being scrambled.  As of CUP 0.10j, <code>Symbol</code> reuse should be
 detected if it occurs; the parser will throw an <code>Error</code>
 telling you to fix your scanner.</a></p><p>
 
-<a name="lex_part">In the </a><a href="#spec">next section</a> a more detailed and formal 
+
+In the </a><a href="#spec">next section</a> a more detailed and formal 
 explanation of all parts of a CUP specification will be given.  
 <a href="#running">Section 3</a> describes options for running the 
 CUP system.  <a href="#parser">Section 4</a> discusses the details 
@@ -340,14 +358,15 @@ discusses the scanner interface added in CUP 0.10j. <a href="#errors">Section
  6</a> considers error recovery.  Finally, <a href="#conclusion">Section 7</a> 
 provides a conclusion.
 
-<a name="spec">
-<h3>2. Specification Syntax</h3></a>
+<a name="spec"></a>
+<h3>2. Specification Syntax</h3>
 Now that we have seen a small example, we present a complete description of all 
 parts of a CUP specification.  A specification has four sections with 
 a total of eight specific parts (however, most of these are optional).  
 A specification consists of:
 </p><ul>
 <li> <a href="#package_spec">package and import specifications</a>,
+</li><li> <a href="#parser_class_name">parser class name</a>,
 </li><li> <a href="#code_part">user code components</a>,
 </li><li> <a href="#symbol_list">symbol (terminal and non-terminal) lists</a>, 
 </li><li> <a href="#precedence">precedence declarations</a>, and
@@ -358,7 +377,7 @@ grammar for the specification language is given in
 <a href="#appendixa">Appendix A</a>.)  The particulars of each part of
 the specification are described in the subsections below.<p>
 
-</p><h5><a name="package_spec">Package and Import Specifications</a></h5>
+</p><h4><a name="package_spec"></a>2.1 Package and Import Specifications</h4>
 
 A specification begins with optional <tt>package</tt> and <tt>import</tt> 
 declarations.  These have the same syntax, and play the same 
@@ -389,10 +408,23 @@ Any import declarations that appear in the specification will also appear
 in the source file for the <tt>parser</tt> class allowing various names from
 that package to be used directly in user supplied action code.
 
-<h5><a name="code_part">User Code Components</a></h5>
+After the package and imports, a specification can include a parser
+class name, as follows:
+
+<pre><tt> class <i>name</i>;</tt>
+</pre>
+
+If a class name is supplied, then that is the name that will be used
+for the generated parser code. As well, the generated symbols class
+will have the given name followed by "<tt>Sym</tt>".
+
+<p>If no class name is supplied, then the parser class is called
+"<tt>parser</tt>", and the symbols class is called "<tt>sym</tt>".
+
+<h4><a name="code_part"></a>2.2 User Code Components</h4>
 
-Following the optional <tt>package</tt> and <tt>import</tt> declarations
-are a series of optional declarations that allow user code to be included
+Following these declarations are another series of optional declarations 
+that allow user code to be included
 as part of the generated parser (see <a href="#parser">Section 4</a> for a 
 full description of how the parser uses this code).  As a part of the parser 
 file, a separate non-public class to contain all embedded user actions is 
@@ -453,7 +485,7 @@ As of CUP 0.10j the action code, parser code, init code, and scan with
 sections may appear in any order. They must, however, precede the
 symbol lists.</p><p>
 
-</p><h5><a name="symbol_list">Symbol Lists</a></h5>
+</p><h4><a name="symbol_list"></a>2.3 Symbol Lists</h4>
 
 Following user supplied code comes the first required part of the 
 specification: the symbol lists.  These declarations are responsible 
@@ -496,7 +528,7 @@ these include "code", "action", "parser", "terminal", "non",
 "nonterminal", "init", "scan", "with", "start", "precedence", "left",
 "right", "nonassoc", "import", and "package".</p><p>
 
-</p><h5><a name="precedence">Precedence and Associativity declarations</a></h5>
+</p><h4><a name="precedence"></a>2.4 Precedence and Associativity declarations</h4>
 
 The third section, which is optional, specifies the precedences and
 associativity of terminals.  This is useful for parsing with ambiguous
@@ -560,7 +592,7 @@ treated as lowest precedence.  If a shift/reduce error results,
 involving two such terminals, it cannot be resolved, as the above
 conflicts are, so it will be reported.</p><p>
 
-</p><h5><a name="production_list">The Grammar</a></h5>
+</p><h4><a name="production_list"></a>2.5 The Grammar</h4>
 
 The final section of a CUP declaration provides the grammar.  This 
 section optionally starts with a declaration of the form:
@@ -581,11 +613,11 @@ production in the grammar has a left hand side non-terminal followed by
 the symbol "<tt>::=</tt>", which is then followed by a series of zero or more
 actions, terminal, or non-terminal
 symbols, followed by an optional contextual precedence assignment, 
-and terminated with a semicolon (;).</p><p>
+and terminated with a semicolon (;).</p>
 
-<a name="label_part">
-
-Each symbol on the right hand side can optionally be labeled with a name.
+<a name="label_part"></a>
+<h5>2.5.1 Labels and locations for symbols</h5>
+<p>Each symbol on the right hand side can optionally be labeled with a name.
 Label names appear after the symbol name separated by a colon (:).  Label
 names must be unique within the production, and can be used within action
 code to refer to the value of the symbol.  Along with the label, two
@@ -594,30 +626,42 @@ the label plus <tt>right</tt>.  These are <tt>int</tt> values that
 contain the right and left locations of what the terminal or
 non-terminal covers in the input file.  These values must be properly
 initialized in the terminals by the lexer. The left and right values
-then propagate to non-terminals to which productions reduce.</a></p><p>
-<a name="label_part"> 
+then propagate to non-terminals to which productions reduce.</p><p>
 If there are several productions for the same non-terminal they may be 
 declared together.  In this case the productions start with the non-terminal 
 and "<tt>::=</tt>".  This is followed by multiple right hand sides each 
 separated by a bar (|).  The full set of productions is then terminated by a 
-semicolon.</a></p><p>
+semicolon.</p>
+<p>However, integers alone might not be good enough for locating symbols in
+an input file. This is why CUP also supports more complex location information
+in the form of <code>Location</code> objects. These objects need to be created
+by the <a href="#advanced-symbols">scanner component</a>. They become available 
+within the actions if the parser generator gets the right commandline parameter. 
+They are accessible via the handles <code>??xleft</code> and <code>??xright</code>, 
+with <code>??</code> being the label for the symbol.
+</p>
+
+<p>
 
-<a name="label_part">Actions appear in the right hand side as code strings (e.g., Java code inside
+<a name="action_part"></a>
+<h5>2.5.2 User Actions</h5>
+Actions appear in the right hand side as code strings (e.g., Java code inside
 <tt>{:</tt> ... <tt>:}</tt> delimiters).  These are executed by the parser
 at the point when the portion of the production to the left of the 
 action has been recognized.  (Note that the scanner will have returned the 
 token one past the point of the action since the parser needs this extra
-<i>lookahead</i> token for recognition.)</a></p><p>
+<i>lookahead</i> token for recognition.)</p>
 
-<a name="cpp">
+<a name="cpp"></a>
+<h5>2.5.3 Contextual precedence</h5>
 
-Contextual precedence assignments follow all the symbols and actions of
+<p>Contextual precedence assignments follow all the symbols and actions of
 the right hand side of the production whose precedence it is assigning.
 Contextual precedence assignment allows a production to be assigned a
 precedence not based on the last terminal in it.  A good example is
 shown in the above sample parser specification:
 
-</a></p><pre><a name="cpp"><tt>
+</p><pre>
 	precedence left PLUS, MINUS;
 	precedence left TIMES, DIVIDE, MOD;
 	precedence left UMINUS;
@@ -625,14 +669,15 @@ shown in the above sample parser specification:
 	expr ::=  MINUS expr:e             
 	          {: RESULT = new Integer(0 - e.intValue()); :} 
 	          %prec UMINUS
-</tt></a></pre>
+</pre>
 
-<a name="cpp">Here, there production is declared as having the precedence of UMINUS.
+<p>Here, there production is declared as having the precedence of UMINUS.
 Hence, the parser can give the MINUS sign two different precedences,
 depending on whether it is a unary minus or a subtraction operation. 
+</p>
 
-</a><a name="running">
-<h3>3. Running CUP</h3></a>
+<a name="running"></a>
+<h3>3. Running CUP</h3>
 <h4>3.1 Command line interface</h4>
 As mentioned above, CUP is written in Java.  To invoke it, one needs
 to use the Java interpreter to invoke the static method 
@@ -640,7 +685,7 @@ to use the Java interpreter to invoke the static method
 Assuming a Unix machine, the simplest way to do this is typically to invoke it 
 directly from the command line with a command such as: 
 
-<pre><tt>    java -jar java-cup-11a.jar <i>options</i>  <i>inputfile</i></tt></pre>
+<pre><tt>    java -jar java-cup-11b.jar <i>options</i>  <i>inputfile</i></tt></pre>
 
 Once running, CUP expects to find a specification file on standard input
 and produces two Java source files as output. <p>
@@ -757,7 +802,19 @@ by passing various options to it.  Legal options are documented in
       computation to not generate these position propagations.  This option
       also keeps the left and right label variables from being generated, so
       any reference to these will cause an error.
-
+  </dd><dt><tt>-locations</tt>          
+  </dt><dd>This option makes CUP generate xleft/xright handles for
+      accessing Location objects for symbol start/end inside actions.
+  </dd><dt><tt>-xmlactions</tt>          
+  </dt><dd>This option makes CUP generate generic actions that produce
+      XMLElement-objects for any symbol, that is labeled by the CUP spec
+      author. These objects directly mirror the according parse subtree. For this
+      option, You will want to remove types from any symbol as well as
+      ignore the RESULT-handle in any action, should you still want
+      to perform any.
+  </dd><dt><tt>-genericlabels</tt>          
+  </dt><dd>This option goes one step further then -xmlactions by producing
+      the full parse tree as XMLElement-tree.
   </dd><dt><tt>-noscanner</tt>
   </dt><dd>CUP 0.10j introduced <a href="#scanner">improved scanner
   integration</a> and a new interface,
@@ -776,19 +833,18 @@ by passing various options to it.  Legal options are documented in
   automated CUP version checking for Makefiles, install scripts and
   other applications which may require it.
 </dd></dl>
-<a name="ant">
+<a name="ant"></a>
 <h4>3.2 Integrating CUP into an <a href="http://ant.apache.org/">ANT</a>
 script</h4>
-</a>
-To use cup in an ANT script, You have to add the following task definition to
-Your <tt>build.xml</tt> file:
+<p>To use cup in an ANT script, You have to add the following task definition to
+Your <tt>build.xml</tt> file:</p>
 <pre><taskdef name="cup"
   classname="java_cup.anttask.CUPTask"
   classpathref="cupclasspath"
 />
 </pre>
-Now, You are ready to use Your new <cup/> task to generate own parsers
-from within ANT. Such a generation statement could look like:
+<p>Now, You are ready to use Your new <cup/> task to generate own parsers
+from within ANT. Such a generation statement could look like:</p>
 <pre><target name="cup">
 <cup srcfile="path/to/cupfile/Parser.cup"
   destdir="path/to/javafiles"
@@ -796,12 +852,12 @@ from within ANT. Such a generation statement could look like:
 />
 </target>
 </pre>
-You can specify all commandline flags from chapter <bf>3.1</bf> as boolean
+<p>You can specify all commandline flags from chapter <bf>3.1</bf> as boolean
 parameters to Your cuptask to achieve a similar behaviour (as done with
-<tt>-interface</tt> in this little example).
+<tt>-interface</tt> in this little example).</p>
 
-<a name="parser">
-<h3>4. Customizing the Parser</h3></a>
+<a name="parser"></a>
+<h3>4. Customizing the Parser</h3>
 
 Each generated parser consists of three generated classes.  The 
 <tt>sym</tt> class (which can be renamed using the <tt>-symbols</tt>
@@ -850,7 +906,7 @@ available for customization include:
 </dt><dd>This method is called by the parser prior to asking for the first token 
     from the scanner.  The body of this method contains the code from the 
     <tt>init with</tt> clause of the the specification.  
-</dd><dt><a name="scan_method"><tt>public java_cup.runtime.Symbol scan()</tt></a>
+</dd><dt><a name="scan_method"></a><tt>public java_cup.runtime.Symbol scan()</tt>
 </dt><dd>This method encapsulates the scanner and is called each time a new
     terminal is needed by the parser.  The body of this method is 
     supplied by the <tt>scan with</tt> clause of the specification, if
@@ -872,6 +928,19 @@ available for customization include:
     by calling the parser method <tt>done_parsing()</tt>, and finally
     throws an exception.  (In general <tt>done_parsing()</tt> should be called 
     at any point that parsing needs to be terminated early).
+</dd><dt><tt>public List<Integer> expected_token_ids()</tt>
+</dt><dd>This method informs during parsing and especially when handling
+    parsing problems and invalid input about valid continuations for parsing.
+    It returns a list of integer constants which correspond to the constants
+    in the generated <tt>sym.java</tt>. You can retranslate the ids to their
+    string representations, which where used in the grammar specification to
+    declare (non)terminal names, with <tt>symbol_name_from_id(id)</tt>
+    This can be typically used to implement syntax completion or more detailed
+    error messages.
+</dd><dt><tt>public String symbol_name_from_id(int id)</tt>
+</dt><dd>This method translates numerical constants, representing symbol ids 
+    back to their textual representation, declared in the <tt>.cup</tt>
+    parser specification file.
 </dd><dt><tt>public void syntax_error(Symbol cur_token)</tt>
 </dt><dd>This method is called by the parser as soon as a syntax error is detected
     (but before error recovery is attempted).  In the default implementation it
@@ -924,26 +993,28 @@ with code such as:
       }
 </pre>
 
-<a name="scanner" />
-<h3>5. Scanner Interface</h3></a>
+<a name="scanner"></a>
+<h3>5. Scanner Interface</h3>
 
-<a name="basic-symbols" />
+<a name="basic-symbols" ></a>
 <h4>5.1 Basic Symbol management</h4>
 
-In CUP 0.10j, scanner integration was improved according to
+<p>In CUP 0.10j, scanner integration was improved according to
 suggestions made by <a href="http://www.smartsc.com/">David MacMahon</a>.
 The changes make it easier to incorporate JLex and other
-automatically-generated scanners into CUP parsers.<p>
+automatically-generated scanners into CUP parsers.</p>
 
-To use the new code, your scanner should implement the
+<p>To use the new code, your scanner should implement the
 <code>java_cup.runtime.Scanner</code> interface, defined as:
-</p><pre>package java_cup.runtime;
+</p>
+<pre>
+package java_cup.runtime;
 
 public interface Scanner {
     public Symbol next_token() throws java.lang.Exception;
 }
-</pre><p>
-
+</pre>
+<p>
 In addition to the methods described in <a href="#parser">section
 4</a>, the <code>java_cup.runtime.lr_parser</code> class has two new
 accessor methods, <code>setScanner()</code> and <code>getScanner()</code>.
@@ -952,7 +1023,8 @@ is:
 </p><pre>  public Symbol scan() throws java.lang.Exception {
     return getScanner().next_token();
   }
-</pre><p>
+</pre>
+<p>
 The generated parser also contains a constructor which takes a
 <code>Scanner</code> and calls <code>setScanner()</code> with it. In
 most cases, then, the <code>init with</code> and <code>scan
@@ -984,8 +1056,9 @@ It is anticipated that the JLex directive <code>%cup</code> will
 abbreviate the above three directive in the next version of JLex.
 Invoking the parser with the JLex scanner is then simply:
 <pre>parser parser_obj = new parser( new Yylex( some_InputStream_or_Reader));
-</pre><p>
+</pre>
 
+<p>
 Note that you still have to handle EOF correctly; the JLex code to do
 so is something like:
 </p><pre>%eofval{
@@ -996,9 +1069,9 @@ where <code>sym</code> is the name of the symbol class for your
 generated parser.<p>
 
 The simple_calc example in the CUP distribution illustrates the use of
-the scanner integration features with a hand-coded scanner.</p><p>
+the scanner integration features with a hand-coded scanner.</p>
 
-<a name="advanced-symbols" />
+<a name="advanced-symbols"></a>
 <h4>5.2 Advanced Symbol management</h4>
 
 <p>Since CUP v11a we offer the possibility of advanced symbol handling in CUP.
@@ -1006,7 +1079,7 @@ Therefore, You can implement Your own SymbolFactory, derived from
 <code>java_cup.runtime.SymbolFactory</code>, and have CUP manage Your own type of
 symbols. We've done that for You already in the pre-defined
 <code>java_cup.runtime.ComplexSymbolFactory</code>, which provides support for
-detailed location information in the symbol class. Just have a look at CUPs own
+detailed location information in the symbol class. Just have a look at CUP's own
 <code>Lexer.jflex</code>, which is already using the new feature.</p>
 
 <p>All You have to do is providing Your CUP-generated parser with the new
@@ -1016,23 +1089,61 @@ SymbolFactory symbolFactory = new ComplexSymbolFactory();
 MyParser parser = new MyParser(new Lexer(inputfile,symbolFactory),symbolFactory); 
 </pre>
 
-<p>Also, You can use the factory methods in Your SymbolFactory to have
-callbacks/hooks into the semantic action methods. That is especially usefull,
-when You want to equip Your syntax tree with Location information as You can do
-as follows:</p>
+<p>The <code>ComplexSymbolFactory</code> is used straight-forward: In Your
+lexer, instead of directly creating <code>Symbol</code>-Objects, You call
+the factory's creation methods, called <code>newSymbol(...)</code>.</p>
+
+<p>Most of the times, You will want to use just the <code>ComplexSymbolFactory</code>.
+You can do that, by adding convenience methods into Your parser's body, like the following one
+for symobls with an attached String-value:</p>
 <pre>
-public Symbol newSymbol(String name, Symbol left, Symbol right, Object value){
-   ComplexSymbol sym = (ComplexSymbol)super.newSymbol(name,left,right,value);
-   SyntaxTreeNode node = (SyntaxTreeNode) value;
-   node.setLeft(left.getLeft());
-   node.setRight(right.getRight());
-   return sym;
-}
+ public Symbol symbol(String plainname, int terminalcode, String lexem){
+    return symbolFactory.newSymbol(plainname, terminalcode, new Location(yyline+1, yycolumn +1), new Location(yyline+1,yycolumn+yylength()), lexem);
+ }
+</pre>
+<p>The <code>Location</code>-Objects provide a convenient way to manage detailed 
+position informations for Your symbols. In order to use them in Your action specifications,
+don't forget to set the <code>-locations</code>-commandline-parameter when running CUP!
+This generates into the frame of each production no plain integer values (referred to via <code>??left,??right</code>,
+with ?? being Your symbol name) any more, but Your beloved Location objects (<code>??xleft,??xright</code>, again
+with ?? Your symbol's name). You can then access all its information like this:</p>
+<pre>
+expr      ::= expr:e1 PLUS expr:e2    
+	      {: RESULT = BinExpr.createAdd(e1,e2);           :} 
+	      | NUMBER:n                 
+	      {: RESULT = Expr.createConst(nxleft,n,nxright); :}
+</pre>
+<p>In the example, we create an expression tree from our input language. Here,
+we store the location information for the subexpressions in the AST. 
+This can be seen in the action for the <code>NUMBER</code>, where we access
+<code>nxleft</code> and <code>nxright</code>. Note, that in this example we
+only store the locations of leaves directly. In a convenient implementation
+of the AST, we would expect a recursive function, that computes the locations for each
+intermediary node in the tree.
+</p>
+
+<a name="symbolstream-caching"></a>
+<h4>5.3 Symbolstream caching</h4>
+
+<p>CUP offers an additional layer between scanner and parser, in order to cache the
+actual sequence of terminal symbols, provided by the scanner for potential later use.
+This comes in handy, if e.g. a pretty printer or syntax highlighter is applied.</p>
+
+<p>Given that the <code>Lexer</code> class implements CUP's <code>Scanner</code>
+interface, we can buffer its output with the <code>ScannerBuffer</code> and access
+the tokenstream with <code>getBuffered()</code>, once the parsing is finished:</p>
+<pre>
+Scanner scanner = new Lexer();
+ScannerBuffer buffer = new ScannerBuffer(lexer);
+Parser p = new Parser(buffer,new ComplexSymbolFactory);
+p.parse();
+System.out.println(buffer.getBuffered());
 </pre>
 
-<a name="errors" />
-<h3>6. Error Recovery</h3></a>
-
+<a name="errors"></a>
+<h3>6. Error Recovery</h3>
+<a name="error_sym"></a>
+<h4>6.1 The error symbol</h4>
 A final important aspect of building parsers with CUP is 
 support for syntactic error recovery.  CUP uses the same 
 error recovery mechanisms as YACC.  In particular, it supports
@@ -1082,8 +1193,27 @@ input is reached without making a successful recovery (or there was no
 suitable error recovery state found on the parse stack to begin with)
 then error recovery fails.
 
-<a name="conclusion">
-<h3>7. Conclusion</h3></a>
+<a name="continuation_symbols"></a>
+<h4>6.2 Viable continuation Symbols</h4>
+<p>In case of parsing errors, CUP offers support in delivering meaningful
+user feedback. Consider that the specified parser is to be applied in a
+fancy IDE which registers parsing errors and makes propositions, on how
+to fix these errors. In these cases, an implementation for the action code
+of an error symbol could consist in telling the IDE about the exact
+location of the unmatched input, as well as the list of viable symbols, with
+which the parser can advance a step in the current state, reaching an
+accepting state. These symbols are coded as integers, and can be decoded to
+their string representations via calls to <code>symbol_name_from_id()</code>.
+Such an action can look like:</p>
+<pre><tt>    stmt ::= expr SEMI | while_stmt SEMI | if_stmt SEMI | ... |
+	     error:e {: 
+                 List<Integer> expected = expected_token_ids();
+                 myIDE.registerParseError(exleft,exright,expected);
+             :} SEMI
+	     ;</tt></pre>
+
+<a name="conclusion"></a>
+<h3>7. Conclusion</h3>
 
 This manual has briefly described the CUP LALR parser generation system.
 CUP is designed to fill the same role as the well known YACC parser
@@ -1093,15 +1223,20 @@ be found in the parser generator and runtime source code.  See the CUP
 home page below for access to the API documentation for the system and its
 runtime.</p><p>
 
-This document covers version 0.10j of the system.  Check the CUP home
+This document covers version 0.11b of the system.  Check the CUP home
 page:
-<a href="http://www.cs.princeton.edu/%7Eappel/modern/java/CUP/">
-http://www.cs.princeton.edu/~appel/modern/java/CUP/</a>
+<a href="http://www2.in.tum.de/projects/cuptum">
+http://www2.in.tum.de/projects/cuptum/</a>
 for the latest release information, instructions for downloading the
 system, and additional news about CUP.  Bug reports and other 
 comments for the developers should be sent to the CUP maintainer, 
+M. Petter, at
+<a href="mailto:petterATcs.tum.edu">
+petterATcs.tum.edu</a></p><p>
+
+Before this, it was maintained by
 C. Scott Ananian, at
-<a href="mailto:cananian at alumni.princeton.edu">
+<a href="cananian at alumni.princeton.edu">
 cananian at alumni.princeton.edu</a></p><p>
 
 CUP was originally written by 
@@ -1117,8 +1252,8 @@ On-going improvements have been done by
 C. Scott Ananian</a>, the CUP maintainer, from December of 1997 to the
 present.</p><p>
 
-<a name="refs">
-<h3>References</h3></a>
+<a name="refs"></a>
+<h3>References</h3>
 </p><dl compact="compact">
 
 <dt><a name="YACCref">[1]</a> 
@@ -1145,15 +1280,16 @@ Redwood City, CA,
 
 </dd></dl>
 
-<h3><a name="appendixa">
+<h3><a name="appendixa" />
 Appendix A. Grammar for CUP Specification Files</a> (0.10j)</h3>
 <hr><br>
-<pre><tt>java_cup_spec      ::= package_spec import_list code_parts
+<pre><tt>java_cup_spec      ::= package_spec import_list class_name code_parts
 		       symbol_list precedence_list start_spec 
 		       production_list
 package_spec       ::= PACKAGE multipart_id SEMI | empty
 import_list        ::= import_list import_spec | empty
 import_spec        ::= IMPORT import_id SEMI
+class_name         ::= CLASS ID SEMI | empty
 code_part          ::= action_code_part | parser_code_part |
                        init_code | scan_code
 code_parts         ::= code_parts code_part | empty
@@ -1203,9 +1339,9 @@ opt_semi	   ::= SEMI | empty
 </tt></pre>
 <hr><p></p><p>
 
-</p><h3><a name="appendixb">Appendix B. A Very Simple Example Scanner</a><a></a></h3>
-<hr><a><br>
-</a><pre><a><tt>// Simple Example Scanner Class
+</p><h3><a name="appendixb"></a>Appendix B. A Very Simple Example Scanner</h3>
+<hr><br>
+<pre><tt>// Simple Example Scanner Class
 
 import java_cup.runtime.*;
 import sym;
@@ -1261,11 +1397,10 @@ public class scanner {
 	  }
     }
 };
-</tt></a></pre>
+</tt></pre>
 
 
-<a name="changes">
-</a><h3><a name="changes">Appendix C:  Incompatibilites between CUP 0.9 and CUP 0.10</a></h3>
+<a name="changes" /><h3><a name="changes">Appendix C:  Incompatibilites between CUP 0.9 and CUP 0.10</a></h3>
 
 CUP version 0.10a is a major overhaul of CUP.  The changes are severe,
 meaning no backwards compatibility to older versions.
@@ -1282,7 +1417,7 @@ The changes consist of:
 </li><li> <a href="#con_prec">Rule contextual precedence assignment</a>
 </li></ul>
 
-<h5><a name="lex_inter">Lexical Interface</a></h5>
+<h5><a name="lex_inter"></a>Lexical Interface</h5>
 
 CUP now interfaces with the lexer in a completely different
 manner.  In the previous releases, a new class was used for every
@@ -1445,7 +1580,7 @@ For a list of any other currently known bugs in CUP, see
 http://www.cs.princeton.edu/~appel/modern/java/CUP/bugs.html</a>.
 
 <a name="version">
-</a></p><h3><a name="version">Appendix E:  Change log</a></h3>
+</a></p><h3>Appendix E:  Change log</h3>
 
 <dl>
 <dt>0.9e</dt><dd>March 1996, Scott Hudson's original version.
@@ -1492,5 +1627,5 @@ CUP is not sponsored by or affiliated with Sun Microsystems, Inc.
 
 <hr>
 
-
-</body></html>
\ No newline at end of file
+</div>
+</body></html>


=====================================
src/java_cup/Main.java
=====================================
@@ -54,6 +54,8 @@ import java_cup.runtime.*;
  *   <dd> turn on debugging messages within JavaCup 
  *   <dt> -nopositions
  *   <dd> don't generate the positions code
+ *   <dt> -locations
+ *   <dd> generate handles xleft/xright for symbol positions in actions
  *   <dt> -noscanner
  *   <dd> don't refer to java_cup.runtime.Scanner in the parser
  *        (for compatibility with old runtimes)
@@ -89,6 +91,8 @@ public class Main {
   protected static boolean opt_show_timing  = false;
   /** User option -- do we run produce extra debugging messages */
   protected static boolean opt_do_debug     = false;
+  /** User option -- do eclipse debug symbols */
+  protected static boolean opt_do_debugsymbols = false; 
   /** User option -- do we compact tables by making most common reduce the 
       default action */
   protected static boolean opt_compact_red  = false;
@@ -103,7 +107,10 @@ public class Main {
   /* frankf added this 6/18/96 */
   /** User option -- should generator generate code for left/right values? */
   protected static boolean lr_values = true;
-
+  protected static boolean locations = false;
+  protected static boolean xmlactions = false;
+  protected static boolean genericlabels = false;
+  
   /** User option -- should symbols be put in a class or an interface? [CSA]*/
   protected static boolean sym_interface = false;
 
@@ -173,7 +180,10 @@ public class Main {
       /* frankf 6/18/96
 	 hackish, yes, but works */
       emit.set_lr_values(lr_values);
-      /* open output files */
+      emit.set_locations(locations);
+      emit.set_xmlactions(xmlactions);
+      emit.set_genericlabels(genericlabels);
+      /* open output set_xmlactionsfiles */
       if (print_progress) System.err.println("Opening files...");
       /* use a buffered version of standard input */
       input_file = new BufferedInputStream(System.in);
@@ -248,6 +258,7 @@ public class Main {
       System.err.println(message);
       System.err.println();
       System.err.println(
+version.title_str + "\n" +
 "Usage: " + version.program_name + " [options] [filename]\n" +
 "  and expects a specification file on standard input if no filename is given.\n" +
 "  Legal options include:\n" +
@@ -263,6 +274,9 @@ public class Main {
 "    -nowarn        don't warn about useless productions, etc.\n" +
 "    -nosummary     don't print the usual summary of parse states, etc.\n" +
 "    -nopositions   don't propagate the left and right token position values\n" +
+"    -locations     generate handles xleft/xright for symbol positions in actions\n" +
+"    -xmlactions    make the generated parser yield its parse tree as XML\n" +
+"    -genericlabels automatically generate labels to all symbols in XML mode\n" +
 "    -noscanner     don't refer to java_cup.runtime.Scanner\n" +
 "    -progress      print messages to indicate progress of the system\n" +
 "    -time          print time usage summary\n" +
@@ -358,8 +372,12 @@ public class Main {
 	        opt_dump_states = opt_dump_tables = opt_dump_grammar = true; 
 	  else if (argv[i].equals("-time"))         opt_show_timing = true; 
 	  else if (argv[i].equals("-debug"))        opt_do_debug = true;
+	  else if (argv[i].equals("-debugsymbols"))        opt_do_debugsymbols = true;
 	  /* frankf 6/18/96 */
 	  else if (argv[i].equals("-nopositions"))  lr_values = false;
+	  else if (argv[i].equals("-locations"))    locations = true;
+	  else if (argv[i].equals("-xmlactions"))   xmlactions = true;
+	  else if (argv[i].equals("-genericlabels"))   genericlabels = true;
 	  /* CSA 12/21/97 */
 	  else if (argv[i].equals("-interface"))    sym_interface = true;
 	  /* CSA 23-Jul-1999 */
@@ -470,6 +488,7 @@ public class Main {
       /* create a parser and parse with it */
       ComplexSymbolFactory csf = new ComplexSymbolFactory();
       parser_obj = new parser(new Lexer(csf),csf);
+      parser_obj.setDebugSymbols(opt_do_debugsymbols);
       try {
 	if (opt_do_debug)
           parser_obj.debug_parse();
@@ -696,7 +715,7 @@ public class Main {
 
       System.err.println(
 	"---------------------------------------------------- (" + 
-	 version.version_str + ")");
+	 version.title_str + ")");
     }
 
   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/


=====================================
src/java_cup/anttask/CUPTask.java
=====================================
@@ -55,7 +55,11 @@ public class CUPTask extends Task
     private boolean dump=false;
     private boolean time=false;
     private boolean debug=false;
+    private boolean debugsymbols=false;
     private boolean nopositions=false;
+    private boolean xmlactions=false;
+    private boolean genericlabels=false;
+    private boolean locations=true;
     private boolean noscanner=false;
     private boolean force=false;
     private boolean quiet=false;
@@ -88,7 +92,11 @@ public class CUPTask extends Task
 	if (dump)          {  sc.add("-dump"); }
 	if (time)          {  sc.add("-time"); }
 	if (debug)         {  sc.add("-debug"); }
+	if (debugsymbols)  {  sc.add("-debugsymbols"); }
 	if (nopositions)   {  sc.add("-nopositions"); }
+	if (locations)     {  sc.add("-locations"); }
+	if (genericlabels) {  sc.add("-genericlabels"); }
+	if (xmlactions)    {  sc.add("-xmlactions"); }
 	if (noscanner)     {  sc.add("-noscanner"); }
 	if (!quiet) log ("This is "+version.title_str);
         if (!quiet) log ("Authors : "+version.author_str);
@@ -159,23 +167,6 @@ public class CUPTask extends Task
             log("CUP error occured int CUP task: "+e);
         }
 	
-	// this is a dirty hack to determine the apropriate class path
-//	URL url = CUPTask.class.getResource("/java_cup/Main.class");
-//	String path = url.getPath().substring(0,url.getPath().length()-20);
-//	// if called from a .jar or .zip remove the last "!"
-//	if (path.endsWith("!")) path=path.substring(0,path.length()-1);
-//	createClasspath().setPath(path);
-//
-//	setFailonerror(true);
-//	setFork(true);
-//	
-
-	// here, we prepare for calling CUP
-//	setClassname("java_cup.Main");
-	
-	// let's call CUP
-//	super.execute();
-
     }
 
     /**
@@ -560,8 +551,26 @@ public class CUPTask extends Task
     public void setDebug(boolean argDebug){
 	this.debug = argDebug;
     }
-
+    
     /**
+      * Gets the value of debug
+     *
+      * @return the value of debug
+      */
+    public boolean isDebugSymbols() {
+ 	return this.debugsymbols;
+    }
+ 
+     /**
+      * Sets the value of debug
+      *
+      * @param argDebug Value to assign to this.debug
+      */
+    public void setDebugSymbols(boolean argDebug){
+ 	this.debugsymbols = argDebug;
+    }
+ 
+     /**
      * Gets the value of nopositions
      *
      * @return the value of nopositions
@@ -578,6 +587,23 @@ public class CUPTask extends Task
     public void setNopositions(boolean argNopositions){
 	this.nopositions = argNopositions;
     }
+    /**
+     * Gets the value of locations
+     *
+     * @return the value of locations
+     */
+    public boolean isLocations() {
+	return this.locations;
+    }
+
+    /**
+     * Sets the value of locations
+     *
+     * @param argLocations Value to assign to this.locations
+     */
+    public void setLocations(boolean argLocations){
+	this.locations = argLocations;
+    }
 
     /**
      * Gets the value of noscanner
@@ -597,6 +623,22 @@ public class CUPTask extends Task
 	this.noscanner = argNoscanner;
     }
 
+	public boolean isXmlactions() {
+		return xmlactions;
+	}
+
+	public void setXmlactions(boolean xmlactions) {
+		this.xmlactions = xmlactions;
+	}
+
+	public boolean isGenericlabels() {
+		return genericlabels;
+	}
+
+	public void setGenericlabels(boolean genericlabels) {
+		this.genericlabels = genericlabels;
+	}
+
 
 }
 


=====================================
src/java_cup/emit.java
=====================================
@@ -3,7 +3,6 @@ package java_cup;
 import java.io.PrintWriter;
 import java.util.Stack;
 import java.util.Enumeration;
-import java.util.Date;
 
 /** 
  * This class handles emitting generated code for the resulting parser.
@@ -210,13 +209,26 @@ public class emit {
 
   /* frankf 6/18/96 */
   protected static boolean _lr_values;
+  protected static boolean _locations;
+  protected static boolean _xmlactions;
+  protected static boolean _genericlabels;
 
   /** whether or not to emit code for left and right values */
   public static boolean lr_values() {return _lr_values;}
+  public static boolean locations() { return _locations; }
   protected static void set_lr_values(boolean b) { _lr_values = b;}
-
+  protected static void set_locations(boolean b) { _locations = b; }
+  protected static void set_genericlabels(boolean b) { _genericlabels = b; }
+  protected static void set_xmlactions(boolean b) { _xmlactions = b; 
+ 	if (!b) return;
+ 	_locations=true; 
+ 	_lr_values=true;
+  }
   //Hm Added clear  to clear all static fields
   public static void clear () {
+	  _genericlabels = false;
+	  _xmlactions = false;
+      _locations = false; 
       _lr_values = true;
       action_code = null;
       import_list = new Stack();
@@ -286,9 +298,7 @@ public class emit {
       /* top of file */
       out.println();
       out.println("//----------------------------------------------------"); 
-      out.println("// The following code was generated by " + 
-							   version.title_str);
-      out.println("// " + new Date());
+      out.println("// The following code was generated by " + version.title_str);
       out.println("//----------------------------------------------------"); 
       out.println();
       emit_package(out);
@@ -311,6 +321,19 @@ public class emit {
 		      term.index() + ";");
 	}
 
+      /* Emit names of terminals */
+      out.println("  public static final String[] terminalNames = new String[] {");
+      for (int i = 0; i < terminal.number(); i++) {
+	  out.print("  \"");
+	  out.print(terminal.find(i).name());
+	  out.print("\"");
+	  if (i < terminal.number() - 1) {
+	      out.print(",");
+	  }
+	  out.println();
+      }
+      out.println("  };");
+
       /* do the non terminals if they want them (parser doesn't need them) */
       if (emit_non_terms)
 	{
@@ -341,6 +364,7 @@ public class emit {
 
   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
 
+  static final int UPPERLIMIT = 300;
   /** Emit code for the non-public class holding the actual action code. 
    * @param out        stream to produce output on.
    * @param start_prod the start production of the grammar.
@@ -357,6 +381,7 @@ public class emit {
       out.println(
        "/** Cup generated class to encapsulate user supplied action code.*/"
       );  
+      out.println("@SuppressWarnings({\"rawtypes\", \"unchecked\", \"unused\"})");
       /* TUM changes; proposed by Henning Niss 20050628: added type arguement */
       out.println("class " +  pre("actions") + typeArgument() + " {");
       /* user supplied code */
@@ -378,35 +403,29 @@ public class emit {
       out.println("    this.parser = parser;");
       out.println("  }");
 
-      /* action method head */
       out.println();
-      out.println("  /** Method with the actual generated action code. */");
+      for (int instancecounter = 0; instancecounter <= production.number()/UPPERLIMIT; instancecounter++) {
+      out.println("  /** Method "+instancecounter+" with the actual generated action code for actions "+(instancecounter*UPPERLIMIT)+" to "+((instancecounter+1)*UPPERLIMIT) +". */");
       out.println("  public final java_cup.runtime.Symbol " + 
-		     pre("do_action") + "(");
+		     pre("do_action_part")+ String.format("%08d",new Integer(instancecounter)) +"(");
       out.println("    int                        " + pre("act_num,"));
       out.println("    java_cup.runtime.lr_parser " + pre("parser,"));
       out.println("    java.util.Stack            " + pre("stack,"));
       out.println("    int                        " + pre("top)"));
       out.println("    throws java.lang.Exception");
       out.println("    {");
-
-      /* declaration of result symbol */
-      /* New declaration!! now return Symbol
-	 6/13/96 frankf */
       out.println("      /* Symbol object for return from actions */");
       out.println("      java_cup.runtime.Symbol " + pre("result") + ";");
       out.println();
-
-      /* switch top */
       out.println("      /* select the action based on the action number */");
       out.println("      switch (" + pre("act_num") + ")");
       out.println("        {");
-
+      // START Switch
       /* emit action code for each production as a separate case */
-      for (Enumeration p = production.all(); p.hasMoreElements(); )
+      int proditeration = instancecounter*UPPERLIMIT;
+      prod=production.find(proditeration);
+      for ( ;proditeration<Math.min((instancecounter+1)*UPPERLIMIT,production.number());prod=(production)production.find(++proditeration) )
 	{
-	  prod = (production)p.nextElement();
-
 	  /* case label */
           out.println("          /*. . . . . . . . . . . . . . . . . . . .*/");
           out.println("          case " + prod.index() + ": // " + 
@@ -505,13 +524,11 @@ public class emit {
                   // TUM 20060327 removed .left
 		  ")";
 	    }
-//	    out.println("              " + pre("result") + " = new java_cup.runtime.Symbol(" + 
 	    out.println("              " + pre("result") + " = parser.getSymbolFactory().newSymbol(" + 
                         "\""+ 	prod.lhs().the_symbol().name() +"\","+ 
 			prod.lhs().the_symbol().index()  +
-			", " + leftstring + ", " + rightstring + ", RESULT);");
+			", " + leftstring + ((prod.rhs_length()==0)?(""):(", " + rightstring)) + ", RESULT);");
 	  } else {
-//	    out.println("              " + pre("result") + " = new java_cup.runtime.Symbol(" + 
 	    out.println("              " + pre("result") + " = parser.getSymbolFactory().newSymbol(" + 
 		"\""+ 	prod.lhs().the_symbol().name() +  "\","+ 
 			prod.lhs().the_symbol().index() + 
@@ -533,14 +550,67 @@ public class emit {
 	  out.println();
 	}
 
-      /* end of switch */
+      // END Switch
       out.println("          /* . . . . . .*/");
       out.println("          default:");
       out.println("            throw new Exception(");
-      out.println("               \"Invalid action number found in " +
+      out.println("               \"Invalid action number \"+"+pre("act_num")+"+\"found in " +
 				  "internal parse table\");");
       out.println();
       out.println("        }");
+      out.println("    } /* end of method */");
+      }
+
+      /* action method head */
+      out.println();
+      out.println("  /** Method splitting the generated action code into several parts. */");
+      out.println("  public final java_cup.runtime.Symbol " + 
+		     pre("do_action") + "(");
+      out.println("    int                        " + pre("act_num,"));
+      out.println("    java_cup.runtime.lr_parser " + pre("parser,"));
+      out.println("    java.util.Stack            " + pre("stack,"));
+      out.println("    int                        " + pre("top)"));
+      out.println("    throws java.lang.Exception");
+      out.println("    {");
+
+      if (production.number()<UPPERLIMIT) { // Make it simple for the optimizer to inline!
+	  out.println("              return " + pre("do_action_part")+ String.format("%08d",new Integer(0))+"(");
+	  out.println("                               " + pre("act_num,"));
+	  out.println("                               " + pre("parser,"));
+	  out.println("                               " + pre("stack,"));
+	  out.println("                               " + pre("top);"));
+	  out.println("    }");
+
+	  /* end of class */
+	  out.println("}");
+	  out.println();
+
+	  action_code_time = System.currentTimeMillis() - start_time;
+	  return;
+      }
+
+      /* switch top */
+      out.println("      /* select the action handler based on the action number */");
+      out.println("      switch (" + pre("act_num") + "/"+UPPERLIMIT+ ")");
+      out.println("        {");
+
+      /* emit action code for each production as a separate case */
+      for (int instancecounter = 0; instancecounter <= production.number()/UPPERLIMIT; instancecounter++) {
+	  /* case label */
+          out.println("          /*. . . . . . . . "+(instancecounter*UPPERLIMIT)+" < #action < "+((instancecounter+1)*UPPERLIMIT)+". . . . . . . . . . . .*/");
+          out.println("          case " + instancecounter + ": ");
+	  out.println("              return " + pre("do_action_part")+ String.format("%08d",new Integer(instancecounter))+"(");
+	  out.println("                               " + pre("act_num,"));
+	  out.println("                               " + pre("parser,"));
+	  out.println("                               " + pre("stack,"));
+	  out.println("                               " + pre("top);"));
+      }
+
+      out.println("          /* . . . no valid action number: . . .*/");
+      out.println("          default:");
+      out.println("            throw new Exception(\"Invalid action number found in internal parse table\");");
+      out.println();
+      out.println("        }      /* end of switch */");
 
       /* end of method */
       out.println("    }");
@@ -844,9 +914,7 @@ public class emit {
       /* top of file */
       out.println();
       out.println("//----------------------------------------------------"); 
-      out.println("// The following code was generated by " + 
-							version.title_str);
-      out.println("// " + new Date());
+      out.println("// The following code was generated by " + version.title_str);
       out.println("//----------------------------------------------------"); 
       out.println();
       emit_package(out);
@@ -854,23 +922,33 @@ public class emit {
       /* user supplied imports */
       for (int i = 0; i < import_list.size(); i++)
 	out.println("import " + import_list.elementAt(i) + ";");
+      if (locations())
+	out.println("import java_cup.runtime.ComplexSymbolFactory.Location;");
+  	out.println("import java_cup.runtime.XMLElement;");
 
       /* class header */
       out.println();
       out.println("/** "+version.title_str+" generated parser.");
-      out.println("  * @version " + new Date());
       out.println("  */");
+      out.println("@SuppressWarnings({\"rawtypes\"})");
       /* TUM changes; proposed by Henning Niss 20050628: added typeArgument */
       out.println("public class " + parser_class_name + typeArgument() +
 		  " extends java_cup.runtime.lr_parser {");
 
+      out.println();
+      out.println(" public final Class getSymbolContainer() {");
+      out.println("    return "+ symbol_const_class_name +".class;");
+      out.println("}");
+      
       /* constructors [CSA/davidm, 24-jul-99] */
       out.println();
       out.println("  /** Default constructor. */");
+      out.println("  @Deprecated");
       out.println("  public " + parser_class_name + "() {super();}");
       if (!suppress_scanner) {
 	  out.println();
 	  out.println("  /** Constructor which sets the default scanner. */");
+	  out.println("  @Deprecated");
 	  out.println("  public " + parser_class_name + 
 		      "(java_cup.runtime.Scanner s) {super(s);}");
           // TUM 20060327 added SymbolFactory aware constructor
@@ -965,14 +1043,227 @@ public class emit {
           out.println(parser_code);
 	}
 
-      /* end of class */
-      out.println("}");
 
       /* put out the action code class */
-      emit_action_code(out, start_prod);
+      if (!_xmlactions)
+    	  emit_action_code(out, start_prod);
+      else
+    	  emit_xmlaction_code(out, start_prod);
+
+      /* end of class */
+      out.println("}");
 
       parser_time = System.currentTimeMillis() - start_time;
     }
+/** Emit code for generic XML parsetree output. 
+   * @param out        stream to produce output on.
+   * @param start_prod the start production of the grammar.
+   */
+  protected static void emit_xmlaction_code(PrintWriter out, production start_prod)
+    throws internal_error
+    {
+      production prod;
+
+      long start_time = System.currentTimeMillis();
+
+      /* class header */
+      out.println();
+      out.println(
+       "/** Cup generated class to encapsulate user supplied action code.*/"
+      );  
+      out.println("@SuppressWarnings({\"rawtypes\", \"unchecked\", \"unused\"})");
+      out.println("class " +  pre("actions") + typeArgument() + " {");
+      /* user supplied code */
+      if (action_code != null)
+	{
+	  out.println();
+          out.println(action_code);
+	}
+
+      /* field for parser object */
+      out.println("  private final "+parser_class_name + typeArgument() + " parser;");
+
+      /* constructor */
+      out.println();
+      out.println("  /** Constructor */");
+      out.println("  " + pre("actions") + "("+parser_class_name+typeArgument()+" parser) {");
+      out.println("    this.parser = parser;");
+      out.println("  }");
+
+      out.println();
+      for (int instancecounter = 0; instancecounter <= production.number()/UPPERLIMIT; instancecounter++) {
+      out.println("  /** Method "+instancecounter+" with the actual generated action code for actions "+(instancecounter*UPPERLIMIT)+" to "+((instancecounter+1)*UPPERLIMIT) +". */");
+      out.println("  public final java_cup.runtime.Symbol " + 
+		     pre("do_action_part")+ String.format("%08d",new Integer(instancecounter)) +"(");
+      out.println("    int                        " + pre("act_num,"));
+      out.println("    java_cup.runtime.lr_parser " + pre("parser,"));
+      out.println("    java.util.Stack            " + pre("stack,"));
+      out.println("    int                        " + pre("top)"));
+      out.println("    throws java.lang.Exception");
+      out.println("    {");
+      out.println("      /* Symbol object for return from actions */");
+      out.println("      java_cup.runtime.Symbol " + pre("result") + ";");
+      out.println();
+      out.println("      /* select the action based on the action number */");
+      out.println("      switch (" + pre("act_num") + ")");
+      out.println("        {");
+      // START Switch
+      /* emit action code for each production as a separate case */
+      int proditeration = instancecounter*UPPERLIMIT;
+      prod=production.find(proditeration);
+      for ( ;proditeration<Math.min((instancecounter+1)*UPPERLIMIT,production.number());prod=(production)production.find(++proditeration) )
+	{
+	  /* case label */
+          out.println("          /*. . . . . . . . . . . . . . . . . . . .*/");
+          out.println("          case " + prod.index() + ": // " + 
+					  prod.to_simple_string());
+
+	  /* give them their own block to work in */
+	  out.println("            {");
+
+
+      out.println("                XMLElement RESULT;");
+      
+
+          // Generate the XML Output
+          String nested="";
+          for (int rhsi=0;rhsi<prod.rhs_length();rhsi++){
+        	  if (!(prod.rhs(rhsi) instanceof symbol_part)) continue;
+        	  String label = prod.rhs(rhsi).label();
+        	  symbol_part sym  = (symbol_part)prod.rhs(rhsi);
+        	  if (label==null) {
+        		  if (!_genericlabels) continue;
+        		  label = sym.the_symbol().name()+rhsi;
+        	  }
+        	  if (sym.the_symbol().is_non_term())
+        		  nested+=",(XMLElement)"+label;
+        	  else 
+        		  nested+=",new XMLElement.Terminal("+label+"xleft,\""+label+"\","+label+","+label+"xright)";
+          }
+          
+          if (prod.action() != null && prod.action().code_string() != null &&
+                  !prod.action().equals(""))
+                out.println(prod.action().code_string());
+          
+          // determine the variant:
+          int variant=0;
+          for (int i=0;i<proditeration;i++)
+        	  if (production.find(i).lhs().equals(prod.lhs())) variant++;
+          
+          String lhsname =prod.lhs().the_symbol().name().replace('$','_'); 
+          out.println("                RESULT = new XMLElement.NonTerminal(\""+
+        		  lhsname+"\","+
+        		  variant+nested+");"); 
+          
+          
+         /* Create the code that assigns the left and right values of
+            the new Symbol that the production is reducing to */
+	  if (emit.lr_values()) {	    
+	    int loffset;
+	    String leftstring, rightstring;
+	    rightstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".peek()"+")"; 	  
+	    if (prod.rhs_length() == 0) 
+	      leftstring = rightstring;
+	    else {
+	      loffset = prod.rhs_length() - 1;
+	      leftstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + 
+		  ((loffset==0)?(".peek()"):(".elementAt(" + emit.pre("top") + "-" + loffset + ")")) +")";
+	    }
+	    out.println("              " + pre("result") + " = parser.getSymbolFactory().newSymbol(" + 
+                        "\""+ 	prod.lhs().the_symbol().name() +"\","+ 
+			prod.lhs().the_symbol().index() + ", " + leftstring + ", " + rightstring + ", RESULT);");
+	  } else {
+	    out.println("              " + pre("result") + " = parser.getSymbolFactory().newSymbol(" + 
+		"\""+ 	prod.lhs().the_symbol().name() +  "\"," + prod.lhs().the_symbol().index() + ", RESULT);");
+	  }
+	  
+	  /* end of their block */
+	  out.println("            }");
+
+	  /* if this was the start production, do action for accept */
+	  if (prod == start_prod)
+	    {
+	      out.println("          /* ACCEPT */");
+	      out.println("          " + pre("parser") + ".done_parsing();");
+	    }
+
+	  /* code to return lhs symbol */
+	  out.println("          return " + pre("result") + ";");
+	  out.println();
+	}
+
+      // END Switch
+      out.println("          /* . . . . . .*/");
+      out.println("          default:");
+      out.println("            throw new Exception(");
+      out.println("               \"Invalid action number \"+"+pre("act_num")+"+\"found in " +
+				  "internal parse table\");");
+      out.println();
+      out.println("        }");
+      out.println("    } /* end of method */");
+      }
+
+      /* action method head */
+      out.println();
+      out.println("  /** Method splitting the generated action code into several parts. */");
+      out.println("  public final java_cup.runtime.Symbol " + 
+		     pre("do_action") + "(");
+      out.println("    int                        " + pre("act_num,"));
+      out.println("    java_cup.runtime.lr_parser " + pre("parser,"));
+      out.println("    java.util.Stack            " + pre("stack,"));
+      out.println("    int                        " + pre("top)"));
+      out.println("    throws java.lang.Exception");
+      out.println("    {");
+
+      if (production.number()<UPPERLIMIT) { // Make it simple for the optimizer to inline!
+	  out.println("              return " + pre("do_action_part")+ String.format("%08d",new Integer(0))+"(");
+	  out.println("                               " + pre("act_num,"));
+	  out.println("                               " + pre("parser,"));
+	  out.println("                               " + pre("stack,"));
+	  out.println("                               " + pre("top);"));
+	  out.println("    }");
+
+	  /* end of class */
+	  out.println("}");
+	  out.println();
+
+	  action_code_time = System.currentTimeMillis() - start_time;
+	  return;
+      }
+
+      /* switch top */
+      out.println("      /* select the action handler based on the action number */");
+      out.println("      switch (" + pre("act_num") + "/"+UPPERLIMIT+ ")");
+      out.println("        {");
+
+      /* emit action code for each production as a separate case */
+      for (int instancecounter = 0; instancecounter <= production.number()/UPPERLIMIT; instancecounter++) {
+	  /* case label */
+          out.println("          /*. . . . . . . . "+(instancecounter*UPPERLIMIT)+" < #action < "+((instancecounter+1)*UPPERLIMIT)+". . . . . . . . . . . .*/");
+          out.println("          case " + instancecounter + ": ");
+	  out.println("              return " + pre("do_action_part")+ String.format("%08d",new Integer(instancecounter))+"(");
+	  out.println("                               " + pre("act_num,"));
+	  out.println("                               " + pre("parser,"));
+	  out.println("                               " + pre("stack,"));
+	  out.println("                               " + pre("top);"));
+      }
+
+      out.println("          /* . . . no valid action number: . . .*/");
+      out.println("          default:");
+      out.println("            throw new Exception(\"Invalid action number found in internal parse table\");");
+      out.println();
+      out.println("        }      /* end of switch */");
+
+      /* end of method */
+      out.println("    }");
+
+      /* end of class */
+      out.println("}");
+      out.println();
+
+      action_code_time = System.currentTimeMillis() - start_time;
+    }
+
 
     /*-----------------------------------------------------------*/
 }


=====================================
src/java_cup/lalr_state.java
=====================================
@@ -747,9 +747,10 @@ public class lalr_state {
 		    }
 		}
 	      /* report S/R conflicts under all the symbols we conflict under */
+	      terminal_set lookahead = itm.lookahead(); 
 	      for (int t = 0; t < terminal.number(); t++)
-		if (conflict_set.contains(t))
-		  report_shift_reduce(itm,t);
+	    	  if (conflict_set.contains(t) && lookahead.contains(t))
+	    		  report_shift_reduce(itm,t);
 	    }
 	}
     }
@@ -808,6 +809,7 @@ public class lalr_state {
       String message = "*** Shift/Reduce conflict found in state #"+index()+"\n" +
       "  between " + red_itm.to_simple_string()+"\n";
 
+      int relevancecounter = 0;
       /* find and report on all items that shift under our conflict symbol */
       for (Enumeration itms = items().all(); itms.hasMoreElements(); )
 	{
@@ -816,10 +818,12 @@ public class lalr_state {
 	  /* only look if its not the same item and not a reduce */
 	  if (itm != red_itm && !itm.dot_at_end())
 	    {
+
 	      /* is it a shift on our conflicting terminal */
 	      shift_sym = itm.symbol_after_dot();
 	      if (!shift_sym.is_non_term() && shift_sym.index() == conflict_sym)
 	        {
+			  relevancecounter++;
 		  /* yes, report on it */
                   message += "  and     " + itm.to_simple_string()+"\n";
 		}
@@ -827,7 +831,7 @@ public class lalr_state {
 	}
       message += "  under symbol "+ terminal.find(conflict_sym).name() + "\n"+
       "  Resolved in favor of shifting.\n";
-
+      if (relevancecounter==0) return;
       /* count the conflict */
       emit.num_conflicts++;
       ErrorManager.getManager().emit_warning(message);


=====================================
src/java_cup/production.java
=====================================
@@ -395,7 +395,8 @@ public class production {
       String ret;
 
       /* Put in the left/right value labels */
-      if (emit.lr_values())
+      if (emit.lr_values()){
+	if (!emit.locations())
         ret = "\t\tint " + labelname + "left = ((java_cup.runtime.Symbol)" + 
 	  emit.pre("stack") + 
  	    // TUM 20050917
@@ -406,6 +407,17 @@ public class production {
  	    // TUM 20050917
 	    ((offset==0)?".peek()":(".elementAt(" + emit.pre("top") + "-" + offset + ")"))+
 	    ").right;\n";
+	else
+        ret = "\t\tLocation " + labelname + "xleft = ((java_cup.runtime.ComplexSymbolFactory.ComplexSymbol)" + 
+	  emit.pre("stack") + 
+ 	    // TUM 20050917
+	    ((offset==0)?".peek()":(".elementAt(" + emit.pre("top") + "-" + offset + ")"))+
+	    ").xleft;\n" +
+	  "\t\tLocation " + labelname + "xright = ((java_cup.runtime.ComplexSymbolFactory.ComplexSymbol)" + 
+	  emit.pre("stack") +
+ 	    // TUM 20050917
+	    ((offset==0)?".peek()":(".elementAt(" + emit.pre("top") + "-" + offset + ")"))+
+	    ").xright;\n";}
       else ret = "";
 
       /* otherwise, just declare label. */
@@ -441,12 +453,13 @@ public class production {
 	  if (!rhs[pos].is_action())
 	    {
 	      part = (symbol_part)rhs[pos];
-
+	      String label;
 	      /* if it has a label, make declaration! */
-	      if (part.label() != null)
+	      if ((label=part.label()) != null || emit._xmlactions)
 		{
+	    	  if (label==null) label=part.the_symbol().name()+pos;
 		  declaration = declaration + 
-		    make_declaration(part.label(), part.the_symbol().stack_type(), 
+		    make_declaration(label, part.the_symbol().stack_type(), 
 				     rhs_len-pos-1);
 		}
 	    }


=====================================
src/java_cup/runtime/ComplexSymbolFactory.java
=====================================
@@ -1,5 +1,8 @@
 package java_cup.runtime;
 
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
 /**
  * Default Implementation for SymbolFactory, creates
  * plain old Symbols
@@ -10,41 +13,143 @@ package java_cup.runtime;
 
 /* *************************************************
   class DefaultSymbolFactory
-
   interface for creating new symbols  
  ***************************************************/
 public class ComplexSymbolFactory implements SymbolFactory{
     public static class Location {
         private String unit="unknown";
-        private int line, column;
+        private int line, column, offset=-1;
+        /**
+         * Copy Constructor for other ComplexSymbolFactory based Locations
+         * @param other
+         */
+        public Location(Location other){
+        	this(other.unit,other.line,other.column,other.offset);
+        }
+	/**
+	 * Location Object
+	 * stores compilation unit, line, column and offset to the file start
+	 * @param unit      compilation unit, e.g. file name
+	 * @param line      line number
+	 * @param column    column number
+	 * @param offset    offset from file start
+	 */
+    public Location(String unit, int line, int column, int offset){
+	   this(unit,line,column);
+	   this.offset=offset;
+	}
+	/**
+	 * Location Object
+	 * stores compilation unit, line and column
+	 * @param unit      compilation unit, e.g. file name
+	 * @param line      line number
+	 * @param column    column number
+	 */
         public Location(String unit, int line, int column){
             this.unit=unit;
             this.line=line;
             this.column=column;
         }
+	/**
+	 * Location Object
+	 * stores line, column and offset to the file start
+	 * @param line      line number
+	 * @param column    column number
+	 * @param offset    offset from file start
+	 */
+        public Location(int line, int column, int offset){
+	    this(line,column);
+	    this.offset=offset;
+	}
+	/**
+	 * Location Object
+	 * stores line and column 
+	 * @param line      line number
+	 * @param column    column number
+	 */
         public Location(int line, int column){
             this.line=line;
             this.column=column;
         }
-        public String toString(){
-            return unit+":"+line+"/"+column;
-        }
+	/**
+	 * getColumn
+	 * @returns column if known, else -1
+	 */
         public int getColumn(){
             return column;
         }
+	/**
+	 * getLine
+	 * @returns line if known, else -1
+	 */
         public int getLine(){
             return line;
         }
+        /**
+         * move moves this Location by the given differences. 
+         * @param linediff
+         * @param coldiff
+         * @param offsetdiff
+         */
+        public void move(int linediff, int coldiff, int offsetdiff){
+    		if (this.line >= 0)
+    			this.line += linediff;
+    		if (this.column >= 0)
+    			this.column += coldiff;
+    		if (this.offset >= 0)
+    			this.offset += offsetdiff;
+        }
+        /**
+         * Cloning factory method
+         * @param other
+         * @return new cloned Location
+         */
+        public static Location clone(Location other){
+        	return new Location(other);
+        }
+	/**
+	 * getUnit
+	 * @returns compilation unit if known, else 'unknown'
+	 */
         public String getUnit(){
             return unit;
         }
+	/**
+	 * getLine
+	 * @returns line if known, else -1
+	 */
+        public String toString(){
+            return getUnit()+":"+getLine()+"/"+getColumn()+"("+offset+")";
+        }
+        /**
+         * Writes the location information directly into an XML document
+         * @param writer the destination XML Document
+         * @param orientation adds details about the orientation of this location as an attribute; often used with the strings "left" or "right"
+         * @throws XMLStreamException
+         */
+        public void toXML(XMLStreamWriter writer,String orientation) throws XMLStreamException {
+        	writer.writeStartElement("location");
+        	writer.writeAttribute("compilationunit", unit);
+        	writer.writeAttribute("orientation", orientation);
+        	writer.writeAttribute("linenumber", line+"");
+        	writer.writeAttribute("columnnumber", column+"");
+        	writer.writeAttribute("offset", offset+"");
+        	writer.writeEndElement();
+        }
+	/**
+	 * getOffset
+	 * @returns offset to start if known, else -1
+	 */
+        public int getOffset(){
+            return offset;
+        }
     }
     /**
      * ComplexSymbol with detailed Location Informations and a Name
      */
     public static class ComplexSymbol extends Symbol {
         protected String name;
-        protected Location xleft,xright;
+        public Location xleft,xright;
         public ComplexSymbol(String name, int id) {
             super(id);
             this.name=name;
@@ -57,6 +162,9 @@ public class ComplexSymbolFactory implements SymbolFactory{
             if (xleft==null || xright==null) return "Symbol: "+name;
             return "Symbol: "+name+" ("+xleft+" - "+xright+")";
         }
+        public String getName(){
+        	return name;
+        }
         public ComplexSymbol(String name, int id, int state) {
             super(id,state);
             this.name=name;
@@ -68,19 +176,27 @@ public class ComplexSymbolFactory implements SymbolFactory{
             if (right!=null) this.xright= ((ComplexSymbol)right).xright;
         }
         public ComplexSymbol(String name, int id, Location left, Location right) {
-            super(id);
+            super(id,left.offset,right.offset);
             this.name=name;
             this.xleft=left;
             this.xright=right;
         }
         public ComplexSymbol(String name, int id, Symbol left, Symbol right, Object value) {
-            super(id,value);
+            super(id,left.left,right.right,value);
             this.name=name;
             if (left!=null)  this.xleft = ((ComplexSymbol)left).xleft;
             if (right!=null) this.xright= ((ComplexSymbol)right).xright;
         }
+        public ComplexSymbol(String name, int id, Symbol left, Object value) {
+            super(id,left.right,left.right,value);
+            this.name=name;
+            if (left!=null) { 
+            	this.xleft = ((ComplexSymbol)left).xright;
+            	this.xright= ((ComplexSymbol)left).xright;
+            }
+        }
         public ComplexSymbol(String name, int id, Location left, Location right, Object value) {
-            super(id,value);
+            super(id,left.offset,right.offset,value);
             this.name=name;
             this.xleft=left;
             this.xright=right;
@@ -95,12 +211,25 @@ public class ComplexSymbolFactory implements SymbolFactory{
 
 
     // Factory methods
+    /**
+     * newSymbol
+     * creates a complex symbol with Location objects for left and right boundaries;
+     * this is used for terminals with values!
+     */
     public Symbol newSymbol(String name, int id, Location left, Location right, Object value){
         return new ComplexSymbol(name,id,left,right,value);
     }
+    /**
+     * newSymbol
+     * creates a complex symbol with Location objects for left and right boundaries;
+     * this is used for terminals without values!
+     */
     public Symbol newSymbol(String name, int id, Location left, Location right){
         return new ComplexSymbol(name,id,left,right);
     }
+	public Symbol newSymbol(String name, int id, Symbol left, Object value) {
+		return new ComplexSymbol(name,id,left,value);
+	}
     public Symbol newSymbol(String name, int id, Symbol left, Symbol right, Object value){
         return new ComplexSymbol(name,id,left,right,value);
     }


=====================================
src/java_cup/runtime/DefaultSymbolFactory.java
=====================================
@@ -31,6 +31,9 @@ public class DefaultSymbolFactory implements SymbolFactory{
     public Symbol newSymbol(String name ,int id, Symbol left, Symbol right, Object value){
         return new Symbol(id,left,right,value);
     }
+    public Symbol newSymbol(String name ,int id, Symbol left, Object value){
+        return new Symbol(id,left,value);
+    }
     public Symbol newSymbol(String name, int id, Symbol left, Symbol right){
         return new Symbol(id,left,right);
     }


=====================================
src/java_cup/runtime/ScannerBuffer.java
=====================================
@@ -0,0 +1,31 @@
+package java_cup.runtime;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ScannerBuffer implements Scanner {
+	private Scanner inner;
+	private List<Symbol> buffer = new LinkedList<Symbol>();
+	/**
+	 * Wraps around a custom scanner and stores all so far produced tokens in a buffer
+	 * @param inner the scanner to buffer
+	 */
+	public ScannerBuffer(Scanner inner){
+		this.inner=inner;
+	}
+	/**
+	 * Read-Only access to the buffered Symbols 
+	 * @return an unmodifiable Version of the buffer
+	 */
+	public List<Symbol> getBuffered() {
+		return Collections.unmodifiableList(buffer);
+	}
+	@Override
+	public Symbol next_token() throws Exception {
+		Symbol buffered = inner.next_token();
+		buffer.add(buffered);
+		return buffered;
+	}
+
+}


=====================================
src/java_cup/runtime/Symbol.java
=====================================
@@ -34,7 +34,10 @@ public class Symbol {
     public Symbol(int id, Symbol left, Symbol right){
         this(id,left.left,right.right);
     }
-/*******************************
+    public Symbol(int id, Symbol left, Object o){
+        this(id,left.right,left.right,o);
+    }
+ /*******************************
   Constructor for l,r values
  *******************************/
 


=====================================
src/java_cup/runtime/SymbolFactory.java
=====================================
@@ -17,17 +17,61 @@ package java_cup.runtime;
 public interface SymbolFactory {
     // Factory methods
     /**
-     * Construction with left/right propagation switched on
+     * newSymbol
+     * creates a symbol with a value, grouping other symbols with left/right locations;
+     * used frequently by the parser to implement non-terminal symbols
+     * @param name    Textual name for the Symbol for verbose error messages
+     * @param id      enum value associated with this symbol, generated by cup via sym.java
+     * @param left    symbol, to take the left location from
+     * @param right   symbol, to take the right location from
+     * @param value   value, attached to this symbol
      */
     public Symbol newSymbol(String name, int id, Symbol left, Symbol right, Object value);
+    /**
+     * newSymbol
+     * creates a symbol, grouping other symbols with left/right locations;
+     * used frequently by the parser to implement non-terminal symbols
+     * @param name    Textual name for the Symbol for verbose error messages
+     * @param id      enum value associated with this symbol, generated by cup via sym.java
+     * @param left    symbol, to take the left location from
+     * @param right   symbol, to take the right location from
+     */
     public Symbol newSymbol(String name, int id, Symbol left, Symbol right);
     /**
-     * Construction with left/right propagation switched off
+     * newSymbol
+     * creates a symbol for an empty production, taking its location from the Symbol on the left
+     * @param name    Textual name for the Symbol for verbose error messages
+     * @param id      enum value associated with this symbol, generated by cup via sym.java
+     * @param left    symbol, to take the left location from
+     * @param value   value, attached to this symbol 
+     */
+    public Symbol newSymbol(String name, int id, Symbol left, Object value);
+    /**
+     * newSymbol
+     * creates a basic symbol with an attached value;
+     * used frequently for terminal symbols like identifiers
+     * @param name    Textual name for the Symbol for verbose error messages
+     * @param id      enum value associated with this symbol, generated by cup via sym.java
+     * @param value   value, attached to this symbol
      */
     public Symbol newSymbol(String name, int id, Object value);
+    /**
+     * newSymbol
+     * creates a basic symbol;
+     * used frequently for terminal symbols, like keywords
+     * @param name    Textual name for the Symbol for verbose error messages
+     * @param id      enum value associated with this symbol, generated by cup via sym.java
+     * @param value   value, attached to this symbol
+     */
     public Symbol newSymbol(String name, int id);
     /**
-     * Construction of start symbol
+     * newSymbol
+     * creates the start symbol
+     * @param name    Textual name for the Symbol for verbose error messages
+     * @param id      enum value associated with this symbol, generated by cup via sym.java
+     * @param left    symbol, to take the left location from
+     * @param right   symbol, to take the right location from
+     * @param value   value, attached to this symbol
      */
     public Symbol startSymbol(String name, int id, int state);
 }


=====================================
src/java_cup/runtime/SyntaxTreeDFS.java
=====================================
@@ -0,0 +1,49 @@
+package java_cup.runtime;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class SyntaxTreeDFS {
+	public static interface ElementHandler {
+		public void handle(XMLElement parent, List<XMLElement> children);
+	}
+	public static abstract class AbstractVisitor implements Visitor {
+		private HashMap<String, ElementHandler> preMap = new HashMap<>();
+		private HashMap<String, ElementHandler> postMap = new HashMap<>();
+		public abstract void defaultPre(XMLElement element, List<XMLElement> children);
+		public abstract void defaultPost(XMLElement element,List<XMLElement> children);
+		@Override
+		public void preVisit(XMLElement element) {
+			ElementHandler handler = preMap.get(element.tagname);
+			if (handler==null) {
+				defaultPre(element,element.getChildren());
+			} else
+				handler.handle(element, element.getChildren());
+		}
+		@Override
+		public void postVisit(XMLElement element) {
+			ElementHandler handler = postMap.get(element.tagname);
+			if (handler==null) {
+				defaultPost(element,element.getChildren());
+			} else
+				handler.handle(element, element.getChildren());			
+		}
+		public void registerPreVisit(String s,ElementHandler h){
+			preMap.put(s, h);
+		}
+		public void registerPostVisit(String s, ElementHandler h){
+			postMap.put(s, h);
+		}
+	}
+	public static interface Visitor {
+		public void preVisit(XMLElement element);
+		public void postVisit(XMLElement element);
+	}
+	public static void dfs(XMLElement element, Visitor visitor){
+		visitor.preVisit(element);
+		for (XMLElement el :element.getChildren()){
+			dfs(el,visitor);
+		}
+		visitor.postVisit(element);
+	}
+}


=====================================
src/java_cup/runtime/SyntaxTreeTransform.java
=====================================
@@ -0,0 +1,37 @@
+package java_cup.runtime;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+public class SyntaxTreeTransform {
+
+	private static class ChainRemover extends SyntaxTreeDFS.AbstractVisitor{
+		public XMLElement root(){
+			return stack.pop();
+		}
+		private Stack<XMLElement> stack = new Stack<XMLElement>();
+		@Override
+		public void defaultPost(XMLElement arg0, List<XMLElement> arg1) {
+			int n = arg1.size();
+			if (n>1){
+				LinkedList<XMLElement> elems = new LinkedList<>();
+				while (n-->0) elems.addFirst(stack.pop());
+				XMLElement ne = new XMLElement.NonTerminal(arg0.getTagname(),0,elems.toArray(new XMLElement[0]));
+				stack.push(ne);
+				return;
+			}
+			//if (n==1){}
+			if (n==0) stack.push(arg0);
+		}
+
+		@Override
+		public void defaultPre(XMLElement arg0, List<XMLElement> arg1) {}
+		
+	}
+	public static XMLElement removeUnaryChains(XMLElement elem) {
+		ChainRemover cr = new ChainRemover();
+		SyntaxTreeDFS.dfs(elem, cr);
+		return cr.root();
+	}
+
+}


=====================================
src/java_cup/runtime/SyntaxTreeXPath.java
=====================================
@@ -0,0 +1,86 @@
+package java_cup.runtime;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SyntaxTreeXPath {
+	public static List<XMLElement> query(String query, XMLElement element){
+		if (query.startsWith("/")) query=query.substring(1);
+		return query0(new LinkedList<String>(Arrays.asList( query.split("/"))),0,element,0);
+	}
+	private static List<XMLElement> query0(List<String> q,int idx, XMLElement element,int seq){
+		
+		if (q.get(idx).isEmpty()) { // match deeper descendant q[1]
+			return matchDeeperDescendant(q,idx+1 ,element,seq);
+		}
+		List<XMLElement> l = new LinkedList<XMLElement>();
+		
+		
+		if (!match(q.get(idx),element,seq)) return new LinkedList();
+		if (q.size()-1==idx) return singleton(element);
+		List<XMLElement> children = element.getChildren();
+		for (int i=0; i< children.size();i++){
+			XMLElement child= children.get(i); 
+			l.addAll(query0(q,idx+1,child,i));
+		}
+		return l;
+	}
+	private static List<XMLElement> matchDeeperDescendant(List<String> query,int idx, XMLElement element, int seq){
+		if (query.size()<=idx) return singleton(element);
+		boolean matches = match(query.get(idx),element,seq); 
+		List<XMLElement> l = new LinkedList<XMLElement>();
+		List<XMLElement> children = element.getChildren();
+		if (matches) return query0(query,idx,element,seq);
+		for (int i=0; i< children.size();i++){
+			XMLElement child= children.get(i);
+			l.addAll(matchDeeperDescendant(query, idx, child,i));
+		}
+		return l;
+	}
+	private static boolean match(String m,XMLElement elem,int seq){
+//		System.out.println("Matching "+elem.tagname+" with "+m);
+		boolean result = true;
+		String[] name = m.split("\\[");
+		String[] tag = name[0].split("\\*");
+		if (tag[0].isEmpty()) { // start is wildcard
+			if (tag.length>2)
+				result &= elem.tagname.contains(tag[1]);
+			else	
+				if (tag.length==2)
+					result &= elem.tagname.endsWith(tag[1]);
+				else
+					result &= false;
+		} else { // match with start
+			if (tag.length==2)
+				result &=elem.tagname.startsWith(tag[1]);
+			else
+				result = elem.tagname.equals(tag[0]);
+		}
+		for (int i=1; i<name.length; i++) {
+			String predicate= name[i];
+			if (!predicate.endsWith("]")) return false;
+			predicate=predicate.substring(0, predicate.length()-1);
+			
+			if (predicate.startsWith("@")){
+				if (predicate.substring(1).startsWith("variant"))
+					if ((elem instanceof XMLElement.NonTerminal)&& Integer.parseInt(predicate.substring(9))==((XMLElement.NonTerminal)elem).getVariant())
+							result&=true;
+					else
+						return false;
+				else return false;
+			} else 
+			if (predicate.matches("\\d+")){
+				result &= Integer.parseInt(predicate)==seq;
+			}
+			else 
+				return false; // submatch
+		}
+		return result;
+	}
+	private static List<XMLElement> singleton(XMLElement elem){
+		LinkedList<XMLElement> l = new LinkedList<XMLElement>();
+		l.add(elem);
+		return l;
+	}
+} 


=====================================
src/java_cup/runtime/XMLElement.java
=====================================
@@ -0,0 +1,215 @@
+package java_cup.runtime;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+public abstract class XMLElement {
+	public abstract List<XMLElement> selectById(String s);
+	public static void dump(XMLStreamWriter writer, XMLElement elem, String ... blacklist) throws XMLStreamException {
+		dump(null,writer,elem,blacklist);
+	}
+	public static void dump(ScannerBuffer buffer, XMLStreamWriter writer, XMLElement elem, String ... blacklist) throws XMLStreamException {
+		writer.writeStartDocument("utf-8", "1.0");
+		writer.writeProcessingInstruction("xml-stylesheet","href=\"tree.xsl\" type=\"text/xsl\"");
+		writer.writeStartElement("document");
+		
+		if (blacklist.length>0) {
+			writer.writeStartElement("blacklist");
+			for (String s: blacklist){
+				writer.writeStartElement("symbol");
+				writer.writeCharacters(s);
+				writer.writeEndElement();
+			}
+			writer.writeEndElement();
+		}
+		
+		writer.writeStartElement("parsetree");
+		elem.dump(writer);
+		writer.writeEndElement();
+
+		if (buffer!=null){
+			writer.writeStartElement("tokensequence");
+			for (Symbol s:buffer.getBuffered()){
+				if (s instanceof ComplexSymbol){
+					ComplexSymbol cs = (ComplexSymbol)s;
+					if (cs.value!=null){
+						writer.writeStartElement("token");
+						writer.writeAttribute("name",cs.getName());
+						cs.getLeft().toXML(writer, "left");
+						writer.writeCharacters(cs.value+"");
+						cs.getRight().toXML(writer, "right");
+						writer.writeEndElement();
+					} else
+					{
+						writer.writeStartElement("keyword");
+						writer.writeAttribute("left",cs.getLeft()+"");
+						writer.writeAttribute("right",cs.getRight()+"");
+						writer.writeCharacters(cs.getName()+"");
+						writer.writeEndElement();
+					}
+				}
+				else 
+					if (s instanceof Symbol) {
+						writer.writeStartElement("token");
+						writer.writeCharacters(s.toString());
+						writer.writeEndElement();						
+					}
+			}
+			writer.writeEndElement();
+		}
+		writer.writeEndElement();
+		writer.writeEndDocument();
+		writer.flush();
+		writer.close();
+	}
+	protected String tagname;
+        public String getTagname() { return tagname; }
+	public abstract Location right();
+	public abstract Location left();
+	protected abstract void dump(XMLStreamWriter writer) throws XMLStreamException;
+        public List<XMLElement> getChildren() {return new LinkedList<XMLElement>(); };
+        public boolean hasChildren() { return false; };
+	public static class NonTerminal extends XMLElement {
+	    public boolean hasChildren()  { return !list.isEmpty(); }
+	    public List<XMLElement> getChildren()  { return list; }
+	    @Override
+		public List<XMLElement> selectById(String s) {
+			LinkedList<XMLElement> response= new LinkedList<XMLElement>();
+			if (tagname.equals(s))
+				response.add(this);
+			for (XMLElement e : list){
+				List<XMLElement> selection =e.selectById(s);
+				response.addAll(selection);
+			}
+			return response;
+		}
+		private int variant;
+	    public int getVariant() {
+		return variant;
+	    }
+		LinkedList<XMLElement> list;
+		public NonTerminal(String tagname, int variant, XMLElement... l) {
+			this.tagname=tagname;
+			this.variant=variant;
+			list = new LinkedList<XMLElement>(Arrays.asList(l));
+		}
+
+		public Location left() {
+			for (XMLElement e : list){
+				Location loc = e.left();
+				if (loc!=null) return loc;
+			}
+			return null;	
+		}
+		public Location right() {
+			for (Iterator<XMLElement> it = list.descendingIterator();it.hasNext();){
+				 Location loc = it.next().right();
+				 if (loc!=null) return loc;
+			}
+			return null;
+		}
+
+		public String toString() {
+			if (list.isEmpty()){
+				return "<nonterminal id=\"" + tagname +"\" variant=\""+variant+"\" />" ;
+			}
+			String ret = "<nonterminal id=\"" + tagname +"\" left=\"" + left()
+					+ "\" right=\"" + right() + "\" variant=\""+variant+"\">";
+			for (XMLElement e : list)
+				ret += e.toString();
+			return ret + "</nonterminal>";
+		}
+		@Override
+		protected void dump(XMLStreamWriter writer) throws XMLStreamException {
+			writer.writeStartElement("nonterminal");
+			writer.writeAttribute("id", tagname);
+			writer.writeAttribute("variant", variant+"");
+//			if (!list.isEmpty()){
+				Location loc = left();
+				if (loc!=null) loc.toXML(writer, "left");
+//			}
+			for (XMLElement e:list)
+				e.dump(writer);
+			loc = right();
+			if (loc!=null) loc.toXML(writer, "right");
+			writer.writeEndElement();
+		}
+	}
+
+	public static class Error extends XMLElement {
+	    public boolean hasChildren()  { return false; }
+	    @Override
+		public List<XMLElement> selectById(String s) {
+			return new LinkedList<XMLElement>();
+		}
+		Location l,r;
+		public Error(Location l, Location r) {
+			this.l=l;
+			this.r=r;
+		}
+		public Location left() {	return l; 	}
+		public Location right() {	return r;	}
+
+		public String toString() {
+			return  "<error left=\"" + l + "\" right=\"" + r + "\"/>";
+		}
+		@Override
+		protected void dump(XMLStreamWriter writer) throws XMLStreamException {
+			writer.writeStartElement("error");
+			writer.writeAttribute("left", left()+"");
+			writer.writeAttribute("right", right()+"");
+			writer.writeEndElement();
+		}
+	}
+	
+	public static class Terminal extends XMLElement {
+	    public boolean hasChildren()  { return false; }
+	    public List<XMLElement> selectById(String s) {
+			List<XMLElement> ret = new LinkedList<XMLElement>();
+			if (tagname.equals(s)) { ret.add(this);	}
+			return ret;
+		};
+		Location l, r;
+		Object value;
+
+		public Terminal(Location l, String symbolname, Location r) {
+			this(l, symbolname, null, r);
+		}
+
+		public Terminal(Location l, String symbolname, Object i, Location r) {
+			this.l = l;
+			this.r = r;
+			this.value = i;
+			this.tagname = symbolname;
+		}
+
+		public Object   value() {return value; }
+		public Location left() {	return l; 	}
+		public Location right() {	return r;	}
+
+		public String toString() {
+			return (value == null) ? "<terminal id=\"" + tagname + "\"/>"
+					: "<terminal id=\"" + tagname + "\" left=\"" + l
+							+ "\" right=\"" + r + "\">" + value
+							+ "</terminal>";
+		}
+		@Override
+		protected void dump(XMLStreamWriter writer) throws XMLStreamException {
+			writer.writeStartElement("terminal");
+			writer.writeAttribute("id", tagname);
+			writer.writeAttribute("left", left()+"");
+			writer.writeAttribute("right", right()+"");
+			if (value!=null) writer.writeCharacters(value+"");
+			writer.writeEndElement();
+		}
+	}
+}


=====================================
src/java_cup/runtime/lr_parser.java
=====================================
@@ -1,8 +1,15 @@
 				    
 package java_cup.runtime;
 
+import java.lang.reflect.Field;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Stack;
 
+import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
+
+
+
 /** 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 
@@ -118,14 +125,24 @@ public abstract class lr_parser {
     /*-----------------------------------------------------------*/
 
     /** 
-     * Simple constructor. 
+     * Simple constructor.  
+     * deprecated; The use of a SymbolFactory, e.g. Complexsymbolfactory is advised  
      */
+	@Deprecated
     public lr_parser() {
+        this(new DefaultSymbolFactory());
+    }
+    /** 
+     * Simple constructor.  
+     */
+    public lr_parser(SymbolFactory fac) {
+        symbolFactory = fac;
     }
-    
     /** 
-     * Constructor that sets the default scanner. [CSA/davidm] 
+     * Constructor that sets the default scanner. [CSA/davidm]
+     * deprecated; The use of a SymbolFactory, e.g. Complexsymbolfactory is advised 
      */
+    @Deprecated
     public lr_parser(Scanner s) {
         this(s,new DefaultSymbolFactory()); // TUM 20060327 old cup v10 Symbols as default
     }
@@ -137,7 +154,7 @@ public abstract class lr_parser {
         symbolFactory = symfac;
         setScanner(s);
     }
-    public SymbolFactory symbolFactory;// = new DefaultSymbolFactory();
+    public SymbolFactory symbolFactory;
     /**
      * Whenever creation of a new Symbol is necessary, one should use this factory.
      */
@@ -388,13 +405,17 @@ public abstract class lr_parser {
    */
   public void report_error(String message, Object info)
     {
-      System.err.print(message);
+      if (info instanceof ComplexSymbol){
+    	  ComplexSymbol cs = (ComplexSymbol)info;
+    	  System.err.println(message+" for input symbol \""+cs.getName()+"\" spanning from "+cs.getLeft() +" to "+cs.getRight());
+    	  return;
+      }
+
+	  System.err.print(message);
       System.err.flush();
       if (info instanceof Symbol)
-	if (((Symbol)info).left != -1)
-	System.err.println(" at character " + ((Symbol)info).left + 
-			   " of input");
-	else System.err.println("");
+    	  if (((Symbol)info).left != -1)
+    		  System.err.println(" at character " + ((Symbol)info).left + " of input");
       else System.err.println("");
     }
 
@@ -409,7 +430,101 @@ public abstract class lr_parser {
   public void syntax_error(Symbol cur_token)
     {
       report_error("Syntax error", cur_token);
+      report_expected_token_ids();
     }
+  /**
+   * We need this Method in order to resolve names for symbol IDs
+   * @return the class that keeps all the symbols
+   */
+  public Class getSymbolContainer() {
+	  return null;
+  };
+  protected void report_expected_token_ids(){
+	  List<Integer> ids = expected_token_ids();
+	  LinkedList<String> list = new LinkedList<String>();
+	  for (Integer expected : ids){
+		  list.add(symbl_name_from_id(expected));
+	  }
+	  System.out.println("instead expected token classes are "+list);
+  }
+  /**
+   * Translates numerical symbol ids to the (non)terminal names from the spec
+   * @param internal id for (non)terminal
+   * @return (non)terminal name as string
+   */
+  public String symbl_name_from_id(int id){
+	  Field[] fields = getSymbolContainer().getFields();
+	  for(Field f : fields){
+		  try {
+			if (f.getInt(null)==id)
+			  return f.getName();
+		} catch (IllegalArgumentException e) {
+			//e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			//e.printStackTrace();
+		}
+	  }
+	  return "invalid symbol id";
+  }
+  /**
+   * Return the expected symbol during this state of state of the parser
+   * @return list of integer (non)temrinal ids
+   */
+  public List<Integer> expected_token_ids(){
+	  List<Integer> ret = new LinkedList<Integer>();
+	  int parse_state = ((Symbol)stack.peek()).parse_state ;
+	  short[] row = action_tab[parse_state];
+	  for (int i = 0; i<row.length; i+=2){
+		  if (row[i]==-1) continue;
+		  if (!validate_expected_symbol(row[i])) continue;
+		  ret.add(new Integer(row[i]));
+	  }
+	  return ret;
+  }
+  private boolean validate_expected_symbol(int id){
+	  short lhs,rhs_size;
+	  int act;
+	  try {
+		  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(), id);
+
+			  /* 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);
+
+				  /* 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())  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();
+
+				  vstack.push(get_reduce(vstack.top(), lhs));
+			  }
+		  }
+
+	  } catch (Exception e) {
+		  e.printStackTrace();
+	  }
+	  return true;
+  }
 
   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
 


=====================================
src/java_cup/terminal_set.java
=====================================
@@ -187,15 +187,7 @@ public class terminal_set {
      throws internal_error
      {
        not_null(other);
-
-       /* make a copy of the other set */
-       BitSet copy = (BitSet)other._elements.clone();
-
-       /* xor out our values */
-       copy.xor(this._elements);
-
-       /* see if its different */
-       return !copy.equals(other._elements);
+       return _elements.intersects(other._elements);
      }
 
   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/


=====================================
src/java_cup/version.java
=====================================
@@ -30,7 +30,7 @@ public class version {
   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
 
   /** The update letter. */
-  public static final String update = "a beta 20060608";
+  public static final String update = "b beta 20140226";
 
   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
 
@@ -46,7 +46,7 @@ public class version {
 
   /** Name of the author */
   public static final String author_str =
-      "Scott E. Hudson, Frank Flannery, Andrea Flexeder, Michael Petter and C. Scott Ananian";
+      "Scott E. Hudson, Frank Flannery, Michael Petter and C. Scott Ananian";
 
   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
 


=====================================
version.txt
=====================================
@@ -0,0 +1 @@
+20160615
\ No newline at end of file



View it on GitLab: https://salsa.debian.org/java-team/cup/commit/7f3969efc2c348bd84d87fa719f8c624b168a352

-- 
View it on GitLab: https://salsa.debian.org/java-team/cup/commit/7f3969efc2c348bd84d87fa719f8c624b168a352
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20180930/f37fadac/attachment.html>


More information about the pkg-java-commits mailing list