ember-source
Version:
A JavaScript framework for creating ambitious web applications
1,893 lines (1,877 loc) • 399 kB
JavaScript
function dict() {
return Object.create(null);
}
const assign = Object.assign;
/**
* This constant exists to make it easier to differentiate normal logs from
* errant console.logs. LOCAL_LOGGER should only be used inside a
* LOCAL_TRACE_LOGGING check.
*
* It does not alleviate the need to check LOCAL_TRACE_LOGGING, which is used
* for stripping.
*/
const LOGGER = console;
/**
* This constant exists to make it easier to differentiate normal logs from
* errant console.logs. LOGGER can be used outside of LOCAL_TRACE_LOGGING checks,
* and is meant to be used in the rare situation where a console.* call is
* actually appropriate.
*/
function assertNever(value, desc = "unexpected unreachable branch") {
throw LOGGER.log("unreachable", value), LOGGER.log(`${desc} :: ${JSON.stringify(value)} (${value})`), new Error("code reached unreachable");
}
const opcodes = {
Append: 1,
TrustingAppend: 2,
Comment: 3,
Modifier: 4,
Block: 6,
Component: 8,
OpenElement: 10,
OpenElementWithSplat: 11,
FlushElement: 12,
CloseElement: 13,
StaticAttr: 14,
DynamicAttr: 15,
ComponentAttr: 16,
AttrSplat: 17,
Yield: 18,
TrustingDynamicAttr: 22,
TrustingComponentAttr: 23,
StaticComponentAttr: 24,
Debugger: 26,
Undefined: 27,
Call: 28,
Concat: 29,
GetSymbol: 30,
GetLexicalSymbol: 32,
GetStrictKeyword: 31,
GetFreeAsComponentOrHelperHead: 35,
GetFreeAsHelperHead: 37,
GetFreeAsModifierHead: 38,
GetFreeAsComponentHead: 39,
InElement: 40,
If: 41,
Each: 42,
Let: 44,
WithDynamicVars: 45,
InvokeComponent: 46,
HasBlock: 48,
HasBlockParams: 49,
Curry: 50,
Not: 51,
IfInline: 52,
GetDynamicVar: 53,
Log: 54
},
WellKnownAttrNames = {
class: 0,
id: 1,
value: 2,
name: 3,
type: 4,
style: 5,
href: 6
},
WellKnownTagNames = {
div: 0,
span: 1,
p: 2,
a: 3
};
var errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack'];
function Exception(message, node) {
var loc = node && node.loc,
line,
endLineNumber,
column,
endColumn;
if (loc) {
line = loc.start.line;
endLineNumber = loc.end.line;
column = loc.start.column;
endColumn = loc.end.column;
message += ' - ' + line + ':' + column;
}
var tmp = Error.prototype.constructor.call(this, message);
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for (var idx = 0; idx < errorProps.length; idx++) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
/* istanbul ignore else */
if (Error.captureStackTrace) {
Error.captureStackTrace(this, Exception);
}
try {
if (loc) {
this.lineNumber = line;
this.endLineNumber = endLineNumber;
// Work around issue under safari where we can't directly set the column value
/* istanbul ignore next */
if (Object.defineProperty) {
Object.defineProperty(this, 'column', {
value: column,
enumerable: true
});
Object.defineProperty(this, 'endColumn', {
value: endColumn,
enumerable: true
});
} else {
this.column = column;
this.endColumn = endColumn;
}
}
} catch (nop) {
/* Ignore if the browser is very particular */
}
}
Exception.prototype = new Error();
function Visitor() {
this.parents = [];
}
Visitor.prototype = {
constructor: Visitor,
mutating: false,
// Visits a given value. If mutating, will replace the value if necessary.
acceptKey: function (node, name) {
var value = this.accept(node[name]);
if (this.mutating) {
// Hacky sanity check: This may have a few false positives for type for the helper
// methods but will generally do the right thing without a lot of overhead.
if (value && !Visitor.prototype[value.type]) {
throw new Exception('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
}
node[name] = value;
}
},
// Performs an accept operation with added sanity check to ensure
// required keys are not removed.
acceptRequired: function (node, name) {
this.acceptKey(node, name);
if (!node[name]) {
throw new Exception(node.type + ' requires ' + name);
}
},
// Traverses a given array. If mutating, empty responses will be removed
// for child elements.
acceptArray: function (array) {
for (var i = 0, l = array.length; i < l; i++) {
this.acceptKey(array, i);
if (!array[i]) {
array.splice(i, 1);
i--;
l--;
}
}
},
accept: function (object) {
if (!object) {
return;
}
/* istanbul ignore next: Sanity code */
if (!this[object.type]) {
throw new Exception('Unknown type: ' + object.type, object);
}
if (this.current) {
this.parents.unshift(this.current);
}
this.current = object;
var ret = this[object.type](object);
this.current = this.parents.shift();
if (!this.mutating || ret) {
return ret;
} else if (ret !== false) {
return object;
}
},
Program: function (program) {
this.acceptArray(program.body);
},
MustacheStatement: visitSubExpression,
Decorator: visitSubExpression,
BlockStatement: visitBlock,
DecoratorBlock: visitBlock,
PartialStatement: visitPartial,
PartialBlockStatement: function (partial) {
visitPartial.call(this, partial);
this.acceptKey(partial, 'program');
},
ContentStatement: function /* content */ () {},
CommentStatement: function /* comment */ () {},
SubExpression: visitSubExpression,
PathExpression: function /* path */ () {},
StringLiteral: function /* string */ () {},
NumberLiteral: function /* number */ () {},
BooleanLiteral: function /* bool */ () {},
UndefinedLiteral: function /* literal */ () {},
NullLiteral: function /* literal */ () {},
Hash: function (hash) {
this.acceptArray(hash.pairs);
},
HashPair: function (pair) {
this.acceptRequired(pair, 'value');
}
};
function visitSubExpression(mustache) {
this.acceptRequired(mustache, 'path');
this.acceptArray(mustache.params);
this.acceptKey(mustache, 'hash');
}
function visitBlock(block) {
visitSubExpression.call(this, block);
this.acceptKey(block, 'program');
this.acceptKey(block, 'inverse');
}
function visitPartial(partial) {
this.acceptRequired(partial, 'name');
this.acceptArray(partial.params);
this.acceptKey(partial, 'hash');
}
function WhitespaceControl(options) {
if (options === void 0) {
options = {};
}
this.options = options;
}
WhitespaceControl.prototype = new Visitor();
WhitespaceControl.prototype.Program = function (program) {
var doStandalone = !this.options.ignoreStandalone;
var isRoot = !this.isRootSeen;
this.isRootSeen = true;
var body = program.body;
for (var i = 0, l = body.length; i < l; i++) {
var current = body[i],
strip = this.accept(current);
if (!strip) {
continue;
}
var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
_isNextWhitespace = isNextWhitespace(body, i, isRoot),
openStandalone = strip.openStandalone && _isPrevWhitespace,
closeStandalone = strip.closeStandalone && _isNextWhitespace,
inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
if (strip.close) {
omitRight(body, i, true);
}
if (strip.open) {
omitLeft(body, i, true);
}
if (doStandalone && inlineStandalone) {
omitRight(body, i);
if (omitLeft(body, i)) {
// If we are on a standalone node, save the indent info for partials
if (current.type === 'PartialStatement') {
// Pull out the whitespace from the final line
current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
}
}
}
if (doStandalone && openStandalone) {
omitRight((current.program || current.inverse).body);
// Strip out the previous content node if it's whitespace only
omitLeft(body, i);
}
if (doStandalone && closeStandalone) {
// Always strip the next node
omitRight(body, i);
omitLeft((current.inverse || current.program).body);
}
}
return program;
};
WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) {
this.accept(block.program);
this.accept(block.inverse);
// Find the inverse program that is involved with whitespace stripping.
var program = block.program || block.inverse,
inverse = block.program && block.inverse,
firstInverse = inverse,
lastInverse = inverse;
if (inverse && inverse.chained) {
firstInverse = inverse.body[0].program;
// Walk the inverse chain to find the last inverse that is actually in the chain.
while (lastInverse.chained) {
lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
}
}
var strip = {
open: block.openStrip.open,
close: block.closeStrip.close,
// Determine the standalone candidacy. Basically flag our content as being possibly standalone
// so our parent can determine if we actually are standalone
openStandalone: isNextWhitespace(program.body),
closeStandalone: isPrevWhitespace((firstInverse || program).body)
};
if (block.openStrip.close) {
omitRight(program.body, null, true);
}
if (inverse) {
var inverseStrip = block.inverseStrip;
if (inverseStrip.open) {
omitLeft(program.body, null, true);
}
if (inverseStrip.close) {
omitRight(firstInverse.body, null, true);
}
if (block.closeStrip.open) {
omitLeft(lastInverse.body, null, true);
}
// Find standalone else statements
if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) {
omitLeft(program.body);
omitRight(firstInverse.body);
}
} else if (block.closeStrip.open) {
omitLeft(program.body, null, true);
}
return strip;
};
WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) {
return mustache.strip;
};
WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) {
/* istanbul ignore next */
var strip = node.strip || {};
return {
inlineStandalone: true,
open: strip.open,
close: strip.close
};
};
function isPrevWhitespace(body, i, isRoot) {
if (i === undefined) {
i = body.length;
}
// Nodes that end with newlines are considered whitespace (but are special
// cased for strip operations)
var prev = body[i - 1],
sibling = body[i - 2];
if (!prev) {
return isRoot;
}
if (prev.type === 'ContentStatement') {
return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original);
}
}
function isNextWhitespace(body, i, isRoot) {
if (i === undefined) {
i = -1;
}
var next = body[i + 1],
sibling = body[i + 2];
if (!next) {
return isRoot;
}
if (next.type === 'ContentStatement') {
return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original);
}
}
// Marks the node to the right of the position as omitted.
// I.e. {{foo}}' ' will mark the ' ' node as omitted.
//
// If i is undefined, then the first child will be marked as such.
//
// If multiple is truthy then all whitespace will be stripped out until non-whitespace
// content is met.
function omitRight(body, i, multiple) {
var current = body[i == null ? 0 : i + 1];
if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) {
return;
}
var original = current.value;
current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '');
current.rightStripped = current.value !== original;
}
// Marks the node to the left of the position as omitted.
// I.e. ' '{{foo}} will mark the ' ' node as omitted.
//
// If i is undefined then the last child will be marked as such.
//
// If multiple is truthy then all whitespace will be stripped out until non-whitespace
// content is met.
function omitLeft(body, i, multiple) {
var current = body[i == null ? body.length - 1 : i - 1];
if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) {
return;
}
// We omit the last node if it's whitespace only and not preceded by a non-content node.
var original = current.value;
current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
current.leftStripped = current.value !== original;
return current.leftStripped;
}
/* parser generated by jison 0.4.18 */
/*
Returns a Parser object of the following structure:
Parser: {
yy: {}
}
Parser.prototype: {
yy: {},
trace: function(),
symbols_: {associative list: name ==> number},
terminals_: {associative list: number ==> name},
productions_: [...],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
table: [...],
defaultActions: {...},
parseError: function(str, hash),
parse: function(input),
lexer: {
EOF: 1,
parseError: function(str, hash),
setInput: function(input),
input: function(),
unput: function(str),
more: function(),
less: function(n),
pastInput: function(),
upcomingInput: function(),
showPosition: function(),
test_match: function(regex_match_array, rule_index),
next: function(),
lex: function(),
begin: function(condition),
popState: function(),
_currentRules: function(),
topState: function(),
pushState: function(condition),
options: {
ranges: boolean (optional: true ==> token location info will include a .range[] member)
flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
},
performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
rules: [...],
conditions: {associative list: name ==> set},
}
}
token location info (@$, _$, etc.): {
first_line: n,
last_line: n,
first_column: n,
last_column: n,
range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
}
the parseError function receives a 'hash' object with these members for lexer and parser errors: {
text: (matched text)
token: (the produced terminal token, if any)
line: (yylineno)
}
while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
loc: (yylloc)
expected: (string describing the set of expected tokens)
recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
}
*/
var parser = function () {
var o = function (k, v, o, l) {
for (o = o || {}, l = k.length; l--; o[k[l]] = v);
return o;
},
$V0 = [2, 52],
$V1 = [1, 20],
$V2 = [5, 14, 15, 19, 29, 34, 39, 44, 47, 48, 53, 57, 61],
$V3 = [1, 44],
$V4 = [1, 40],
$V5 = [1, 43],
$V6 = [1, 33],
$V7 = [1, 34],
$V8 = [1, 35],
$V9 = [1, 36],
$Va = [1, 37],
$Vb = [1, 42],
$Vc = [1, 46],
$Vd = [14, 15, 19, 29, 34, 39, 44, 47, 48, 53, 57, 61],
$Ve = [14, 15, 19, 29, 34, 44, 47, 48, 53, 57, 61],
$Vf = [15, 18],
$Vg = [14, 15, 19, 29, 34, 47, 48, 53, 57, 61],
$Vh = [33, 67, 73, 75, 84, 85, 86, 87, 88, 89],
$Vi = [23, 33, 56, 67, 68, 73, 75, 77, 79, 84, 85, 86, 87, 88, 89],
$Vj = [1, 62],
$Vk = [1, 63],
$Vl = [23, 33, 56, 68, 73, 79],
$Vm = [23, 33, 56, 67, 68, 73, 75, 77, 79, 84, 85, 86, 87, 88, 89, 92, 93],
$Vn = [2, 51],
$Vo = [1, 64],
$Vp = [67, 73, 75, 77, 84, 85, 86, 87, 88, 89],
$Vq = [56, 67, 73, 75, 84, 85, 86, 87, 88, 89],
$Vr = [1, 75],
$Vs = [1, 76],
$Vt = [1, 83],
$Vu = [33, 67, 73, 75, 79, 84, 85, 86, 87, 88, 89],
$Vv = [23, 67, 73, 75, 84, 85, 86, 87, 88, 89],
$Vw = [67, 68, 73, 75, 84, 85, 86, 87, 88, 89],
$Vx = [33, 79],
$Vy = [1, 134],
$Vz = [73, 81];
var parser = {
trace: function trace() {},
yy: {},
symbols_: {
"error": 2,
"root": 3,
"program": 4,
"EOF": 5,
"program_repetition0": 6,
"statement": 7,
"mustache": 8,
"block": 9,
"rawBlock": 10,
"partial": 11,
"partialBlock": 12,
"content": 13,
"COMMENT": 14,
"CONTENT": 15,
"openRawBlock": 16,
"rawBlock_repetition0": 17,
"END_RAW_BLOCK": 18,
"OPEN_RAW_BLOCK": 19,
"helperName": 20,
"openRawBlock_repetition0": 21,
"openRawBlock_option0": 22,
"CLOSE_RAW_BLOCK": 23,
"openBlock": 24,
"block_option0": 25,
"closeBlock": 26,
"openInverse": 27,
"block_option1": 28,
"OPEN_BLOCK": 29,
"openBlock_repetition0": 30,
"openBlock_option0": 31,
"openBlock_option1": 32,
"CLOSE": 33,
"OPEN_INVERSE": 34,
"openInverse_repetition0": 35,
"openInverse_option0": 36,
"openInverse_option1": 37,
"openInverseChain": 38,
"OPEN_INVERSE_CHAIN": 39,
"openInverseChain_repetition0": 40,
"openInverseChain_option0": 41,
"openInverseChain_option1": 42,
"inverseAndProgram": 43,
"INVERSE": 44,
"inverseChain": 45,
"inverseChain_option0": 46,
"OPEN_ENDBLOCK": 47,
"OPEN": 48,
"hash": 49,
"expr": 50,
"mustache_repetition0": 51,
"mustache_option0": 52,
"OPEN_UNESCAPED": 53,
"mustache_repetition1": 54,
"mustache_option1": 55,
"CLOSE_UNESCAPED": 56,
"OPEN_PARTIAL": 57,
"partial_repetition0": 58,
"partial_option0": 59,
"openPartialBlock": 60,
"OPEN_PARTIAL_BLOCK": 61,
"openPartialBlock_repetition0": 62,
"openPartialBlock_option0": 63,
"exprHead": 64,
"arrayLiteral": 65,
"sexpr": 66,
"OPEN_SEXPR": 67,
"CLOSE_SEXPR": 68,
"sexpr_repetition0": 69,
"sexpr_option0": 70,
"hash_repetition_plus0": 71,
"hashSegment": 72,
"ID": 73,
"EQUALS": 74,
"OPEN_ARRAY": 75,
"arrayLiteral_repetition0": 76,
"CLOSE_ARRAY": 77,
"blockParams": 78,
"OPEN_BLOCK_PARAMS": 79,
"blockParams_repetition_plus0": 80,
"CLOSE_BLOCK_PARAMS": 81,
"path": 82,
"dataName": 83,
"STRING": 84,
"NUMBER": 85,
"BOOLEAN": 86,
"UNDEFINED": 87,
"NULL": 88,
"DATA": 89,
"pathSegments": 90,
"sep": 91,
"SEP": 92,
"PRIVATE_SEP": 93,
"$accept": 0,
"$end": 1
},
terminals_: {
2: "error",
5: "EOF",
14: "COMMENT",
15: "CONTENT",
18: "END_RAW_BLOCK",
19: "OPEN_RAW_BLOCK",
23: "CLOSE_RAW_BLOCK",
29: "OPEN_BLOCK",
33: "CLOSE",
34: "OPEN_INVERSE",
39: "OPEN_INVERSE_CHAIN",
44: "INVERSE",
47: "OPEN_ENDBLOCK",
48: "OPEN",
53: "OPEN_UNESCAPED",
56: "CLOSE_UNESCAPED",
57: "OPEN_PARTIAL",
61: "OPEN_PARTIAL_BLOCK",
67: "OPEN_SEXPR",
68: "CLOSE_SEXPR",
73: "ID",
74: "EQUALS",
75: "OPEN_ARRAY",
77: "CLOSE_ARRAY",
79: "OPEN_BLOCK_PARAMS",
81: "CLOSE_BLOCK_PARAMS",
84: "STRING",
85: "NUMBER",
86: "BOOLEAN",
87: "UNDEFINED",
88: "NULL",
89: "DATA",
92: "SEP",
93: "PRIVATE_SEP"
},
productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 3], [8, 5], [8, 5], [11, 5], [12, 3], [60, 5], [50, 1], [50, 1], [64, 1], [64, 1], [66, 3], [66, 5], [49, 1], [72, 3], [65, 3], [78, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [83, 2], [91, 1], [91, 1], [82, 3], [82, 1], [90, 3], [90, 1], [6, 0], [6, 2], [17, 0], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [51, 0], [51, 2], [52, 0], [52, 1], [54, 0], [54, 2], [55, 0], [55, 1], [58, 0], [58, 2], [59, 0], [59, 1], [62, 0], [62, 2], [63, 0], [63, 1], [69, 0], [69, 2], [70, 0], [70, 1], [71, 1], [71, 2], [76, 0], [76, 2], [80, 1], [80, 2]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */
var $0 = $$.length - 1;
switch (yystate) {
case 1:
return $$[$0 - 1];
case 2:
this.$ = yy.prepareProgram($$[$0]);
break;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 20:
case 28:
case 29:
case 30:
case 31:
case 38:
case 39:
case 46:
case 47:
this.$ = $$[$0];
break;
case 9:
this.$ = {
type: 'CommentStatement',
value: yy.stripComment($$[$0]),
strip: yy.stripFlags($$[$0], $$[$0]),
loc: yy.locInfo(this._$)
};
break;
case 10:
this.$ = {
type: 'ContentStatement',
original: $$[$0],
value: $$[$0],
loc: yy.locInfo(this._$)
};
break;
case 11:
this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
break;
case 12:
this.$ = {
path: $$[$0 - 3],
params: $$[$0 - 2],
hash: $$[$0 - 1]
};
break;
case 13:
this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$);
break;
case 14:
this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$);
break;
case 15:
this.$ = {
open: $$[$0 - 5],
path: $$[$0 - 4],
params: $$[$0 - 3],
hash: $$[$0 - 2],
blockParams: $$[$0 - 1],
strip: yy.stripFlags($$[$0 - 5], $$[$0])
};
break;
case 16:
case 17:
this.$ = {
path: $$[$0 - 4],
params: $$[$0 - 3],
hash: $$[$0 - 2],
blockParams: $$[$0 - 1],
strip: yy.stripFlags($$[$0 - 5], $$[$0])
};
break;
case 18:
this.$ = {
strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]),
program: $$[$0]
};
break;
case 19:
var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$),
program = yy.prepareProgram([inverse], $$[$0 - 1].loc);
program.chained = true;
this.$ = {
strip: $$[$0 - 2].strip,
program: program,
chain: true
};
break;
case 21:
this.$ = {
path: $$[$0 - 1],
strip: yy.stripFlags($$[$0 - 2], $$[$0])
};
break;
case 22:
this.$ = yy.prepareMustache(yy.syntax.hash($$[$0 - 1], yy.locInfo(this._$), {
yy: yy,
syntax: 'expr'
}), [], undefined, $$[$0 - 2], yy.stripFlags($$[$0 - 2], $$[$0]), this._$);
break;
case 23:
case 24:
this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
break;
case 25:
this.$ = {
type: 'PartialStatement',
name: $$[$0 - 3],
params: $$[$0 - 2],
hash: $$[$0 - 1],
indent: '',
strip: yy.stripFlags($$[$0 - 4], $$[$0]),
loc: yy.locInfo(this._$)
};
break;
case 26:
this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
break;
case 27:
this.$ = {
path: $$[$0 - 3],
params: $$[$0 - 2],
hash: $$[$0 - 1],
strip: yy.stripFlags($$[$0 - 4], $$[$0])
};
break;
case 32:
this.$ = yy.syntax.hash($$[$0 - 1], yy.locInfo(this._$), {
yy: yy,
syntax: 'expr'
});
break;
case 33:
this.$ = {
type: 'SubExpression',
path: $$[$0 - 3],
params: $$[$0 - 2],
hash: $$[$0 - 1],
loc: yy.locInfo(this._$)
};
break;
case 34:
this.$ = {
type: 'Hash',
pairs: $$[$0],
loc: yy.locInfo(this._$)
};
break;
case 35:
this.$ = {
type: 'HashPair',
key: yy.id($$[$0 - 2]),
value: $$[$0],
loc: yy.locInfo(this._$)
};
break;
case 36:
this.$ = yy.syntax.square($$[$0 - 1], yy.locInfo(this._$), {
yy: yy,
syntax: 'expr'
});
break;
case 37:
this.$ = yy.id($$[$0 - 1]);
break;
case 40:
this.$ = {
type: 'StringLiteral',
value: $$[$0],
original: $$[$0],
loc: yy.locInfo(this._$)
};
break;
case 41:
this.$ = {
type: 'NumberLiteral',
value: Number($$[$0]),
original: Number($$[$0]),
loc: yy.locInfo(this._$)
};
break;
case 42:
this.$ = {
type: 'BooleanLiteral',
value: $$[$0] === 'true',
original: $$[$0] === 'true',
loc: yy.locInfo(this._$)
};
break;
case 43:
this.$ = {
type: 'UndefinedLiteral',
original: undefined,
value: undefined,
loc: yy.locInfo(this._$)
};
break;
case 44:
this.$ = {
type: 'NullLiteral',
original: null,
value: null,
loc: yy.locInfo(this._$)
};
break;
case 45:
this.$ = yy.preparePath(true, false, $$[$0], this._$);
break;
case 48:
this.$ = yy.preparePath(false, $$[$0 - 2], $$[$0], this._$);
break;
case 49:
this.$ = yy.preparePath(false, false, $$[$0], this._$);
break;
case 50:
$$[$0 - 2].push({
part: yy.id($$[$0]),
original: $$[$0],
separator: $$[$0 - 1]
});
this.$ = $$[$0 - 2];
break;
case 51:
this.$ = [{
part: yy.id($$[$0]),
original: $$[$0]
}];
break;
case 52:
case 54:
case 56:
case 64:
case 70:
case 76:
case 84:
case 88:
case 92:
case 96:
case 100:
case 106:
this.$ = [];
break;
case 53:
case 55:
case 57:
case 65:
case 71:
case 77:
case 85:
case 89:
case 93:
case 97:
case 101:
case 105:
case 107:
case 109:
$$[$0 - 1].push($$[$0]);
break;
case 104:
case 108:
this.$ = [$$[$0]];
break;
}
},
table: [o([5, 14, 15, 19, 29, 34, 48, 53, 57, 61], $V0, {
3: 1,
4: 2,
6: 3
}), {
1: [3]
}, {
5: [1, 4]
}, o([5, 39, 44, 47], [2, 2], {
7: 5,
8: 6,
9: 7,
10: 8,
11: 9,
12: 10,
13: 11,
24: 15,
27: 16,
16: 17,
60: 19,
14: [1, 12],
15: $V1,
19: [1, 23],
29: [1, 21],
34: [1, 22],
48: [1, 13],
53: [1, 14],
57: [1, 18],
61: [1, 24]
}), {
1: [2, 1]
}, o($V2, [2, 53]), o($V2, [2, 3]), o($V2, [2, 4]), o($V2, [2, 5]), o($V2, [2, 6]), o($V2, [2, 7]), o($V2, [2, 8]), o($V2, [2, 9]), {
20: 28,
49: 25,
50: 26,
64: 29,
65: 38,
66: 39,
67: $V3,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
20: 28,
50: 45,
64: 29,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, o($Vd, $V0, {
6: 3,
4: 47
}), o($Ve, $V0, {
6: 3,
4: 48
}), o($Vf, [2, 54], {
17: 49
}), {
20: 28,
50: 50,
64: 29,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, o($Vg, $V0, {
6: 3,
4: 51
}), o([5, 14, 15, 18, 19, 29, 34, 39, 44, 47, 48, 53, 57, 61], [2, 10]), {
20: 52,
64: 53,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
20: 54,
64: 53,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
20: 55,
64: 53,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
20: 28,
50: 56,
64: 29,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
33: [1, 57]
}, o($Vh, [2, 84], {
51: 58
}), o([23, 33, 56, 68, 79], [2, 34], {
72: 59,
73: [1, 60]
}), o($Vi, [2, 28]), o($Vi, [2, 29], {
91: 61,
92: $Vj,
93: $Vk
}), o($Vl, [2, 104]), o($Vi, [2, 38]), o($Vi, [2, 39]), o($Vi, [2, 40]), o($Vi, [2, 41]), o($Vi, [2, 42]), o($Vi, [2, 43]), o($Vi, [2, 44]), o($Vm, [2, 30]), o($Vm, [2, 31]), o([23, 33, 56, 67, 68, 73, 75, 79, 84, 85, 86, 87, 88, 89, 92, 93], $Vn, {
74: $Vo
}), o($Vi, [2, 49], {
91: 65,
92: $Vj,
93: $Vk
}), {
73: $Vc,
90: 66
}, o($Vp, [2, 106], {
76: 67
}), {
20: 28,
49: 68,
50: 69,
64: 29,
65: 38,
66: 39,
67: $V3,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, o($Vq, [2, 88], {
54: 70
}), o($Vm, $Vn), {
25: 71,
38: 73,
39: $Vr,
43: 74,
44: $Vs,
45: 72,
47: [2, 60]
}, {
28: 77,
43: 78,
44: $Vs,
47: [2, 62]
}, {
13: 80,
15: $V1,
18: [1, 79]
}, o($Vh, [2, 92], {
58: 81
}), {
26: 82,
47: $Vt
}, o($Vu, [2, 64], {
30: 84
}), {
91: 61,
92: $Vj,
93: $Vk
}, o($Vu, [2, 70], {
35: 85
}), o($Vv, [2, 56], {
21: 86
}), o($Vh, [2, 96], {
62: 87
}), o($V2, [2, 22]), {
20: 28,
33: [2, 86],
49: 90,
50: 89,
52: 88,
64: 29,
65: 38,
66: 39,
67: $V3,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, o($Vl, [2, 105]), {
74: $Vo
}, {
73: $Vc,
90: 91
}, {
73: [2, 46]
}, {
73: [2, 47]
}, {
20: 28,
50: 92,
64: 29,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
73: [1, 93]
}, o($Vi, [2, 45], {
91: 65,
92: $Vj,
93: $Vk
}), {
20: 28,
50: 95,
64: 29,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
77: [1, 94],
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
68: [1, 96]
}, o($Vw, [2, 100], {
69: 97
}), {
20: 28,
49: 100,
50: 99,
55: 98,
56: [2, 90],
64: 29,
65: 38,
66: 39,
67: $V3,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
26: 101,
47: $Vt
}, {
47: [2, 61]
}, o($Vd, $V0, {
6: 3,
4: 102
}), {
47: [2, 20]
}, {
20: 103,
64: 53,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, o($Vg, $V0, {
6: 3,
4: 104
}), {
26: 105,
47: $Vt
}, {
47: [2, 63]
}, o($V2, [2, 11]), o($Vf, [2, 55]), {
20: 28,
33: [2, 94],
49: 108,
50: 107,
59: 106,
64: 29,
65: 38,
66: 39,
67: $V3,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, o($V2, [2, 26]), {
20: 109,
64: 53,
65: 38,
66: 39,
67: $V3,
73: $Vc,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, o($Vx, [2, 66], {
71: 27,
20: 28,
64: 29,
72: 30,
82: 31,
83: 32,
65: 38,
66: 39,
90: 41,
31: 110,
50: 111,
49: 112,
67: $V3,
73: $V4,
75: $V5,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb
}), o($Vx, [2, 72], {
71: 27,
20: 28,
64: 29,
72: 30,
82: 31,
83: 32,
65: 38,
66: 39,
90: 41,
36: 113,
50: 114,
49: 115,
67: $V3,
73: $V4,
75: $V5,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb
}), {
20: 28,
22: 116,
23: [2, 58],
49: 118,
50: 117,
64: 29,
65: 38,
66: 39,
67: $V3,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
20: 28,
33: [2, 98],
49: 121,
50: 120,
63: 119,
64: 29,
65: 38,
66: 39,
67: $V3,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
33: [1, 122]
}, o($Vh, [2, 85]), {
33: [2, 87]
}, o($Vi, [2, 48], {
91: 65,
92: $Vj,
93: $Vk
}), o($Vl, [2, 35]), o($Vm, [2, 50]), o($Vm, [2, 36]), o($Vp, [2, 107]), o($Vm, [2, 32]), {
20: 28,
49: 125,
50: 124,
64: 29,
65: 38,
66: 39,
67: $V3,
68: [2, 102],
70: 123,
71: 27,
72: 30,
73: $V4,
75: $V5,
82: 31,
83: 32,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb,
90: 41
}, {
56: [1, 126]
}, o($Vq, [2, 89]), {
56: [2, 91]
}, o($V2, [2, 13]), {
38: 73,
39: $Vr,
43: 74,
44: $Vs,
45: 128,
46: 127,
47: [2, 82]
}, o($Vu, [2, 76], {
40: 129
}), {
47: [2, 18]
}, o($V2, [2, 14]), {
33: [1, 130]
}, o($Vh, [2, 93]), {
33: [2, 95]
}, {
33: [1, 131]
}, {
32: 132,
33: [2, 68],
78: 133,
79: $Vy
}, o($Vu, [2, 65]), o($Vx, [2, 67]), {
33: [2, 74],
37: 135,
78: 136,
79: $Vy
}, o($Vu, [2, 71]), o($Vx, [2, 73]), {
23: [1, 137]
}, o($Vv, [2, 57]), {
23: [2, 59]
}, {
33: [1, 138]
}, o($Vh, [2, 97]), {
33: [2, 99]
}, o($V2, [2, 23]), {
68: [1, 139]
}, o($Vw, [2, 101]), {
68: [2, 103]
}, o($V2, [2, 24]), {
47: [2, 19]
}, {
47: [2, 83]
}, o($Vx, [2, 78], {
71: 27,
20: 28,
64: 29,
72: 30,
82: 31,
83: 32,
65: 38,
66: 39,
90: 41,
41: 140,
50: 141,
49: 142,
67: $V3,
73: $V4,
75: $V5,
84: $V6,
85: $V7,
86: $V8,
87: $V9,
88: $Va,
89: $Vb
}), o($V2, [2, 25]), o($V2, [2, 21]), {
33: [1, 143]
}, {
33: [2, 69]
}, {
73: [1, 145],
80: 144
}, {
33: [1, 146]
}, {
33: [2, 75]
}, o($Vf, [2, 12]), o($Vg, [2, 27]), o($Vm, [2, 33]), {
33: [2, 80],
42: 147,
78: 148,
79: $Vy
}, o($Vu, [2, 77]), o($Vx, [2, 79]), o($Vd, [2, 15]), {
73: [1, 150],
81: [1, 149]
}, o($Vz, [2, 108]), o($Ve, [2, 16]), {
33: [1, 151]
}, {
33: [2, 81]
}, {
33: [2, 37]
}, o($Vz, [2, 109]), o($Vd, [2, 17])],
defaultActions: {
4: [2, 1],
62: [2, 46],
63: [2, 47],
72: [2, 61],
74: [2, 20],
78: [2, 63],
90: [2, 87],
100: [2, 91],
104: [2, 18],
108: [2, 95],
118: [2, 59],
121: [2, 99],
125: [2, 103],
127: [2, 19],
128: [2, 83],
133: [2, 69],
136: [2, 75],
148: [2, 81],
149: [2, 37]
},
parseError: function parseError(str, hash) {
if (hash.recoverable) {
this.trace(str);
} else {
var error = new Error(str);
error.hash = hash;
throw error;
}
},
parse: function parse(input) {
var self = this,
stack = [0],
vstack = [null],
lstack = [],
table = this.table,
yytext = '',
yylineno = 0,
yyleng = 0,
TERROR = 2,
EOF = 1;
var args = lstack.slice.call(arguments, 1);
var lexer = Object.create(this.lexer);
var sharedState = {
yy: {}
};
for (var k in this.yy) {
if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
sharedState.yy[k] = this.yy[k];
}
}
lexer.setInput(input, sharedState.yy);
sharedState.yy.lexer = lexer;
sharedState.yy.parser = this;
if (typeof lexer.yylloc == 'undefined') {
lexer.yylloc = {};
}
var yyloc = lexer.yylloc;
lstack.push(yyloc);
var ranges = lexer.options && lexer.options.ranges;
if (typeof sharedState.yy.parseError === 'function') {
this.parseError = sharedState.yy.parseError;
} else {
this.parseError = Object.getPrototypeOf(this).parseError;
}
var lex = function () {
var token;
token = lexer.lex() || EOF;
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
};
var symbol,
state,
action,
r,
yyval = {},
p,
len,
newState,
expected;
while (true) {
state = stack[stack.length - 1];
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol === null || typeof symbol == 'undefined') {
symbol = lex();
}
action = table[state] && table[state][symbol];
}
if (typeof action === 'undefined' || !action.length || !action[0]) {
var errStr = '';
expected = [];
for (p in table[state]) {
if (this.terminals_[p] && p > TERROR) {
expected.push('\'' + this.terminals_[p] + '\'');
}
}
if (lexer.showPosition) {
errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
} else {
errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
}
this.parseError(errStr, {
text: lexer.match,
token: this.terminals_[symbol] || symbol,
line: lexer.yylineno,
loc: yyloc,
expected: expected
});
}
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
}
switch (action[0]) {
case 1:
stack.push(symbol);
vstack.push(lexer.yytext);
lstack.push(lexer.yylloc);
stack.push(action[1]);
symbol = null;
{
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
}
break;
case 2:
len = this.productions_[action[1]][1];
yyval.$ = vstack[vstack.length - len];
yyval._$ = {
first_line: lstack[lstack.length - (len || 1)].first_line,
last_line: lstack[lstack.length - 1].last_line,
first_column: lstack[lstack.length - (len || 1)].first_column,
last_column: lstack[lstack.length - 1].last_column
};
if (ranges) {
yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
}
r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args));
if (typeof r !== 'undefined') {
return r;
}
if (len) {
stack = stack.slice(0, -1 * len * 2);
vstack = vstack.slice(0, -1 * len);
lstack = lstack.slice(0, -1 * len);
}
stack.push(this.productions_[action[1]][0]);
vstack.push(yyval.$);
lstack.push(yyval._$);
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
stack.push(newState);
break;
case 3:
return true;
}
}
return true;
}
};
/* generated by jison-lex 0.3.4 */
var lexer = function () {
var lexer = {
EOF: 1,
parseError: function parseError(str, hash) {
if (this.yy.parser) {
this.yy.parser.parseError(str, hash);
} else {
throw new Error(str);
}
},
// resets the lexer, sets new input
setInput: function (input, yy) {
this.yy = yy || this.yy || {};
this._input = input;
this._more = this._backtrack = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (this.options.ranges) {
this.yylloc.range = [0, 0];
}
this.offset = 0;
return this;
},
// consumes and returns one char from the input
input: function () {
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
var lines = ch.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
} else {
this.yylloc.last_column++;
}
if (this.options.ranges) {
this.yylloc.range[1]++;
}
this._input = this._input.slice(1);
return ch;
},
// unshifts one char (or a string) into the input
unput: function (ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - 1);
this.matched = this.matched.substr(0, this.matched.length - 1);
if (lines.length - 1) {
this.yylineno -= lines.length - 1;
}
var r = this.yylloc.range;
this.yylloc = {
first_line: this.yylloc.first_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.first_column,
last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
};
if (this.options.ranges) {
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
}
this.yyleng = this.yytext.length;
return this;
},
// When called from action, caches matched text and appends it on next action
more: function () {
this._more = true;
return this;
},
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject: function () {
if (this.options.backtrack_lexer) {
this._backtrack = true;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
return this;
},
// retain first n characters of the match
less: function (n) {
this.unput(this.match.slice(n));
},
// displays already matched input, i.e. for error messages
pastInput: function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
},
// displays upcoming input, i.e. for error messages
upcomingInput: function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20 - next.length);
}
return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
},
// displays the character position where the lexing error occurred, i.e. for error messages
showPosition: function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c + "^";
},
// test the lexed token: return FALSE when not a match, otherwise return token
test_match: function (match, indexed_rule) {
var token, lines, backup;
if (this.options.backtrack_lexer) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
matched: this.matched,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
_input: this._input,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (this.options.ranges) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
lines = match[0].match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno += lines.length;
}
this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : thi