diff --git a/Makefile.dryice.js b/Makefile.dryice.js
index b743a5b3..894af0ae 100755
--- a/Makefile.dryice.js
+++ b/Makefile.dryice.js
@@ -231,7 +231,7 @@ function buildAce(aceProject, options) {
"tomorrow_night_blue", "tomorrow_night_bright", "tomorrow_night_eighties",
"twilight", "vibrant_ink"
],
- workers: ["javascript", "coffee", "css", "json"],
+ workers: ["javascript", "coffee", "css", "json", "xquery"],
keybindings: ["vim", "emacs"]
};
diff --git a/build/demo/kitchen-sink/mode-xquery-uncompressed.js b/build/demo/kitchen-sink/mode-xquery-uncompressed.js
index 66fee6ef..efd009ff 100644
--- a/build/demo/kitchen-sink/mode-xquery-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-xquery-uncompressed.js
@@ -16,9 +16,16 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see 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. 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. 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. 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. Operates in a number of modes:
+ *
+ * org.antlr.namespace("really.long.nested.namespace");
+ *
+ * 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
+ *
+ *
+ * ((BitSet)obj).get(k) == this.get(k)
+ *
+ * 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; iFor 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.
+ * + *If a grammar g is passed, print g.getTokenDisplayName(i) for each set + * index instead of the numerical index.
+ * + * <>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. + * + * @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 = "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.
+ * @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. + * + *This is different from rewind in its multi-directional + * requirement and in that its argument is strictly an input cursor + * (index).
+ * + *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.
+ * + *Currently, this method is only used for efficient backtracking using + * memoization, but in the future it may be used for incremental + * parsing.
+ * + *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.
+ * + *Esentially this method method moves the input position, + * {@link #consume}-ing data if necessary.
+ * + * @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.pThis class should not be instantiated directly. Instead, use one of its + * subclasses.
+ * + * @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; iThis 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:
+ *If you override, make sure to update this.state.syntaxErrors if you + * care about that.
+ * @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 isline + * lineNumber:positionInLine. + * @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) { + throw msg; + //console.log(msg); + }, + + /** What error message should be generated for the various + * exception types? + * + *
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.
+ * + *For grammar debugging, you will want to override this to add + * more information such as the stack frame and no viable alts.
+ * + *Override this to change the message generated for one or more + * exception types.
+ * + * @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="
+ * org.antlr.namespace("really.long.nested.namespace");
+ *
+ * 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; iTo 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.
+ * + *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.
+ * + *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.
+ * + * @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. + * + *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.
+ * + * @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. + * + *Operates in a number of modes: + *
+ * ((BitSet)obj).get(k) == this.get(k)
+ *
+ * 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; iFor 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.
+ * + *If a grammar g is passed, print g.getTokenDisplayName(i) for each set + * index instead of the numerical index.
+ * + * <>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. + * + * @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 = "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.
+ * @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. + * + *This is different from rewind in its multi-directional + * requirement and in that its argument is strictly an input cursor + * (index).
+ * + *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.
+ * + *Currently, this method is only used for efficient backtracking using + * memoization, but in the future it may be used for incremental + * parsing.
+ * + *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.
+ * + *Esentially this method method moves the input position, + * {@link #consume}-ing data if necessary.
+ * + * @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.pThis class should not be instantiated directly. Instead, use one of its + * subclasses.
+ * + * @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; iThis 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:
+ *If you override, make sure to update this.state.syntaxErrors if you + * care about that.
+ * @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 isline + * lineNumber:positionInLine. + * @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) { + throw msg; + //console.log(msg); + }, + + /** What error message should be generated for the various + * exception types? + * + *
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.
+ * + *For grammar debugging, you will want to override this to add + * more information such as the stack frame and no viable alts.
+ * + *Override this to change the message generated for one or more + * exception types.
+ * + * @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="
+ * org.antlr.namespace("really.long.nested.namespace");
+ *
+ * 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; iTo 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.
+ * + *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.
+ * + *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.
+ * + * @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. + * + *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.
+ * + * @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. + * + *Operates in a number of modes: + *
+ * ((BitSet)obj).get(k) == this.get(k)
+ *
+ * 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; iFor 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.
+ * + *If a grammar g is passed, print g.getTokenDisplayName(i) for each set + * index instead of the numerical index.
+ * + * <>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. + * + * @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 = "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.
+ * @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. + * + *This is different from rewind in its multi-directional + * requirement and in that its argument is strictly an input cursor + * (index).
+ * + *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.
+ * + *Currently, this method is only used for efficient backtracking using + * memoization, but in the future it may be used for incremental + * parsing.
+ * + *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.
+ * + *Esentially this method method moves the input position, + * {@link #consume}-ing data if necessary.
+ * + * @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.pThis class should not be instantiated directly. Instead, use one of its + * subclasses.
+ * + * @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; iThis 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:
+ *If you override, make sure to update this.state.syntaxErrors if you + * care about that.
+ * @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 isline + * lineNumber:positionInLine. + * @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) { + throw msg; + //console.log(msg); + }, + + /** What error message should be generated for the various + * exception types? + * + *
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.
+ * + *For grammar debugging, you will want to override this to add + * more information such as the stack frame and no viable alts.
+ * + *Override this to change the message generated for one or more + * exception types.
+ * + * @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="