[Pkg-mozext-commits] [noscript] 04/05: Rebuild antlr.js from source

David Prévot taffit at moszumanska.debian.org
Sun Mar 30 21:05:53 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository noscript.

commit 821252c4f42eac0ffbd1fc1592b624e1145b3a5e
Author: David Prévot <taffit at debian.org>
Date:   Sun Mar 30 16:07:00 2014 -0400

    Rebuild antlr.js from source
---
 debian/antlr3-all.js            | 6130 +++++++++++++++++++++++++++++++++++++++
 debian/clean                    |    1 +
 debian/control                  |    2 +-
 debian/copyright                |   17 +-
 debian/rules                    |    8 +-
 debian/source/lintian-overrides |    4 +
 6 files changed, 6152 insertions(+), 10 deletions(-)

diff --git a/debian/antlr3-all.js b/debian/antlr3-all.js
new file mode 100644
index 0000000..af384d3
--- /dev/null
+++ b/debian/antlr3-all.js
@@ -0,0 +1,6130 @@
+/*
+Copyright (c) 2003-2008 Terence Parr. All rights reserved.
+Code licensed under the BSD License:
+http://www.antlr.org/license.html
+
+Some parts of the ANTLR class:
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+*/
+/*
+Some portions:
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+
+// create org.antlr module
+if (typeof org == "undefined" || !org) {
+    var org = {};
+}
+if (typeof org.antlr == "undefined" || !org.antlr) {
+    /**
+     * The org.antlr global namespace object.  If antlr is already defined, the
+     * existing antlr object will not be overwritten so that defined
+     * namespaces are preserved.
+     * @namespace org.antlr
+     */
+    org.antlr = {};
+}
+
+/**
+ * The global JavaScript object.
+ */
+org.antlr.global = (function() {
+    return this;
+}).call(null);
+
+/**
+ * Returns the namespace specified and creates it if it doesn't exist.
+ *
+ * Be careful when naming packages. Reserved words may work in some browsers
+ * and not others. For instance, the following will fail in Safari:
+ * <pre>
+ * org.antlr.namespace("really.long.nested.namespace");
+ * </pre>
+ * This fails because "long" is a future reserved word in ECMAScript
+ *
+ * @static
+ * @param  {String*} arguments 1-n namespaces to create 
+ * @return {Object}  A reference to the last namespace object created
+ * @example
+ * org.antlr.namespace("org.antlr.property.package");
+ */
+org.antlr.namespace = function() {
+    var a=arguments, o=null, i, j, d;
+    for (i=0; i<a.length; i=i+1) {
+        d=a[i].split(".");
+        o=org.antlr.global;
+
+        // ANTLR is implied, so it is ignored if it is included
+        for (j=0; j<d.length; j=j+1) {
+            o[d[j]]=o[d[j]] || {};
+            o=o[d[j]];
+        }
+    }
+
+    return o;
+};
+
+/**
+ * org.antlr.env is used to keep track of what is known about the library and
+ * the browsing environment
+ * @namespace org.antlr.env
+ */
+org.antlr.env = org.antlr.env || {};
+
+/**
+ * Do not fork for a browser if it can be avoided.  Use feature detection when
+ * you can.  Use the user agent as a last resort.  org.antlr.env.ua stores a
+ * version number for the browser engine, 0 otherwise.  This value may or may
+ * not map to the version number of the browser using the engine.  The value is 
+ * presented as a float so that it can easily be used for boolean evaluation 
+ * as well as for looking for a particular range of versions.  Because of this, 
+ * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 
+ * reports 1.8).
+ * @namespace org.antlr.env.ua
+ */
+org.antlr.env.ua = function() {
+    var o= /** @lends org.antlr.env.ua */ {
+
+        /**
+         * Internet Explorer version number or 0.  Example: 6
+         * @property ie
+         * @type float
+         */
+        ie:0,
+
+        /**
+         * Opera version number or 0.  Example: 9.2
+         * @property opera
+         * @type float
+         */
+        opera:0,
+
+        /**
+         * Gecko engine revision number.  Will evaluate to 1 if Gecko 
+         * is detected but the revision could not be found. Other browsers
+         * will be 0.  Example: 1.8
+         * <pre>
+         * Firefox 1.0.0.4: 1.7.8   <-- Reports 1.7
+         * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8
+         * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8
+         * Firefox 3 alpha: 1.9a4   <-- Reports 1.9
+         * </pre>
+         * @property gecko
+         * @type float
+         */
+        gecko:0,
+
+        /**
+         * AppleWebKit version.  KHTML browsers that are not WebKit browsers 
+         * will evaluate to 1, other browsers 0.  Example: 418.9.1
+         * <pre>
+         * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the 
+         *                                   latest available for Mac OSX 10.3.
+         * Safari 2.0.2:         416     <-- hasOwnProperty introduced
+         * Safari 2.0.4:         418     <-- preventDefault fixed
+         * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
+         *                                   different versions of webkit
+         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
+         *                                   updated, but not updated
+         *                                   to the latest patch.
+         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
+         *                                   and many major issues fixed).  
+         * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
+         *                                   string when hitting yahoo.com and 
+         *                                   flickr.com.
+         * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
+         *                                   from 2.x via the 10.4.11 OS patch
+         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
+         *                                   yahoo.com user agent hack removed.
+         *                                   
+         * </pre>
+         * http://developer.apple.com/internet/safari/uamatrix.html
+         * @property webkit
+         * @type float
+         */
+        webkit: 0,
+
+        /**
+         * The mobile property will be set to a string containing any relevant
+         * user agent information when a modern mobile browser is detected.
+         * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series
+         * devices with the WebKit-based browser, and Opera Mini.  
+         * @property mobile 
+         * @type string
+         */
+        mobile: null,
+
+        /**
+         * Adobe AIR version number or 0.  Only populated if webkit is detected.
+         * Example: 1.0
+         * @property air
+         * @type float
+         */
+        air: 0,
+
+        /**
+         * Is this the Rhino interpreter?
+         * @property rhino
+         * @type Boolean
+         */
+        rhino: false
+
+    };
+
+    var ua, m;
+
+    try {
+        ua = navigator.userAgent;
+
+        // Modern KHTML browsers should qualify as Safari X-Grade
+        if ((/KHTML/).test(ua)) {
+            o.webkit=1;
+        }
+        // Modern WebKit browsers are at least X-Grade
+        m=ua.match(/AppleWebKit\/([^\s]*)/);
+        if (m&&m[1]) {
+            o.webkit=parseFloat(m[1]);
+
+            // Mobile browser check
+            if (/ Mobile\//.test(ua)) {
+                o.mobile = "Apple"; // iPhone or iPod Touch
+        } else {
+            m=ua.match(/NokiaN[^\/]*/);
+            if (m) {
+                o.mobile = m[0]; // Nokia N-series, ex: NokiaN95
+            }
+        }
+
+        m=ua.match(/AdobeAIR\/([^\s]*)/);
+        if (m) {
+            o.air = m[0]; // Adobe AIR 1.0 or better
+        }
+
+        }
+
+        if (!o.webkit) { // not webkit
+            // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; ssr)
+            m=ua.match(/Opera[\s\/]([^\s]*)/);
+            if (m&&m[1]) {
+                o.opera=parseFloat(m[1]);
+                m=ua.match(/Opera Mini[^;]*/);
+            if (m) {
+                o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316
+            }
+            } else { // not opera or webkit
+                m=ua.match(/MSIE\s([^;]*)/);
+                if (m&&m[1]) {
+                    o.ie=parseFloat(m[1]);
+                } else { // not opera, webkit, or ie
+                    m=ua.match(/Gecko\/([^\s]*)/);
+                    if (m) {
+                        o.gecko=1; // Gecko detected, look for revision
+                        m=ua.match(/rv:([^\s\)]*)/);
+                        if (m&&m[1]) {
+                            o.gecko=parseFloat(m[1]);
+                        }
+                    }
+                }
+            }
+        }
+    } catch(e) {
+        // ignore this if we're not in a browser
+    }
+
+    try {
+        if (typeof window=="undefined" && loadClass) {
+            o.rhino = true;
+        }
+    } catch(e) {}
+
+    
+    return o;
+}();
+
+/**
+ * JavaScript runtime library code.
+ * @name org.antlr.runtime
+ * @namespace
+ */
+/**
+ * JavaScript runtime library tree parser code.
+ * @name org.antlr.runtime.tree
+ * @namespace
+ */
+org.antlr.namespace("org.antlr.runtime.tree");
+
+/**
+ * Provides the language utilites and extensions used by the library
+ * @namespace org.antlr.lang
+ */
+org.antlr.lang = org.antlr.lang || /** @lends org.antlr.lang */ {
+    /**
+     * Determines whether or not the provided object is an array.
+     * Testing typeof/instanceof/constructor of arrays across frame 
+     * boundaries isn't possible in Safari unless you have a reference
+     * to the other frame to test against its Array prototype.  To
+     * handle this case, we test well-known array properties instead.
+     * properties.
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */
+    isArray: function(o) { 
+        if (o) {
+           var l = org.antlr.lang;
+           return l.isNumber(o.length) && l.isFunction(o.splice);
+        }
+        return false;
+    },
+
+    /**
+     * Determines whether or not the provided object is a boolean
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */
+    isBoolean: function(o) {
+        return typeof o === 'boolean';
+    },
+    
+    /**
+     * Determines whether or not the provided object is a function
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */
+    isFunction: function(o) {
+        return typeof o === 'function';
+    },
+        
+    /**
+     * Determines whether or not the provided object is null
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */
+    isNull: function(o) {
+        return o === null;
+    },
+        
+    /**
+     * Determines whether or not the provided object is a legal number
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */
+    isNumber: function(o) {
+        return typeof o === 'number' && isFinite(o);
+    },
+      
+    /**
+     * Determines whether or not the provided object is of type object
+     * or function
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */  
+    isObject: function(o) {
+return (o && (typeof o === 'object' || org.antlr.lang.isFunction(o))) || false;
+    },
+        
+    /**
+     * Determines whether or not the provided object is a string
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */
+    isString: function(o) {
+        return typeof o === 'string';
+    },
+        
+    /**
+     * Determines whether or not the provided object is undefined
+     * @param {any} o The object being testing
+     * @return {boolean} the result
+     */
+    isUndefined: function(o) {
+        return typeof o === 'undefined';
+    },
+    
+    /**
+     * IE will not enumerate native functions in a derived object even if the
+     * function was overridden.  This is a workaround for specific functions 
+     * we care about on the Object prototype. 
+     * @param {Function} r  the object to receive the augmentation
+     * @param {Function} s  the object that supplies the properties to augment
+     * @private
+     */
+    _IEEnumFix: function(r, s) {
+        if (org.antlr.env.ua.ie) {
+            var add=["toString", "valueOf"], i;
+            for (i=0;i<add.length;i=i+1) {
+                var fname=add[i],f=s[fname];
+                if (org.antlr.lang.isFunction(f) && f!=Object.prototype[fname]) {
+                    r[fname]=f;
+                }
+            }
+        }
+    },
+       
+    /**
+     * Utility to set up the prototype, constructor and superclass properties to
+     * support an inheritance strategy that can chain constructors and methods.
+     * Static members will not be inherited.
+     *
+     * @method extend
+     * @static
+     * @param {Function} subc   the object to modify
+     * @param {Function} superc the object to inherit
+     * @param {Object} [overrides]  additional properties/methods to add to the
+     *                              subclass prototype.  These will override the
+     *                              matching items obtained from the superclass 
+     *                              if present.
+     */
+    extend: function(subc, superc, overrides) {
+        if (!superc||!subc) {
+            throw new Error("org.antlr.lang.extend failed, please check that " +
+                            "all dependencies are included.");
+        }
+        var F = function() {};
+        F.prototype=superc.prototype;
+        subc.prototype=new F();
+        subc.prototype.constructor=subc;
+        subc.superclass=superc.prototype;
+        if (superc.prototype.constructor == Object.prototype.constructor) {
+            superc.prototype.constructor=superc;
+        }
+    
+        if (overrides) {
+            for (var i in overrides) {
+                subc.prototype[i]=overrides[i];
+            }
+
+            org.antlr.lang._IEEnumFix(subc.prototype, overrides);
+        }
+    },
+   
+    /**
+     * Applies all properties in the supplier to the receiver if the
+     * receiver does not have these properties yet.  Optionally, one or 
+     * more methods/properties can be specified (as additional 
+     * parameters).  This option will overwrite the property if receiver 
+     * has it already.  If true is passed as the third parameter, all 
+     * properties will be applied and _will_ overwrite properties in 
+     * the receiver.
+     *
+     * @param {Function} r  the object to receive the augmentation
+     * @param {Function} s  the object that supplies the properties to augment
+     * @param {String*|boolean}  [arguments] zero or more properties methods 
+     *        to augment the receiver with.  If none specified, everything
+     *        in the supplier will be used unless it would
+     *        overwrite an existing property in the receiver. If true
+     *        is specified as the third parameter, all properties will
+     *        be applied and will overwrite an existing property in
+     *        the receiver
+     */
+    augmentObject: function(r, s) {
+        if (!s||!r) {
+            throw new Error("Absorb failed, verify dependencies.");
+        }
+        var a=arguments, i, p, override=a[2];
+        if (override && override!==true) { // only absorb the specified properties
+            for (i=2; i<a.length; i=i+1) {
+                r[a[i]] = s[a[i]];
+            }
+        } else { // take everything, overwriting only if the third parameter is true
+            for (p in s) { 
+                if (override || !r[p]) {
+                    r[p] = s[p];
+                }
+            }
+            
+            org.antlr.lang._IEEnumFix(r, s);
+        }
+    },
+ 
+    /**
+     * Same as org.antlr.lang.augmentObject, except it only applies prototype properties
+     * @see org.antlr.lang.augmentObject
+     * @param {Function} r  the object to receive the augmentation
+     * @param {Function} s  the object that supplies the properties to augment
+     * @param {String*|boolean}  [arguments] zero or more properties methods 
+     *        to augment the receiver with.  If none specified, everything 
+     *        in the supplier will be used unless it would overwrite an existing 
+     *        property in the receiver.  if true is specified as the third 
+     *        parameter, all properties will be applied and will overwrite an 
+     *        existing property in the receiver
+     */
+    augmentProto: function(r, s) {
+        if (!s||!r) {
+            throw new Error("Augment failed, verify dependencies.");
+        }
+        //var a=[].concat(arguments);
+        var a=[r.prototype,s.prototype];
+        for (var i=2;i<arguments.length;i=i+1) {
+            a.push(arguments[i]);
+        }
+        org.antlr.lang.augmentObject.apply(this, a);
+    },
+
+    /**
+     * Returns a new object containing all of the properties of
+     * all the supplied objects.  The properties from later objects
+     * will overwrite those in earlier objects.
+     * @param arguments {Object*} the objects to merge
+     * @return the new merged object
+     */
+    merge: function() {
+        var o={}, a=arguments;
+        for (var i=0, l=a.length; i<l; i=i+1) {
+            org.antlr.lang.augmentObject(o, a[i], true);
+        }
+        return o;
+    },
+
+    /**
+     * A convenience method for detecting a legitimate non-null value.
+     * Returns false for null/undefined/NaN, true for other values, 
+     * including 0/false/''
+     * @param o {any} the item to test
+     * @return {boolean} true if it is not null/undefined/NaN || false
+     */
+    isValue: function(o) {
+        var l = org.antlr.lang;
+return (l.isObject(o) || l.isString(o) || l.isNumber(o) || l.isBoolean(o));
+    },
+
+    /** @namespace org.antlr.lang.array Array convenience methods. */
+    array: /** @lends org.antlr.lang.array */ {
+        /**
+         * Retrieve the last element of an array. Throws an error if a is not
+         * an array or empty.
+         * @param a {Array} the array stack to peek in
+         * @return the last element of the array
+         */
+         peek: function(a) {
+            if (!org.antlr.lang.isArray(a)) {
+                throw new Error("org.antlr.lang.array.peek: a is not an array.");
+            }
+            var l = a.length;
+            if (l<=0) {
+                throw new Error("org.antlr.lang.array.peek: a is empty.");
+            }
+            return a[l-1];
+        }
+    }
+};
+/** The set of fields needed by an abstract recognizer to recognize input
+ *  and recover from errors etc...  As a separate state object, it can be
+ *  shared among multiple grammars; e.g., when one grammar imports another.
+ *
+ *  These fields are publically visible but the actual state pointer per
+ *  parser is protected.
+ */
+org.antlr.runtime.RecognizerSharedState = function() {
+    /** Track the set of token types that can follow any rule invocation.
+     *  Stack grows upwards.  When it hits the max, it grows 2x in size
+     *  and keeps going.
+     */
+    this.following = [];
+
+    this._fsp = -1;
+
+    /** This is true when we see an error and before having successfully
+     *  matched a token.  Prevents generation of more than one error message
+     *  per error.
+     */
+    this.errorRecovery = false;
+
+    /** The index into the input stream where the last error occurred.
+     *  This is used to prevent infinite loops where an error is found
+     *  but no token is consumed during recovery...another error is found,
+     *  ad naseum.  This is a failsafe mechanism to guarantee that at least
+     *  one token/tree node is consumed for two errors.
+     */
+    this.lastErrorIndex = -1;
+
+    /** In lieu of a return value, this indicates that a rule or token
+     *  has failed to match.  Reset to false upon valid token match.
+     */
+    this.failed = false;
+
+    /** Did the recognizer encounter a syntax error?  Track how many. */
+    this.syntaxErrors = 0;
+
+    /** If 0, no backtracking is going on.  Safe to exec actions etc...
+     *  If >0 then it's the level of backtracking.
+     */
+    this.backtracking = 0;
+
+    /** An array[size num rules] of Map<Integer,Integer> that tracks
+     *  the stop token index for each rule.  ruleMemo[ruleIndex] is
+     *  the memoization table for ruleIndex.  For key ruleStartIndex, you
+     *  get back the stop token for associated rule or MEMO_RULE_FAILED.
+     *
+     *  This is only used if rule memoization is on (which it is by default).
+     */
+    this.ruleMemo = null;
+
+
+    // LEXER FIELDS (must be in same state object to avoid casting
+    //               constantly in generated code and Lexer object) :(
+
+
+    /** The goal of all lexer rules/methods is to create a token object.
+     *  This is an instance variable as multiple rules may collaborate to
+     *  create a single token.  nextToken will return this object after
+     *  matching lexer rule(s).  If you subclass to allow multiple token
+     *  emissions, then set this to the last token to be matched or
+     *  something nonnull so that the auto token emit mechanism will not
+     *  emit another token.
+     */
+    this.token = null;
+
+    /** What character index in the stream did the current token start at?
+     *  Needed, for example, to get the text for current token.  Set at
+     *  the start of nextToken.
+     */
+    this.tokenStartCharIndex = -1;
+
+    /** The line on which the first character of the token resides */
+    // this.tokenStartLine;
+
+    /** The character position of first character within the line */
+    // this.tokenStartCharPositionInLine;
+
+    /** The channel number for the current token */
+    // this.channel;
+
+    /** The token type for the current token */
+    // this.type;
+
+    /** You can set the text for the current token to override what is in
+     *  the input char buffer.  Use setText() or can set this instance var.
+     */
+    this.text = null;
+};
+org.antlr.runtime.IndexOutOfBoundsException = function(m) {
+    org.antlr.runtime.IndexOutOfBoundsException.superclass.constructor.call(this, m);
+};
+
+org.antlr.lang.extend(org.antlr.runtime.IndexOutOfBoundsException, Error, {
+    name: "org.antlr.runtime.IndexOutOfBoundsException"
+});
+/** The root of the ANTLR exception hierarchy.
+ *
+ *  <p>To avoid English-only error messages and to generally make things
+ *  as flexible as possible, these exceptions are not created with strings,
+ *  but rather the information necessary to generate an error.  Then
+ *  the various reporting methods in Parser and Lexer can be overridden
+ *  to generate a localized error message.  For example, MismatchedToken
+ *  exceptions are built with the expected token type.
+ *  So, don't expect getMessage() to return anything.</p>
+ *
+ *  <p>ANTLR generates code that throws exceptions upon recognition error and
+ *  also generates code to catch these exceptions in each rule.  If you
+ *  want to quit upon first error, you can turn off the automatic error
+ *  handling mechanism using rulecatch action, but you still need to
+ *  override methods mismatch and recoverFromMismatchSet.</p>
+ *
+ *  <p>In general, the recognition exceptions can track where in a grammar a
+ *  problem occurred and/or what was the expected input.  While the parser
+ *  knows its state (such as current input symbol and line info) that
+ *  state can change before the exception is reported so current token index
+ *  is computed and stored at exception time.  From this info, you can
+ *  perhaps print an entire line of input not just a single token, for example.
+ *  Better to just say the recognizer had a problem and then let the parser
+ *  figure out a fancy report.</p>
+ *
+ *  @class
+ *  @param {org.antlr.runtime.CommonTokenStream|org.antlr.runtime.tree.TreeNodeStream|org.antlr.runtime.ANTLRStringStream} input input stream that has an exception.
+ *  @extends Error
+ *
+ */
+org.antlr.runtime.RecognitionException = function(input) {
+    org.antlr.runtime.RecognitionException.superclass.constructor.call(this);
+    this.input = input;
+    this.index = input.index();
+    if ( input instanceof org.antlr.runtime.CommonTokenStream ) {
+        this.token = input.LT(1);
+        this.line = this.token.getLine();
+        this.charPositionInLine = this.token.getCharPositionInLine();
+    }
+    if ( input instanceof org.antlr.runtime.tree.TreeNodeStream ) {
+        this.extractInformationFromTreeNodeStream(input);
+    }
+    else if ( input instanceof org.antlr.runtime.ANTLRStringStream ) {
+        // Note: removed CharStream from hierarchy in JS port so checking for
+        // StringStream instead
+        this.c = input.LA(1);
+        this.line = input.getLine();
+        this.charPositionInLine = input.getCharPositionInLine();
+    }
+    else {
+        this.c = input.LA(1);
+    }
+
+    this.message = this.toString();
+};
+
+org.antlr.lang.extend(org.antlr.runtime.RecognitionException, Error,
+/** @lends org.antlr.runtime.RecognitionException.prototype */
+{
+	/**
+     * What input stream did the error occur in?
+     */
+    input: null,
+
+    /** What is index of token/char were we looking at when the error occurred?
+     *  @type Number
+     */
+	index: null,
+
+	/** The current Token when an error occurred.  Since not all streams
+	 *  can retrieve the ith Token, we have to track the Token object.
+	 *  For parsers.  Even when it's a tree parser, token might be set.
+     *  @type org.antlr.runtime.CommonToken
+	 */
+	token: null,
+
+	/** If this is a tree parser exception, node is set to the node with
+	 *  the problem.
+     *  @type Object
+	 */
+	node: null,
+
+	/** The current char when an error occurred. For lexers.
+     *  @type Number
+     */
+	c: null,
+
+	/** Track the line at which the error occurred in case this is
+	 *  generated from a lexer.  We need to track this since the
+	 *  unexpected char doesn't carry the line info.
+     *  @type Number
+	 */
+	line: null,
+
+    /** The exception's class name.
+     *  @type String
+     */
+    name: "org.antlr.runtime.RecognitionException",
+
+    /** Position in the line where exception occurred.
+     *  @type Number
+     */
+	charPositionInLine: null,
+
+	/** If you are parsing a tree node stream, you will encounter som
+	 *  imaginary nodes w/o line/col info.  We now search backwards looking
+	 *  for most recent token with line/col info, but notify getErrorHeader()
+	 *  that info is approximate.
+     *  @type Boolean
+	 */
+	approximateLineInfo: null,
+
+    /** Gather exception information from input stream.
+     *  @param {org.antlr.runtime.CommonTokenStream|org.antlr.runtime.tree.TreeNodeStream|org.antlr.runtime.ANTLRStringStream} input input stream that has an exception.
+     */
+	extractInformationFromTreeNodeStream: function(input) {
+		var nodes = input,
+            priorNode,
+            priorPayLoad,
+            type,
+            text,
+            i;
+
+		this.node = nodes.LT(1);
+		var adaptor = nodes.getTreeAdaptor(),
+		    payload = adaptor.getToken(this.node);
+		if ( payload ) {
+			this.token = payload;
+			if ( payload.getLine()<= 0 ) {
+				// imaginary node; no line/pos info; scan backwards
+				i = -1;
+				priorNode = nodes.LT(i);
+				while ( priorNode ) {
+					priorPayload = adaptor.getToken(priorNode);
+					if ( priorPayload && priorPayload.getLine()>0 ) {
+						// we found the most recent real line / pos info
+						this.line = priorPayload.getLine();
+						this.charPositionInLine = priorPayload.getCharPositionInLine();
+						this.approximateLineInfo = true;
+						break;
+					}
+					--i;
+					priorNode = nodes.LT(i);
+				}
+			}
+			else { // node created from real token
+				this.line = payload.getLine();
+				this.charPositionInLine = payload.getCharPositionInLine();
+			}
+		}
+		else if ( this.node instanceof org.antlr.runtime.tree.CommonTree) {
+			this.line = this.node.getLine();
+			this.charPositionInLine = this.node.getCharPositionInLine();
+			if ( this.node instanceof org.antlr.runtime.tree.CommonTree) {
+				this.token = this.node.token;
+			}
+		}
+		else {
+			type = adaptor.getType(this.node);
+			text = adaptor.getText(this.node);
+			this.token = new org.antlr.runtime.CommonToken(type, text);
+		}
+	},
+
+	/** Return the token type or char of the unexpected input element
+     *  @return {Number} type of the unexpected input element.
+     */
+    getUnexpectedType: function() {
+		if ( this.input instanceof org.antlr.runtime.CommonTokenStream ) {
+			return this.token.getType();
+		}
+		else if ( this.input instanceof org.antlr.runtime.tree.TreeNodeStream ) {
+			var nodes = this.input;
+			var adaptor = nodes.getTreeAdaptor();
+			return adaptor.getType(this.node);
+		}
+		else {
+			return this.c;
+		}
+	}
+});
+org.antlr.runtime.MismatchedTokenException = function(expecting, input) {
+    if (arguments.length===0) {
+        this.expecting = org.antlr.runtime.Token.INVALID_TOKEN_TYPE;
+    } else {
+        org.antlr.runtime.MismatchedTokenException.superclass.constructor.call(
+                this, input);
+        this.expecting = expecting;
+    }
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.MismatchedTokenException,
+    org.antlr.runtime.RecognitionException, {
+    toString: function() {
+        return "MismatchedTokenException(" +
+                this.getUnexpectedType() + "!=" + this.expecting + ")";
+    },
+    name: "org.antlr.runtime.MismatchedTokenException"
+});
+/** An extra token while parsing a TokenStream */
+org.antlr.runtime.UnwantedTokenException = function(expecting, input) {
+    if (arguments.length>0) {
+        org.antlr.runtime.UnwantedTokenException.superclass.constructor.call(
+                this, expecting, input);
+    }
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.UnwantedTokenException,
+    org.antlr.runtime.MismatchedTokenException, {
+    getUnexpectedToken: function() {
+        return this.token;
+    },
+    toString: function() {
+        var exp = ", expected "+this.expecting;
+        if ( this.expecting===org.antlr.runtime.Token.INVALID_TOKEN_TYPE ) {
+            exp = "";
+        }
+        if ( !org.antlr.lang.isValue(this.token) ) {
+            return "UnwantedTokenException(found="+exp+")";
+        }
+        return "UnwantedTokenException(found="+this.token.getText()+exp+")";
+    },
+    name: "org.antlr.runtime.UnwantedTokenException"
+});
+org.antlr.runtime.MissingTokenException = function(expecting, input, inserted) {
+    if (arguments.length>0) {
+        org.antlr.runtime.MissingTokenException.superclass.constructor.call(
+                this, expecting, input);
+        this.inserted = inserted;
+    }
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.MissingTokenException,
+    org.antlr.runtime.MismatchedTokenException, {
+    getMissingType: function() {
+        return this.expecting;
+    },
+
+    toString: function() {
+        if (org.antlr.lang.isValue(this.inserted) &&
+            org.antlr.lang.isValue(this.token))
+        {
+            return "MissingTokenException(inserted "+this.inserted+" at "+this.token.getText()+")";
+        }
+        if ( org.antlr.lang.isValue(this.token) ) {
+            return "MissingTokenException(at "+this.token.getText()+")";
+        }
+        return "MissingTokenException";
+    },
+    name: "org.antlr.runtime.MissingTokenException"
+});
+org.antlr.runtime.NoViableAltException = function(grammarDecisionDescription,
+                                            decisionNumber,
+                                            stateNumber,
+                                            input)
+{
+    org.antlr.runtime.NoViableAltException.superclass.constructor.call(this, input);
+    this.grammarDecisionDescription = grammarDecisionDescription;
+    this.decisionNumber = decisionNumber;
+    this.stateNumber = stateNumber;
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.NoViableAltException,
+    org.antlr.runtime.RecognitionException, {
+    toString: function() {
+        if ( this.input instanceof org.antlr.runtime.ANTLRStringStream ) {
+            return "NoViableAltException('"+this.getUnexpectedType()+"'@["+this.grammarDecisionDescription+"])";
+        }
+        else {
+            return "NoViableAltException("+this.getUnexpectedType()+"@["+this.grammarDecisionDescription+"])";
+        }
+    },
+    name: "org.antlr.runtime.NoViableAltException"
+});
+/** The recognizer did not match anything for a ()+ loop.
+ *
+ *  @class
+ *  @param {Number} decisionNumber
+ *  @param {org.antlr.runtime.CommonTokenStream|org.antlr.runtime.tree.TreeNodeStream|org.antlr.runtime.ANTLRStringStream} input input stream that has an exception.
+ *  @extends org.antlr.runtime.RecognitionException
+ */
+org.antlr.runtime.EarlyExitException = function(decisionNumber, input) {
+    org.antlr.runtime.EarlyExitException.superclass.constructor.call(
+            this, input);
+    this.decisionNumber = decisionNumber;
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.EarlyExitException,
+    org.antlr.runtime.RecognitionException,
+/** @lends org.antlr.runtime.EarlyExitException.prototype */
+{
+    /** Name of this class.
+     *  @type String
+     */
+    name: "org.antlr.runtime.EarlyExitException"
+});
+org.antlr.runtime.MismatchedSetException = function(expecting, input) {
+    org.antlr.runtime.MismatchedSetException.superclass.constructor.call(
+            this, input);
+    this.expecting = expecting;
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.MismatchedSetException,
+    org.antlr.runtime.RecognitionException, {
+    toString: function() {
+        return "MismatchedSetException(" +
+                this.getUnexpectedType() + "!=" + this.expecting + ")";
+    },
+    name: "org.antlr.runtime.MismatchedSetException"
+});
+org.antlr.runtime.MismatchedNotSetException = function(expecting, input) {
+    org.antlr.runtime.MismatchedNotSetException.superclass.constructor.call(this, expecting, input);
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.MismatchedNotSetException,
+    org.antlr.runtime.MismatchedSetException, {
+    toString: function() {
+        return "MismatchedNotSetException(" +
+                this.getUnexpectedType() + "!=" + this.expecting + ")";
+    },
+    name: "org.antlr.runtime.MismatchedNotSetException"
+});
+org.antlr.runtime.MismatchedRangeException = function(a, b, input) {
+    if (arguments.length===0) {
+        return this;
+    }
+
+    org.antlr.runtime.MismatchedRangeException.superclass.constructor.call(
+            this, input);
+    this.a = a;
+    this.b = b;
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.MismatchedRangeException,
+    org.antlr.runtime.RecognitionException, {
+    toString: function() {
+        return "MismatchedRangeException(" +
+                this.getUnexpectedType()+" not in ["+this.a+","+this.b+"])";
+    },
+    name: "org.antlr.runtime.MismatchedRangeException"
+});
+/** A semantic predicate failed during validation.  Validation of predicates
+ *  occurs when normally parsing the alternative just like matching a token.
+ *  Disambiguating predicate evaluation occurs when we hoist a predicate into
+ *  a prediction decision.
+ *
+ *  @class
+ *  @param {org.antlr.runtime.CommonTokenStream|org.antlr.runtime.tree.TreeNodeStream|org.antlr.runtime.ANTLRStringStream} input input stream that has an exception.
+ *  @param {String} ruleName name of the rule in which the exception occurred.
+ *  @param {String} predicateText the predicate that failed.
+ *  @extends org.antlr.runtime.RecognitionException
+ */
+org.antlr.runtime.FailedPredicateException = function(input, ruleName, predicateText){
+    org.antlr.runtime.FailedPredicateException.superclass.constructor.call(this, input);
+    this.ruleName = ruleName;
+    this.predicateText = predicateText;
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.FailedPredicateException,
+    org.antlr.runtime.RecognitionException,
+/** @lends org.antlr.runtime.FailedPredicateException.prototype */
+{
+    /** Create a string representation of this exception.
+     *  @returns {String}
+     */ 
+    toString: function() {
+        return "FailedPredicateException("+this.ruleName+",{"+this.predicateText+"}?)";
+    },
+
+    /** Name of this class.
+     *  @type String
+     */
+    name: "org.antlr.runtime.FailedPredicateException"
+});
+/**
+ * A BitSet similar to java.util.BitSet.
+ *
+ * <p>JavaScript Note: There is no good way to implement something like this in 
+ * JavaScript.  JS has no true int type, arrays are usually implemented as
+ * hashes, etc.  This class should probably be nixed for something that is
+ * similarly (in)efficient, but more clear.</p>
+ *
+ * @class
+ * @param {Number|Array} [bits] a 32 bit number or array of 32 bit numbers
+ *                              representing the bitset.  These are typically
+ *                              generated by the ANTLR Tool.
+ */
+org.antlr.runtime.BitSet = function(bits) {
+    if (!bits) {
+        bits = org.antlr.runtime.BitSet.BITS;
+    }
+
+    if (org.antlr.lang.isArray(bits)) {
+        /**
+         * An array of Numbers representing the BitSet.
+         * @type Array
+         */
+        this.bits = bits;
+    } else if(org.antlr.lang.isNumber(bits)) {
+        this.bits = [];
+    }
+};
+
+org.antlr.lang.augmentObject(org.antlr.runtime.BitSet, {
+    /**
+     * Number of bits in each number.
+     * @constant
+     * @memberOf org.antlr.runtime.BitSet
+     */
+    BITS: 32,
+
+    /**
+     * Log (base 2) of the number of bits in each number.
+     * @constant
+     * @memberOf org.antlr.runtime.BitSet
+     */
+    LOG_BITS: 5,  // 2^5 == 32 
+
+    /**
+     * We will often need to do a mod operator (i mod nbits).  Its
+     * turns out that, for powers of two, this mod operation is
+     * same as (i & (nbits-1)).  Since mod is slow, we use a
+     * precomputed mod mask to do the mod instead.
+     * @constant
+     * @memberOf org.antlr.runtime.BitSet
+     */
+    MOD_MASK: 31, // BITS - 1
+
+    /**
+     * Create mask for bit modded to fit in a single word.
+     * @example
+     * bitmask(35) => 00000000000000000000000000000100
+     * bitmask(3)  => 00000000000000000000000000000100
+     * @param {Number} bitNumber the bit to create a mask for.
+     * @returns {Number} the bitmask.
+     * @memberOf org.antlr.runtime.BitSet
+     * @private
+     */
+    bitMask: function(bitNumber) {
+        var bitPosition = bitNumber & org.antlr.runtime.BitSet.MOD_MASK;
+        return 1 << bitPosition;
+    },
+
+    /**
+     * Calculate the minimum number of bits needed to represent el.
+     * @param {Number} el a number to be included in the BitSet.
+     * @returns {Number} the number of bits need to create a BitSet with member
+     *                   el.
+     * @memberOf org.antlr.runtime.BitSet
+     * @private
+     */
+    numWordsToHold: function(el) {
+        return (el >> org.antlr.runtime.BitSet.LOG_BITS) + 1;
+    },
+
+    /**
+     * @param {Number} bit a number to be included in the BitSet
+     * @returns {Number} the index of the word in the field bits that would
+     *                   hold bit.
+     * @memberOf org.antlr.runtime.BitSet
+     * @private
+     */
+    wordNumber: function(bit) {
+        return bit >> org.antlr.runtime.BitSet.LOG_BITS; // bit / BITS
+    },
+
+    /**
+     * BitSet factory method.
+     * 
+     * <p>Operates in a number of modes:
+     * <ul>
+     * <li>If el is a number create the BitSet containing that number.</li>
+     * <li>If el is an array create the BitSet containing each number in the
+     * array.</li>
+     * <li>If el is a BitSet return el.</li>
+     * <li>If el is an Object create the BitSet containing each numeric value
+     * in el.</li>
+     * <li>If el is a number and el2 is a number return a BitSet containing
+     * the numbers between el and el2 (inclusive).</li>
+     * </ul>
+     * </p>
+     * @param {Number|Array|org.antlr.runtime.BitSet|Object} el
+     * @param {Number} el2
+     * @returns {org.antlr.runtime.BitSet}
+     * @memberOf org.antlr.runtime.BitSet
+     */
+    of: function(el, el2) {
+        var i, n, s, keys;
+
+        if (org.antlr.lang.isNumber(el)) {
+            if (org.antlr.lang.isNumber(el2)) {
+                s = new org.antlr.runtime.BitSet(el2 + 1);
+                for (i = el; i <= el2; i++) {
+                    n = org.antlr.runtime.BitSet.wordNumber(i);
+                    s.bits[n] |= org.antlr.runtime.BitSet.bitMask(i);
+                }
+                return s;
+            } else {
+                s = new org.antlr.runtime.BitSet(el + 1);
+                s.add(el);
+                return s;
+            }
+        } else if(org.antlr.lang.isArray(el)) {
+            s = new org.antlr.runtime.BitSet();
+            for (i=el.length-1; i>=0; i--) {
+                s.add(el[i]);
+            }
+            return s;
+        } else if (el instanceof org.antlr.runtime.BitSet) {
+            if (!el) {
+                return null;
+            }
+            return el;
+        } else if (el instanceof org.antlr.runtime.IntervalSet) {
+            if (!el) {
+                return null;
+            }
+            s = new org.antlr.runtime.BitSet();
+            s.addAll(el);
+            return s;
+        } else if (org.antlr.lang.isObject(el)) {
+            keys = [];
+            for (i in el) {
+                if (org.antlr.lang.isNumber(i)) {
+                    keys.push(i);
+                }
+            }
+            return org.antlr.runtime.BitSet.of(keys);
+        }
+    }
+});
+
+
+
+org.antlr.runtime.BitSet.prototype = {
+    /**
+     * Add el into this set.
+     * @param {Number} el the number to add to the set.
+     */
+    add: function(el) {
+        var n = org.antlr.runtime.BitSet.wordNumber(el);
+        if (n >= this.bits.length) {
+            this.growToInclude(el);
+        }
+        this.bits[n] |= org.antlr.runtime.BitSet.bitMask(el);
+    },
+
+    /**
+     * Add multiple elements into this set.
+     * @param {Array|org.antlr.runtime.BitSet} elements the elements to be added to
+     *                                           this set.
+     */
+    addAll: function(elements) {
+        var other,
+            i,
+            e;
+
+        if ( elements instanceof org.antlr.runtime.BitSet ) {
+            this.orInPlace(elements);
+        }
+		else if ( elements instanceof org.antlr.runtime.IntervalSet ) {
+			other = elements;
+			// walk set and add each interval
+            /* @todo after implementing intervalset
+			for (Iterator iter = other.intervals.iterator(); iter.hasNext();) {
+				Interval I = (Interval) iter.next();
+				this.orInPlace(BitSet.range(I.a,I.b));
+			}*/
+		} else if (org.antlr.lang.isArray(elements)) {
+    		for (i = 0; i < elements.length; i++) {
+	    		e = elements[i];
+		    	this.add(e);
+    		}
+        } else {
+            return;
+        }
+	},
+
+    /**
+     * Clone this BitSet and then {@link #andInPlace} with a.
+     * @param {org.antlr.runtime.BitSet} a a bit set.
+     * @returns {org.antlr.runtime.BitSet}
+     */
+    and: function(a) {
+        var s = this.clone();
+        s.andInPlace(a);
+        return s;
+    },
+
+    /**
+     * Perform a logical AND of this target BitSet with the argument BitSet.
+     *
+     * This bit set is modified so that each bit in it has the value true if 
+     * and only if it both initially had the value true and the corresponding 
+     * bit in the bit set argument also had the value true. 
+     * @param {org.antlr.runtime.BitSet} a a bit set.
+     * @returns {org.antlr.runtime.BitSet}
+     */
+    andInPlace: function(a) {
+        var min = Math.min(this.bits.length, a.bits.length),
+            i;
+        for (i = min - 1; i >= 0; i--) {
+            this.bits[i] &= a.bits[i];
+        }
+        // clear all bits in this not present in a (if this bigger than a).
+        for (i = min; i < this.bits.length; i++) {
+            this.bits[i] = 0;
+        }
+    },
+
+    /**
+     * Clear all bits or a specific bit.
+     *
+     * If no arguments given, sets all of the bits in this BitSet to false.
+     * If one argument given, sets the bit specified by the index to false.
+     * @param {Number} [el] the index of the bit to be cleared.
+     */
+    clear: function(el) {
+        if (arguments.length===0) {
+            var i;
+            for (i = this.bits.length - 1; i >= 0; i--) {
+                this.bits[i] = 0;
+            }
+            return;
+        }
+
+        var n = org.antlr.runtime.BitSet.wordNumber(el);
+        if (n >= this.bits.length) {	// grow as necessary to accommodate
+            this.growToInclude(el);
+        }
+        this.bits[n] &= ~org.antlr.runtime.BitSet.bitMask(el);
+    },
+
+    /**
+     * Cloning this BitSet produces a new BitSet  that is equal to it. 
+     *
+     * The clone of the bit set is another bit set that has exactly the same
+     * bit set to true as this bit set. 
+     * @returns {org.antlr.runtime.BitSet} a clone of this BitSet.
+     */
+    clone: function() {
+        var i, len, b=[];
+        for (i=0, len=this.bits.length; i<len; i++) {
+            b[i] = this.bits[i];
+        }
+        return new org.antlr.runtime.BitSet(b);
+    },
+
+    /**
+     * Returns the number of bits of space actually in use by this BitSet to 
+     * represent bit values.
+     *
+     * The maximum element in the set is the size - 1st element. 
+     * @returns {Number} the number of bits currently in this bit set.
+     */
+    size: function() {
+        var deg = 0, i, word, bit;
+        for (i = this.bits.length - 1; i >= 0; i--) {
+            word = this.bits[i];
+            if (word !== 0) {
+                for (bit = org.antlr.runtime.BitSet.BITS - 1; bit >= 0; bit--) {
+                    if ((word & (1 << bit)) !== 0) {
+                        deg++;
+                    }
+                }
+            }
+        }
+        return deg;
+    },
+
+    /**
+     * Compares this object against the specified object.
+     *
+     * The result is true if and only if the argument is not null and is a
+     * BitSet object that has exactly the same set of bits set to true as
+     * this bit set. That is, for every nonnegative int index k,
+     * <pre><code>
+     * ((BitSet)obj).get(k) == this.get(k)
+     * </code></pre>
+     * must be true. The current sizes of the two bit sets are not compared.
+     * @param {Object} other the object to compare with.
+     * @returns {Boolean} if the objects are the same; false otherwise.
+     */
+    equals: function(other) {
+        if ( !other || !(other instanceof org.antlr.runtime.BitSet) ) {
+            return false;
+        }
+
+        var otherSet = other,
+            i,
+            n = Math.min(this.bits.length, otherSet.bits.length);
+
+        // for any bits in common, compare
+        for (i=0; i<n; i++) {
+            if (this.bits[i] != otherSet.bits[i]) {
+                return false;
+            }
+        }
+
+        // make sure any extra bits are off
+
+        if (this.bits.length > n) {
+            for (i = n+1; i<this.bits.length; i++) {
+                if (this.bits[i] !== 0) {
+                    return false;
+                }
+            }
+        }
+        else if (otherSet.bits.length > n) {
+            for (i = n+1; i<otherSet.bits.length; i++) {
+                if (otherSet.bits[i] !== 0) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    },
+
+    /**
+     * Grows the set to a larger number of bits.
+     * @param {Number} bit element that must fit in set
+     * @private
+     */
+    growToInclude: function(bit) {
+        var newSize = Math.max(this.bits.length << 1, org.antlr.runtime.BitSet.numWordsToHold(bit)),
+            newbits = [], //new Array(newSize),
+            i;
+        for (i=0, len=this.bits.length; i<len; i++) {
+            newbits[i] = this.bits[i];
+        }
+        this.bits = newbits;
+    },
+
+    /**
+     * Returns the value of the bit with the specified index.
+     *
+     * The value is true if the bit with the index el is currently set 
+     * in this BitSet; otherwise, the result is false.
+     * @param {Number} el the bit index.
+     * @returns {Boolean} the value of the bit with the specified index.
+     */
+    member: function(el) {
+        var n = org.antlr.runtime.BitSet.wordNumber(el);
+        if (n >= this.bits.length) { return false; }
+        return (this.bits[n] & org.antlr.runtime.BitSet.bitMask(el)) !== 0;
+    },
+
+    /**
+     * Returns the index of the first bit that is set to true.
+     * If no such bit exists then -1 is returned.
+     * @returns {Number} the index of the next set bit.
+     */
+    getSingleElement: function() {
+        var i;
+        for (i = 0; i < (this.bits.length << org.antlr.runtime.BitSet.LOG_BITS); i++) {
+            if (this.member(i)) {
+                return i;
+            }
+        }
+        return -1; //Label.INVALID;
+    },
+
+    /**
+     * Returns true if this BitSet contains no bits that are set to true.
+     * @returns {Boolean} boolean indicating whether this BitSet is empty.
+     */
+    isNil: function() {
+        var i;
+        for (i = this.bits.length - 1; i >= 0; i--) {
+            if (this.bits[i] !== 0) {
+                return false;
+            }
+        }
+        return true;
+    },
+
+    /**
+     * If a bit set argument is passed performs a {@link #subtract} of this bit
+     * set with the argument bit set.  If no argument is passed, clone this bit
+     * set and {@link #notInPlace}.
+     * @param {org.antlr.runtime.BitSet} [set]
+     * @returns {org.antlr.runtime.BitSet}
+     */
+    complement: function(set) {
+        if (set) {
+            return set.subtract(this);
+        } else {
+            var s = this.clone();
+            s.notInPlace();
+            return s;
+        }
+    },
+
+    /**
+     * If no arguments are passed sets all bits to the complement of their
+     * current values.  If one argument is passed sets each bit from the
+     * beginning of the bit set to index1 (inclusive) to the complement of its
+     * current value.  If two arguments are passed sets each bit from the
+     * specified index1 (inclusive) to the sepcified index2 (inclusive) to the
+     * complement of its current value.
+     * @param {Number} index1
+     * @param {Number} index2
+     */
+    notInPlace: function() {
+        var minBit, maxBit, i, n;
+        if (arguments.length===0) {
+            for (i = this.bits.length - 1; i >= 0; i--) {
+                this.bits[i] = ~this.bits[i];
+            }
+        } else {
+            if (arguments.length===1) {
+                minBit = 0;
+                maxBit = arguments[0];
+            } else {
+                minBit = arguments[0];
+                maxBit = arguments[1];
+            }
+            // make sure that we have room for maxBit
+            this.growToInclude(maxBit);
+            for (i = minBit; i <= maxBit; i++) {
+                n = org.antlr.runtime.BitSet.wordNumber(i);
+                this.bits[n] ^= org.antlr.runtime.BitSet.bitMask(i);
+            }
+        }
+
+    },
+
+    /**
+     * Performs a logical OR of this bit set with the bit set argument.
+     * If no argument is passed, return this bit set.  Otherwise a clone of
+     * this bit set is modified so that a bit in it has the value true if and
+     * only if it either already had the value true or the corresponding bit
+     * in the bit set argument has the value true.
+     * @param {org.antlr.runtime.BitSet} [a] a bit set.
+     * @returns {org.antlr.runtime.BitSet}
+     */
+    or: function(a) {
+		if ( !a ) {
+			return this;
+		}
+        var s = this.clone();
+        s.orInPlace(a);
+        return s;
+    },
+
+    /**
+     * Performs a logical {@link #or} in place.
+     * @param {org.antlr.runtime.BitSet} [a]
+     * @returns {org.antlr.runtime.BitSet}
+     */
+    orInPlace: function(a) {
+		if ( !a ) {
+			return;
+		}
+        // If this is smaller than a, grow this first
+        if (a.bits.length > this.bits.length) {
+            this.setSize(a.bits.length);
+        }
+        var min = Math.min(this.bits.length, a.bits.length),
+            i;
+        for (i = min - 1; i >= 0; i--) {
+            this.bits[i] |= a.bits[i];
+        }
+    },
+
+    /**
+     * Sets the bit specified by the index to false.
+     * @param {Number} bitIndex the index of the bit to be cleared.
+     */
+    remove: function(el) {
+        var n = org.antlr.runtime.BitSet.wordNumber(el);
+        if (n >= this.bits.length) {
+            this.growToInclude(el);
+        }
+        this.bits[n] &= ~org.antlr.runtime.BitSet.bitMask(el);
+    },
+
+    /**
+     * Grows the internal bits array to include at least nwords numbers.
+     * @private
+     * @param {Number} nwords how many words the new set should be
+     * @private
+     */
+    setSize: function(nwords) {
+        var n = nwords - this.bits.length;
+        while (n>=0) {
+            this.bits.push(0);
+            n--;
+        }
+    },
+
+    /**
+     * Returns the number of bits capable of being represented by this bit set
+     * given its current size.
+     * @returns {Number} the maximum number of bits that can be represented at
+     *                   the moment.
+     * @private
+     */
+    numBits: function() {
+        return this.bits.length << org.antlr.runtime.BitSet.LOG_BITS; // num words * bits per word
+    },
+
+    /**
+     * Return how much space is being used by the bits array not
+     * how many actually have member bits on.
+     * @returns {Number} the length of the internal bits array.
+     * @private
+     */
+    lengthInLongWords: function() {
+        return this.bits.length;
+    },
+
+    /**
+     * Is this bit set contained within a?
+     * @param {org.antlr.runtime.BitSet} a bit set
+     * @returns {Boolean} true if and only if a is a subset of this bit set.
+     */
+    subset: function(a) {
+        if (!a) { return false; }
+        return this.and(a).equals(this);
+    },
+
+    /**
+     * Subtract the elements of the argument bit set from this bit set in place.
+     * That is, for each set bit in the argument bit set, set the corresponding
+     * bit in this bit set to false.
+     * @param {org.antlr.runtime.BitSet} a bit set.
+     */
+    subtractInPlace: function(a) {
+        if (!a) { return; }
+        // for all words of 'a', turn off corresponding bits of 'this'
+        var i;
+        for (i = 0; i < this.bits.length && i < a.bits.length; i++) {
+            this.bits[i] &= ~a.bits[i];
+        }
+    },
+
+    /**
+     * Perform a {@link #subtractInPlace} on a clone of this bit set.
+     * @param {org.antlr.runtime.BitSet} a bit set.
+     * @returns {org.antlr.runtime.BitSet} the new bit set.
+     */
+    subtract: function(a) {
+        if (!a || !(a instanceof org.antlr.runtime.BitSet)) { return null; }
+
+        var s = this.clone();
+        s.subtractInPlace(a);
+        return s;
+    },
+
+    /* antlr-java needs this to make its class hierarchy happy . . .
+    toList: function() {
+		throw new Error("BitSet.toList() unimplemented");
+	},
+    */
+
+    /**
+     * Creates an array of the indexes of each bit set in this bit set.
+     * @returns {Array}
+     */
+    toArray: function() {
+        var elems = [], //new Array(this.size()),
+            i,
+            en = 0;
+        for (i = 0; i < (this.bits.length << org.antlr.runtime.BitSet.LOG_BITS); i++) {
+            if (this.member(i)) {
+                elems[en++] = i;
+            }
+        }
+        return elems;
+    },
+
+    /**
+     * Returns the internal representation of this bit set.
+     * This representation is an array of numbers, each representing 32 bits.
+     * @returns {Array}
+     */
+    toPackedArray: function() {
+        return this.bits;
+    },
+
+    /**
+     * Returns a string representation of this bit set.
+     * <p>For every index for which this BitSet contains a bit in the set state,
+     * the decimal representation of that index is included in the result.
+     * Such indices are listed in order from lowest to highest, separated by
+     * ", " (a comma and a space) and surrounded by braces, resulting in the
+     * usual mathematical notation for a set of integers.</p>
+     * 
+     * <p>If a grammar g is passed, print g.getTokenDisplayName(i) for each set
+     * index instead of the numerical index.</p>
+     *
+     * <>If two arguments are passed, the first will be used as a custom
+     * separator string.  The second argument is an array whose i-th element
+     * will be added if the corresponding bit is set.</p>
+     *
+     * @param {Object|String} [arg1] an Object with function property
+     *      getTokenDispalyName or a String that will be used as a list
+     *      separator.
+     * @param {Array} [vocabulary] array from which the i-th value will be
+     *      drawn if the corresponding bit is set.  Must pass a string as the
+     *      first argument if using this option.
+     * @return A commma-separated list of values
+     */
+    toString: function() {
+        if (arguments.length===0) {
+            return this.toString1(null);
+        } else {
+            if (org.antlr.lang.isString(arguments[0])) {
+                if (!org.antlr.lang.isValue(arguments[1])) {
+                    return this.toString1(null);
+                } else {
+                    return this.toString2(arguments[0], arguments[1]);
+                }
+            } else {
+                return this.toString1(arguments[0]);
+            }
+        }
+    },
+
+    /**
+     * Transform a bit set into a string by formatting each element as an
+     * integer separator The string to put in between elements
+     * @private
+     * @return A commma-separated list of values
+     */
+    toString1: function(g) {
+        var buf = "{",
+            separator = ",",
+            i,
+		    havePrintedAnElement = false;
+
+        for (i = 0; i < (this.bits.length << org.antlr.runtime.BitSet.LOG_BITS); i++) {
+            if (this.member(i)) {
+                if (i > 0 && havePrintedAnElement ) {
+                    buf += separator;
+                }
+                if ( g ) {
+                    buf += g.getTokenDisplayName(i);
+                }
+                else {
+                    buf += i.toString();
+                }
+				havePrintedAnElement = true;
+            }
+        }
+        return buf + "}";
+    },
+
+    /**
+     * Create a string representation where instead of integer elements, the
+     * ith element of vocabulary is displayed instead.  Vocabulary is a Vector
+     * of Strings.
+     * separator The string to put in between elements
+     * @private
+     * @return A commma-separated list of character constants.
+     */
+    toString2: function(separator, vocabulary) {
+        var str = "",
+            i;
+        for (i = 0; i < (this.bits.length << org.antlr.runtime.BitSet.LOG_BITS); i++) {
+            if (this.member(i)) {
+                if (str.length > 0) {
+                    str += separator;
+                }
+                if (i >= vocabulary.size()) {
+                    str += "'" + i + "'";
+                }
+                else if (!org.antlr.lang.isValue(vocabulary.get(i))) {
+                    str += "'" + i + "'";
+                }
+                else {
+                    str += vocabulary.get(i);
+                }
+            }
+        }
+        return str;
+    }
+
+    /*
+     * Dump a comma-separated list of the words making up the bit set.
+     * Split each 32 bit number into two more manageable 16 bit numbers.
+     * @returns {String} comma separated list view of the this.bits property.
+     *
+    toStringOfHalfWords: function() {
+        var s = "",
+            tmp,
+            i;
+        for (i = 0; i < this.bits.length; i++) {
+            if (i !== 0) {
+                s+=", ";
+            }
+            tmp = this.bits[i];
+            tmp &= 0xFFFF;
+            s += tmp + "UL, ";
+            tmp = this.bits[i] >> 16;
+            tmp &= 0xFFFF;
+            s += tmp+"UL";
+        }
+		return s;
+    },
+    */
+
+    /*
+     * Dump a comma-separated list of the words making up the bit set.
+     * This generates a comma-separated list of Java-like long int constants.
+     *
+    toStringOfWords: function() {
+        var s="",
+            i;
+        for (i = 0; i < this.bits.length; i++) {
+            if (i !== 0) {
+                s+=", ";
+            }
+            s += this.bits[i]+"L";
+        }
+        return s;
+    },
+
+    toStringWithRanges: function() {
+        return this.toString();
+    }
+    */
+};
+
+/*
+ *
+ *
+org.antlr.runtime.IntervalSet = function() {
+        throw new Error("not implemented");
+};
+*/
+org.antlr.runtime.CharStream = {
+    EOF: -1
+};
+org.antlr.runtime.CommonToken = function() {
+    var oldToken;
+
+    this.charPositionInLine = -1; // set to invalid position
+    this.channel = 0; // org.antlr.runtime.CommonToken.DEFAULT_CHANNEL
+    this.index = -1;
+
+    if (arguments.length == 1) {
+        if (org.antlr.lang.isNumber(arguments[0])) {
+            this.type = arguments[0];
+        } else {
+            oldToken = arguments[0];
+            this.text = oldToken.getText();
+            this.type = oldToken.getType();
+            this.line = oldToken.getLine();
+            this.index = oldToken.getTokenIndex();
+            this.charPositionInLine = oldToken.getCharPositionInLine();
+            this.channel = oldToken.getChannel();
+            if ( oldToken instanceof org.antlr.runtime.CommonToken ) {
+                this.start = oldToken.start;
+                this.stop = oldToken.stop;
+            }
+        }
+    } else if (arguments.length == 2) {
+        this.type = arguments[0];
+        this.text = arguments[1];
+        this.channel = 0; // org.antlr.runtime.CommonToken.DEFAULT_CHANNEL
+    } else if (arguments.length == 5) {
+        this.input = arguments[0];
+        this.type = arguments[1];
+        this.channel = arguments[2];
+        this.start = arguments[3];
+        this.stop = arguments[4];
+    }
+};
+
+org.antlr.runtime.CommonToken.prototype = {
+    getType: function() {
+        return this.type;
+    },
+
+    setLine: function(line) {
+        this.line = line;
+    },
+
+    getText: function() {
+        if ( org.antlr.lang.isString(this.text) ) {
+            return this.text;
+        }
+        if ( !this.input ) {
+            return null;
+        }
+        this.text = this.input.substring(this.start,this.stop);
+        return this.text;
+    },
+
+    /** Override the text for this token.  getText() will return this text
+     *  rather than pulling from the buffer.  Note that this does not mean
+     *  that start/stop indexes are not valid.  It means that that input
+     *  was converted to a new string in the token object.
+     */
+    setText: function(text) {
+        this.text = text;
+    },
+
+    getLine: function() {
+        return this.line;
+    },
+
+    getCharPositionInLine: function() {
+        return this.charPositionInLine;
+    },
+
+    setCharPositionInLine: function(charPositionInLine) {
+        this.charPositionInLine = charPositionInLine;
+    },
+
+    getChannel: function() {
+        return this.channel;
+    },
+
+    setChannel: function(channel) {
+        this.channel = channel;
+    },
+
+    setType: function(type) {
+        this.type = type;
+    },
+
+    getStartIndex: function() {
+        return this.start;
+    },
+
+    setStartIndex: function(start) {
+        this.start = start;
+    },
+
+    getStopIndex: function() {
+        return this.stop;
+    },
+
+    setStopIndex: function(stop) {
+        this.stop = stop;
+    },
+
+    getTokenIndex: function() {
+        return this.index;
+    },
+
+    setTokenIndex: function(index) {
+        this.index = index;
+    },
+
+    getInputStream: function() {
+        return this.input;
+    },
+
+    setInputStream: function(input) {
+        this.input = input;
+    },
+
+    toString: function() {
+        var channelStr = "";
+        if ( this.channel>0 ) {
+            channelStr=",channel="+this.channel;
+        }
+        var txt = this.getText();
+        if ( !org.antlr.lang.isNull(txt) ) {
+            txt = txt.replace(/\n/g,"\\\\n");
+            txt = txt.replace(/\r/g,"\\\\r");
+            txt = txt.replace(/\t/g,"\\\\t");
+        }
+        else {
+            txt = "<no text>";
+        }
+        return "[@"+this.getTokenIndex()+","+this.start+":"+this.stop+"='"+txt+"',<"+this.type+">"+channelStr+","+this.line+":"+this.getCharPositionInLine()+"]";
+    }
+};
+// NB: Because Token has static members of type CommonToken, the Token dummy
+// constructor is defined in CommonToken.  All methods and vars of Token are
+// defined here.  Token is an interface, not a subclass in the Java runtime.
+
+/**
+ * @class Abstract base class of all token types.
+ * @name Token
+ * @memberOf org.antlr.runtime
+ */
+org.antlr.runtime.Token = function() {};
+org.antlr.lang.augmentObject(org.antlr.runtime.Token, /** @lends Token */ {
+    EOR_TOKEN_TYPE: 1,
+
+    /** imaginary tree navigation type; traverse "get child" link */
+    DOWN: 2,
+    /** imaginary tree navigation type; finish with a child list */
+    UP: 3,
+
+    MIN_TOKEN_TYPE: 4, // UP+1,
+
+    EOF: org.antlr.runtime.CharStream.EOF,
+    EOF_TOKEN: new org.antlr.runtime.CommonToken(org.antlr.runtime.CharStream.EOF),
+
+    INVALID_TOKEN_TYPE: 0,
+    INVALID_TOKEN: new org.antlr.runtime.CommonToken(0),
+
+    /** In an action, a lexer rule can set token to this SKIP_TOKEN and ANTLR
+     *  will avoid creating a token for this symbol and try to fetch another.
+     */
+    SKIP_TOKEN: new org.antlr.runtime.CommonToken(0),
+
+    /** All tokens go to the parser (unless skip() is called in that rule)
+     *  on a particular "channel".  The parser tunes to a particular channel
+     *  so that whitespace etc... can go to the parser on a "hidden" channel.
+     */
+    DEFAULT_CHANNEL: 0,
+
+    /** Anything on different channel than DEFAULT_CHANNEL is not parsed
+     *  by parser.
+     */
+    HIDDEN_CHANNEL: 99
+});
+
+org.antlr.lang.augmentObject(org.antlr.runtime.CommonToken, org.antlr.runtime.Token);
+org.antlr.runtime.tree.RewriteCardinalityException = function(elementDescription) {
+    this.elementDescription = elementDescription;
+};
+
+/** Base class for all exceptions thrown during AST rewrite construction.
+ *  This signifies a case where the cardinality of two or more elements
+ *  in a subrule are different: (ID INT)+ where |ID|!=|INT|
+ */
+org.antlr.lang.extend(org.antlr.runtime.tree.RewriteCardinalityException, Error, {
+    getMessage: function() {
+		if ( org.antlr.lang.isString(this.elementDescription) ) {
+			return this.elementDescription;
+		}
+		return null;
+	},
+    name: function() {
+        return "org.antlr.runtime.tree.RewriteCardinalityException";
+    }
+});
+/** Ref to ID or expr but no tokens in ID stream or subtrees in expr stream */
+org.antlr.runtime.tree.RewriteEmptyStreamException = function(elementDescription) {
+    var sup = org.antlr.runtime.tree.RewriteEmptyStreamException.superclass; 
+    sup.constructor.call(this, elementDescription);
+};
+
+org.antlr.lang.extend(org.antlr.runtime.tree.RewriteEmptyStreamException,
+                  org.antlr.runtime.tree.RewriteCardinalityException, {
+    name: function() {
+        return "org.antlr.runtime.tree.RewriteEmptyStreamException";
+    }
+});
+/** No elements within a (...)+ in a rewrite rule */
+org.antlr.runtime.tree.RewriteEarlyExitException = function(elementDescription) {
+    var sup = org.antlr.runtime.tree.RewriteEarlyExitException.superclass;
+    if (org.antlr.lang.isUndefined(elementDescription)) {
+        elementDescription = null;
+    }
+    sup.constructor.call(this, elementDescription);
+};
+
+org.antlr.lang.extend(org.antlr.runtime.tree.RewriteEarlyExitException,
+                  org.antlr.runtime.tree.RewriteCardinalityException, {
+    name: function() {
+        return "org.antlr.runtime.tree.RewriteEarlyExitException";
+    }    
+});
+org.antlr.runtime.MismatchedTreeNodeException = function(expecting, input) {
+    if (expecting && input) {
+        org.antlr.runtime.MismatchedTreeNodeException.superclass.constructor.call(
+                this, input);
+        this.expecting = expecting;
+    }
+};
+
+org.antlr.lang.extend(
+    org.antlr.runtime.MismatchedTreeNodeException,
+    org.antlr.runtime.RecognitionException, {
+    toString: function() {
+        return "MismatchedTreeNodeException(" +
+                this.getUnexpectedType() + "!=" + this.expecting + ")";
+    },
+    name: "org.antlr.runtime.MismatchedTreeNodeException"
+});
+/** A generic tree implementation with no payload.  You must subclass to
+ *  actually have any user data.  ANTLR v3 uses a list of children approach
+ *  instead of the child-sibling approach in v2.  A flat tree (a list) is
+ *  an empty node whose children represent the list.  An empty, but
+ *  non-null node is called "nil".
+ */
+org.antlr.runtime.tree.BaseTree = function() {};
+
+org.antlr.runtime.tree.BaseTree.prototype = {
+    getChild: function(i) {
+        if ( !this.children || i>=this.children.length ) {
+            return null;
+        }
+        return this.children[i];
+    },
+
+    /** Get the children internal List; note that if you directly mess with
+     *  the list, do so at your own risk.
+     */
+    getChildren: function() {
+        return this.children;
+    },
+
+    getFirstChildWithType: function(type) {
+        var i, t;
+        for (i = 0; this.children && i < this.children.length; i++) {
+            t = this.children[i];
+            if ( t.getType()===type ) {
+                return t;
+            }
+        }    
+        return null;
+    },
+
+    getChildCount: function() {
+        if ( !this.children ) {
+            return 0;
+        }
+        return this.children.length;
+    },
+
+    /** Add t as child of this node.
+     *
+     *  Warning: if t has no children, but child does
+     *  and child isNil then this routine moves children to t via
+     *  t.children = child.children; i.e., without copying the array.
+     */
+    addChild: function(t) {
+        if ( !org.antlr.lang.isValue(t) ) {
+            return; // do nothing upon addChild(null)
+        }
+        var childTree = t, n, i, c;
+        if ( childTree.isNil() ) { // t is an empty node possibly with children
+            if ( this.children && this.children == childTree.children ) {
+                throw new Error("attempt to add child list to itself");
+            }
+            // just add all of childTree's children to this
+            if ( childTree.children ) {
+                if ( this.children ) { // must copy, this has children already
+                    n = childTree.children.length;
+                    for (i = 0; i < n; i++) {
+                        c = childTree.children[i];
+                        this.children.push(c);
+                        // handle double-link stuff for each child of nil root
+                        c.setParent(this);
+                        c.setChildIndex(this.children.length-1);
+                    }
+                }
+                else {
+                    // no children for this but t has children; just set pointer
+                    // call general freshener routine
+                    this.children = childTree.children;
+                    this.freshenParentAndChildIndexes();
+                }
+            }
+        }
+        else { // child is not nil (don't care about children)
+            if ( !this.children ) {
+                this.children = this.createChildrenList(); // create children list on demand
+            }
+            this.children.push(t);
+            childTree.setParent(this);
+            childTree.setChildIndex(this.children.length-1);
+        }
+    },
+
+    /** Add all elements of kids list as children of this node */
+    addChildren: function(kids) {
+        var i, t;
+        for (i = 0; i < kids.length; i++) {
+            t = kids[i];
+            this.addChild(t);
+        }
+    },
+
+    setChild: function(i, t) {
+        if ( !t ) {
+            return;
+        }
+        if ( t.isNil() ) {
+            throw new Error("Can't set single child to a list");
+        }
+        if ( !this.children ) {
+            this.children = this.createChildrenList();
+        }
+        this.children[i] = t;
+        t.setParent(this);
+        t.setChildIndex(i);
+    },
+
+    deleteChild: function(i) {
+        if ( !this.children ) {
+            return null;
+        }
+        if (i<0 || i>=this.children.length) {
+            throw new Error("Index out of bounds.");
+        }
+        var killed = this.children.splice(i, 1)[0];
+        // walk rest and decrement their child indexes
+        this.freshenParentAndChildIndexes(i);
+        return killed;
+    },
+
+    /** Delete children from start to stop and replace with t even if t is
+     *  a list (nil-root tree).  num of children can increase or decrease.
+     *  For huge child lists, inserting children can force walking rest of
+     *  children to set their childindex; could be slow.
+     */
+    replaceChildren: function(startChildIndex, stopChildIndex, t) {
+        if ( !this.children ) {
+            throw new Error("indexes invalid; no children in list");
+        }
+        var replacingHowMany = stopChildIndex - startChildIndex + 1;
+        var replacingWithHowMany;
+        var newTree = t;
+        var newChildren = null;
+        // normalize to a list of children to add: newChildren
+        if ( newTree.isNil() ) {
+            newChildren = newTree.children;
+        }
+        else {
+            newChildren = [];
+            newChildren.push(newTree);
+        }
+        replacingWithHowMany = newChildren.length;
+        var numNewChildren = newChildren.length;
+        var delta = replacingHowMany - replacingWithHowMany;
+        var j, i, child, indexToDelete, c, killed, numToInsert;
+        // if same number of nodes, do direct replace
+        if ( delta === 0 ) {
+            j = 0; // index into new children
+            for (i=startChildIndex; i<=stopChildIndex; i++) {
+                child = newChildren[j];
+                this.children[i] = child;
+                child.setParent(this);
+                child.setChildIndex(i);
+                j++;
+            }
+        }
+        else if ( delta > 0 ) { // fewer new nodes than there were
+            // set children and then delete extra
+            for (j=0; j<numNewChildren; j++) {
+                this.children[startChildIndex+j] = newChildren[j];
+            }
+            indexToDelete = startChildIndex+numNewChildren;
+            for (c=indexToDelete; c<=stopChildIndex; c++) {
+                // delete same index, shifting everybody down each time
+                killed = this.children.splice(indexToDelete, 1)[0];
+            }
+            this.freshenParentAndChildIndexes(startChildIndex);
+        }
+        else { // more new nodes than were there before
+            // fill in as many children as we can (replacingHowMany) w/o moving data
+            for (j=0; j<replacingHowMany; j++) {
+                this.children[startChildIndex+j] = newChildren[j];
+            }
+            numToInsert = replacingWithHowMany-replacingHowMany;
+            for (j=replacingHowMany; j<replacingWithHowMany; j++) {
+                this.children.splice(startChildIndex+j, 0, newChildren[j]);
+            }
+            this.freshenParentAndChildIndexes(startChildIndex);
+        }
+    },
+
+    /** Override in a subclass to change the impl of children list */
+    createChildrenList: function() {
+        return [];
+    },
+
+    isNil: function() {
+        return false;
+    },
+
+    freshenParentAndChildIndexes: function(offset) {
+        if (!org.antlr.lang.isNumber(offset)) {
+            offset = 0;
+        }
+        var n = this.getChildCount(),
+            c,
+            child;
+        for (c = offset; c < n; c++) {
+            child = this.getChild(c);
+            child.setChildIndex(c);
+            child.setParent(this);
+        }
+    },
+
+    sanityCheckParentAndChildIndexes: function(parent, i) {
+        if (arguments.length===0) {
+            parent = null;
+            i = -1;
+        }
+
+        if ( parent!==this.getParent() ) {
+            throw new Error("parents don't match; expected "+parent+" found "+this.getParent());
+        }
+        if ( i!==this.getChildIndex() ) {
+            throw new Error("child indexes don't match; expected "+i+" found "+this.getChildIndex());
+        }
+        var n = this.getChildCount(),
+            c,
+            child;
+        for (c = 0; c < n; c++) {
+            child = this.getChild(c);
+            child.sanityCheckParentAndChildIndexes(this, c);
+        }
+    },
+
+    /** BaseTree doesn't track child indexes. */
+    getChildIndex: function() {
+        return 0;
+    },
+    setChildIndex: function(index) {
+    },
+
+    /** BaseTree doesn't track parent pointers. */
+    getParent: function() {
+        return null;
+    },
+    setParent: function(t) {
+    },
+
+    getTree: function() {
+        return this;
+    },
+
+    /** Print out a whole tree not just a node */
+    toStringTree: function() {
+        if ( !this.children || this.children.length===0 ) {
+            return this.toString();
+        }
+        var buf = "",
+            i,
+            t;
+        if ( !this.isNil() ) {
+            buf += "(";
+            buf += this.toString();
+            buf += ' ';
+        }
+        for (i = 0; this.children && i < this.children.length; i++) {
+            t = this.children[i];
+            if ( i>0 ) {
+                buf += ' ';
+            }
+            buf += t.toStringTree();
+        }
+        if ( !this.isNil() ) {
+            buf += ")";
+        }
+        return buf;
+    },
+
+    getLine: function() {
+        return 0;
+    },
+
+    getCharPositionInLine: function() {
+        return 0;
+    }
+};
+/** A tree node that is wrapper for a Token object.  After 3.0 release
+ *  while building tree rewrite stuff, it became clear that computing
+ *  parent and child index is very difficult and cumbersome.  Better to
+ *  spend the space in every tree node.  If you don't want these extra
+ *  fields, it's easy to cut them out in your own BaseTree subclass.
+ */
+org.antlr.runtime.tree.CommonTree = function(node) {
+    /** What token indexes bracket all tokens associated with this node
+     *  and below?
+     */
+    this.startIndex = -1;
+    this.stopIndex = -1;
+
+    /** What index is this node in the child list? Range: 0..n-1 */
+    this.childIndex = -1;
+
+    /** Who is the parent node of this node; if null, implies node is root */
+    this.parent = null;
+
+    /** A single token is the payload */
+    this.token = null;
+
+    if (node instanceof org.antlr.runtime.tree.CommonTree) {
+        org.antlr.runtime.tree.CommonTree.superclass.constructor.call(this, node);
+        this.token = node.token;
+        this.startIndex = node.startIndex;
+        this.stopIndex = node.stopIndex;
+    } else if (node instanceof org.antlr.runtime.CommonToken) {
+        this.token = node;
+    }
+};
+
+/** A tree node that is wrapper for a Token object. */
+org.antlr.lang.extend(org.antlr.runtime.tree.CommonTree, org.antlr.runtime.tree.BaseTree, {
+    getToken: function() {
+        return this.token;
+    },
+
+    dupNode: function() {
+        return new org.antlr.runtime.tree.CommonTree(this);
+    },
+
+    isNil: function() {
+        return !this.token;
+    },
+
+    getType: function() {
+        if ( !this.token ) {
+            return org.antlr.runtime.Token.INVALID_TOKEN_TYPE;
+        }
+        return this.token.getType();
+    },
+
+    getText: function() {
+        if ( !this.token ) {
+            return null;
+        }
+        return this.token.getText();
+    },
+
+    getLine: function() {
+        if ( !this.token || this.token.getLine()===0 ) {
+            if ( this.getChildCount()>0 ) {
+                return this.getChild(0).getLine();
+            }
+            return 0;
+        }
+        return this.token.getLine();
+    },
+
+    getCharPositionInLine: function() {
+        if ( !this.token || this.token.getCharPositionInLine()===-1 ) {
+            if ( this.getChildCount()>0 ) {
+                return this.getChild(0).getCharPositionInLine();
+            }
+            return 0;
+        }
+        return this.token.getCharPositionInLine();
+    },
+
+    getTokenStartIndex: function() {
+        if ( this.token ) {
+            return this.token.getTokenIndex();
+        }
+        return this.startIndex;
+    },
+
+    setTokenStartIndex: function(index) {
+        this.startIndex = index;
+    },
+
+    getTokenStopIndex: function() {
+        if ( this.token ) {
+            return this.token.getTokenIndex();
+        }
+        return this.stopIndex;
+    },
+
+    setTokenStopIndex: function(index) {
+        this.stopIndex = index;
+    },
+
+    getChildIndex: function() {
+        return this.childIndex;
+    },
+
+    getParent: function() {
+        return this.parent;
+    },
+
+    setParent: function(t) {
+        this.parent = t;
+    },
+
+    setChildIndex: function(index) {
+        this.childIndex = index;
+    },
+
+    toString: function() {
+        if ( this.isNil() ) {
+            return "nil";
+        }
+        if ( this.getType()===org.antlr.runtime.Token.INVALID_TOKEN_TYPE ) {
+            return "<errornode>";
+        }
+        if ( !this.token ) {
+            return null;
+        }
+        return this.token.getText();
+    }
+});
+/** What does a tree look like?  ANTLR has a number of support classes
+ *  such as CommonTreeNodeStream that work on these kinds of trees.  You
+ *  don't have to make your trees implement this interface, but if you do,
+ *  you'll be able to use more support code.
+ *
+ *  NOTE: When constructing trees, ANTLR can build any kind of tree; it can
+ *  even use Token objects as trees if you add a child list to your tokens.
+ *
+ *  This is a tree node without any payload; just navigation and factory stuff.
+ */
+org.antlr.runtime.tree.Tree = {
+    INVALID_NODE: new org.antlr.runtime.tree.CommonTree(org.antlr.runtime.Token.INVALID_TOKEN)
+};
+org.antlr.runtime.tree.CommonErrorNode = function(input, start, stop, e) {
+    if ( !stop ||
+            (stop.getTokenIndex() < start.getTokenIndex() &&
+             stop.getType()!=org.antlr.runtime.Token.EOF) )
+    {
+        // sometimes resync does not consume a token (when LT(1) is
+        // in follow set.  So, stop will be 1 to left to start. adjust.
+        // Also handle case where start is the first token and no token
+        // is consumed during recovery; LT(-1) will return null.
+        stop = start;
+    }
+    this.input = input;
+    this.start = start;
+    this.stop = stop;
+    this.trappedException = e;
+};
+
+org.antlr.lang.extend(org.antlr.runtime.tree.CommonErrorNode, org.antlr.runtime.tree.CommonTree, {
+    isNil: function() {
+        return false;
+    },
+
+    getType: function() {
+        return org.antlr.runtime.Token.INVALID_TOKEN_TYPE;
+    },
+
+    getText: function() {
+        var badText = null;
+        if ( this.start instanceof org.antlr.runtime.CommonToken ) {
+            var i = this.start.getTokenIndex();
+            var j = this.stop.getTokenIndex();
+            if ( this.stop.getType() === org.antlr.runtime.Token.EOF ) {
+                j = this.input.size();
+            }
+            badText = this.input.toString(i, j);
+        }
+        else if ( this.start instanceof org.antlr.runtime.tree.CommonTree ) {
+            badText = this.input.toString(this.start, this.stop);
+        }
+        else {
+            // people should subclass if they alter the tree type so this
+            // next one is for sure correct.
+            badText = "<unknown>";
+        }
+        return badText;
+    },
+
+    toString: function() {
+        if ( this.trappedException instanceof org.antlr.runtime.MissingTokenException ) {
+            return "<missing type: "+
+                   this.trappedException.getMissingType()+
+                   ">";
+        }
+        else if ( this.trappedException instanceof org.antlr.runtime.UnwantedTokenException ) {
+            return "<extraneous: "+
+                   this.trappedException.getUnexpectedToken()+
+                   ", resync="+this.getText()+">";
+        }
+        else if ( this.trappedException instanceof org.antlr.runtime.MismatchedTokenException ) {
+            return "<mismatched token: "+this.trappedException.token+", resync="+this.getText()+">";
+        }
+        else if ( this.trappedException instanceof org.antlr.runtime.NoViableAltException ) {
+            return "<unexpected: "+this.trappedException.token+
+                   ", resync="+this.getText()+">";
+        }
+        return "<error: "+this.getText()+">";
+    }
+});
+/** A TreeAdaptor that works with any Tree implementation. */
+org.antlr.runtime.tree.BaseTreeAdaptor = function() {
+    this.uniqueNodeID = 1;
+};
+
+org.antlr.runtime.tree.BaseTreeAdaptor.prototype = {
+    nil: function() {
+        return this.create(null);
+    },
+
+    /** create tree node that holds the start and stop tokens associated
+     *  with an error.
+     *
+     *  If you specify your own kind of tree nodes, you will likely have to
+     *  override this method. CommonTree returns Token.INVALID_TOKEN_TYPE
+     *  if no token payload but you might have to set token type for diff
+     *  node type.
+     */
+    errorNode: function(input, start, stop, e) {
+        var t = new org.antlr.runtime.tree.CommonErrorNode(input, start, stop, e);
+        return t;
+    },
+
+    isNil: function(tree) {
+        return tree.isNil();
+    },
+
+    /** This is generic in the sense that it will work with any kind of
+     *  tree (not just Tree interface).  It invokes the adaptor routines
+     *  not the tree node routines to do the construction.  
+     */
+    dupTree: function(t, parent) {
+        if (arguments.length===1) {
+            parent = null;
+        }
+        if ( !t ) {
+            return null;
+        }
+        var newTree = this.dupNode(t);
+        // ensure new subtree root has parent/child index set
+        this.setChildIndex(newTree, this.getChildIndex(t)); // same index in new tree
+        this.setParent(newTree, parent);
+        var n = this.getChildCount(t),
+            i, child, newSubTree;
+        for (i = 0; i < n; i++) {
+            child = this.getChild(t, i);
+            newSubTree = this.dupTree(child, t);
+            this.addChild(newTree, newSubTree);
+        }
+        return newTree;
+    },
+
+    /** Add a child to the tree t.  If child is a flat tree (a list), make all
+     *  in list children of t.  Warning: if t has no children, but child does
+     *  and child isNil then you can decide it is ok to move children to t via
+     *  t.children = child.children; i.e., without copying the array.  Just
+     *  make sure that this is consistent with have the user will build
+     *  ASTs.
+     */
+    addChild: function(t, child) {
+        if ( t && org.antlr.lang.isValue(child) ) {
+            t.addChild(child);
+        }
+    },
+
+    /** If oldRoot is a nil root, just copy or move the children to newRoot.
+     *  If not a nil root, make oldRoot a child of newRoot.
+     *
+     *    old=^(nil a b c), new=r yields ^(r a b c)
+     *    old=^(a b c), new=r yields ^(r ^(a b c))
+     *
+     *  If newRoot is a nil-rooted single child tree, use the single
+     *  child as the new root node.
+     *
+     *    old=^(nil a b c), new=^(nil r) yields ^(r a b c)
+     *    old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
+     *
+     *  If oldRoot was null, it's ok, just return newRoot (even if isNil).
+     *
+     *    old=null, new=r yields r
+     *    old=null, new=^(nil r) yields ^(nil r)
+     *
+     *  Return newRoot.  Throw an exception if newRoot is not a
+     *  simple node or nil root with a single child node--it must be a root
+     *  node.  If newRoot is ^(nil x) return x as newRoot.
+     *
+     *  Be advised that it's ok for newRoot to point at oldRoot's
+     *  children; i.e., you don't have to copy the list.  We are
+     *  constructing these nodes so we should have this control for
+     *  efficiency.
+     */
+    becomeRoot: function(newRoot, oldRoot) {
+        if (newRoot instanceof org.antlr.runtime.CommonToken || !newRoot) {
+            newRoot = this.create(newRoot);
+        }
+
+        var newRootTree = newRoot,
+            oldRootTree = oldRoot;
+        if ( !oldRoot ) {
+            return newRoot;
+        }
+        // handle ^(nil real-node)
+        if ( newRootTree.isNil() ) {
+            if ( newRootTree.getChildCount()>1 ) {
+                // TODO: make tree run time exceptions hierarchy
+                throw new Error("more than one node as root (TODO: make exception hierarchy)");
+            }
+            newRootTree = newRootTree.getChild(0);
+        }
+        // add oldRoot to newRoot; addChild takes care of case where oldRoot
+        // is a flat list (i.e., nil-rooted tree).  All children of oldRoot
+        // are added to newRoot.
+        newRootTree.addChild(oldRootTree);
+        return newRootTree;
+    },
+
+    /** Transform ^(nil x) to x */
+    rulePostProcessing: function(root) {
+        var r = root;
+        if ( r && r.isNil() ) {
+            if ( r.getChildCount()===0 ) {
+                r = null;
+            }
+            else if ( r.getChildCount()===1 ) {
+                r = r.getChild(0);
+                // whoever invokes rule will set parent and child index
+                r.setParent(null);
+                r.setChildIndex(-1);
+            }
+        }
+        return r;
+    },
+
+    create: function(tokenType, fromToken) {
+        var text, t;
+        if (arguments.length===2) {
+            if (org.antlr.lang.isString(arguments[1])) {
+                text = arguments[1];
+                fromToken = this.createToken(tokenType, text);
+                t = this.create(fromToken);
+                return t;
+            } else {
+                fromToken = this.createToken(fromToken);
+                fromToken.setType(tokenType);
+                t = this.create(fromToken);
+                return t;
+            }
+        } else if (arguments.length===3) {
+            text = arguments[2];
+            fromToken = this.createToken(fromToken);
+            fromToken.setType(tokenType);
+            fromToken.setText(text);
+            t = this.create(fromToken);
+            return t;
+        }
+    },
+
+    getType: function(t) {
+        t.getType();
+        return 0;
+    },
+
+    setType: function(t, type) {
+        throw new Error("don't know enough about Tree node");
+    },
+
+    getText: function(t) {
+        return t.getText();
+    },
+
+    setText: function(t, text) {
+        throw new Error("don't know enough about Tree node");
+    },
+
+    getChild: function(t, i) {
+        return t.getChild(i);
+    },
+
+    setChild: function(t, i, child) {
+        t.setChild(i, child);
+    },
+
+    deleteChild: function(t, i) {
+        return t.deleteChild(i);
+    },
+
+    getChildCount: function(t) {
+        return t.getChildCount();
+    },
+
+    getUniqueID: function(node) {
+        if ( !this.treeToUniqueIDMap ) {
+             this.treeToUniqueIDMap = {};
+        }
+        var prevID = this.treeToUniqueIDMap[node];
+        if ( org.antlr.lang.isValue(prevID) ) {
+            return prevID;
+        }
+        var ID = this.uniqueNodeID;
+        this.treeToUniqueIDMap[node] = ID;
+        this.uniqueNodeID++;
+        return ID;
+        // GC makes these nonunique:
+        // return System.identityHashCode(node);
+    }
+};
+/** A TreeAdaptor that works with any Tree implementation.  It provides
+ *  really just factory methods; all the work is done by BaseTreeAdaptor.
+ *  If you would like to have different tokens created than ClassicToken
+ *  objects, you need to override this and then set the parser tree adaptor to
+ *  use your subclass.
+ *
+ *  To get your parser to build nodes of a different type, override
+ *  create(Token).
+ */
+org.antlr.runtime.tree.CommonTreeAdaptor = function() {};
+
+org.antlr.lang.extend(org.antlr.runtime.tree.CommonTreeAdaptor,
+                  org.antlr.runtime.tree.BaseTreeAdaptor, {
+    /** Duplicate a node.  This is part of the factory;
+     *    override if you want another kind of node to be built.
+     *
+     *  I could use reflection to prevent having to override this
+     *  but reflection is slow.
+     */
+    dupNode: function(t) {
+        if ( !org.antlr.lang.isValue(t) ) {
+            return null;
+        }
+        return t.dupNode();
+    },
+
+    create: function(payload) {
+        if (arguments.length>1) {
+            return org.antlr.runtime.tree.CommonTreeAdaptor.superclass.create.apply(this, arguments);
+        }
+        return new org.antlr.runtime.tree.CommonTree(payload);
+    },
+
+    /** Tell me how to create a token for use with imaginary token nodes.
+     *  For example, there is probably no input symbol associated with imaginary
+     *  token DECL, but you need to create it as a payload or whatever for
+     *  the DECL node as in ^(DECL type ID).
+     *
+     *  If you care what the token payload objects' type is, you should
+     *  override this method and any other createToken variant.
+     *
+     * Tell me how to create a token for use with imaginary token nodes.
+     *  For example, there is probably no input symbol associated with imaginary
+     *  token DECL, but you need to create it as a payload or whatever for
+     *  the DECL node as in ^(DECL type ID).
+     *
+     *  This is a variant of createToken where the new token is derived from
+     *  an actual real input token.  Typically this is for converting '{'
+     *  tokens to BLOCK etc...  You'll see
+     *
+     *    r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
+     *
+     *  If you care what the token payload objects' type is, you should
+     *  override this method and any other createToken variant.
+     */
+    createToken: function(fromToken) {
+        if (arguments.length===2) {
+            return new org.antlr.runtime.CommonToken(arguments[0], arguments[1]);
+        } else {
+            return new org.antlr.runtime.CommonToken(arguments[0]);
+        }
+    },
+
+    /** Track start/stop token for subtree root created for a rule.
+     *  Only works with Tree nodes.  For rules that match nothing,
+     *  seems like this will yield start=i and stop=i-1 in a nil node.
+     *  Might be useful info so I'll not force to be i..i.
+     */
+    setTokenBoundaries: function(t, startToken, stopToken) {
+        if ( !org.antlr.lang.isValue(t) ) {
+            return;
+        }
+        var start = 0,
+            stop = 0;
+        if ( org.antlr.lang.isValue(startToken) ) {
+            if (startToken.getTokenIndex) {
+                start = startToken.getTokenIndex();
+            } else if (startToken.getStartIndex) {
+                start = startToken.getStartIndex();
+            } else {
+                start = startToken.getTokenStartIndex();
+            }
+        }
+        if ( org.antlr.lang.isValue(stopToken) ) {
+            if (stop.getTokenIndex) {
+                stop = stopToken.getTokenIndex();
+            } else if (stopToken.getStopIndex) {
+                stop = stopToken.getStopIndex();
+            } else {
+                stop = stopToken.getTokenStopIndex();
+            }
+        }
+        t.setTokenStartIndex(start);
+        t.setTokenStopIndex(stop);
+    },
+
+    getTokenStartIndex: function(t) {
+        if (!t) {
+            return -1;
+        }
+        return t.getTokenStartIndex();
+    },
+
+    getTokenStopIndex: function(t) {
+        if (!t) {
+            return -1;
+        }
+        return t.getTokenStopIndex();
+    },
+
+    getText: function(t) {
+        if (!t) {
+            return null;
+        }
+        return t.getText();
+    },
+
+    getType: function(t) {
+        if (!t) {
+            return org.antlr.runtime.Token.INVALID_TOKEN_TYPE;
+        }
+        return t.getType();
+    },
+
+    /** What is the Token associated with this node?  If
+     *  you are not using CommonTree, then you must
+     *  override this in your own adaptor.
+     */
+    getToken: function(t) {
+        if ( t instanceof org.antlr.runtime.tree.CommonTree ) {
+            return t.getToken();
+        }
+        return null; // no idea what to do
+    },
+
+    getChild: function(t, i) {
+        if (!t) {
+            return null;
+        }
+        return t.getChild(i);
+    },
+
+    getChildCount: function(t) {
+        if (!t) {
+            return 0;
+        }
+        return t.getChildCount();
+    },
+
+    getParent: function(t) {
+        return t.getParent();
+    },
+
+    setParent: function(t, parent) {
+        t.setParent(parent);
+    },
+
+    getChildIndex: function(t) {
+        return t.getChildIndex();
+    },
+
+    setChildIndex: function(t, index) {
+        t.setChildIndex(index);
+    },
+
+    replaceChildren: function(parent, startChildIndex, stopChildIndex, t) {
+        if ( parent ) {
+            parent.replaceChildren(startChildIndex, stopChildIndex, t);
+        }
+    }
+});
+/**
+ * A stream of characters created from a JavaScript string that in turn gets
+ * fed to a lexer.
+ * @class
+ * @param {String} data the string from which this stream will be created.
+ */
+org.antlr.runtime.ANTLRStringStream = function(data) {
+    /**
+     * Location in the stream.
+     * Ranges from 0 to (stream length - 1).
+     * @private
+     * @type Number
+     */
+    this.p = 0;
+
+    /**
+     * The current line in the input.
+     * Ranges from 1 to (number of lines).
+     * @private
+     * @type Number
+     */
+    this.line = 1;
+
+    /**
+     * The index of the character relative to the beginning of the line.
+     * Ranges from 0 to (length of line - 1).
+     * @private
+     * @type Number
+     */
+    this.charPositionInLine = 0;
+
+    /**
+     * Tracks how deep mark() calls are nested
+     * @private
+     * @type Number
+     */
+    this.markDepth = 0;
+
+    /**
+     * An Array of objects that tracks the stream state
+     * values line, charPositionInLine, and p that can change as you
+     * move through the input stream.  Indexed from 1..markDepth.
+     * A null is kept at index 0.  Created upon first call to mark().
+     * @private
+     * @type Array
+     */
+    this.markers = null;
+
+    /**
+     * Track the last mark() call result value for use in rewind().
+     * @private
+     * @type Number
+     */
+    this.lastMarker = null;
+
+    /**
+     * The data being scanned.
+     * @private
+     * @type String
+     */
+    this.data = data;
+
+    /**
+     * The number of characters in the stream.
+     * @private
+     * @type Number
+     */
+    this.n = data.length;
+};
+
+org.antlr.runtime.ANTLRStringStream.prototype = {
+    /**
+     * Reset the stream so that it's in the same state it was
+     * when the object was created *except* the data array is not
+     * touched.
+     */
+    reset: function() {
+       this.p = 0;
+       this.line = 1;
+       this.charPositionInLine = 0;
+       this.markDepth = 0;
+    },
+
+    /**
+     * Consume the next character of data in the stream.
+     */
+    consume: function() {
+        if ( this.p < this.n ) {
+            this.charPositionInLine++;
+            if ( this.data.charAt(this.p)==="\n" ) {
+                this.line++;
+                this.charPositionInLine=0;
+            }
+            this.p++;
+        }
+    },
+
+    /**
+     * Get character at current input pointer + i ahead where i=1 is next int.
+     * Negative indexes are allowed.  LA(-1) is previous token (token
+     * just matched).  LA(-i) where i is before first token should
+     * yield -1, invalid char / EOF.
+     * @param {Number} i non-zero amount of lookahead or lookback
+     * @returns {String|Number} The charcter at the specified position or -1 if
+     *      you fell off either end of the stream.
+     */
+    LA: function(i) {
+        if ( i<0 ) {
+            i++; // e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
+        }
+
+        var new_pos = this.p+i-1;
+        if (new_pos>=this.n || new_pos<0) {
+            return org.antlr.runtime.CharStream.EOF;
+        }
+        return this.data.charAt(new_pos);
+    },
+
+
+    /**
+     * Return the current input symbol index 0..n where n indicates the
+     * last symbol has been read.  The index is the index of char to
+     * be returned from LA(1) (i.e. the one about to be consumed).
+     * @returns {Number} the index of the current input symbol
+     */
+    index: function() {
+        return this.p;
+    },
+
+    /**
+     * The length of this stream.
+     * @returns {Number} the length of this stream.
+     */
+    size: function() {
+        return this.n;
+    },
+
+    /**
+     * Tell the stream to start buffering if it hasn't already.  Return
+     * current input position, index(), or some other marker so that
+     * when passed to rewind() you get back to the same spot.
+     * rewind(mark()) should not affect the input cursor.  The Lexer
+     * tracks line/col info as well as input index so its markers are
+     * not pure input indexes.  Same for tree node streams.
+     *
+     * <p>Marking is a mechanism for storing the current position of a stream
+     * in a stack.  This corresponds with the predictive look-ahead mechanism
+     * used in Lexers.</p>
+     * @returns {Number} the current size of the mark stack.
+     */
+    mark: function() {
+        if ( !this.markers ) {
+            this.markers = [];
+            this.markers.push(null); // depth 0 means no backtracking, leave blank
+        }
+        this.markDepth++;
+        var state = null;
+        if ( this.markDepth>=this.markers.length ) {
+            state = {};
+            this.markers.push(state);
+        }
+        else {
+            state = this.markers[this.markDepth];
+        }
+        state.p = this.p;
+        state.line = this.line;
+        state.charPositionInLine = this.charPositionInLine;
+        this.lastMarker = this.markDepth;
+        return this.markDepth;
+    },
+
+    /**
+     * Rewind to the input position of the last marker.
+     * Used currently only after a cyclic DFA and just
+     * before starting a sem/syn predicate to get the
+     * input position back to the start of the decision.
+     * Do not "pop" the marker off the state.  mark(i)
+     * and rewind(i) should balance still. It is
+     * like invoking rewind(last marker) but it should not "pop"
+     * the marker off.  It's like seek(last marker's input position).
+     * @param {Number} [m] the index in the mark stack to load instead of the
+     *      last.
+     */
+    rewind: function(m) {
+        if (!org.antlr.lang.isNumber(m)) {
+            m = this.lastMarker;
+        }
+
+        var state = this.markers[m];
+        // restore stream state
+        this.seek(state.p);
+        this.line = state.line;
+        this.charPositionInLine = state.charPositionInLine;
+        this.release(m);
+    },
+
+    /**
+     * You may want to commit to a backtrack but don't want to force the
+     * stream to keep bookkeeping objects around for a marker that is
+     * no longer necessary.  This will have the same behavior as
+     * rewind() except it releases resources without the backward seek.
+     * This must throw away resources for all markers back to the marker
+     * argument.  So if you're nested 5 levels of mark(), and then release(2)
+     * you have to release resources for depths 2..5.
+     * @param {Number} marker the mark depth above which all mark states will
+     *      be released.
+     */
+    release: function(marker) {
+        // unwind any other markers made after m and release m
+        this.markDepth = marker;
+        // release this marker
+        this.markDepth--;
+    },
+
+    /**
+     * Set the input cursor to the position indicated by index.  This is
+     * normally used to seek ahead in the input stream.  No buffering is
+     * required to do this unless you know your stream will use seek to
+     * move backwards such as when backtracking.
+     *
+     * <p>This is different from rewind in its multi-directional
+     * requirement and in that its argument is strictly an input cursor
+     * (index).</p>
+     *
+     * <p>For char streams, seeking forward must update the stream state such
+     * as line number.  For seeking backwards, you will be presumably
+     * backtracking using the mark/rewind mechanism that restores state and
+     * so this method does not need to update state when seeking backwards.</p>
+     *
+     * <p>Currently, this method is only used for efficient backtracking using
+     * memoization, but in the future it may be used for incremental
+     * parsing.</p>
+     *
+     * <p>The index is 0..n-1.  A seek to position i means that LA(1) will
+     * return the ith symbol.  So, seeking to 0 means LA(1) will return the
+     * first element in the stream.</p>
+     *
+     * <p>Esentially this method method moves the input position,
+     * {@link #consume}-ing data if necessary.</p>
+     *
+     * @param {Number} index the position to seek to.
+     */
+    seek: function(index) {
+        if ( index<=this.p ) {
+            this.p = index; // just jump; don't update stream state (line, ...)
+            return;
+        }
+        // seek forward, consume until p hits index
+        while ( this.p<index ) {
+            this.consume();
+        }
+    },
+
+    /**
+     * Retrieve a substring from this stream.
+     * @param {Number} start the starting index of the substring (inclusive).
+     * @param {Number} stop the last index of the substring (inclusive).
+     * @returns {String}
+     */
+    substring: function(start, stop) {
+        return this.data.substr(start,stop-start+1);
+    },
+
+    /**
+     * Return the current line position in the stream.
+     * @returns {Number} the current line position in the stream (1..numlines).
+     */
+    getLine: function() {
+        return this.line;
+    },
+
+    /**
+     * Get the index of the character relative to the beginning of the line.
+     * Ranges from 0 to (length of line - 1).
+     * @returns {Number}
+     */
+    getCharPositionInLine: function() {
+        return this.charPositionInLine;
+    },
+
+    /**
+     * Set the current line in the input stream.
+     * This is used internally when performing rewinds.
+     * @param {Number} line
+     * @private
+     */
+    setLine: function(line) {
+        this.line = line;
+    },
+
+    /**
+     * Set the index of the character relative to the beginning of the line.
+     * Ranges from 0 to (length of line - 1).
+     * @param {Number} pos
+     * @private
+     */
+    setCharPositionInLine: function(pos) {
+        this.charPositionInLine = pos;
+    },
+
+    /** Where are you getting symbols from? Normally, implementations will
+     *  pass the buck all the way to the lexer who can ask its input stream
+     *  for the file name or whatever.
+     */
+    getSourceName: function() {
+        return null;
+    }
+};
+
+/**
+ * Alias for {@link #LA}.
+ * @methodOf org.antlr.runtime.ANTLRStringStream.prototype
+ * @name LT
+ */
+org.antlr.runtime.ANTLRStringStream.LT = org.antlr.runtime.ANTLRStringStream.LA;
+/** The most common stream of tokens is one where every token is buffered up
+ *  and tokens are prefiltered for a certain channel (the parser will only
+ *  see these tokens and cannot change the filter channel number during the
+ *  parse).
+ *
+ *  TODO: how to access the full token stream?  How to track all tokens matched per rule?
+ */
+org.antlr.runtime.CommonTokenStream = function(tokenSource, channel) {
+    this.p = -1;
+    this.channel = org.antlr.runtime.Token.DEFAULT_CHANNEL;
+    this.v_discardOffChannelTokens = false;
+
+    this.tokens = [];
+    if (arguments.length >= 2) {
+        this.channel = channel;
+    } else if (arguments.length === 1) {
+        this.tokenSource = tokenSource;
+    }
+};
+
+org.antlr.runtime.CommonTokenStream.prototype = {
+    /** Reset this token stream by setting its token source. */
+    setTokenSource: function(tokenSource) {
+        this.tokenSource = tokenSource;
+        this.tokens = [];
+        this.p = -1;
+        this.channel = org.antlr.runtime.Token.DEFAULT_CHANNEL;
+    },
+
+    /** Load all tokens from the token source and put in tokens.
+     *  This is done upon first LT request because you might want to
+     *  set some token type / channel overrides before filling buffer.
+     */
+    fillBuffer: function() {
+        var index = 0,
+            t = this.tokenSource.nextToken(),
+            discard,
+            channelI;
+        while ( org.antlr.lang.isValue(t) && 
+                t.getType()!=org.antlr.runtime.CharStream.EOF )
+        {
+            discard = false;
+            // is there a channel override for token type?
+            if ( this.channelOverrideMap ) {
+                channelI = this.channelOverrideMap[t.getType()];
+                if ( org.antlr.lang.isValue(channelI) ) {
+                    t.setChannel(channelI);
+                }
+            }
+            if ( this.discardSet && this.discardSet[t.getType()] )
+            {
+                discard = true;
+            }
+            else if ( this.v_discardOffChannelTokens &&
+                    t.getChannel()!=this.channel )
+            {
+                discard = true;
+            }
+            if ( !discard )    {
+                t.setTokenIndex(index);
+                this.tokens.push(t);
+                index++;
+            }
+            t = this.tokenSource.nextToken();
+        }
+        // leave p pointing at first token on channel
+        this.p = 0;
+        this.p = this.skipOffTokenChannels(this.p);
+    },
+
+    /** Move the input pointer to the next incoming token.  The stream
+     *  must become active with LT(1) available.  consume() simply
+     *  moves the input pointer so that LT(1) points at the next
+     *  input symbol. Consume at least one token.
+     *
+     *  Walk past any token not on the channel the parser is listening to.
+     */
+    consume: function() {
+        if ( this.p<this.tokens.length ) {
+            this.p++;
+            this.p = this.skipOffTokenChannels(this.p); // leave p on valid token
+        }
+    },
+
+    /** Given a starting index, return the index of the first on-channel
+     *  token.
+     */
+    skipOffTokenChannels: function(i) {
+        var n = this.tokens.length;
+        while ( i<n && (this.tokens[i]).getChannel()!=this.channel ) {
+            i++;
+        }
+        return i;
+    },
+
+    skipOffTokenChannelsReverse: function(i) {
+        while ( i>=0 && (this.tokens[i]).getChannel()!=this.channel ) {
+            i--;
+        }
+        return i;
+    },
+
+    /** A simple filter mechanism whereby you can tell this token stream
+     *  to force all tokens of type ttype to be on channel.  For example,
+     *  when interpreting, we cannot exec actions so we need to tell
+     *  the stream to force all WS and NEWLINE to be a different, ignored
+     *  channel.
+     */
+    setTokenTypeChannel: function(ttype, channel) {
+        if ( !this.channelOverrideMap ) {
+            this.channelOverrideMap = {};
+        }
+        this.channelOverrideMap[ttype] = channel;
+    },
+
+    discardTokenType: function(ttype) {
+        if ( !this.discardSet ) {
+            this.discardSet = {};
+        }
+        this.discardSet[ttype] = true;
+    },
+
+    discardOffChannelTokens: function(b) {
+        this.v_discardOffChannelTokens = b;
+    },
+
+    /** Given a start and stop index, return a List of all tokens in
+     *  the token type BitSet.  Return null if no tokens were found.  This
+     *  method looks at both on and off channel tokens.
+     */
+    getTokens: function(start, stop, types) {
+        if ( this.p === -1 ) {
+            this.fillBuffer();
+        }
+
+        if (arguments.length===0) {
+            return this.tokens;
+        }
+
+        if (org.antlr.lang.isArray(types)) {
+            types = new org.antlr.runtime.BitSet(types);
+        } else if (org.antlr.lang.isNumber(types)) {
+            types = org.antlr.runtime.BitSet.of(types);
+        }
+
+        if ( stop>=this.tokens.length ) {
+            stop=this.tokens.length-1;
+        }
+        if ( start<0 ) {
+            start=0;
+        }
+        if ( start>stop ) {
+            return null;
+        }
+
+        // list = tokens[start:stop]:{Token t, t.getType() in types}
+        var filteredTokens = [],
+            i,
+            t;
+        for (i=start; i<=stop; i++) {
+            t = this.tokens[i];
+            if ( !this.types || types.member(t.getType()) ) {
+                filteredTokens.push(t);
+            }
+        }
+        if ( filteredTokens.length===0 ) {
+            filteredTokens = null;
+        }
+        return filteredTokens;
+    },
+
+    /** Get the ith token from the current position 1..n where k=1 is the
+     *  first symbol of lookahead.
+     */
+    LT: function(k) {
+        if ( this.p === -1 ) {
+            this.fillBuffer();
+        }
+        if ( k===0 ) {
+            return null;
+        }
+        if ( k<0 ) {
+            return this.LB(-1*k);
+        }
+        if ( (this.p+k-1) >= this.tokens.length ) {
+            return org.antlr.runtime.Token.EOF_TOKEN;
+        }
+        var i = this.p,
+            n = 1;
+        // find k good tokens
+        while ( n<k ) {
+            // skip off-channel tokens
+            i = this.skipOffTokenChannels(i+1); // leave p on valid token
+            n++;
+        }
+        if ( i>=this.tokens.length ) {
+            return org.antlr.runtime.Token.EOF_TOKEN;
+        }
+        return this.tokens[i];
+    },
+
+    /** Look backwards k tokens on-channel tokens */
+    LB: function(k) {
+        if ( this.p === -1 ) {
+            this.fillBuffer();
+        }
+        if ( k===0 ) {
+            return null;
+        }
+        if ( (this.p-k)<0 ) {
+            return null;
+        }
+
+        var i = this.p,
+            n = 1;
+        // find k good tokens looking backwards
+        while ( n<=k ) {
+            // skip off-channel tokens
+            i = this.skipOffTokenChannelsReverse(i-1); // leave p on valid token
+            n++;
+        }
+        if ( i<0 ) {
+            return null;
+        }
+        return this.tokens[i];
+    },
+
+    /** Return absolute token i; ignore which channel the tokens are on;
+     *  that is, count all tokens not just on-channel tokens.
+     */
+    get: function(i) {
+        return this.tokens[i];
+    },
+
+    LA: function(i) {
+        return this.LT(i).getType();
+    },
+
+    mark: function() {
+        if ( this.p === -1 ) {
+            this.fillBuffer();
+        }
+        this.lastMarker = this.index();
+        return this.lastMarker;
+    },
+
+    release: function(marker) {
+        // no resources to release
+    },
+
+    size: function() {
+        return this.tokens.length;
+    },
+
+    index: function() {
+        return this.p;
+    },
+
+    rewind: function(marker) {
+        if (!org.antlr.lang.isNumber(marker)) {
+            marker = this.lastMarker;
+        }
+        this.seek(marker);
+    },
+
+    reset: function() {
+        this.p = -1;
+        this.lastMarker = 0;
+    },
+
+    seek: function(index) {
+        this.p = index;
+    },
+
+    getTokenSource: function() {
+        return this.tokenSource;
+    },
+
+    getSourceName: function() {
+        return this.getTokenSource().getSourceName();
+    },
+
+    toString: function(start, stop) {
+        if (arguments.length===0) {
+            if ( this.p === -1 ) {
+                this.fillBuffer();
+            }
+            start = 0;
+            stop = this.tokens.length-1;
+        }
+
+        if (!org.antlr.lang.isNumber(start) && !org.antlr.lang.isNumber(stop)) {
+            if ( org.antlr.lang.isValue(start) && org.antlr.lang.isValue(stop) ) {
+                start = start.getTokenIndex();
+                stop = stop.getTokenIndex();
+            } else {
+                return null;
+            }
+        }
+
+        var buf = "",
+            i;
+ 
+        if ( start<0 || stop<0 ) {
+            return null;
+        }
+        if ( this.p == -1 ) {
+            this.fillBuffer();
+        }
+        if ( stop>=this.tokens.length ) {
+            stop = this.tokens.length-1;
+        }
+        for (i = start; i <= stop; i++) {
+            t = this.tokens[i];
+            buf = buf + this.tokens[i].getText();
+        }
+        return buf;
+    }
+};
+/* Useful for dumping out the input stream after doing some
+ *  augmentation or other manipulations.
+ *
+ *  You can insert stuff, replace, and delete chunks.  Note that the
+ *  operations are done lazily--only if you convert the buffer to a
+ *  String.  This is very efficient because you are not moving data around
+ *  all the time.  As the buffer of tokens is converted to strings, the
+ *  toString() method(s) check to see if there is an operation at the
+ *  current index.  If so, the operation is done and then normal String
+ *  rendering continues on the buffer.  This is like having multiple Turing
+ *  machine instruction streams (programs) operating on a single input tape. :)
+ *
+ *  Since the operations are done lazily at toString-time, operations do not
+ *  screw up the token index values.  That is, an insert operation at token
+ *  index i does not change the index values for tokens i+1..n-1.
+ *
+ *  Because operations never actually alter the buffer, you may always get
+ *  the original token stream back without undoing anything.  Since
+ *  the instructions are queued up, you can easily simulate transactions and
+ *  roll back any changes if there is an error just by removing instructions.
+ *  For example,
+ *
+ *   CharStream input = new ANTLRFileStream("input");
+ *   TLexer lex = new TLexer(input);
+ *   TokenRewriteStream tokens = new TokenRewriteStream(lex);
+ *   T parser = new T(tokens);
+ *   parser.startRule();
+ *
+ *      Then in the rules, you can execute
+ *      Token t,u;
+ *      ...
+ *      input.insertAfter(t, "text to put after t");}
+ *         input.insertAfter(u, "text after u");}
+ *         System.out.println(tokens.toString());
+ *
+ *  Actually, you have to cast the 'input' to a TokenRewriteStream. :(
+ *
+ *  You can also have multiple "instruction streams" and get multiple
+ *  rewrites from a single pass over the input.  Just name the instruction
+ *  streams and use that name again when printing the buffer.  This could be
+ *  useful for generating a C file and also its header file--all from the
+ *  same buffer:
+ *
+ *      tokens.insertAfter("pass1", t, "text to put after t");}
+ *         tokens.insertAfter("pass2", u, "text after u");}
+ *         System.out.println(tokens.toString("pass1"));
+ *         System.out.println(tokens.toString("pass2"));
+ *
+ *  If you don't use named rewrite streams, a "default" stream is used as
+ *  the first example shows.
+ */
+
+org.antlr.runtime.TokenRewriteStream = function() {
+    var sup = org.antlr.runtime.TokenRewriteStream.superclass;
+
+    /** You may have multiple, named streams of rewrite operations.
+     *  I'm calling these things "programs."
+     *  Maps String (name) -> rewrite (List)
+     */
+    this.programs = null;
+
+    /** Map String (program name) -> Integer index */
+    this.lastRewriteTokenIndexes = null;
+
+
+    if (arguments.length===0) {
+        this.init();
+    } else {
+        sup.constructor.apply(this, arguments);
+        this.init();
+    }
+};
+
+(function(){
+var trs = org.antlr.runtime.TokenRewriteStream;
+
+org.antlr.lang.augmentObject(trs, {
+    DEFAULT_PROGRAM_NAME: "default",
+    PROGRAM_INIT_SIZE: 100,
+    MIN_TOKEN_INDEX: 0
+});
+
+//
+// Define the rewrite operation hierarchy
+//
+
+trs.RewriteOperation = function(index, text) {
+    this.index = index;
+    this.text = text;
+};
+
+/** Execute the rewrite operation by possibly adding to the buffer.
+ *  Return the index of the next token to operate on.
+ */
+trs.RewriteOperation.prototype = {
+    execute: function(buf) {
+        return this.index;
+    },
+    toString: function() {
+        /*String opName = getClass().getName();
+        int $index = opName.indexOf('$');
+        opName = opName.substring($index+1, opName.length());
+        return opName+"@"+index+'"'+text+'"';*/
+        return this.text;
+    }
+};
+
+trs.InsertBeforeOp = function(index, text) {
+    trs.InsertBeforeOp.superclass.constructor.call(this, index, text);
+};
+org.antlr.lang.extend(trs.InsertBeforeOp, trs.RewriteOperation, {
+    execute: function(buf) {
+        buf.push(this.text);
+        return this.index;
+    }
+});
+
+/** I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp
+ *  instructions.
+ */
+trs.ReplaceOp = function(from, to, text) {
+    trs.ReplaceOp.superclass.constructor.call(this, from, text); 
+    this.lastIndex = to;
+};
+org.antlr.lang.extend(trs.ReplaceOp, trs.RewriteOperation, {
+    execute: function(buf) {
+        if (org.antlr.lang.isValue(this.text)) {
+            buf.push(this.text);
+        }
+        return this.lastIndex+1;
+    }
+});
+
+trs.DeleteOp = function(from, to) {
+    trs.DeleteOp.superclass.constructor.call(this, from, to); 
+};
+org.antlr.lang.extend(trs.DeleteOp, trs.ReplaceOp);
+
+org.antlr.lang.extend(trs, org.antlr.runtime.CommonTokenStream, {
+    init: function() {
+        this.programs = {};
+        this.programs[trs.DEFAULT_PROGRAM_NAME] = [];
+        this.lastRewriteTokenIndexes = {};
+    },
+
+    /** Rollback the instruction stream for a program so that
+     *  the indicated instruction (via instructionIndex) is no
+     *  longer in the stream.  UNTESTED!
+     */
+    rollback: function() {
+        var programName,
+            instructionIndex;
+
+        if (arguments.length===1) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            instructionIndex = arguments[0];
+        } else if (arguments.length===2) {
+            programName = arguments[0];
+            instructionIndex = arguments[1];
+        }
+        var is = this.programs[programName];
+        if (is) {
+            programs[programName] = is.slice(trs.MIN_TOKEN_INDEX, this.instructionIndex);
+        }
+    },
+
+    /** Reset the program so that no instructions exist */
+    deleteProgram: function(programName) {
+        programName = programName || trs.DEFAULT_PROGRAM_NAME;
+        this.rollback(programName, trs.MIN_TOKEN_INDEX);
+    },
+
+    /** Add an instruction to the rewrite instruction list ordered by
+     *  the instruction number (use a binary search for efficiency).
+     *  The list is ordered so that toString() can be done efficiently.
+     *
+     *  When there are multiple instructions at the same index, the instructions
+     *  must be ordered to ensure proper behavior.  For example, a delete at
+     *  index i must kill any replace operation at i.  Insert-before operations
+     *  must come before any replace / delete instructions.  If there are
+     *  multiple insert instructions for a single index, they are done in
+     *  reverse insertion order so that "insert foo" then "insert bar" yields
+     *  "foobar" in front rather than "barfoo".  This is convenient because
+     *  I can insert new InsertOp instructions at the index returned by
+     *  the binary search.  A ReplaceOp kills any previous replace op.  Since
+     *  delete is the same as replace with null text, i can check for
+     *  ReplaceOp and cover DeleteOp at same time. :)
+     */
+    addToSortedRewriteList: function() {
+        var programName,
+            op;
+        if (arguments.length===1) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            op = arguments[0];
+        } else if (arguments.length===2) {
+            programName = arguments[0];
+            op = arguments[1];
+        }
+
+        var rewrites = this.getProgram(programName);
+        var len, pos, searchOp, replaced, prevOp, i;
+        for (pos=0, len=rewrites.length; pos<len; pos++) {
+            searchOp = rewrites[pos];
+            if (searchOp.index===op.index) {
+                // now pos is the index in rewrites of first op with op.index
+
+                // an instruction operating already on that index was found;
+                // make this one happen after all the others
+                if (op instanceof trs.ReplaceOp) {
+                    replaced = false;
+                    // look for an existing replace
+                    for (i=pos; i<rewrites.length; i++) {
+                        prevOp = rewrites[pos];
+                        if (prevOp.index!==op.index) {
+                            break;
+                        }
+                        if (prevOp instanceof trs.ReplaceOp) {
+                            rewrites[pos] = op; // replace old with new
+                            replaced=true;
+                            break;
+                        }
+                        // keep going; must be an insert
+                    }
+                    if ( !replaced ) {
+                        // add replace op to the end of all the inserts
+                        rewrites.splice(i, 0, op);
+                    }
+                } else {
+                    // inserts are added in front of existing inserts
+                    rewrites.splice(pos, 0, op);
+                }
+                break;
+            } else if (searchOp.index > op.index) {
+                rewrites.splice(pos, 0, op);
+                break;
+            }
+        }
+        if (pos===len) {
+            rewrites.push(op);
+        }
+    },
+
+    insertAfter: function() {
+        var index, programName, text;
+        if (arguments.length===2) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            index = arguments[0];
+            text = arguments[1];
+        } else if (arguments.length===3) {
+            programName = arguments[0];
+            index = arguments[1];
+            text = arguments[2];
+        }
+
+        if (index instanceof org.antlr.runtime.CommonToken) {
+            // index is a Token, grab it's stream index
+            index = index.index; // that's ugly
+        }
+
+        // insert after is the same as insert before the next index
+        this.insertBefore(programName, index+1, text);
+    },
+
+    insertBefore: function() {
+        var index, programName, text;
+        if (arguments.length===2) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            index = arguments[0];
+            text = arguments[1];
+        } else if (arguments.length===3) {
+            programName = arguments[0];
+            index = arguments[1];
+            text = arguments[2];
+        }
+
+        if (index instanceof org.antlr.runtime.CommonToken) {
+            // index is a Token, grab it's stream index
+            index = index.index; // that's ugly
+        }
+
+        this.addToSortedRewriteList(
+                programName,
+                new trs.InsertBeforeOp(index,text)
+                );
+    },
+
+    replace: function() {
+        var programName, first, last, text;
+        if (arguments.length===2) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            first = arguments[0];
+            last = arguments[0];
+            text = arguments[1];
+        } else if (arguments.length===3) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            first = arguments[0];
+            last = arguments[1];
+            text = arguments[2];
+        } if (arguments.length===4) {
+            programName = arguments[0];
+            first = arguments[1];
+            last = arguments[2];
+            text = arguments[3];
+        } 
+
+        if (first instanceof org.antlr.runtime.CommonToken) {
+            first = first.index;
+        }
+
+        if (last instanceof org.antlr.runtime.CommonToken) {
+            last = last.index; // that's ugly
+        }
+
+        if ( first > last || last<0 || first<0 ) {
+            return;
+        }
+        this.addToSortedRewriteList(
+                programName,
+                new trs.ReplaceOp(first, last, text));
+    },
+
+    // !!! API Break: delete is a JS keyword, so using remove instead.
+    remove: function() {
+        // convert arguments to a real array
+        var args=[], i=arguments.length-1;
+        while (i>=0) {
+            args[i] = arguments[i];
+            i--;
+        }
+
+        args.push("");
+        this.replace.apply(this, args);
+    },
+
+    getLastRewriteTokenIndex: function(programName) {
+        programName = programName || trs.DEFAULT_PROGRAM_NAME;
+        return this.lastRewriteTokenIndexes[programName] || -1;
+    },
+
+    setLastRewriteTokenIndex: function(programName, i) {
+        this.lastRewriteTokenIndexes[programName] = i;
+    },
+
+    getProgram: function(name) {
+        var is = this.programs[name];
+        if ( !is ) {
+            is = this.initializeProgram(name);
+        }
+        return is;
+    },
+
+    initializeProgram: function(name) {
+        var is = [];
+        this.programs[name] = is;
+        return is;
+    },
+
+    toOriginalString: function(start, end) {
+        if (!org.antlr.lang.isNumber(start)) {
+            start = trs.MIN_TOKEN_INDEX;
+        }
+        if (!org.antlr.lang.isNumber(end)) {
+            end = this.size()-1;
+        }
+
+        var buf = [], i;
+        for (i=start; i>=trs.MIN_TOKEN_INDEX && i<=end && i<this.tokens.length; i++) {
+            buf.push(this.get(i).getText());
+        }
+        return buf.join("");
+    },
+
+    toString: function() {
+        var programName, start, end;
+        if (arguments.length===0) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            start = trs.MIN_TOKEN_INDEX;
+            end = this.size() - 1;
+        } else if (arguments.length===1) {
+            programName = arguments[0];
+            start = trs.MIN_TOKEN_INDEX;
+            end = this.size() - 1;
+        } else if (arguments.length===2) {
+            programName = trs.DEFAULT_PROGRAM_NAME;
+            start = arguments[0];
+            end = arguments[1];
+        }
+
+        var rewrites = this.programs[programName];
+        if ( !rewrites || rewrites.length===0 ) {
+            return this.toOriginalString(start,end);
+        }
+
+        /// Index of first rewrite we have not done
+        var rewriteOpIndex = 0,
+            tokenCursor=start,
+            buf = [],
+            op;
+        while ( tokenCursor>=trs.MIN_TOKEN_INDEX &&
+                tokenCursor<=end &&
+                tokenCursor<this.tokens.length )
+        {
+            // execute instructions associated with this token index
+            if ( rewriteOpIndex<rewrites.length ) {
+                op = rewrites[rewriteOpIndex];
+
+                // skip all ops at lower index
+                while (op.index<tokenCursor && rewriteOpIndex<rewrites.length) {
+                    rewriteOpIndex++;
+                    if ( rewriteOpIndex<rewrites.length ) {
+                        op = rewrites[rewriteOpIndex];
+                    }
+                }
+
+                // while we have ops for this token index, exec them
+                while (tokenCursor===op.index && rewriteOpIndex<rewrites.length) {
+                    //System.out.println("execute "+op+" at instruction "+rewriteOpIndex);
+                    tokenCursor = op.execute(buf);
+                    //System.out.println("after execute tokenCursor = "+tokenCursor);
+                    rewriteOpIndex++;
+                    if ( rewriteOpIndex<rewrites.length ) {
+                        op = rewrites[rewriteOpIndex];
+                    }
+                }
+            }
+            // dump the token at this index
+            if ( tokenCursor<=end ) {
+                buf.push(this.get(tokenCursor).getText());
+                tokenCursor++;
+            }
+        }
+        // now see if there are operations (append) beyond last token index
+        var opi;
+        for (opi=rewriteOpIndex; opi<rewrites.length; opi++) {
+            op = rewrites[opi];
+            if ( op.index>=this.size() ) {
+                op.execute(buf); // must be insertions if after last token
+            }
+        }
+
+        return buf.join("");
+    },
+
+    toDebugString: function(start, end) {
+        if (!org.antlr.lang.isNumber(start)) {
+            start = trs.MIN_TOKEN_INDEX;
+        }
+        if (!org.antlr.lang.isNumber(end)) {
+            end = this.size()-1;
+        }
+
+        var buf = [],
+            i;
+        for (i=start; i>=trs.MIN_TOKEN_INDEX && i<=end && i<this.tokens.length; i++) {
+            buf.push(this.get(i));
+        }
+        return buf.join("");
+    }
+});
+
+})();
+/** A stream of tree nodes, accessing nodes from a tree of some kind */
+org.antlr.runtime.tree.TreeNodeStream = function() {};
+/** A buffered stream of tree nodes.  Nodes can be from a tree of ANY kind.
+ *
+ *  This node stream sucks all nodes out of the tree specified in
+ *  the constructor during construction and makes pointers into
+ *  the tree using an array of Object pointers. The stream necessarily
+ *  includes pointers to DOWN and UP and EOF nodes.
+ *
+ *  This stream knows how to mark/release for backtracking.
+ *
+ *  This stream is most suitable for tree interpreters that need to
+ *  jump around a lot or for tree parsers requiring speed (at cost of memory).
+ *  There is some duplicated functionality here with UnBufferedTreeNodeStream
+ *  but just in bookkeeping, not tree walking etc...
+ *
+ *  @see UnBufferedTreeNodeStream
+ */
+org.antlr.runtime.tree.CommonTreeNodeStream = function(adaptor,
+                                                    tree,
+                                                    initialBufferSize)
+{
+    if (arguments.length===1) {
+        tree = adaptor;
+        adaptor = new org.antlr.runtime.tree.CommonTreeAdaptor();
+    }
+    if (arguments.length <= 2) {
+        initialBufferSize =
+            org.antlr.runtime.tree.CommonTreeNodeStream.DEFAULT_INITIAL_BUFFER_SIZE;
+    }
+
+    /** Reuse same DOWN, UP navigation nodes unless this is true */
+    this.uniqueNavigationNodes = false;
+
+    /** The index into the nodes list of the current node (next node
+     *  to consume).  If -1, nodes array not filled yet.
+     */
+    this.p = -1;
+
+    var Token = org.antlr.runtime.Token;
+    this.root = tree;
+    this.adaptor = adaptor;
+    this.nodes = []; //new ArrayList(initialBufferSize);
+    this.down = this.adaptor.create(Token.DOWN, "DOWN");
+    this.up = this.adaptor.create(Token.UP, "UP");
+    this.eof = this.adaptor.create(Token.EOF, "EOF");
+};
+
+org.antlr.lang.augmentObject(org.antlr.runtime.tree.CommonTreeNodeStream, {
+    DEFAULT_INITIAL_BUFFER_SIZE: 100,
+    INITIAL_CALL_STACK_SIZE: 10
+});
+
+org.antlr.lang.extend(org.antlr.runtime.tree.CommonTreeNodeStream,
+                  org.antlr.runtime.tree.TreeNodeStream, 
+{
+    StreamIterator: function() {
+        var i = 0,
+            nodes = this.nodes,
+            eof = this.eof;
+
+        return {
+            hasNext: function() {
+                return i<nodes.length;
+            },
+
+            next: function() {
+                var current = i;
+                i++;
+                if ( current < nodes.length ) {
+                    return nodes[current];
+                }
+                return eof;
+            },
+
+            remove: function() {
+                throw new Error("cannot remove nodes from stream");
+            }
+        };
+    },
+
+    /** Walk tree with depth-first-search and fill nodes buffer.
+     *  Don't do DOWN, UP nodes if its a list (t is isNil).
+     */
+    fillBuffer: function(t) {
+        var reset_p = false;
+        if (org.antlr.lang.isUndefined(t)) {
+            t = this.root;
+            reset_p = true;
+        }
+
+        var nil = this.adaptor.isNil(t);
+        if ( !nil ) {
+            this.nodes.push(t); // add this node
+        }
+        // add DOWN node if t has children
+        var n = this.adaptor.getChildCount(t);
+        if ( !nil && n>0 ) {
+            this.addNavigationNode(org.antlr.runtime.Token.DOWN);
+        }
+        // and now add all its children
+        var c, child;
+        for (c=0; c<n; c++) {
+            child = this.adaptor.getChild(t,c);
+            this.fillBuffer(child);
+        }
+        // add UP node if t has children
+        if ( !nil && n>0 ) {
+            this.addNavigationNode(org.antlr.runtime.Token.UP);
+        }
+
+        if (reset_p) {
+            this.p = 0; // buffer of nodes intialized now
+        }
+    },
+
+    getNodeIndex: function(node) {
+        if ( this.p==-1 ) {
+            this.fillBuffer();
+        }
+        var i, t;
+        for (i=0; i<this.nodes.length; i++) {
+            t = this.nodes[i];
+            if ( t===node ) {
+                return i;
+            }
+        }
+        return -1;
+    },
+
+    /** As we flatten the tree, we use UP, DOWN nodes to represent
+     *  the tree structure.  When debugging we need unique nodes
+     *  so instantiate new ones when uniqueNavigationNodes is true.
+     */
+    addNavigationNode: function(ttype) {
+        var navNode = null;
+        if ( ttype===org.antlr.runtime.Token.DOWN ) {
+            if ( this.hasUniqueNavigationNodes() ) {
+                navNode = this.adaptor.create(org.antlr.runtime.Token.DOWN, "DOWN");
+            }
+            else {
+                navNode = this.down;
+            }
+        }
+        else {
+            if ( this.hasUniqueNavigationNodes() ) {
+                navNode = this.adaptor.create(org.antlr.runtime.Token.UP, "UP");
+            }
+            else {
+                navNode = this.up;
+            }
+        }
+        this.nodes.push(navNode);
+    },
+
+    get: function(i) {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        return this.nodes[i];
+    },
+
+    LT: function(k) {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        if ( k===0 ) {
+            return null;
+        }
+        if ( k<0 ) {
+            return this.LB(-1*k);
+        }
+        if ( (this.p+k-1) >= this.nodes.length ) {
+            return this.eof;
+        }
+        return this.nodes[this.p+k-1];
+    },
+
+    getCurrentSymbol: function() { return this.LT(1); },
+
+    /** Look backwards k nodes */
+    LB: function(k) {
+        if ( k===0 ) {
+            return null;
+        }
+        if ( (this.p-k)<0 ) {
+            return null;
+        }
+        return this.nodes[this.p-k];
+    },
+
+    getTreeSource: function() {
+        return this.root;
+    },
+
+    getSourceName: function() {
+        return this.getTokenStream().getSourceName();
+    },
+
+    getTokenStream: function() {
+        return this.tokens;
+    },
+
+    setTokenStream: function(tokens) {
+        this.tokens = tokens;
+    },
+
+    getTreeAdaptor: function() {
+        return this.adaptor;
+    },
+
+    setTreeAdaptor: function(adaptor) {
+        this.adaptor = adaptor;
+    },
+
+    hasUniqueNavigationNodes: function() {
+        return this.uniqueNavigationNodes;
+    },
+
+    setUniqueNavigationNodes: function(uniqueNavigationNodes) {
+        this.uniqueNavigationNodes = uniqueNavigationNodes;
+    },
+
+    consume: function() {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        this.p++;
+    },
+
+    LA: function(i) {
+        return this.adaptor.getType(this.LT(i));
+    },
+
+    mark: function() {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        this.lastMarker = this.index();
+        return this.lastMarker;
+    },
+
+    release: function(marker) {
+        // no resources to release
+    },
+
+    index: function() {
+        return this.p;
+    },
+
+    rewind: function(marker) {
+        if (!org.antlr.lang.isNumber(marker)) {
+            marker = this.lastMarker;
+        }
+        this.seek(marker);
+    },
+
+    seek: function(index) {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        this.p = index;
+    },
+
+    /** Make stream jump to a new location, saving old location.
+     *  Switch back with pop().
+     */
+    push: function(index) {
+        if ( !this.calls ) {
+            this.calls = [];
+        }
+        this.calls.push(this.p); // save current index
+        this.seek(index);
+    },
+
+    /** Seek back to previous index saved during last push() call.
+     *  Return top of stack (return index).
+     */
+    pop: function() {
+        var ret = this.calls.pop();
+        this.seek(ret);
+        return ret;
+    },
+
+    reset: function() {
+        this.p = -1;
+        this.lastMarker = 0;
+        if (this.calls) {
+            this.calls = [];
+        }
+    },
+
+    size: function() {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        return this.nodes.length;
+    },
+
+    iterator: function() {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        return this.StreamIterator();
+    },
+
+    replaceChildren: function(parent, startChildIndex, stopChildIndex, t) {
+        if ( parent ) {
+            this.adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t);
+        }
+    },
+
+    /** Debugging */
+    toTokenString: function(start, stop) {
+        if ( this.p===-1 ) {
+            this.fillBuffer();
+        }
+        var buf='', i, t;
+        for (i = start; i < this.nodes.length && i <= stop; i++) {
+            t = this.nodes[i];
+            buf += " "+this.adaptor.getToken(t);
+        }
+        return buf;
+    },
+
+    /** Used for testing, just return the token type stream */
+    toString: function(start, stop) {
+        var buf = "",
+            text,
+            t,
+            i;
+        if (arguments.length===0) {
+            if ( this.p===-1 ) {
+                this.fillBuffer();
+            }
+            for (i = 0; i < this.nodes.length; i++) {
+                t = this.nodes[i];
+                buf += " ";
+                buf += this.adaptor.getType(t);
+            }
+            return buf;
+        } else {
+            if ( !org.antlr.lang.isNumber(start) || !org.antlr.lang.isNumber(stop) ) {
+                return null;
+            }
+            if ( this.p===-1 ) {
+                this.fillBuffer();
+            }
+            //System.out.println("stop: "+stop);
+            if ( start instanceof org.antlr.runtime.tree.CommonTree ) {
+                //System.out.print("toString: "+((CommonTree)start).getToken()+", ");
+            } else {
+                //System.out.println(start);
+            }
+            if ( stop instanceof org.antlr.runtime.tree.CommonTree ) {
+                //System.out.println(((CommonTree)stop).getToken());
+            } else {
+                //System.out.println(stop);
+            }
+            // if we have the token stream, use that to dump text in order
+            var beginTokenIndex,
+                endTokenIndex;
+            if ( this.tokens ) {
+                beginTokenIndex = this.adaptor.getTokenStartIndex(start);
+                endTokenIndex = this.adaptor.getTokenStopIndex(stop);
+                // if it's a tree, use start/stop index from start node
+                // else use token range from start/stop nodes
+                if ( this.adaptor.getType(stop)===org.antlr.runtime.Token.UP ) {
+                    endTokenIndex = this.adaptor.getTokenStopIndex(start);
+                }
+                else if ( this.adaptor.getType(stop)==org.antlr.runtime.Token.EOF )
+                {
+                    endTokenIndex = this.size()-2; // don't use EOF
+                }
+                return this.tokens.toString(beginTokenIndex, endTokenIndex);
+            }
+            // walk nodes looking for start
+            t = null;
+            i = 0;
+            for (; i < this.nodes.length; i++) {
+                t = this.nodes[i];
+                if ( t===start ) {
+                    break;
+                }
+            }
+            // now walk until we see stop, filling string buffer with text
+            buf = text = "";
+            t = this.nodes[i];
+            while ( t!==stop ) {
+                text = this.adaptor.getText(t);
+                if ( !org.antlr.lang.isString(text) ) {
+                    text = " "+this.adaptor.getType(t).toString();
+                }
+                buf += text;
+                i++;
+                t = nodes[i];
+            }
+            // include stop node too
+            text = this.adaptor.getText(stop);
+            if ( !org.antlr.lang.isString(text) ) {
+                text = " "+this.adaptor.getType(stop).toString();
+            }
+            buf += text;
+            return buf;
+        }
+    }
+});
+/** A generic list of elements tracked in an alternative to be used in
+ *  a -> rewrite rule.  We need to subclass to fill in the next() method,
+ *  which returns either an AST node wrapped around a token payload or
+ *  an existing subtree.
+ *
+ *  Once you start next()ing, do not try to add more elements.  It will
+ *  break the cursor tracking I believe.
+ *
+ *  @see org.antlr.runtime.tree.RewriteRuleSubtreeStream
+ *  @see org.antlr.runtime.tree.RewriteRuleTokenStream
+ *
+ *  TODO: add mechanism to detect/puke on modification after reading from stream
+ */
+org.antlr.runtime.tree.RewriteRuleElementStream = function(adaptor, elementDescription, el) {
+    /** Cursor 0..n-1.  If singleElement!=null, cursor is 0 until you next(),
+     *  which bumps it to 1 meaning no more elements.
+     */
+    this.cursor = 0;
+
+    /** Once a node / subtree has been used in a stream, it must be dup'd
+     *  from then on.  Streams are reset after subrules so that the streams
+     *  can be reused in future subrules.  So, reset must set a dirty bit.
+     *  If dirty, then next() always returns a dup.
+     *
+     *  I wanted to use "naughty bit" here, but couldn't think of a way
+     *  to use "naughty".
+     */
+    this.dirty = false;
+
+    this.elementDescription = elementDescription;
+    this.adaptor = adaptor;
+    if (el) {
+        if (org.antlr.lang.isArray(el)) {
+            this.singleElement = null;
+            this.elements = el;
+        } else {
+            this.add(el);
+        }
+    }
+};
+
+org.antlr.runtime.tree.RewriteRuleElementStream.prototype = {
+    /** Reset the condition of this stream so that it appears we have
+     *  not consumed any of its elements.  Elements themselves are untouched.
+     *  Once we reset the stream, any future use will need duplicates.  Set
+     *  the dirty bit.
+     */
+    reset: function() {
+        this.cursor = 0;
+        this.dirty = true;
+    },
+
+    add: function(el) {
+        if ( !org.antlr.lang.isValue(el) ) {
+            return;
+        }
+        if ( this.elements ) { // if in list, just add
+            this.elements.push(el);
+            return;
+        }
+        if ( !org.antlr.lang.isValue(this.singleElement) ) { // no elements yet, track w/o list
+            this.singleElement = el;
+            return;
+        }
+        // adding 2nd element, move to list
+        this.elements = [];
+        this.elements.push(this.singleElement);
+        this.singleElement = null;
+        this.elements.push(el);
+    },
+
+    /** Return the next element in the stream.  If out of elements, throw
+     *  an exception unless size()==1.  If size is 1, then return elements[0].
+     *  Return a duplicate node/subtree if stream is out of elements and
+     *  size==1.  If we've already used the element, dup (dirty bit set).
+     */
+    nextTree: function() {
+        var n = this.size(),
+            el;
+        if ( this.dirty || (this.cursor>=n && n==1) ) {
+            // if out of elements and size is 1, dup
+            el = this._next();
+            return this.dup(el);
+        }
+        // test size above then fetch
+        el = this._next();
+        return el;
+    },
+
+    /** do the work of getting the next element, making sure that it's
+     *  a tree node or subtree.  Deal with the optimization of single-
+     *  element list versus list of size > 1.  Throw an exception
+     *  if the stream is empty or we're out of elements and size>1.
+     *  protected so you can override in a subclass if necessary.
+     */
+    _next: function() {
+        var n = this.size();
+        if (n===0) {
+            throw new org.antlr.runtime.tree.RewriteEmptyStreamException(this.elementDescription);
+        }
+        if ( this.cursor>= n) { // out of elements?
+            if ( n===1 ) {  // if size is 1, it's ok; return and we'll dup
+                return this.toTree(this.singleElement);
+            }
+            // out of elements and size was not 1, so we can't dup
+            throw new org.antlr.runtime.tree.RewriteCardinalityException(this.elementDescription);
+        }
+        // we have elements
+        if ( org.antlr.lang.isValue(this.singleElement) ) {
+            this.cursor++; // move cursor even for single element list
+            return this.toTree(this.singleElement);
+        }
+        // must have more than one in list, pull from elements
+        var o = this.toTree(this.elements[this.cursor]);
+        this.cursor++;
+        return o;
+    },
+
+    /** Ensure stream emits trees; tokens must be converted to AST nodes.
+     *  AST nodes can be passed through unmolested.
+     */
+    toTree: function(el) {
+        if (el && el.getTree) {
+            return el.getTree();
+        }
+        return el;
+    },
+
+    hasNext: function() {
+         return (org.antlr.lang.isValue(this.singleElement) && this.cursor < 1) ||
+               (this.elements && this.cursor < this.elements.length);
+    },
+
+    size: function() {
+        var n = 0;
+        if ( org.antlr.lang.isValue(this.singleElement) ) {
+            n = 1;
+        }
+        if ( this.elements ) {
+            return this.elements.length;
+        }
+        return n;
+    },
+
+    getDescription: function() {
+        return this.elementDescription;
+    }
+};
+/** Queues up nodes matched on left side of -> in a tree parser. This is
+ *  the analog of RewriteRuleTokenStream for normal parsers. 
+ */
+org.antlr.runtime.tree.RewriteRuleNodeStream = function(adaptor, elementDescription, el) {
+    org.antlr.runtime.tree.RewriteRuleNodeStream.superclass.constructor.apply(this, arguments);
+};
+
+org.antlr.lang.extend(org.antlr.runtime.tree.RewriteRuleNodeStream,
+                  org.antlr.runtime.tree.RewriteRuleElementStream,
+{
+    nextNode: function() {
+        return this._next();
+    },
+
+    toTree: function(el) {
+        return this.adaptor.dupNode(el);
+    },
+
+    dup: function() {
+        // we dup every node, so don't have to worry about calling dup; short-
+        // circuited next() so it doesn't call.
+        throw new Error("dup can't be called for a node stream.");
+    }
+});
+org.antlr.runtime.tree.RewriteRuleTokenStream = function(adaptor, elementDescription, el) {
+    var sup = org.antlr.runtime.tree.RewriteRuleTokenStream.superclass;
+    sup.constructor.apply(this, arguments);
+};
+
+org.antlr.lang.extend(org.antlr.runtime.tree.RewriteRuleTokenStream,
+                  org.antlr.runtime.tree.RewriteRuleElementStream, {
+    /** Get next token from stream and make a node for it */
+    nextNode: function() {
+        var t = this._next();
+        return this.adaptor.create(t);
+    },
+
+    nextToken: function() {
+        return this._next();
+    },
+
+    /** Don't convert to a tree unless they explicitly call nextTree.
+     *  This way we can do hetero tree nodes in rewrite.
+     */
+    toTree: function(el) {
+        return el;
+    },
+
+    dup: function(el) {
+        throw new Error("dup can't be called for a token stream.");
+    }
+});
+org.antlr.runtime.tree.RewriteRuleSubtreeStream = function() {
+    var sup = org.antlr.runtime.tree.RewriteRuleSubtreeStream.superclass;
+    sup.constructor.apply(this, arguments);
+};
+
+org.antlr.lang.extend(org.antlr.runtime.tree.RewriteRuleSubtreeStream,
+                  org.antlr.runtime.tree.RewriteRuleElementStream, {
+	/** Treat next element as a single node even if it's a subtree.
+	 *  This is used instead of next() when the result has to be a
+	 *  tree root node.  Also prevents us from duplicating recently-added
+	 *  children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
+	 *  must dup the type node, but ID has been added.
+	 *
+	 *  Referencing a rule result twice is ok; dup entire tree as
+	 *  we can't be adding trees as root; e.g., expr expr.
+	 *
+	 *  Hideous code duplication here with super.next().  Can't think of
+	 *  a proper way to refactor.  This needs to always call dup node
+	 *  and super.next() doesn't know which to call: dup node or dup tree.
+	 */
+    nextNode: function() {
+		var n = this.size(),
+            el;
+		if ( this.dirty || (this.cursor>=n && n===1) ) {
+			// if out of elements and size is 1, dup (at most a single node
+			// since this is for making root nodes).
+			el = this._next();
+			return this.adaptor.dupNode(el);
+		}
+		// test size above then fetch
+		el = this._next();
+		return el;
+	},
+
+    dup: function(el) {
+		return this.adaptor.dupTree(el);
+	}
+});/** A generic recognizer that can handle recognizers generated from
+ *  lexer, parser, and tree grammars.  This is all the parsing
+ *  support code essentially; most of it is error recovery stuff and
+ *  backtracking.
+ *
+ *  <p>This class should not be instantiated directly.  Instead, use one of its
+ *  subclasses.</p>
+ *
+ *  @class
+ *  @param {org.antlr.runtime.RecognizerSharedState} [state] optional state object
+ *      with which to initialize this recognizer.
+ */
+org.antlr.runtime.BaseRecognizer = function(state) {
+    /** State of a lexer, parser, or tree parser are collected into a state
+     *  object so the state can be shared.  This sharing is needed to
+     *  have one grammar import others and share same error variables
+     *  and other state variables.  It's a kind of explicit multiple
+     *  inheritance via delegation of methods and shared state.
+     */
+    this.state = state || new org.antlr.runtime.RecognizerSharedState();
+};
+
+/* static vars, methods */
+org.antlr.lang.augmentObject(org.antlr.runtime.BaseRecognizer, {
+    MEMO_RULE_FAILED: -2,
+    MEMO_RULE_UNKNOWN: -1,
+    INITIAL_FOLLOW_STACK_SIZE: 100,
+    MEMO_RULE_FAILED_I: -2,
+    DEFAULT_TOKEN_CHANNEL: org.antlr.runtime.Token.DEFAULT_CHANNEL,
+    HIDDEN: org.antlr.runtime.Token.HIDDEN_CHANNEL,
+    NEXT_TOKEN_RULE_NAME: "nextToken"
+});
+
+org.antlr.runtime.BaseRecognizer.prototype = {
+    /** Reset the parser's state.  Subclasses must rewinds the input stream */
+    reset: function() {
+        var i, len;
+
+        // wack everything related to error recovery
+        if (!this.state) {
+            return; // no shared state work to do
+        }
+        this.state._fsp = -1;
+        this.state.errorRecovery = false;
+        this.state.lastErrorIndex = -1;
+        this.state.failed = false;
+        this.state.syntaxErrors = 0;
+        // wack everything related to backtracking and memoization
+        this.state.backtracking = 0;
+        // wipe cache
+        if (this.state.ruleMemo) {
+            for (i=0, len=this.state.ruleMemo.length; i<len; i++) {
+                this.state.ruleMemo[i] = null;
+            }
+        }
+    },
+
+    /** Match current input symbol against ttype.  Attempt
+     *  single token insertion or deletion error recovery.  If
+     *  that fails, throw {@link org.antlr.runtime.MismatchedTokenException}.
+     *
+     *  <p>To turn off single token insertion or deletion error
+     *  recovery, override {@link #mismatchRecover} and have it call
+     *  plain {@link #mismatch}, which does not recover.  Then any error
+     *  in a rule will cause an exception and immediate exit from
+     *  rule.  Rule would recover by resynchronizing to the set of
+     *  symbols that can follow rule ref.</p>
+     *
+     *  @param {org.antlr.runtime.IntStream} input input stream to match against.
+     *  @param {Number} ttype  input type to match.
+     *  @param {org.antlr.runtime.BitSet} [follow] set of tokens that can follow the
+     *      matched token.
+     *  @returns {Object} the matched symbol
+     */
+    match: function(input, ttype, follow) {
+        var matchedSymbol = this.getCurrentInputSymbol(input);
+        if ( input.LA(1)===ttype ) {
+            input.consume();
+            this.state.errorRecovery = false;
+            this.state.failed = false;
+            return matchedSymbol;
+        }
+        if ( this.state.backtracking>0 ) {
+            this.state.failed = true;
+            return matchedSymbol;
+        }
+        matchedSymbol = this.recoverFromMismatchedToken(input, ttype, follow);
+        return matchedSymbol;
+    },
+
+    /**
+     * Match any token.
+     * @param {org.antlr.runtime.IntStream} input input stream to match against.
+     */
+    matchAny: function(input) {
+        this.state.errorRecovery = false;
+        this.state.failed = false;
+        input.consume();
+    },
+
+    /**
+     * Is the following token (LA(2)) the unwanted type (ttype)?
+     * @param {org.antlr.runtime.IntStream} input input stream to match against.
+     * @param {Number} ttype the undesired token type.
+     * @returns {Boolean} true if and only if the following token is the
+     *      unwanted type.
+     */
+    mismatchIsUnwantedToken: function(input, ttype) {
+        return input.LA(2)===ttype;
+    },
+
+    /**
+     * Does the stream appear to be missing a single token?
+     * @param {org.antlr.runtime.IntStream} input input stream to match against.
+     * @param {org.antlr.runtime.BitSet} [follow] set of tokens that can follow the
+     *      matched token.
+     * @returns {Boolean} true if and only if it appears that the stream is
+     *      missing a single token.
+     */
+    mismatchIsMissingToken: function(input, follow) {
+        if ( !follow ) {
+            // we have no information about the follow; we can only consume
+            // a single token and hope for the best
+            return false;
+        }
+        // compute what can follow this grammar element reference
+        if ( follow.member(org.antlr.runtime.Token.EOR_TOKEN_TYPE) ) {
+            if ( this.state._fsp>=0 ) { // remove EOR if we're not the start symbol
+                follow.remove(org.antlr.runtime.Token.EOR_TOKEN_TYPE);
+            }
+            var viableTokensFollowingThisRule = this.computeContextSensitiveRuleFOLLOW();
+            follow = follow.or(this.viableTokensFollowingThisRule);
+        }
+        // if current token is consistent with what could come after set
+        // then we know we're missing a token; error recovery is free to
+        // "insert" the missing token
+
+        // BitSet cannot handle negative numbers like -1 (EOF) so I leave EOR
+        // in follow set to indicate that the fall of the start symbol is
+        // in the set (EOF can follow).
+        if ( follow.member(input.LA(1)) ||
+             follow.member(org.antlr.runtime.Token.EOR_TOKEN_TYPE) )
+        {
+            return true;
+        }
+        return false;
+    },
+
+    /** Factor out what to do upon token mismatch so tree parsers can behave
+     *  differently.  Override and call {@link #mismatchRecover}
+     *  to get single token insertion and deletion.
+     *
+     *  @param {org.antlr.runtime.IntStream} input input stream to match against.
+     *  @param {Number} ttype  input type to match.
+     *  @param {org.antlr.runtime.BitSet} [follow] set of tokens that can follow the
+     *      matched token.
+     */
+    mismatch: function(input, ttype, follow) {
+        if ( this.mismatchIsUnwantedToken(input, ttype) ) {
+            throw new org.antlr.runtime.UnwantedTokenException(ttype, input);
+        } else if ( this.mismatchIsMissingToken(input, follow) ) {
+            throw new org.antlr.runtime.MissingTokenException(ttype, input, null);
+        }
+        throw new org.antlr.runtime.MismatchedTokenException(ttype, input);
+    },
+
+    /** Report a recognition problem.
+     *
+     *  <p>This method sets errorRecovery to indicate the parser is recovering
+     *  not parsing.  Once in recovery mode, no errors are generated.
+     *  To get out of recovery mode, the parser must successfully match
+     *  a token (after a resync).  So it will go:</p>
+     *  <ol>
+     *      <li>error occurs</li>
+     *      <li>enter recovery mode, report error</li>
+     *      <li>consume until token found in resynch set</li>
+     *      <li>try to resume parsing</li>
+     *      <li>next match() will reset errorRecovery mode</li>
+     *  </ol>
+     *
+     *  <p>If you override, make sure to update this.state.syntaxErrors if you
+     *  care about that.</p>
+     *  @param {org.antlr.runtime.RecognitionException} e the error to be reported.
+     */
+    reportError: function(e) {
+        // if we've already reported an error and have not matched a token
+        // yet successfully, don't report any errors.
+        if ( this.state.errorRecovery ) {
+            return;
+        }
+        this.state.syntaxErrors++;
+        this.state.errorRecovery = true;
+
+        this.displayRecognitionError(this.getTokenNames(), e);
+    },
+
+    /**
+     * Assemble recognition error message.
+     * @param {Array} tokenNames array of token names (strings).
+     * @param {org.antlr.runtime.RecognitionException} e the error to be reported.
+     */
+    displayRecognitionError: function(tokenNames, e) {
+        var hdr = this.getErrorHeader(e),
+            msg = this.getErrorMessage(e, tokenNames);
+        this.emitErrorMessage(hdr+" "+msg);
+    },
+
+    /**
+     * Create error header message.  Format is <q>line
+     * lineNumber:positionInLine</q>.
+     * @param {org.antlr.runtime.RecognitionException} e the error to be reported.
+     * @returns {String} The error header.
+     */
+    getErrorHeader: function(e) {
+        /* handle null input */
+        if (!org.antlr.lang.isNumber(e.line)) {
+            e.line = 0;
+        }
+        return "line "+e.line+":"+e.charPositionInLine;
+    },
+
+    /**
+     * Override this method to change where error messages go.
+     * Defaults to "alert"-ing the error in browsers and "print"-ing the error
+     * in other environments (e.g. Rhino, SpiderMonkey).
+     * @param {String} msg the error message to be displayed.
+     */
+    emitErrorMessage: function(msg) {
+        if (typeof(window) != 'undefined' && window.alert) {
+            alert(msg);
+        } else {
+            print(msg);
+        }
+    },
+
+    /** What error message should be generated for the various
+     *  exception types?
+     *
+     *  <p>Not very object-oriented code, but I like having all error message
+     *  generation within one method rather than spread among all of the
+     *  exception classes. This also makes it much easier for the exception
+     *  handling because the exception classes do not have to have pointers back
+     *  to this object to access utility routines and so on. Also, changing
+     *  the message for an exception type would be difficult because you
+     *  would have to be subclassing exceptions, but then somehow get ANTLR
+     *  to make those kinds of exception objects instead of the default.</p>
+     *
+     *  <p>For grammar debugging, you will want to override this to add
+     *  more information such as the stack frame and no viable alts.</p>
+     *
+     *  <p>Override this to change the message generated for one or more
+     *  exception types.</p>
+     *
+     * @param {Array} tokenNames array of token names (strings).
+     * @param {org.antlr.runtime.RecognitionException} e the error to be reported.
+     * @returns {String} the error message to be emitted.
+     */
+    getErrorMessage: function(e, tokenNames) {
+        var msg = (e && e.getMessage) ? e.getMessage() : null,
+            mte,
+            tokenName;
+        if ( e instanceof org.antlr.runtime.UnwantedTokenException ) {
+            var ute = e;
+            tokenName="<unknown>";
+            if ( ute.expecting== org.antlr.runtime.Token.EOF ) {
+                tokenName = "EOF";
+            } else {
+                tokenName = tokenNames[ute.expecting];
+            }
+            msg = "extraneous input "+this.getTokenErrorDisplay(ute.getUnexpectedToken())+
+                " expecting "+tokenName;
+        }
+        else if ( e instanceof org.antlr.runtime.MissingTokenException ) {
+            mte = e;
+            tokenName="<unknown>";
+            if ( mte.expecting== org.antlr.runtime.Token.EOF ) {
+                tokenName = "EOF";
+            } else {
+                tokenName = tokenNames[mte.expecting];
+            }
+            msg = "missing "+tokenName+" at "+this.getTokenErrorDisplay(e.token);
+        }
+        else if ( e instanceof org.antlr.runtime.MismatchedTokenException ) {
+            mte = e;
+            tokenName="<unknown>";
+            if ( mte.expecting== org.antlr.runtime.Token.EOF ) {
+                tokenName = "EOF";
+            }
+            else {
+                tokenName = tokenNames[mte.expecting];
+            }
+            msg = "mismatched input "+this.getTokenErrorDisplay(e.token)+
+                " expecting "+tokenName;
+        }
+        else if ( e instanceof org.antlr.runtime.NoViableAltException ) {
+            msg = "no viable alternative at input "+this.getTokenErrorDisplay(e.token);
+        }
+        else if ( e instanceof org.antlr.runtime.EarlyExitException ) {
+            msg = "required (...)+ loop did not match anything at input "+
+                this.getTokenErrorDisplay(e.token);
+        }
+        else if ( e instanceof org.antlr.runtime.MismatchedSetException ) {
+            msg = "mismatched input "+this.getTokenErrorDisplay(e.token)+
+                " expecting set "+e.expecting;
+        }
+        else if ( e instanceof org.antlr.runtime.MismatchedNotSetException ) {
+            msg = "mismatched input "+this.getTokenErrorDisplay(e.token)+
+                " expecting set "+e.expecting;
+        }
+        else if ( e instanceof org.antlr.runtime.FailedPredicateException ) {
+            msg = "rule "+e.ruleName+" failed predicate: {"+
+                e.predicateText+"}?";
+        }
+        return msg;
+    },
+
+    /** Get number of recognition errors (lexer, parser, tree parser).  Each
+     *  recognizer tracks its own number.  So parser and lexer each have
+     *  separate count.  Does not count the spurious errors found between
+     *  an error and next valid token match
+     *
+     *  See also reportError()
+     */
+    getNumberOfSyntaxErrors: function() {
+        return this.state.syntaxErrors;
+    },
+
+    /** How should a token be displayed in an error message? The default
+     *  is to display just the text, but during development you might
+     *  want to have a lot of information spit out.  Override in that case
+     *  to use t.toString() (which, for CommonToken, dumps everything about
+     *  the token). This is better than forcing you to override a method in
+     *  your token objects because you don't have to go modify your lexer
+     *  so that it creates a new Java type.
+     */
+    getTokenErrorDisplay: function(t) {
+        var s = t.getText();
+        if ( !org.antlr.lang.isValue(s) ) {
+            if ( t.getType()==org.antlr.runtime.Token.EOF ) {
+                s = "<EOF>";
+            }
+            else {
+                s = "<"+t.getType()+">";
+            }
+        }
+        s = s.replace(/\n/g,"\\n");
+        s = s.replace(/\r/g,"\\r");
+        s = s.replace(/\t/g,"\\t");
+        return "'"+s+"'";
+    },
+
+    /** Recover from an error found on the input stream.  This is
+     *  for NoViableAlt and mismatched symbol exceptions.  If you enable
+     *  single token insertion and deletion, this will usually not
+     *  handle mismatched symbol exceptions but there could be a mismatched
+     *  token that the match() routine could not recover from.
+     */
+    recover: function(input, re) {
+        if ( this.state.lastErrorIndex==input.index() ) {
+            // uh oh, another error at same token index; must be a case
+            // where LT(1) is in the recovery token set so nothing is
+            // consumed; consume a single token so at least to prevent
+            // an infinite loop; this is a failsafe.
+            input.consume();
+        }
+        this.state.lastErrorIndex = input.index();
+        var followSet = this.computeErrorRecoverySet();
+        this.beginResync();
+        this.consumeUntil(input, followSet);
+        this.endResync();
+    },
+
+    /** A hook to listen in on the token consumption during error recovery.
+     *  The DebugParser subclasses this to fire events to the listenter.
+     */
+    beginResync: function() {
+    },
+
+    endResync: function() {
+    },
+
+    /*  Compute the error recovery set for the current rule.  During
+     *  rule invocation, the parser pushes the set of tokens that can
+     *  follow that rule reference on the stack; this amounts to
+     *  computing FIRST of what follows the rule reference in the
+     *  enclosing rule. This local follow set only includes tokens
+     *  from within the rule; i.e., the FIRST computation done by
+     *  ANTLR stops at the end of a rule.
+     *
+     *  EXAMPLE
+     *
+     *  When you find a "no viable alt exception", the input is not
+     *  consistent with any of the alternatives for rule r.  The best
+     *  thing to do is to consume tokens until you see something that
+     *  can legally follow a call to r *or* any rule that called r.
+     *  You don't want the exact set of viable next tokens because the
+     *  input might just be missing a token--you might consume the
+     *  rest of the input looking for one of the missing tokens.
+     *
+     *  Consider grammar:
+     *
+     *  a : '[' b ']'
+     *    | '(' b ')'
+     *    ;
+     *  b : c '^' INT ;
+     *  c : ID
+     *    | INT
+     *    ;
+     *
+     *  At each rule invocation, the set of tokens that could follow
+     *  that rule is pushed on a stack.  Here are the various "local"
+     *  follow sets:
+     *
+     *  FOLLOW(b1_in_a) = FIRST(']') = ']'
+     *  FOLLOW(b2_in_a) = FIRST(')') = ')'
+     *  FOLLOW(c_in_b) = FIRST('^') = '^'
+     *
+     *  Upon erroneous input "[]", the call chain is
+     *
+     *  a -> b -> c
+     *
+     *  and, hence, the follow context stack is:
+     *
+     *  depth  local follow set     after call to rule
+     *    0         <EOF>                    a (from main())
+     *    1          ']'                     b
+     *    3          '^'                     c
+     *
+     *  Notice that ')' is not included, because b would have to have
+     *  been called from a different context in rule a for ')' to be
+     *  included.
+     *
+     *  For error recovery, we cannot consider FOLLOW(c)
+     *  (context-sensitive or otherwise).  We need the combined set of
+     *  all context-sensitive FOLLOW sets--the set of all tokens that
+     *  could follow any reference in the call chain.  We need to
+     *  resync to one of those tokens.  Note that FOLLOW(c)='^' and if
+     *  we resync'd to that token, we'd consume until EOF.  We need to
+     *  sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.
+     *  In this case, for input "[]", LA(1) is in this set so we would
+     *  not consume anything and after printing an error rule c would
+     *  return normally.  It would not find the required '^' though.
+     *  At this point, it gets a mismatched token error and throws an
+     *  exception (since LA(1) is not in the viable following token
+     *  set).  The rule exception handler tries to recover, but finds
+     *  the same recovery set and doesn't consume anything.  Rule b
+     *  exits normally returning to rule a.  Now it finds the ']' (and
+     *  with the successful match exits errorRecovery mode).
+     *
+     *  So, you cna see that the parser walks up call chain looking
+     *  for the token that was a member of the recovery set.
+     *
+     *  Errors are not generated in errorRecovery mode.
+     *
+     *  ANTLR's error recovery mechanism is based upon original ideas:
+     *
+     *  "Algorithms + Data Structures = Programs" by Niklaus Wirth
+     *
+     *  and
+     *
+     *  "A note on error recovery in recursive descent parsers":
+     *  http://portal.acm.org/citation.cfm?id=947902.947905
+     *
+     *  Later, Josef Grosch had some good ideas:
+     *
+     *  "Efficient and Comfortable Error Recovery in Recursive Descent
+     *  Parsers":
+     *  ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip
+     *
+     *  Like Grosch I implemented local FOLLOW sets that are combined
+     *  at run-time upon error to avoid overhead during parsing.
+     */
+    computeErrorRecoverySet: function() {
+        return this.combineFollows(false);
+    },
+
+
+    /** Compute the context-sensitive FOLLOW set for current rule.
+     *  This is set of token types that can follow a specific rule
+     *  reference given a specific call chain.  You get the set of
+     *  viable tokens that can possibly come next (lookahead depth 1)
+     *  given the current call chain.  Contrast this with the
+     *  definition of plain FOLLOW for rule r:
+     *
+     *   FOLLOW(r)={x | S=>*alpha r beta in G and x in FIRST(beta)}
+     *
+     *  where x in T* and alpha, beta in V*; T is set of terminals and
+     *  V is the set of terminals and nonterminals.  In other words,
+     *  FOLLOW(r) is the set of all tokens that can possibly follow
+     *  references to r in *any* sentential form (context).  At
+     *  runtime, however, we know precisely which context applies as
+     *  we have the call chain.  We may compute the exact (rather
+     *  than covering superset) set of following tokens.
+     *
+     *  For example, consider grammar:
+     *
+     *  stat : ID '=' expr ';'      // FOLLOW(stat)=={EOF}
+     *       | "return" expr '.'
+     *       ;
+     *  expr : atom ('+' atom)* ;   // FOLLOW(expr)=={';','.',')'}
+     *  atom : INT                  // FOLLOW(atom)=={'+',')',';','.'}
+     *       | '(' expr ')'
+     *       ;
+     *
+     *  The FOLLOW sets are all inclusive whereas context-sensitive
+     *  FOLLOW sets are precisely what could follow a rule reference.
+     *  For input input "i=(3);", here is the derivation:
+     *
+     *  stat => ID '=' expr ';'
+     *       => ID '=' atom ('+' atom)* ';'
+     *       => ID '=' '(' expr ')' ('+' atom)* ';'
+     *       => ID '=' '(' atom ')' ('+' atom)* ';'
+     *       => ID '=' '(' INT ')' ('+' atom)* ';'
+     *       => ID '=' '(' INT ')' ';'
+     *
+     *  At the "3" token, you'd have a call chain of
+     *
+     *    stat -> expr -> atom -> expr -> atom
+     *
+     *  What can follow that specific nested ref to atom?  Exactly ')'
+     *  as you can see by looking at the derivation of this specific
+     *  input.  Contrast this with the FOLLOW(atom)={'+',')',';','.'}.
+     *
+     *  You want the exact viable token set when recovering from a
+     *  token mismatch.  Upon token mismatch, if LA(1) is member of
+     *  the viable next token set, then you know there is most likely
+     *  a missing token in the input stream.  "Insert" one by just not
+     *  throwing an exception.
+     */
+    computeContextSensitiveRuleFOLLOW: function() {
+        return this.combineFollows(true);
+    },
+
+    combineFollows: function(exact) {
+        var top = this.state._fsp,
+            i,
+            localFollowSet,
+            followSet = new org.antlr.runtime.BitSet();
+        for (i=top; i>=0; i--) {
+            localFollowSet = this.state.following[i];
+            followSet.orInPlace(localFollowSet);
+            if ( exact ) {
+                // can we see end of rule?
+                if ( localFollowSet.member(org.antlr.runtime.Token.EOR_TOKEN_TYPE) )
+                {
+                    // Only leave EOR in set if at top (start rule); this lets
+                    // us know if have to include follow(start rule); i.e., EOF
+                    if ( i>0 ) {
+                        followSet.remove(org.antlr.runtime.Token.EOR_TOKEN_TYPE);
+                    }
+                }
+                else { // can't see end of rule, quit
+                    break;
+                }
+            }
+        }
+        return followSet;
+    },
+
+    /** Attempt to recover from a single missing or extra token.
+     *
+     *  EXTRA TOKEN
+     *
+     *  LA(1) is not what we are looking for.  If LA(2) has the right token,
+     *  however, then assume LA(1) is some extra spurious token.  Delete it
+     *  and LA(2) as if we were doing a normal match(), which advances the
+     *  input.
+     *
+     *  MISSING TOKEN
+     *
+     *  If current token is consistent with what could come after
+     *  ttype then it is ok to "insert" the missing token, else throw
+     *  exception For example, Input "i=(3;" is clearly missing the
+     *  ')'.  When the parser returns from the nested call to expr, it
+     *  will have call chain:
+     *
+     *    stat -> expr -> atom
+     *
+     *  and it will be trying to match the ')' at this point in the
+     *  derivation:
+     *
+     *       => ID '=' '(' INT ')' ('+' atom)* ';'
+     *                          ^
+     *  match() will see that ';' doesn't match ')' and report a
+     *  mismatched token error.  To recover, it sees that LA(1)==';'
+     *  is in the set of tokens that can follow the ')' token
+     *  reference in rule atom.  It can assume that you forgot the ')'.
+     */
+    recoverFromMismatchedToken: function(input,
+                                         ttype,
+                                         follow)
+    {
+        var e = null;
+        // if next token is what we are looking for then "delete" this token
+        if ( this.mismatchIsUnwantedToken(input, ttype) ) {
+            e = new org.antlr.runtime.UnwantedTokenException(ttype, input);
+            this.beginResync();
+            input.consume(); // simply delete extra token
+            this.endResync();
+            this.reportError(e);  // report after consuming so AW sees the token in the exception
+            // we want to return the token we're actually matching
+            var matchedSymbol = this.getCurrentInputSymbol(input);
+            input.consume(); // move past ttype token as if all were ok
+            return matchedSymbol;
+        }
+        // can't recover with single token deletion, try insertion
+        if ( this.mismatchIsMissingToken(input, follow) ) {
+            var inserted = this.getMissingSymbol(input, e, ttype, follow);
+            e = new org.antlr.runtime.MissingTokenException(ttype, input, inserted);
+            this.reportError(e);  // report after inserting so AW sees the token in the exception
+            return inserted;
+        }
+        // even that didn't work; must throw the exception
+        e = new org.antlr.runtime.MismatchedTokenException(ttype, input);
+        throw e;
+    },
+
+    recoverFromMismatchedSet: function(input,
+                                       e,
+                                       follow)
+    {
+        if ( this.mismatchIsMissingToken(input, follow) ) {
+            // System.out.println("missing token");
+            this.reportError(e);
+            // we don't know how to conjure up a token for sets yet
+            return this.getMissingSymbol(input, e, org.antlr.runtime.Token.INVALID_TOKEN_TYPE, follow);
+        }
+        throw e;
+    },
+
+    /** Match needs to return the current input symbol, which gets put
+     *  into the label for the associated token ref; e.g., x=ID.  Token
+     *  and tree parsers need to return different objects. Rather than test
+     *  for input stream type or change the IntStream interface, I use
+     *  a simple method to ask the recognizer to tell me what the current
+     *  input symbol is.
+     * 
+     *  This is ignored for lexers.
+     */
+    getCurrentInputSymbol: function(input) { return null; },
+
+    /** Conjure up a missing token during error recovery.
+     *
+     *  The recognizer attempts to recover from single missing
+     *  symbols. But, actions might refer to that missing symbol.
+     *  For example, x=ID {f($x);}. The action clearly assumes
+     *  that there has been an identifier matched previously and that
+     *  $x points at that token. If that token is missing, but
+     *  the next token in the stream is what we want we assume that
+     *  this token is missing and we keep going. Because we
+     *  have to return some token to replace the missing token,
+     *  we have to conjure one up. This method gives the user control
+     *  over the tokens returned for missing tokens. Mostly,
+     *  you will want to create something special for identifier
+     *  tokens. For literals such as '{' and ',', the default
+     *  action in the parser or tree parser works. It simply creates
+     *  a CommonToken of the appropriate type. The text will be the token.
+     *  If you change what tokens must be created by the lexer,
+     *  override this method to create the appropriate tokens.
+     */
+    getMissingSymbol: function(input,
+                               e,
+                               expectedTokenType,
+                               follow)
+    {
+        return null;
+    },
+
+
+    /** Consume tokens until one matches the given token set */
+    consumeUntil: function(input, set) {
+        var ttype = input.LA(1);
+        while (ttype != org.antlr.runtime.Token.EOF && !set.member(ttype) ) {
+            input.consume();
+            ttype = input.LA(1);
+        }
+    },
+
+    /** Push a rule's follow set using our own hardcoded stack */
+    pushFollow: function(fset) {
+        if ( (this.state._fsp +1)>=this.state.following.length ) {
+            var f = [];
+            var i;
+            for (i=this.state.following.length-1; i>=0; i--) {
+                f[i] = this.state.following[i];
+            }
+            this.state.following = f;
+        }
+        this.state._fsp++;
+        this.state.following[this.state._fsp] = fset;
+    },
+
+    /** Return List<String> of the rules in your parser instance
+     *  leading up to a call to this method.  You could override if
+     *  you want more details such as the file/line info of where
+     *  in the parser java code a rule is invoked.
+     *
+     *  This is very useful for error messages and for context-sensitive
+     *  error recovery.
+     *
+     *  A more general version of getRuleInvocationStack where you can
+     *  pass in, for example, a RecognitionException to get it's rule
+     *  stack trace.  This routine is shared with all recognizers, hence,
+     *  static.
+     *
+     *  TODO: move to a utility class or something; weird having lexer call this
+     *
+     *  Most JS interpreters can't do real stack reflection.  See this
+     *  spidermonkey bug, for example:
+     *  https://bugzilla.mozilla.org/show_bug.cgi?id=332104
+     *
+     *  JS is supposed to get real stack traces in v4, at which time it would
+     *  be easy to implement this function.
+     *
+     *  Until then I'll leave this unimplemented.  If there is enough clamor
+     *  it would be possible to keep track of the invocation stack using an
+     *  auxillary array, but that will definitely be a performance hit.
+     */
+    getRuleInvocationStack: function(e, recognizerClassName)
+    {
+        throw new Error("Not implemented.");
+    },
+
+    getBacktrackingLevel: function() {
+        return this.state.backtracking;
+    },
+
+    /** Used to print out token names like ID during debugging and
+     *  error reporting.  The generated parsers implement a method
+     *  that overrides this to point to their String[] tokenNames.
+     */
+    getTokenNames: function() {
+        return null;
+    },
+
+    /** For debugging and other purposes, might want the grammar name.
+     *  Have ANTLR generate an implementation for this method.
+     */
+    getGrammarFileName: function() {
+        return null;
+    },
+
+    /** A convenience method for use most often with template rewrites.
+     *  Convert a List<Token> to List<String>
+     */
+    toStrings: function(tokens) {
+        if ( !tokens ) {
+            return null;
+        }
+        var strings = [];
+        var i;
+        for (i=0; i<tokens.length; i++) {
+            strings.push(tokens[i].getText());
+        }
+        return strings;
+    },
+
+    /** Given a rule number and a start token index number, return
+     *  MEMO_RULE_UNKNOWN if the rule has not parsed input starting from
+     *  start index.  If this rule has parsed input starting from the
+     *  start index before, then return where the rule stopped parsing.
+     *  It returns the index of the last token matched by the rule.
+     *
+     *  For now we use a hashtable and just the slow Object-based one.
+     *  Later, we can make a special one for ints and also one that
+     *  tosses out data after we commit past input position i.
+     */
+    getRuleMemoization: function(ruleIndex, ruleStartIndex) {
+        if ( !this.state.ruleMemo[ruleIndex] ) {
+            this.state.ruleMemo[ruleIndex] = {};
+        }
+        var stopIndexI =
+            this.state.ruleMemo[ruleIndex][ruleStartIndex];
+        if ( !org.antlr.lang.isNumber(stopIndexI) ) {
+            return org.antlr.runtime.BaseRecognizer.MEMO_RULE_UNKNOWN;
+        }
+        return stopIndexI;
+    },
+
+    /** Has this rule already parsed input at the current index in the
+     *  input stream?  Return the stop token index or MEMO_RULE_UNKNOWN.
+     *  If we attempted but failed to parse properly before, return
+     *  MEMO_RULE_FAILED.
+     *
+     *  This method has a side-effect: if we have seen this input for
+     *  this rule and successfully parsed before, then seek ahead to
+     *  1 past the stop token matched for this rule last time.
+     */
+    alreadyParsedRule: function(input, ruleIndex) {
+        var stopIndex = this.getRuleMemoization(ruleIndex, input.index());
+        if ( stopIndex==org.antlr.runtime.BaseRecognizer.MEMO_RULE_UNKNOWN ) {
+            return false;
+        }
+        if ( stopIndex==org.antlr.runtime.BaseRecognizer.MEMO_RULE_FAILED ) {
+            //System.out.println("rule "+ruleIndex+" will never succeed");
+            this.state.failed=true;
+        }
+        else {
+            input.seek(stopIndex+1); // jump to one past stop token
+        }
+        return true;
+    },
+
+    /** Record whether or not this rule parsed the input at this position
+     *  successfully.  Use a standard java hashtable for now.
+     */
+    memoize: function(input,
+                      ruleIndex,
+                      ruleStartIndex)
+    {
+        var stopTokenIndex = this.state.failed ? 
+            org.antlr.runtime.BaseRecognizer.MEMO_RULE_FAILED : input.index()-1;
+        if ( !org.antlr.lang.isValue(this.state.ruleMemo) ) {
+            throw new Error("!!!!!!!!! memo array is null for "+ this.getGrammarFileName());
+        }
+        if ( ruleIndex >= this.state.ruleMemo.length ) {
+            throw new Error("!!!!!!!!! memo size is "+this.state.ruleMemo.length+", but rule index is "+ruleIndex);
+        }
+        if ( org.antlr.lang.isValue(this.state.ruleMemo[ruleIndex]) ) {
+            this.state.ruleMemo[ruleIndex][ruleStartIndex] = stopTokenIndex;
+        }
+    },
+
+    /** return how many rule/input-index pairs there are in total.
+     *  TODO: this includes synpreds.
+     */
+    getRuleMemoizationCacheSize: function() {
+        var n = 0, i;
+        for (i = 0; this.state.ruleMemo && i < this.state.ruleMemo.length; i++) {
+            var ruleMap = this.state.ruleMemo[i];
+            if ( ruleMap ) {
+                // @todo need to get size of rulemap?
+                n += ruleMap.length; // how many input indexes are recorded?
+            }
+        }
+        return n;
+    },
+
+    traceIn: function(ruleName, ruleIndex, inputSymbol)  {
+        this.emitErrorMessage("enter "+ruleName+" "+inputSymbol);
+        if ( this.state.failed ) {
+            this.emitErrorMessage(" failed="+this.failed);
+        }
+        if ( this.state.backtracking>0 ) {
+            this.emitErrorMessage(" backtracking="+this.state.backtracking);
+        }
+        // System.out.println();
+    },
+
+    traceOut: function(ruleName, ruleIndex, inputSymbol) {
+        this.emitErrorMessage("exit "+ruleName+" "+inputSymbol);
+        if ( this.state.failed ) {
+            this.emitErrorMessage(" failed="+this.state.failed);
+        }
+        if ( this.state.backtracking>0 ) {
+            this.emitErrorMessage(" backtracking="+this.state.backtracking);
+        }
+    }
+};
+/** A lexer is recognizer that draws input symbols from a character stream.
+ *  lexer grammars result in a subclass of this object. A Lexer object
+ *  uses simplified match() and error recovery mechanisms in the interest
+ *  of speed.
+ */
+org.antlr.runtime.Lexer = function(input, state) {
+    if (state) {
+        org.antlr.runtime.Lexer.superclass.constructor.call(this, state);
+    }
+    if (input) {
+        this.input = input;
+    }
+};
+
+org.antlr.lang.extend(org.antlr.runtime.Lexer, org.antlr.runtime.BaseRecognizer, {
+    reset: function() {
+        // reset all recognizer state variables
+        org.antlr.runtime.Lexer.superclass.reset.call(this);
+        if ( org.antlr.lang.isValue(this.input) ) {
+            this.input.seek(0); // rewind the input
+        }
+        if ( !org.antlr.lang.isValue(this.state) ) {
+            return; // no shared state work to do
+        }
+        this.state.token = null;
+        this.state.type = org.antlr.runtime.Token.INVALID_TOKEN_TYPE;
+        this.state.channel = org.antlr.runtime.Token.DEFAULT_CHANNEL;
+        this.state.tokenStartCharIndex = -1;
+        this.state.tokenStartCharPositionInLine = -1;
+        this.state.tokenStartLine = -1;
+        this.state.text = null;
+    },
+
+    /** Return a token from this source; i.e., match a token on the char
+     *  stream.
+     */
+    nextToken: function() {
+        while (true) {
+            this.state.token = null;
+            this.state.channel = org.antlr.runtime.Token.DEFAULT_CHANNEL;
+            this.state.tokenStartCharIndex = this.input.index();
+            this.state.tokenStartCharPositionInLine = this.input.getCharPositionInLine();
+            this.state.tokenStartLine = this.input.getLine();
+            this.state.text = null;
+            if ( this.input.LA(1)===org.antlr.runtime.CharStream.EOF ) {
+                return org.antlr.runtime.Token.EOF_TOKEN;
+            }
+            try {
+                this.mTokens();
+                if ( !org.antlr.lang.isValue(this.state.token) ) {
+                    this.emit();
+                }
+                else if ( this.state.token==org.antlr.runtime.Token.SKIP_TOKEN ) {
+                    continue;
+                }
+                return this.state.token;
+            }
+            catch (re) {
+                if ( re instanceof org.antlr.runtime.RecognitionException ) {
+                    this.reportError(re);
+                } else if (re instanceof org.antlr.runtime.NoViableAltException) {
+                    this.reportError(re);
+                    this.recover(re);
+                } else {
+                    throw re;
+                }
+            }
+        }
+    },
+
+    /** Instruct the lexer to skip creating a token for current lexer rule
+     *  and look for another token.  nextToken() knows to keep looking when
+     *  a lexer rule finishes with token set to SKIP_TOKEN.  Recall that
+     *  if token==null at end of any token rule, it creates one for you
+     *  and emits it.
+     */
+    skip: function() {
+        this.state.token = org.antlr.runtime.Token.SKIP_TOKEN;
+    },
+
+    /** Set the char stream and reset the lexer */
+    setCharStream: function(input) {
+        this.input = null;
+        this.reset();
+        this.input = input;
+    },
+
+    getCharStream: function() {
+        return this.input;
+    },
+
+    getSourceName: function() {
+        return this.input.getSourceName();
+    },
+
+    /** Currently does not support multiple emits per nextToken invocation
+     *  for efficiency reasons.  Subclass and override this method and
+     *  nextToken (to push tokens into a list and pull from that list rather
+     *  than a single variable as this implementation does).
+     *
+     *  The standard method called to automatically emit a token at the
+     *  outermost lexical rule.  The token object should point into the
+     *  char buffer start..stop.  If there is a text override in 'text',
+     *  use that to set the token's text.  Override this method to emit
+     *  custom Token objects.
+     *
+     *  If you are building trees, then you should also override
+     *  Parser or TreeParser.getMissingSymbol().
+     */
+    emit: function() {
+        if (arguments.length===0) {
+            var t = new org.antlr.runtime.CommonToken(this.input, this.state.type, this.state.channel, this.state.tokenStartCharIndex, this.getCharIndex()-1);
+            t.setLine(this.state.tokenStartLine);
+            t.setText(this.state.text);
+            t.setCharPositionInLine(this.state.tokenStartCharPositionInLine);
+            this.state.token = t;
+            return t;
+        } else {
+            this.state.token = arguments[0];
+        }
+    },
+
+    match: function(s) {
+        var i = 0,
+            mte;
+
+        if (org.antlr.lang.isString(s)) {
+            while ( i<s.length ) {
+                if ( this.input.LA(1)!=s.charAt(i) ) {
+                    if ( this.state.backtracking>0 ) {
+                        this.state.failed = true;
+                        return;
+                    }
+                    mte = new org.antlr.runtime.MismatchedTokenException(s.charAt(i), this.input);
+                    this.recover(mte);
+                    throw mte;
+                }
+                i++;
+                this.input.consume();
+                this.state.failed = false;
+            }
+        } else if (org.antlr.lang.isNumber(s)) {
+            if ( this.input.LA(1)!=s ) {
+                if ( this.state.backtracking>0 ) {
+                    this.state.failed = true;
+                    return;
+                }
+                mte = new org.antlr.runtime.MismatchedTokenException(s, this.input);
+                this.recover(mte);
+                throw mte;
+            }
+            this.input.consume();
+            this.state.failed = false;
+        }
+    },
+
+    matchAny: function() {
+        this.input.consume();
+    },
+
+    matchRange: function(a, b) {
+        if ( this.input.LA(1)<a || this.input.LA(1)>b ) {
+            if ( this.state.backtracking>0 ) {
+                this.state.failed = true;
+                return;
+            }
+            mre = new org.antlr.runtime.MismatchedRangeException(a,b,this.input);
+            this.recover(mre);
+            throw mre;
+        }
+        this.input.consume();
+        this.state.failed = false;
+    },
+
+    getLine: function() {
+        return this.input.getLine();
+    },
+
+    getCharPositionInLine: function() {
+        return this.input.getCharPositionInLine();
+    },
+
+    /** What is the index of the current character of lookahead? */
+    getCharIndex: function() {
+        return this.input.index();
+    },
+
+    /** Return the text matched so far for the current token or any
+     *  text override.
+     */
+    getText: function() {
+        if ( org.antlr.lang.isString(this.state.text) ) {
+            return this.state.text;
+        }
+        return this.input.substring(this.state.tokenStartCharIndex,this.getCharIndex()-1);
+    },
+
+    /** Set the complete text of this token; it wipes any previous
+     *  changes to the text.
+     */
+    setText: function(text) {
+        this.state.text = text;
+    },
+
+    reportError: function(e) {
+        /** TODO: not thought about recovery in lexer yet.
+         *
+        // if we've already reported an error and have not matched a token
+        // yet successfully, don't report any errors.
+        if ( errorRecovery ) {
+            //System.err.print("[SPURIOUS] ");
+            return;
+        }
+        errorRecovery = true;
+         */
+
+        this.displayRecognitionError(this.getTokenNames(), e);
+    },
+
+    getErrorMessage: function(e, tokenNames) {
+        var msg = null;
+        if ( e instanceof org.antlr.runtime.MismatchedTokenException ) {
+            msg = "mismatched character "+this.getCharErrorDisplay(e.c)+" expecting "+this.getCharErrorDisplay(e.expecting);
+        }
+        else if ( e instanceof org.antlr.runtime.NoViableAltException ) {
+            msg = "no viable alternative at character "+this.getCharErrorDisplay(e.c);
+        }
+        else if ( e instanceof org.antlr.runtime.EarlyExitException ) {
+            msg = "required (...)+ loop did not match anything at character "+this.getCharErrorDisplay(e.c);
+        }
+        else if ( e instanceof org.antlr.runtime.MismatchedNotSetException ) {
+            msg = "mismatched character "+this.getCharErrorDisplay(e.c)+" expecting set "+e.expecting;
+        }
+        else if ( e instanceof org.antlr.runtime.MismatchedSetException ) {
+            msg = "mismatched character "+this.getCharErrorDisplay(e.c)+" expecting set "+e.expecting;
+        }
+        else if ( e instanceof org.antlr.runtime.MismatchedRangeException ) {
+            msg = "mismatched character "+this.getCharErrorDisplay(e.c)+" expecting set "+
+                this.getCharErrorDisplay(e.a)+".."+this.getCharErrorDisplay(e.b);
+        }
+        else {
+            msg = org.antlr.runtime.Lexer.superclass.getErrorMessage.call(this, e, tokenNames);
+        }
+        return msg;
+    },
+
+    getCharErrorDisplay: function(c) {
+        var s = c; //String.fromCharCode(c);
+        switch ( s ) {
+            case org.antlr.runtime.Token.EOF :
+                s = "<EOF>";
+                break;
+            case "\n" :
+                s = "\\n";
+                break;
+            case "\t" :
+                s = "\\t";
+                break;
+            case "\r" :
+                s = "\\r";
+                break;
+        }
+        return "'"+s+"'";
+    },
+
+    /** Lexers can normally match any char in it's vocabulary after matching
+     *  a token, so do the easy thing and just kill a character and hope
+     *  it all works out.  You can instead use the rule invocation stack
+     *  to do sophisticated error recovery if you are in a fragment rule.
+     */
+    recover: function(re) {
+        this.input.consume();
+    },
+
+    traceIn: function(ruleName, ruleIndex)  {
+        var inputSymbol = String.fromCharCode(this.input.LT(1))+" line="+this.getLine()+":"+this.getCharPositionInLine();
+        org.antlr.runtime.Lexer.superclass.traceIn.call(this, ruleName, ruleIndex, inputSymbol);
+    },
+
+    traceOut: function(ruleName, ruleIndex)  {
+		var inputSymbol = String.fromCharCode(this.input.LT(1))+" line="+this.getLine()+":"+this.getCharPositionInLine();
+		org.antlr.runtime.Lexer.superclass.traceOut.call(this, ruleName, ruleIndex, inputSymbol);
+	}
+});
+/** Rules that return more than a single value must return an object
+ *  containing all the values.  Besides the properties defined in
+ *  RuleLabelScope.predefinedRulePropertiesScope there may be user-defined
+ *  return values.  This class simply defines the minimum properties that
+ *  are always defined and methods to access the others that might be
+ *  available depending on output option such as template and tree.
+ *
+ *  Note text is not an actual property of the return value, it is computed
+ *  from start and stop using the input stream's toString() method.  I
+ *  could add a ctor to this so that we can pass in and store the input
+ *  stream, but I'm not sure we want to do that.  It would seem to be undefined
+ *  to get the .text property anyway if the rule matches tokens from multiple
+ *  input streams.
+ *
+ *  I do not use getters for fields of objects that are used simply to
+ *  group values such as this aggregate.  The getters/setters are there to
+ *  satisfy the superclass interface.
+ */
+org.antlr.runtime.ParserRuleReturnScope = function() {};
+
+org.antlr.runtime.ParserRuleReturnScope.prototype = {
+    getStart: function() { return this.start; },
+    getStop: function() { return this.stop; }
+};
+/** This is identical to the ParserRuleReturnScope except that
+ *  the start property is a tree nodes not Token object
+ *  when you are parsing trees.  To be generic the tree node types
+ *  have to be Object.
+ */
+org.antlr.runtime.tree.TreeRuleReturnScope = function(){};
+
+org.antlr.runtime.tree.TreeRuleReturnScope.prototype = {
+    getStart: function() { return this.start; }
+};
+/** A parser for TokenStreams.  "parser grammars" result in a subclass
+ *  of this.
+ */
+org.antlr.runtime.Parser = function(input, state) {
+    org.antlr.runtime.Parser.superclass.constructor.call(this, state);
+    this.setTokenStream(input);
+};
+
+org.antlr.lang.extend(org.antlr.runtime.Parser, org.antlr.runtime.BaseRecognizer, {
+    reset: function() {
+        // reset all recognizer state variables
+		org.antlr.runtime.Parser.superclass.reset.call(this);
+		if ( org.antlr.lang.isValue(this.input) ) {
+			this.input.seek(0); // rewind the input
+		}
+	},
+
+    getCurrentInputSymbol: function(input) {
+        return input.LT(1);
+    },
+
+    getMissingSymbol: function(input,
+                               e,
+                               expectedTokenType,
+                               follow)
+    {
+        var tokenText =
+            "<missing "+this.getTokenNames()[expectedTokenType]+">";
+        var t = new org.antlr.runtime.CommonToken(expectedTokenType, tokenText);
+        var current = input.LT(1);
+        var old_current;
+        if ( current.getType() === org.antlr.runtime.Token.EOF ) {
+            old_current = current;
+            current = input.LT(-1);
+            // handle edge case where there are no good tokens in the stream
+            if (!current) {
+                current = old_current;
+            }
+        }
+        t.line = current.getLine();
+        t.charPositionInLine = current.getCharPositionInLine();
+        t.channel = org.antlr.runtime.BaseRecognizer.DEFAULT_TOKEN_CHANNEL;
+        return t;
+    },
+
+
+	/** Set the token stream and reset the parser */
+    setTokenStream: function(input) {
+		this.input = null;
+		this.reset();
+		this.input = input;
+	},
+
+    getTokenStream: function() {
+		return this.input;
+	},
+
+    getSourceName: function() {
+        return this.input.getSourceName();
+    },
+
+    traceIn: function(ruleName, ruleIndex)  {
+		org.antlr.runtime.Parser.superclass.traceIn.call(
+                this, ruleName, ruleIndex, this.input.LT(1));
+	},
+
+    traceOut: function(ruleName, ruleIndex)  {
+		org.antlr.runtime.Parser.superclass.traceOut.call(
+                this, ruleName, ruleIndex, this.input.LT(1));
+	}
+});
+/** A DFA implemented as a set of transition tables.
+ *
+ *  Any state that has a semantic predicate edge is special; those states
+ *  are generated with if-then-else structures in a specialStateTransition()
+ *  which is generated by cyclicDFA template.
+ *
+ *  There are at most 32767 states (16-bit signed short).
+ *  Could get away with byte sometimes but would have to generate different
+ *  types and the simulation code too.  For a point of reference, the Java
+ *  lexer's Tokens rule DFA has 326 states roughly.
+ */
+org.antlr.runtime.DFA = function() {};
+
+org.antlr.runtime.DFA.prototype = {
+    /** From the input stream, predict what alternative will succeed
+     *  using this DFA (representing the covering regular approximation
+     *  to the underlying CFL).  Return an alternative number 1..n.  Throw
+     *  an exception upon error.
+     */
+    predict: function(input) {
+        var mark = input.mark(), // remember where decision started in input
+            s = 0, // we always start at s0
+            specialState,
+            c,
+            snext;
+
+        try {
+            while ( true ) {
+                specialState = this.special[s];
+                if ( specialState>=0 ) {
+                    s = this.specialStateTransition(specialState,input);
+                    if (s===-1) {
+                        this.noViableAlt(s, input);
+                        return 0;
+                    }
+                    input.consume();
+                    continue;
+                }
+                if ( this.accept[s] >= 1 ) {
+                    return this.accept[s];
+                }
+                // look for a normal char transition
+                c = input.LA(1); // -1 == \uFFFF, all tokens fit in 65000 space
+
+                if (c===org.antlr.runtime.Token.EOF) {
+                    c = -1;
+                } else if (org.antlr.lang.isString(c)) {
+                    c = c.charCodeAt(0);
+                }
+
+                if (c>=this.min[s] && c<=this.max[s]) {
+                    snext = this.transition[s][c-this.min[s]]; // move to next state
+                    if ( snext < 0 ) {
+                        // was in range but not a normal transition
+                        // must check EOT, which is like the else clause.
+                        // eot[s]>=0 indicates that an EOT edge goes to another
+                        // state.
+                        if ( this.eot[s]>=0 ) {  // EOT Transition to accept state?
+                            s = this.eot[s];
+                            input.consume();
+                            // TODO: I had this as return accept[eot[s]]
+                            // which assumed here that the EOT edge always
+                            // went to an accept...faster to do this, but
+                            // what about predicated edges coming from EOT
+                            // target?
+                            continue;
+                        }
+                        this.noViableAlt(s,input);
+                        return 0;
+                    }
+                    s = snext;
+                    input.consume();
+                    continue;
+                }
+                if ( this.eot[s]>=0 ) {  // EOT Transition?
+                    s = this.eot[s];
+                    input.consume();
+                    continue;
+                }
+                if ( c==org.antlr.runtime.Token.EOF && this.eof[s]>=0 ) {  // EOF Transition to accept state?
+                    return this.accept[this.eof[s]];
+                }
+                // not in range and not EOF/EOT, must be invalid symbol
+                this.noViableAlt(s,input);
+                return 0;
+            }
+        }
+        finally {
+            input.rewind(mark);
+        }
+    },
+
+    noViableAlt: function(s, input) {
+        if (this.recognizer.state.backtracking>0) {
+            this.recognizer.state.failed=true;
+            return;
+        }
+        var nvae =
+            new org.antlr.runtime.NoViableAltException(this.getDescription(),
+                                     this.decisionNumber,
+                                     s,
+                                     input);
+        this.error(nvae);
+        throw nvae;
+    },
+
+    /** A hook for debugging interface */
+    error: function(nvae) { },
+
+    specialStateTransition: function(s, input) {
+        return -1;
+    },
+
+    getDescription: function() {
+        return "n/a";
+    }
+};
+
+org.antlr.lang.augmentObject(org.antlr.runtime.DFA, {
+    /** Given a String that has a run-length-encoding of some unsigned shorts
+     *  like "\1\2\3\9", convert to short[] {2,9,9,9}.
+     */
+    unpackEncodedString: function(encodedString) {
+        // walk first to find how big it is.
+        var i,
+            data = [],
+            di = 0,
+            n,
+            v,
+            j;
+        for (i=0; i<encodedString.length; i+=2) {
+            n = encodedString.charCodeAt(i);
+            v = encodedString.charCodeAt(i+1);
+            if (v===0xffff) {
+                v = -1; // overflow at 16 bits
+            }
+            // add v n times to data
+            for (j=1; j<=n; j++) {
+                data[di++] = v;
+            }
+        }
+        return data;
+    },
+
+    // alias
+    unpackEncodedStringToUnsignedChars: function(encodedString) {
+        return org.antlr.runtime.DFA.unpackEncodedString(encodedString);
+    }
+});
+/** A parser for a stream of tree nodes.  "tree grammars" result in a subclass
+ *  of this.  All the error reporting and recovery is shared with Parser via
+ *  the BaseRecognizer superclass.
+*/
+org.antlr.runtime.tree.TreeParser = function(input) {
+    org.antlr.runtime.tree.TreeParser.superclass.constructor.call(this, arguments[1]);
+    this.setTreeNodeStream(input);
+};
+
+(function(){
+var TP = org.antlr.runtime.tree.TreeParser;
+
+org.antlr.lang.augmentObject(TP, {
+    DOWN: org.antlr.runtime.Token.DOWN,
+    UP: org.antlr.runtime.Token.UP
+});
+
+org.antlr.lang.extend(TP, org.antlr.runtime.BaseRecognizer, {
+    reset: function() {
+        TP.superclass.reset.call(this); // reset all recognizer state variables
+        if ( this.input ) {
+            this.input.seek(0); // rewind the input
+        }
+    },
+
+    /** Set the input stream */
+    setTreeNodeStream: function(input) {
+        this.input = input;
+    },
+
+    getTreeNodeStream: function() {
+        return this.input;
+    },
+
+    getSourceName: function() {
+        return this.input.getSourceName();
+    },
+
+    getCurrentInputSymbol: function(input) {
+        return input.LT(1);
+    },
+
+    getMissingSymbol: function(input, e, expectedTokenType, follow) {
+        var tokenText =
+            "<missing "+this.getTokenNames()[expectedTokenType]+">";
+        return new org.antlr.runtime.tree.CommonTree(new org.antlr.runtime.CommonToken(expectedTokenType, tokenText));
+    },
+
+    /** Match '.' in tree parser has special meaning.  Skip node or
+     *  entire tree if node has children.  If children, scan until
+     *  corresponding UP node.
+     */
+    matchAny: function(ignore) { // ignore stream, copy of this.input
+        this.state.errorRecovery = false;
+        this.state.failed = false;
+        var look = this.input.LT(1);
+        if ( this.input.getTreeAdaptor().getChildCount(look)===0 ) {
+            this.input.consume(); // not subtree, consume 1 node and return
+            return;
+        }
+        // current node is a subtree, skip to corresponding UP.
+        // must count nesting level to get right UP
+        var level=0,
+            tokenType = this.input.getTreeAdaptor().getType(look);
+        while ( tokenType!==org.antlr.runtime.Token.EOF &&
+                !(tokenType===TP.UP && level===0) )
+        {
+            this.input.consume();
+            look = this.input.LT(1);
+            tokenType = this.input.getTreeAdaptor().getType(look);
+            if ( tokenType === TP.DOWN ) {
+                level++;
+            }
+            else if ( tokenType === TP.UP ) {
+                level--;
+            }
+        }
+        this.input.consume(); // consume UP
+    },
+
+    /** We have DOWN/UP nodes in the stream that have no line info; override.
+     *  plus we want to alter the exception type.  Don't try to recover
+     *       *  from tree parser errors inline...
+     */
+    mismatch: function(input, ttype, follow) {
+        throw new org.antlr.runtime.MismatchedTreeNodeException(ttype, input);
+    },
+
+    /** Prefix error message with the grammar name because message is
+     *  always intended for the programmer because the parser built
+     *  the input tree not the user.
+     */
+    getErrorHeader: function(e) {
+        return this.getGrammarFileName()+": node from "+
+               (e.approximateLineInfo?"after ":"")+"line "+e.line+":"+e.charPositionInLine;
+    },
+
+    /** Tree parsers parse nodes they usually have a token object as
+     *  payload. Set the exception token and do the default behavior.
+     */
+    getErrorMessage: function(e, tokenNames) {
+        var adaptor;
+        if ( this instanceof TP ) {
+            adaptor = e.input.getTreeAdaptor();
+            e.token = adaptor.getToken(e.node);
+            if ( !org.antlr.lang.isValue(e.token) ) { // could be an UP/DOWN node
+                e.token = new org.antlr.runtime.CommonToken(
+                        adaptor.getType(e.node),
+                        adaptor.getText(e.node));
+            }
+        }
+        return TP.superclass.getErrorMessage.call(this, e, tokenNames);
+    },
+
+    traceIn: function(ruleName, ruleIndex) {
+        TP.superclass.traceIn.call(this, ruleName, ruleIndex, this.input.LT(1));
+    },
+
+    traceOut: function(ruleName, ruleIndex) {
+        TP.superclass.traceOut.call(this, ruleName, ruleIndex, this.input.LT(1));
+    }
+});
+
+})();
diff --git a/debian/clean b/debian/clean
new file mode 100644
index 0000000..c1473d5
--- /dev/null
+++ b/debian/clean
@@ -0,0 +1 @@
+chrome/noscript.jar!/content/noscript/antlr.js
diff --git a/debian/control b/debian/control
index d9a507d..2f9bf9b 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,7 @@ Section: web
 Priority: optional
 Maintainer: Debian Mozilla Extension Maintainers <pkg-mozext-maintainers at lists.alioth.debian.org>
 Uploaders: Damyan Ivanov <dmn at debian.org>, Jérémy Bobbio <lunar at debian.org>
-Build-Depends: debhelper (>= 8), mozilla-devscripts
+Build-Depends: debhelper (>= 8), mozilla-devscripts, node-uglify
 Standards-Version: 3.9.5
 Homepage: http://noscript.net/
 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-mozext/noscript.git
diff --git a/debian/copyright b/debian/copyright
index 7375a5b..35c4cd8 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -7,7 +7,15 @@ Files: *
 Copyright: Copyright 2004-2013 Giorgio Maone <g.maone at informaction.com>
 License: GPL-2+
 
+Files: debian/*
+Copyright:
+ Copyright 2012-2013 Jérémy Bobbio <lunar at debian.org>
+ Copyright      2012 Damyan Ivanov <dmn at debian.org>
+ Copyright 2007-2011 Arnaud Renenevier <arenevier at fdn.fr>
+License: GPL-2+
+
 Files: chrome/noscript.jar!/content/noscript/antlr.js
+       debian/antlr3-all.js
 Copyright: Copyright 2003-2008 Terence Parr. All rights reserved.
            Copyright      2008 Yahoo! Inc. All rights reserved.
 License: BSD
@@ -82,13 +90,8 @@ License: BSD
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.
-
-Files: debian/*
-Copyright:
- Copyright 2012-2013 Jérémy Bobbio <lunar at debian.org>
- Copyright      2012 Damyan Ivanov <dmn at debian.org>
- Copyright 2007-2011 Arnaud Renenevier <arenevier at fdn.fr>
-License: GPL-2+
+Comment: Source downloaded from the following URL
+ http://code.google.com/p/antlr-javascript/downloads/detail?name=antlr-javascript-runtime-3.1.zip
 
 License: GPL-2+
    This package is free software; you can redistribute it and/or modify
diff --git a/debian/rules b/debian/rules
index 2efd887..06d8796 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,9 +1,13 @@
 #!/usr/bin/make -f
-# -*- makefile -*-
-
 %:
 	dh $@ --with xul-ext --buildsystem=xul_ext --parallel
 
+override_dh_auto_build:
+	uglifyjs -o \
+		chrome/noscript.jar!/content/noscript/antlr.js \
+		debian/antlr3-all.js
+	dh_auto_build -O--buildsystem=xul_ext -O--parallel
+
 override_dh_install:
 	dh_install -O--buildsystem=xul_ext -O--parallel
 	rm -f debian/xul-ext-noscript/usr/share/xul-ext/noscript/NoScript_License.txt
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
new file mode 100644
index 0000000..66c3149
--- /dev/null
+++ b/debian/source/lintian-overrides
@@ -0,0 +1,4 @@
+# The minified JavaScript is rebuilt from it source present in the debian directory
+source-contains-prebuilt-javascript-object chrome/noscript.jar!/content/noscript/antlr.js means line length is about 15883 characters
+source-is-missing chrome/noscript.jar!/content/noscript/antlr.js
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/noscript.git



More information about the Pkg-mozext-commits mailing list