Skip to content

Instantly share code, notes, and snippets.

@vic
Created Feb 19, 2009
Embed
What would you like to do?
An attempt to parse Ioke in javascript
To compile the grammar you need the antlr jar provided with ioke.
A v8 linux binary has been included to run the test.js
There seems to be a bug in the port of ioke.g, it doesnt create
tree for a simple ioke expr.
I think Ioke would be a wondeful language to have on the browser. It's very lightweight and I believe it would be wonderful to have it's homoiconic power for scripting webpages. Given that Ioke's primary platform is the JVM, I think we could develop some webapps that inject ioke code to the browser. Ioke's syntax would also allows to define web DSL
div(class: "content",
p("This is a paragraph")
script(language: "ioke",
we couldEven(call jsLibrary)))
/*
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();