|
|
- /*!
- Based on ndef.parser, by Raphael Graf(r@undefined.ch)
- http://www.undefined.ch/mparser/index.html
-
- Ported to JavaScript and modified by Matthew Crumley (email@matthewcrumley.com, http://silentmatt.com/)
-
- You are free to use and modify this code in anyway you find useful. Please leave this comment in the code
- to acknowledge its original source. If you feel like it, I enjoy hearing about projects that use my code,
- but don't feel like you have to let me know or ask permission.
- */
-
- // Added by stlsmiths 6/13/2011
- // re-define Array.indexOf, because IE doesn't know it ...
- //
- // from http://stellapower.net/content/javascript-support-and-arrayindexof-ie
- if (!Array.indexOf) {
- Array.prototype.indexOf = function (obj, start) {
- for (var i = (start || 0); i < this.length; i++) {
- if (this[i] === obj) {
- return i;
- }
- }
- return -1;
- }
- }
-
- var Parser = (function (scope) {
- function object(o) {
- function F() {}
- F.prototype = o;
- return new F();
- }
-
- var TNUMBER = 0;
- var TOP1 = 1;
- var TOP2 = 2;
- var TVAR = 3;
- var TFUNCALL = 4;
-
- function Token(type_, index_, prio_, number_) {
- this.type_ = type_;
- this.index_ = index_ || 0;
- this.prio_ = prio_ || 0;
- this.number_ = (number_ !== undefined && number_ !== null) ? number_ : 0;
- this.toString = function () {
- switch (this.type_) {
- case TNUMBER:
- return this.number_;
- case TOP1:
- case TOP2:
- case TVAR:
- return this.index_;
- case TFUNCALL:
- return "CALL";
- default:
- return "Invalid Token";
- }
- };
- }
-
- function Expression(tokens, ops1, ops2, functions) {
- this.tokens = tokens;
- this.ops1 = ops1;
- this.ops2 = ops2;
- this.functions = functions;
- }
-
- // Based on http://www.json.org/json2.js
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\'\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- "'" : "\\'",
- '\\': '\\\\'
- };
-
- function escapeValue(v) {
- if (typeof v === "string") {
- escapable.lastIndex = 0;
- return escapable.test(v) ?
- "'" + v.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string' ? c :
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + "'" :
- "'" + v + "'";
- }
- return v;
- }
-
- Expression.prototype = {
- simplify: function (values) {
- values = values || {};
- var nstack = [];
- var newexpression = [];
- var n1;
- var n2;
- var f;
- var L = this.tokens.length;
- var item;
- var i = 0;
- for (i = 0; i < L; i++) {
- item = this.tokens[i];
- var type_ = item.type_;
- if (type_ === TNUMBER) {
- nstack.push(item);
- }
- else if (type_ === TVAR && (item.index_ in values)) {
- item = new Token(TNUMBER, 0, 0, values[item.index_]);
- nstack.push(item);
- }
- else if (type_ === TOP2 && nstack.length > 1) {
- n2 = nstack.pop();
- n1 = nstack.pop();
- f = this.ops2[item.index_];
- item = new Token(TNUMBER, 0, 0, f(n1.number_, n2.number_));
- nstack.push(item);
- }
- else if (type_ === TOP1 && nstack.length > 0) {
- n1 = nstack.pop();
- f = this.ops1[item.index_];
- item = new Token(TNUMBER, 0, 0, f(n1.number_));
- nstack.push(item);
- }
- else {
- while (nstack.length > 0) {
- newexpression.push(nstack.shift());
- }
- newexpression.push(item);
- }
- }
- while (nstack.length > 0) {
- newexpression.push(nstack.shift());
- }
-
- return new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
- },
-
- substitute: function (variable, expr) {
- if (!(expr instanceof Expression)) {
- expr = new Parser().parse(String(expr));
- }
- var newexpression = [];
- var L = this.tokens.length;
- var item;
- var i = 0;
- for (i = 0; i < L; i++) {
- item = this.tokens[i];
- var type_ = item.type_;
- if (type_ === TVAR && item.index_ === variable) {
- for (var j = 0; j < expr.tokens.length; j++) {
- var expritem = expr.tokens[j];
- var replitem = new Token(expritem.type_, expritem.index_, expritem.prio_, expritem.number_);
- newexpression.push(replitem);
- }
- }
- else {
- newexpression.push(item);
- }
- }
-
- var ret = new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
- return ret;
- },
-
- evaluate: function (values) {
- values = values || {};
- var nstack = [];
- var n1;
- var n2;
- var f;
- var L = this.tokens.length;
- var item;
- var i = 0;
- for (i = 0; i < L; i++) {
- item = this.tokens[i];
- var type_ = item.type_;
- if (type_ === TNUMBER) {
- nstack.push(item.number_);
- }
- else if (type_ === TOP2) {
- n2 = nstack.pop();
- n1 = nstack.pop();
- f = this.ops2[item.index_];
- nstack.push(f(n1, n2));
- }
- else if (type_ === TVAR) {
- if (item.index_ in values) {
- nstack.push(values[item.index_]);
- }
- else if (item.index_ in this.functions) {
- nstack.push(this.functions[item.index_]);
- }
- else {
- throw new Error("undefined variable: " + item.index_);
- }
- }
- else if (type_ === TOP1) {
- n1 = nstack.pop();
- f = this.ops1[item.index_];
- nstack.push(f(n1));
- }
- else if (type_ === TFUNCALL) {
- n1 = nstack.pop();
- f = nstack.pop();
- if (f.apply && f.call) {
- if (Object.prototype.toString.call(n1) == "[object Array]") {
- nstack.push(f.apply(undefined, n1));
- }
- else {
- nstack.push(f.call(undefined, n1));
- }
- }
- else {
- throw new Error(f + " is not a function");
- }
- }
- else {
- throw new Error("invalid Expression");
- }
- }
- if (nstack.length > 1) {
- throw new Error("invalid Expression (parity)");
- }
- return nstack[0];
- },
-
- toString: function (toJS) {
- var nstack = [];
- var n1;
- var n2;
- var f;
- var L = this.tokens.length;
- var item;
- var i = 0;
- for (i = 0; i < L; i++) {
- item = this.tokens[i];
- var type_ = item.type_;
- if (type_ === TNUMBER) {
- nstack.push(escapeValue(item.number_));
- }
- else if (type_ === TOP2) {
- n2 = nstack.pop();
- n1 = nstack.pop();
- f = item.index_;
- if (toJS && f == "^") {
- nstack.push("Math.pow(" + n1 + "," + n2 + ")");
- }
- else {
- nstack.push("(" + n1 + f + n2 + ")");
- }
- }
- else if (type_ === TVAR) {
- nstack.push(item.index_);
- }
- else if (type_ === TOP1) {
- n1 = nstack.pop();
- f = item.index_;
- if (f === "-") {
- nstack.push("(" + f + n1 + ")");
- }
- else {
- nstack.push(f + "(" + n1 + ")");
- }
- }
- else if (type_ === TFUNCALL) {
- n1 = nstack.pop();
- f = nstack.pop();
- nstack.push(f + "(" + n1 + ")");
- }
- else {
- throw new Error("invalid Expression");
- }
- }
- if (nstack.length > 1) {
- throw new Error("invalid Expression (parity)");
- }
- return nstack[0];
- },
-
- variables: function () {
- var L = this.tokens.length;
- var vars = [];
- for (var i = 0; i < L; i++) {
- var item = this.tokens[i];
- if (item.type_ === TVAR && (vars.indexOf(item.index_) == -1)) {
- vars.push(item.index_);
- }
- }
-
- return vars;
- },
-
- toJSFunction: function (param, variables) {
- var f = new Function(param, "with(Parser.values) { return " + this.simplify(variables).toString(true) + "; }");
- return f;
- }
- };
-
- function add(a, b) {
- return Number(a) + Number(b);
- }
- function sub(a, b) {
- return a - b;
- }
- function mul(a, b) {
- return a * b;
- }
- function div(a, b) {
- return a / b;
- }
- function mod(a, b) {
- return a % b;
- }
- function concat(a, b) {
- return "" + a + b;
- }
- function sinh(a) {
- return Math.sinh ? Math.sinh(a) : ((Math.exp(a) - Math.exp(-a)) / 2);
- }
- function cosh(a) {
- return Math.cosh ? Math.cosh(a) : ((Math.exp(a) + Math.exp(-a)) / 2);
- }
- function tanh(a) {
- if (Math.tanh) return Math.tanh(a);
- if(a === Infinity) return 1;
- if(a === -Infinity) return -1;
- return (Math.exp(a) - Math.exp(-a)) / (Math.exp(a) + Math.exp(-a));
- }
- function asinh(a) {
- if (Math.asinh) return Math.asinh(a);
- if(a === -Infinity) return a;
- return Math.log(a + Math.sqrt(a * a + 1));
- }
- function acosh(a) {
- return Math.acosh ? Math.acosh(a) : Math.log(a + Math.sqrt(a * a - 1));
- }
- function atanh(a) {
- return Math.atanh ? Math.atanh(a) : (Math.log((1+a)/(1-a)) / 2);
- }
- function log10(a) {
- return Math.log(a) * Math.LOG10E;
- }
- function neg(a) {
- return -a;
- }
- function trunc(a) {
- if(Math.trunc) return Math.trunc(a);
- else return x < 0 ? Math.ceil(x) : Math.floor(x);
- }
- function random(a) {
- return Math.random() * (a || 1);
- }
- function fac(a) { //a!
- a = Math.floor(a);
- var b = a;
- while (a > 1) {
- b = b * (--a);
- }
- return b;
- }
-
- // TODO: use hypot that doesn't overflow
- function hypot() {
- if(Math.hypot) return Math.hypot.apply(this, arguments);
- var y = 0;
- var length = arguments.length;
- for (var i = 0; i < length; i++) {
- if (arguments[i] === Infinity || arguments[i] === -Infinity) {
- return Infinity;
- }
- y += arguments[i] * arguments[i];
- }
- return Math.sqrt(y);
- }
-
- function append(a, b) {
- if (Object.prototype.toString.call(a) != "[object Array]") {
- return [a, b];
- }
- a = a.slice();
- a.push(b);
- return a;
- }
-
- function Parser() {
- this.success = false;
- this.errormsg = "";
- this.expression = "";
-
- this.pos = 0;
-
- this.tokennumber = 0;
- this.tokenprio = 0;
- this.tokenindex = 0;
- this.tmpprio = 0;
-
- this.ops1 = {
- "sin": Math.sin,
- "cos": Math.cos,
- "tan": Math.tan,
- "asin": Math.asin,
- "acos": Math.acos,
- "atan": Math.atan,
- "sinh": sinh,
- "cosh": cosh,
- "tanh": tanh,
- "asinh": asinh,
- "acosh": acosh,
- "atanh": atanh,
- "sqrt": Math.sqrt,
- "log": Math.log,
- "lg" : log10,
- "log10" : log10,
- "abs": Math.abs,
- "ceil": Math.ceil,
- "floor": Math.floor,
- "round": Math.round,
- "trunc": trunc,
- "-": neg,
- "exp": Math.exp
- };
-
- this.ops2 = {
- "+": add,
- "-": sub,
- "*": mul,
- "/": div,
- "%": mod,
- "^": Math.pow,
- ",": append,
- "||": concat
- };
-
- this.functions = {
- "random": random,
- "fac": fac,
- "min": Math.min,
- "max": Math.max,
- "hypot": hypot,
- "pyt": hypot, // backward compat
- "pow": Math.pow,
- "atan2": Math.atan2
- };
-
- this.consts = {
- "E": Math.E,
- "PI": Math.PI
- };
- }
-
- Parser.parse = function (expr) {
- return new Parser().parse(expr);
- };
-
- Parser.evaluate = function (expr, variables) {
- return Parser.parse(expr).evaluate(variables);
- };
-
- Parser.Expression = Expression;
-
- Parser.values = {
- sin: Math.sin,
- cos: Math.cos,
- tan: Math.tan,
- asin: Math.asin,
- acos: Math.acos,
- atan: Math.atan,
- sinh: sinh,
- cosh: cosh,
- tanh: tanh,
- asinh: asinh,
- acosh: acosh,
- atanh: atanh,
- sqrt: Math.sqrt,
- log: Math.log,
- lg: log10,
- log10: log10,
- abs: Math.abs,
- ceil: Math.ceil,
- floor: Math.floor,
- round: Math.round,
- trunc: trunc,
- random: random,
- fac: fac,
- exp: Math.exp,
- min: Math.min,
- max: Math.max,
- hypot: hypot,
- pyt: hypot, // backward compat
- pow: Math.pow,
- atan2: Math.atan2,
- E: Math.E,
- PI: Math.PI
- };
-
- var PRIMARY = 1 << 0;
- var OPERATOR = 1 << 1;
- var FUNCTION = 1 << 2;
- var LPAREN = 1 << 3;
- var RPAREN = 1 << 4;
- var COMMA = 1 << 5;
- var SIGN = 1 << 6;
- var CALL = 1 << 7;
- var NULLARY_CALL = 1 << 8;
-
- Parser.prototype = {
- parse: function (expr) {
- this.errormsg = "";
- this.success = true;
- var operstack = [];
- var tokenstack = [];
- this.tmpprio = 0;
- var expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
- var noperators = 0;
- this.expression = expr;
- this.pos = 0;
-
- while (this.pos < this.expression.length) {
- if (this.isOperator()) {
- if (this.isSign() && (expected & SIGN)) {
- if (this.isNegativeSign()) {
- this.tokenprio = 2;
- this.tokenindex = "-";
- noperators++;
- this.addfunc(tokenstack, operstack, TOP1);
- }
- expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
- }
- else if (this.isComment()) {
-
- }
- else {
- if ((expected & OPERATOR) === 0) {
- this.error_parsing(this.pos, "unexpected operator");
- }
- noperators += 2;
- this.addfunc(tokenstack, operstack, TOP2);
- expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
- }
- }
- else if (this.isNumber()) {
- if ((expected & PRIMARY) === 0) {
- this.error_parsing(this.pos, "unexpected number");
- }
- var token = new Token(TNUMBER, 0, 0, this.tokennumber);
- tokenstack.push(token);
-
- expected = (OPERATOR | RPAREN | COMMA);
- }
- else if (this.isString()) {
- if ((expected & PRIMARY) === 0) {
- this.error_parsing(this.pos, "unexpected string");
- }
- var token = new Token(TNUMBER, 0, 0, this.tokennumber);
- tokenstack.push(token);
-
- expected = (OPERATOR | RPAREN | COMMA);
- }
- else if (this.isLeftParenth()) {
- if ((expected & LPAREN) === 0) {
- this.error_parsing(this.pos, "unexpected \"(\"");
- }
-
- if (expected & CALL) {
- noperators += 2;
- this.tokenprio = -2;
- this.tokenindex = -1;
- this.addfunc(tokenstack, operstack, TFUNCALL);
- }
-
- expected = (PRIMARY | LPAREN | FUNCTION | SIGN | NULLARY_CALL);
- }
- else if (this.isRightParenth()) {
- if (expected & NULLARY_CALL) {
- var token = new Token(TNUMBER, 0, 0, []);
- tokenstack.push(token);
- }
- else if ((expected & RPAREN) === 0) {
- this.error_parsing(this.pos, "unexpected \")\"");
- }
-
- expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
- }
- else if (this.isComma()) {
- if ((expected & COMMA) === 0) {
- this.error_parsing(this.pos, "unexpected \",\"");
- }
- this.addfunc(tokenstack, operstack, TOP2);
- noperators += 2;
- expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
- }
- else if (this.isConst()) {
- if ((expected & PRIMARY) === 0) {
- this.error_parsing(this.pos, "unexpected constant");
- }
- var consttoken = new Token(TNUMBER, 0, 0, this.tokennumber);
- tokenstack.push(consttoken);
- expected = (OPERATOR | RPAREN | COMMA);
- }
- else if (this.isOp2()) {
- if ((expected & FUNCTION) === 0) {
- this.error_parsing(this.pos, "unexpected function");
- }
- this.addfunc(tokenstack, operstack, TOP2);
- noperators += 2;
- expected = (LPAREN);
- }
- else if (this.isOp1()) {
- if ((expected & FUNCTION) === 0) {
- this.error_parsing(this.pos, "unexpected function");
- }
- this.addfunc(tokenstack, operstack, TOP1);
- noperators++;
- expected = (LPAREN);
- }
- else if (this.isVar()) {
- if ((expected & PRIMARY) === 0) {
- this.error_parsing(this.pos, "unexpected variable");
- }
- var vartoken = new Token(TVAR, this.tokenindex, 0, 0);
- tokenstack.push(vartoken);
-
- expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
- }
- else if (this.isWhite()) {
- }
- else {
- if (this.errormsg === "") {
- this.error_parsing(this.pos, "unknown character");
- }
- else {
- this.error_parsing(this.pos, this.errormsg);
- }
- }
- }
- if (this.tmpprio < 0 || this.tmpprio >= 10) {
- this.error_parsing(this.pos, "unmatched \"()\"");
- }
- while (operstack.length > 0) {
- var tmp = operstack.pop();
- tokenstack.push(tmp);
- }
- if (noperators + 1 !== tokenstack.length) {
- //print(noperators + 1);
- //print(tokenstack);
- this.error_parsing(this.pos, "parity");
- }
-
- return new Expression(tokenstack, object(this.ops1), object(this.ops2), object(this.functions));
- },
-
- evaluate: function (expr, variables) {
- return this.parse(expr).evaluate(variables);
- },
-
- error_parsing: function (column, msg) {
- this.success = false;
- this.errormsg = "parse error [column " + (column) + "]: " + msg;
- this.column = column;
- throw new Error(this.errormsg);
- },
-
- //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
-
- addfunc: function (tokenstack, operstack, type_) {
- var operator = new Token(type_, this.tokenindex, this.tokenprio + this.tmpprio, 0);
- while (operstack.length > 0) {
- if (operator.prio_ <= operstack[operstack.length - 1].prio_) {
- tokenstack.push(operstack.pop());
- }
- else {
- break;
- }
- }
- operstack.push(operator);
- },
-
- isNumber: function () {
- var r = false;
- var str = "";
- while (this.pos < this.expression.length) {
- var code = this.expression.charCodeAt(this.pos);
- if ((code >= 48 && code <= 57) || code === 46) {
- str += this.expression.charAt(this.pos);
- this.pos++;
- this.tokennumber = parseFloat(str);
- r = true;
- }
- else {
- break;
- }
- }
- return r;
- },
-
- // Ported from the yajjl JSON parser at http://code.google.com/p/yajjl/
- unescape: function(v, pos) {
- var buffer = [];
- var escaping = false;
-
- for (var i = 0; i < v.length; i++) {
- var c = v.charAt(i);
-
- if (escaping) {
- switch (c) {
- case "'":
- buffer.push("'");
- break;
- case '\\':
- buffer.push('\\');
- break;
- case '/':
- buffer.push('/');
- break;
- case 'b':
- buffer.push('\b');
- break;
- case 'f':
- buffer.push('\f');
- break;
- case 'n':
- buffer.push('\n');
- break;
- case 'r':
- buffer.push('\r');
- break;
- case 't':
- buffer.push('\t');
- break;
- case 'u':
- // interpret the following 4 characters as the hex of the unicode code point
- var codePoint = parseInt(v.substring(i + 1, i + 5), 16);
- buffer.push(String.fromCharCode(codePoint));
- i += 4;
- break;
- default:
- throw this.error_parsing(pos + i, "Illegal escape sequence: '\\" + c + "'");
- }
- escaping = false;
- } else {
- if (c == '\\') {
- escaping = true;
- } else {
- buffer.push(c);
- }
- }
- }
-
- return buffer.join('');
- },
-
- isString: function () {
- var r = false;
- var str = "";
- var startpos = this.pos;
- if (this.pos < this.expression.length && this.expression.charAt(this.pos) == "'") {
- this.pos++;
- while (this.pos < this.expression.length) {
- var code = this.expression.charAt(this.pos);
- if (code != "'" || str.slice(-1) == "\\") {
- str += this.expression.charAt(this.pos);
- this.pos++;
- }
- else {
- this.pos++;
- this.tokennumber = this.unescape(str, startpos);
- r = true;
- break;
- }
- }
- }
- return r;
- },
-
- isConst: function () {
- var str;
- for (var i in this.consts) {
- if (true) {
- var L = i.length;
- str = this.expression.substr(this.pos, L);
- if (i === str) {
- this.tokennumber = this.consts[i];
- this.pos += L;
- return true;
- }
- }
- }
- return false;
- },
-
- isOperator: function () {
- var code = this.expression.charCodeAt(this.pos);
- if (code === 43) { // +
- this.tokenprio = 0;
- this.tokenindex = "+";
- }
- else if (code === 45) { // -
- this.tokenprio = 0;
- this.tokenindex = "-";
- }
- else if (code === 124) { // |
- if (this.expression.charCodeAt(this.pos + 1) === 124) {
- this.pos++;
- this.tokenprio = 0;
- this.tokenindex = "||";
- }
- else {
- return false;
- }
- }
- else if (code === 42 || code === 8729 || code === 8226) { // * or ∙ or •
- this.tokenprio = 1;
- this.tokenindex = "*";
- }
- else if (code === 47) { // /
- this.tokenprio = 2;
- this.tokenindex = "/";
- }
- else if (code === 37) { // %
- this.tokenprio = 2;
- this.tokenindex = "%";
- }
- else if (code === 94) { // ^
- this.tokenprio = 3;
- this.tokenindex = "^";
- }
- else {
- return false;
- }
- this.pos++;
- return true;
- },
-
- isSign: function () {
- var code = this.expression.charCodeAt(this.pos - 1);
- if (code === 45 || code === 43) { // -
- return true;
- }
- return false;
- },
-
- isPositiveSign: function () {
- var code = this.expression.charCodeAt(this.pos - 1);
- if (code === 43) { // +
- return true;
- }
- return false;
- },
-
- isNegativeSign: function () {
- var code = this.expression.charCodeAt(this.pos - 1);
- if (code === 45) { // -
- return true;
- }
- return false;
- },
-
- isLeftParenth: function () {
- var code = this.expression.charCodeAt(this.pos);
- if (code === 40) { // (
- this.pos++;
- this.tmpprio += 10;
- return true;
- }
- return false;
- },
-
- isRightParenth: function () {
- var code = this.expression.charCodeAt(this.pos);
- if (code === 41) { // )
- this.pos++;
- this.tmpprio -= 10;
- return true;
- }
- return false;
- },
-
- isComma: function () {
- var code = this.expression.charCodeAt(this.pos);
- if (code === 44) { // ,
- this.pos++;
- this.tokenprio = -1;
- this.tokenindex = ",";
- return true;
- }
- return false;
- },
-
- isWhite: function () {
- var code = this.expression.charCodeAt(this.pos);
- if (code === 32 || code === 9 || code === 10 || code === 13) {
- this.pos++;
- return true;
- }
- return false;
- },
-
- isOp1: function () {
- var str = "";
- for (var i = this.pos; i < this.expression.length; i++) {
- var c = this.expression.charAt(i);
- if (c.toUpperCase() === c.toLowerCase()) {
- if (i === this.pos || (c != '_' && (c < '0' || c > '9'))) {
- break;
- }
- }
- str += c;
- }
- if (str.length > 0 && (str in this.ops1)) {
- this.tokenindex = str;
- this.tokenprio = 5;
- this.pos += str.length;
- return true;
- }
- return false;
- },
-
- isOp2: function () {
- var str = "";
- for (var i = this.pos; i < this.expression.length; i++) {
- var c = this.expression.charAt(i);
- if (c.toUpperCase() === c.toLowerCase()) {
- if (i === this.pos || (c != '_' && (c < '0' || c > '9'))) {
- break;
- }
- }
- str += c;
- }
- if (str.length > 0 && (str in this.ops2)) {
- this.tokenindex = str;
- this.tokenprio = 5;
- this.pos += str.length;
- return true;
- }
- return false;
- },
-
- isVar: function () {
- var str = "";
- for (var i = this.pos; i < this.expression.length; i++) {
- var c = this.expression.charAt(i);
- if (c.toUpperCase() === c.toLowerCase()) {
- if (i === this.pos || (c != '_' && (c < '0' || c > '9'))) {
- break;
- }
- }
- str += c;
- }
- if (str.length > 0) {
- this.tokenindex = str;
- this.tokenprio = 4;
- this.pos += str.length;
- return true;
- }
- return false;
- },
-
- isComment: function () {
- var code = this.expression.charCodeAt(this.pos - 1);
- if (code === 47 && this.expression.charCodeAt(this.pos) === 42) {
- this.pos = this.expression.indexOf("*/", this.pos) + 2;
- if (this.pos === 1) {
- this.pos = this.expression.length;
- }
- return true;
- }
- return false;
- }
- };
-
- scope.Parser = Parser;
- return Parser
- })(typeof exports === 'undefined' ? {} : exports);
|