ember-source
Version:
A JavaScript framework for creating ambitious web applications
1,776 lines (1,763 loc) • 284 kB
JavaScript
import '../@ember/debug/index.js';
import { assert as debugAssert, isPresentArray, assertNever, getFirst, getLast, assign, dict, unwrap, asPresentArray, assertPresentArray, deprecate, expect } from '../@glimmer/util/index.js';
import { SexpOpcodes as opcodes } from '../@glimmer/wire-format/index.js';
import { isDevelopingApp } from '@embroider/macros';
import calculateLocationDisplay from '../@ember/template-compiler/lib/system/calculate-location-display.js';
import { isPath, trackLocals, isStringLiteral } from '../@ember/template-compiler/lib/plugins/utils.js';
import { assert } from '../@ember/debug/lib/assert.js';
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 respnses 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 involed 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 candiacy. 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 statments
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, 44],
$V1 = [1, 20],
$V2 = [5, 14, 15, 19, 29, 34, 39, 44, 47, 48, 52, 56, 60],
$V3 = [1, 35],
$V4 = [1, 38],
$V5 = [1, 30],
$V6 = [1, 31],
$V7 = [1, 32],
$V8 = [1, 33],
$V9 = [1, 34],
$Va = [1, 37],
$Vb = [14, 15, 19, 29, 34, 39, 44, 47, 48, 52, 56, 60],
$Vc = [14, 15, 19, 29, 34, 44, 47, 48, 52, 56, 60],
$Vd = [15, 18],
$Ve = [14, 15, 19, 29, 34, 47, 48, 52, 56, 60],
$Vf = [33, 64, 71, 79, 80, 81, 82, 83, 84],
$Vg = [23, 33, 55, 64, 67, 71, 74, 79, 80, 81, 82, 83, 84],
$Vh = [1, 51],
$Vi = [23, 33, 55, 64, 67, 71, 74, 79, 80, 81, 82, 83, 84, 86],
$Vj = [2, 43],
$Vk = [55, 64, 71, 79, 80, 81, 82, 83, 84],
$Vl = [1, 58],
$Vm = [1, 59],
$Vn = [1, 66],
$Vo = [33, 64, 71, 74, 79, 80, 81, 82, 83, 84],
$Vp = [23, 64, 71, 79, 80, 81, 82, 83, 84],
$Vq = [1, 76],
$Vr = [64, 67, 71, 79, 80, 81, 82, 83, 84],
$Vs = [33, 74],
$Vt = [23, 33, 55, 67, 71, 74],
$Vu = [1, 106],
$Vv = [1, 118],
$Vw = [71, 76];
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,
"expr": 49,
"mustache_repetition0": 50,
"mustache_option0": 51,
"OPEN_UNESCAPED": 52,
"mustache_repetition1": 53,
"mustache_option1": 54,
"CLOSE_UNESCAPED": 55,
"OPEN_PARTIAL": 56,
"partial_repetition0": 57,
"partial_option0": 58,
"openPartialBlock": 59,
"OPEN_PARTIAL_BLOCK": 60,
"openPartialBlock_repetition0": 61,
"openPartialBlock_option0": 62,
"sexpr": 63,
"OPEN_SEXPR": 64,
"sexpr_repetition0": 65,
"sexpr_option0": 66,
"CLOSE_SEXPR": 67,
"hash": 68,
"hash_repetition_plus0": 69,
"hashSegment": 70,
"ID": 71,
"EQUALS": 72,
"blockParams": 73,
"OPEN_BLOCK_PARAMS": 74,
"blockParams_repetition_plus0": 75,
"CLOSE_BLOCK_PARAMS": 76,
"path": 77,
"dataName": 78,
"STRING": 79,
"NUMBER": 80,
"BOOLEAN": 81,
"UNDEFINED": 82,
"NULL": 83,
"DATA": 84,
"pathSegments": 85,
"SEP": 86,
"$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",
52: "OPEN_UNESCAPED",
55: "CLOSE_UNESCAPED",
56: "OPEN_PARTIAL",
60: "OPEN_PARTIAL_BLOCK",
64: "OPEN_SEXPR",
67: "CLOSE_SEXPR",
71: "ID",
72: "EQUALS",
74: "OPEN_BLOCK_PARAMS",
76: "CLOSE_BLOCK_PARAMS",
79: "STRING",
80: "NUMBER",
81: "BOOLEAN",
82: "UNDEFINED",
83: "NULL",
84: "DATA",
86: "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, 5], [8, 5], [11, 5], [12, 3], [59, 5], [49, 1], [49, 1], [63, 5], [68, 1], [70, 3], [73, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [78, 2], [77, 1], [85, 3], [85, 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], [50, 0], [50, 2], [51, 0], [51, 1], [53, 0], [53, 2], [54, 0], [54, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [65, 0], [65, 2], [66, 0], [66, 1], [69, 1], [69, 2], [75, 1], [75, 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 27:
case 28:
case 33:
case 34:
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:
case 23:
this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
break;
case 24:
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 25:
this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
break;
case 26:
this.$ = {
path: $$[$0 - 3],
params: $$[$0 - 2],
hash: $$[$0 - 1],
strip: yy.stripFlags($$[$0 - 4], $$[$0])
};
break;
case 29:
this.$ = {
type: 'SubExpression',
path: $$[$0 - 3],
params: $$[$0 - 2],
hash: $$[$0 - 1],
loc: yy.locInfo(this._$)
};
break;
case 30:
this.$ = {
type: 'Hash',
pairs: $$[$0],
loc: yy.locInfo(this._$)
};
break;
case 31:
this.$ = {
type: 'HashPair',
key: yy.id($$[$0 - 2]),
value: $$[$0],
loc: yy.locInfo(this._$)
};
break;
case 32:
this.$ = yy.id($$[$0 - 1]);
break;
case 35:
this.$ = {
type: 'StringLiteral',
value: $$[$0],
original: $$[$0],
loc: yy.locInfo(this._$)
};
break;
case 36:
this.$ = {
type: 'NumberLiteral',
value: Number($$[$0]),
original: Number($$[$0]),
loc: yy.locInfo(this._$)
};
break;
case 37:
this.$ = {
type: 'BooleanLiteral',
value: $$[$0] === 'true',
original: $$[$0] === 'true',
loc: yy.locInfo(this._$)
};
break;
case 38:
this.$ = {
type: 'UndefinedLiteral',
original: undefined,
value: undefined,
loc: yy.locInfo(this._$)
};
break;
case 39:
this.$ = {
type: 'NullLiteral',
original: null,
value: null,
loc: yy.locInfo(this._$)
};
break;
case 40:
this.$ = yy.preparePath(true, $$[$0], this._$);
break;
case 41:
this.$ = yy.preparePath(false, $$[$0], this._$);
break;
case 42:
$$[$0 - 2].push({
part: yy.id($$[$0]),
original: $$[$0],
separator: $$[$0 - 1]
});
this.$ = $$[$0 - 2];
break;
case 43:
this.$ = [{
part: yy.id($$[$0]),
original: $$[$0]
}];
break;
case 44:
case 46:
case 48:
case 56:
case 62:
case 68:
case 76:
case 80:
case 84:
case 88:
case 92:
this.$ = [];
break;
case 45:
case 47:
case 49:
case 57:
case 63:
case 69:
case 77:
case 81:
case 85:
case 89:
case 93:
case 97:
case 99:
$$[$0 - 1].push($$[$0]);
break;
case 96:
case 98:
this.$ = [$$[$0]];
break;
}
},
table: [o([5, 14, 15, 19, 29, 34, 48, 52, 56, 60], $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,
59: 19,
14: [1, 12],
15: $V1,
19: [1, 23],
29: [1, 21],
34: [1, 22],
48: [1, 13],
52: [1, 14],
56: [1, 18],
60: [1, 24]
}), {
1: [2, 1]
}, o($V2, [2, 45]), 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: 26,
49: 25,
63: 27,
64: $V3,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
20: 26,
49: 39,
63: 27,
64: $V3,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Vb, $V0, {
6: 3,
4: 40
}), o($Vc, $V0, {
6: 3,
4: 41
}), o($Vd, [2, 46], {
17: 42
}), {
20: 26,
49: 43,
63: 27,
64: $V3,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Ve, $V0, {
6: 3,
4: 44
}), o([5, 14, 15, 18, 19, 29, 34, 39, 44, 47, 48, 52, 56, 60], [2, 10]), {
20: 45,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
20: 46,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
20: 47,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
20: 26,
49: 48,
63: 27,
64: $V3,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Vf, [2, 76], {
50: 49
}), o($Vg, [2, 27]), o($Vg, [2, 28]), o($Vg, [2, 33]), o($Vg, [2, 34]), o($Vg, [2, 35]), o($Vg, [2, 36]), o($Vg, [2, 37]), o($Vg, [2, 38]), o($Vg, [2, 39]), {
20: 26,
49: 50,
63: 27,
64: $V3,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Vg, [2, 41], {
86: $Vh
}), {
71: $V4,
85: 52
}, o($Vi, $Vj), o($Vk, [2, 80], {
53: 53
}), {
25: 54,
38: 56,
39: $Vl,
43: 57,
44: $Vm,
45: 55,
47: [2, 52]
}, {
28: 60,
43: 61,
44: $Vm,
47: [2, 54]
}, {
13: 63,
15: $V1,
18: [1, 62]
}, o($Vf, [2, 84], {
57: 64
}), {
26: 65,
47: $Vn
}, o($Vo, [2, 56], {
30: 67
}), o($Vo, [2, 62], {
35: 68
}), o($Vp, [2, 48], {
21: 69
}), o($Vf, [2, 88], {
61: 70
}), {
20: 26,
33: [2, 78],
49: 72,
51: 71,
63: 27,
64: $V3,
68: 73,
69: 74,
70: 75,
71: $Vq,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Vr, [2, 92], {
65: 77
}), {
71: [1, 78]
}, o($Vg, [2, 40], {
86: $Vh
}), {
20: 26,
49: 80,
54: 79,
55: [2, 82],
63: 27,
64: $V3,
68: 81,
69: 74,
70: 75,
71: $Vq,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
26: 82,
47: $Vn
}, {
47: [2, 53]
}, o($Vb, $V0, {
6: 3,
4: 83
}), {
47: [2, 20]
}, {
20: 84,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Ve, $V0, {
6: 3,
4: 85
}), {
26: 86,
47: $Vn
}, {
47: [2, 55]
}, o($V2, [2, 11]), o($Vd, [2, 47]), {
20: 26,
33: [2, 86],
49: 88,
58: 87,
63: 27,
64: $V3,
68: 89,
69: 74,
70: 75,
71: $Vq,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($V2, [2, 25]), {
20: 90,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Vs, [2, 58], {
20: 26,
63: 27,
77: 28,
78: 29,
85: 36,
69: 74,
70: 75,
31: 91,
49: 92,
68: 93,
64: $V3,
71: $Vq,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va
}), o($Vs, [2, 64], {
20: 26,
63: 27,
77: 28,
78: 29,
85: 36,
69: 74,
70: 75,
36: 94,
49: 95,
68: 96,
64: $V3,
71: $Vq,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va
}), {
20: 26,
22: 97,
23: [2, 50],
49: 98,
63: 27,
64: $V3,
68: 99,
69: 74,
70: 75,
71: $Vq,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
20: 26,
33: [2, 90],
49: 101,
62: 100,
63: 27,
64: $V3,
68: 102,
69: 74,
70: 75,
71: $Vq,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
33: [1, 103]
}, o($Vf, [2, 77]), {
33: [2, 79]
}, o([23, 33, 55, 67, 74], [2, 30], {
70: 104,
71: [1, 105]
}), o($Vt, [2, 96]), o($Vi, $Vj, {
72: $Vu
}), {
20: 26,
49: 108,
63: 27,
64: $V3,
66: 107,
67: [2, 94],
68: 109,
69: 74,
70: 75,
71: $Vq,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, o($Vi, [2, 42]), {
55: [1, 110]
}, o($Vk, [2, 81]), {
55: [2, 83]
}, o($V2, [2, 13]), {
38: 56,
39: $Vl,
43: 57,
44: $Vm,
45: 112,
46: 111,
47: [2, 74]
}, o($Vo, [2, 68], {
40: 113
}), {
47: [2, 18]
}, o($V2, [2, 14]), {
33: [1, 114]
}, o($Vf, [2, 85]), {
33: [2, 87]
}, {
33: [1, 115]
}, {
32: 116,
33: [2, 60],
73: 117,
74: $Vv
}, o($Vo, [2, 57]), o($Vs, [2, 59]), {
33: [2, 66],
37: 119,
73: 120,
74: $Vv
}, o($Vo, [2, 63]), o($Vs, [2, 65]), {
23: [1, 121]
}, o($Vp, [2, 49]), {
23: [2, 51]
}, {
33: [1, 122]
}, o($Vf, [2, 89]), {
33: [2, 91]
}, o($V2, [2, 22]), o($Vt, [2, 97]), {
72: $Vu
}, {
20: 26,
49: 123,
63: 27,
64: $V3,
71: $V4,
77: 28,
78: 29,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va,
85: 36
}, {
67: [1, 124]
}, o($Vr, [2, 93]), {
67: [2, 95]
}, o($V2, [2, 23]), {
47: [2, 19]
}, {
47: [2, 75]
}, o($Vs, [2, 70], {
20: 26,
63: 27,
77: 28,
78: 29,
85: 36,
69: 74,
70: 75,
41: 125,
49: 126,
68: 127,
64: $V3,
71: $Vq,
79: $V5,
80: $V6,
81: $V7,
82: $V8,
83: $V9,
84: $Va
}), o($V2, [2, 24]), o($V2, [2, 21]), {
33: [1, 128]
}, {
33: [2, 61]
}, {
71: [1, 130],
75: 129
}, {
33: [1, 131]
}, {
33: [2, 67]
}, o($Vd, [2, 12]), o($Ve, [2, 26]), o($Vt, [2, 31]), o($Vg, [2, 29]), {
33: [2, 72],
42: 132,
73: 133,
74: $Vv
}, o($Vo, [2, 69]), o($Vs, [2, 71]), o($Vb, [2, 15]), {
71: [1, 135],
76: [1, 134]
}, o($Vw, [2, 98]), o($Vc, [2, 16]), {
33: [1, 136]
}, {
33: [2, 73]
}, {
33: [2, 32]
}, o($Vw, [2, 99]), o($Vb, [2, 17])],
defaultActions: {
4: [2, 1],
55: [2, 53],
57: [2, 20],
61: [2, 55],
73: [2, 79],
81: [2, 83],
85: [2, 18],
89: [2, 87],
99: [2, 51],
102: [2, 91],
109: [2, 95],
111: [2, 19],
112: [2, 75],
117: [2, 61],
120: [2, 67],
133: [2, 73],
134: [2, 32]
},
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 : this.yylloc.last_column + match[0].length
};
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset += this.yyleng];
}
this._more = false;
this._backtrack = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
if (this.done && this._input) {
this.done = false;
}
if (token) {
return token;
} else if (this._backtrack) {
// recover context
for (var k in backup) {
this[k] = backup[k];
}
return false; // rule action called reject() implying the next rule should be tested instead.
}
return false;
},
// return next match in input
next: function () {
if (this.done) {
return this.EOF;
}
if (!this._input) {
this.done = true;
}
var token, match, tempMatch, index;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i = 0; i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (this.options.backtrack_lexer) {
token = this.test_match(tempMatch, rules[i]);
if (token !== false) {
return token;
} else if (this._backtrack) {
match = false;
continue; // rule action called reject() implying a rule MISmatch.
} else {
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
} else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rules[index]);
if (token !== false) {
return token;
}
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
if (this._input === "") {
return this.EOF;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
},
// return next match that has a token
lex: function lex() {
var r = this.next();
if (r) {
return r;
} else {
return this.lex();
}
},
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin: function begin(condition) {
this.conditionStack.push(condition);
},
// pop the previously active lexer condition state off the condition stack
popState: function popState() {
var n = this.conditionStack.length - 1;
if (n > 0) {
return this.conditionStack.pop();
} else {
return this.conditionStack[0];
}
},
// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules: function _currentRules() {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
} else {
return this.conditions["INITIAL"].rules;
}
},
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState: function topState(n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
if (n >= 0) {
return this.conditionStack[n];
} else {
return "INITIAL";
}
},
// alias for begin(condition)
pushState: function pushState(condition) {
this.begin(condition);
},
// return the number of states currently on the stack
stateStackSize: function stateStackSize() {
return this.conditionStack.length