Use Codie for code templates

This will allow moving some code into the templates later.
redux
David Majda 13 years ago
parent 38c25efde0
commit 0748fee1d3

@ -1,79 +1,238 @@
/* Emits the generated code for the AST. */
PEG.compiler.emitter = function(ast) {
/*
* Takes parts of code, interpolates variables inside them and joins them with
* a newline.
*
* Variables are delimited with "${" and "}" and their names must be valid
* identifiers (i.e. they must match [a-zA-Z_][a-zA-Z0-9_]*). Variable values
* are specified as properties of the last parameter (if this is an object,
* otherwise empty variable set is assumed). Undefined variables result in
* throwing |Error|.
*
* There can be a filter specified after the variable name, prefixed with "|".
* The filter name must be a valid identifier. The only recognized filter
* right now is "string", which quotes the variable value as a JavaScript
* string. Unrecognized filters result in throwing |Error|.
*
* If any part has multiple lines and the first line is indented by some
* amount of whitespace (as defined by the /\s+/ JavaScript regular
* expression), second to last lines are indented by the same amount of
* whitespace. This results in nicely indented multiline code in variables
* without making the templates look ugly.
*
* Examples:
*
* formatCode("foo", "bar"); // "foo\nbar"
* formatCode("foo", "${bar}", { bar: "baz" }); // "foo\nbaz"
* formatCode("foo", "${bar}"); // throws Error
* formatCode("foo", "${bar|string}", { bar: "baz" }); // "foo\n\"baz\""
* formatCode("foo", "${bar|eeek}", { bar: "baz" }); // throws Error
* formatCode("foo", "${bar}", { bar: " baz\nqux" }); // "foo\n baz\n qux"
*/
function formatCode() {
function interpolateVariablesInParts(parts) {
return map(parts, function(part) {
return part.replace(
/\$\{([a-zA-Z_][a-zA-Z0-9_]*)(\|([a-zA-Z_][a-zA-Z0-9_]*))?\}/g,
function(match, name, dummy, filter) {
var value = vars[name];
if (value === undefined) {
throw new Error("Undefined variable: \"" + name + "\".");
}
var Codie = (function(undefined) {
function stringEscape(s) {
function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
if (filter !== undefined && filter !== "") { // JavaScript engines differ here.
if (filter === "string") {
return quote(value);
} else {
throw new Error("Unrecognized filter: \"" + filter + "\".");
}
/*
* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
* string literal except for the closing quote character, backslash,
* carriage return, line separator, paragraph separator, and line feed.
* Any character may appear in the form of an escape sequence.
*
* For portability, we also escape escape all control and non-ASCII
* characters. Note that "\0" and "\v" escape sequences are not used
* because JSHint does not like the first and IE the second.
*/
return s
.replace(/\\/g, '\\\\') // backslash
.replace(/"/g, '\\"') // closing double quote
.replace(/\x08/g, '\\b') // backspace
.replace(/\t/g, '\\t') // horizontal tab
.replace(/\n/g, '\\n') // line feed
.replace(/\f/g, '\\f') // form feed
.replace(/\r/g, '\\r') // carriage return
.replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
.replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
.replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
}
function push(s) { return '__p.push(' + s + ');'; }
function pushRaw(template, length, state) {
function unindent(code, level, unindentFirst) {
return code.replace(
new RegExp('^.{' + level +'}', "gm"),
function(str, offset) {
if (offset === 0) {
return unindentFirst ? '' : str;
} else {
return value;
return "";
}
}
);
});
}
}
function indentMultilineParts(parts) {
return map(parts, function(part) {
if (!/\n/.test(part)) { return part; }
var escaped = stringEscape(unindent(
template.substring(0, length),
state.indentLevel(),
state.atBOL
));
var firstLineWhitespacePrefix = part.match(/^\s*/)[0];
var lines = part.split("\n");
var linesIndented = [lines[0]].concat(
map(lines.slice(1), function(line) {
return firstLineWhitespacePrefix + line;
})
);
return linesIndented.join("\n");
});
return escaped.length > 0 ? push('"' + escaped + '"') : '';
}
var Codie = {
/*
* Specifies by how many characters do #if/#else and #for unindent their
* content in the generated code.
*/
indentStep: 2,
/* Description of #-commands. Extend to define your own commands. */
commands: {
"if": {
params: /^(.*)$/,
compile: function(state, prefix, params) {
return ['if(' + params[0] + '){', []];
},
stackOp: "push"
},
"else": {
params: /^$/,
compile: function(state) {
var stack = state.commandStack,
insideElse = stack[stack.length - 1] === "else",
insideIf = stack[stack.length - 1] === "if";
if (insideElse) { throw new Error("Multiple #elses."); }
if (!insideIf) { throw new Error("Using #else outside of #if."); }
return ['}else{', []];
},
stackOp: "replace"
},
"for": {
params: /^([a-zA-Z_][a-zA-Z0-9_]*)[ \t]+in[ \t]+(.*)$/,
init: function(state) {
state.forCurrLevel = 0; // current level of #for loop nesting
state.forMaxLevel = 0; // maximum level of #for loop nesting
},
compile: function(state, prefix, params) {
var c = '__c' + state.forCurrLevel, // __c for "collection"
l = '__l' + state.forCurrLevel, // __l for "length"
i = '__i' + state.forCurrLevel; // __i for "index"
state.forCurrLevel++;
if (state.forMaxLevel < state.forCurrLevel) {
state.forMaxLevel = state.forCurrLevel;
}
return [
c + '=' + params[1] + ';'
+ l + '=' + c + '.length;'
+ 'for(' + i + '=0;' + i + '<' + l + ';' + i + '++){'
+ params[0] + '=' + c + '[' + i + '];',
[params[0], c, l, i]
];
},
exit: function(state) { state.forCurrLevel--; },
stackOp: "push"
},
"end": {
params: /^$/,
compile: function(state) {
var stack = state.commandStack, exit;
if (stack.length === 0) { throw new Error("Too many #ends."); }
exit = Codie.commands[stack[stack.length - 1]].exit;
if (exit) { exit(state); }
return ['}', []];
},
stackOp: "pop"
},
"block": {
params: /^(.*)$/,
compile: function(state, prefix, params) {
return [
push('(' + params[0] + ').toString().replace(/^/gm, "'
+ stringEscape(prefix.substring(state.indentLevel()))
+ '") + "\\n"'),
[]
];
},
stackOp: "nop"
}
},
/*
* Compiles a template into a function. When called, this function will
* execute the template in the context of an object passed in a parameter and
* return the result.
*/
template: function(template) {
var stackOps = {
push: function(stack, name) { stack.push(name); },
replace: function(stack, name) { stack[stack.length - 1] = name; },
pop: function(stack) { stack.pop(); },
nop: function() { }
};
function compileExpr(state, expr) {
state.atBOL = false;
return [push(expr), []];
}
function compileCommand(state, prefix, name, params) {
var command, match, result;
command = Codie.commands[name];
if (!command) { throw new Error("Unknown command: #" + name + "."); }
match = command.params.exec(params);
if (match === null) {
throw new Error(
"Invalid params for command #" + name + ": " + params + "."
);
}
result = command.compile(state, prefix, match.slice(1));
stackOps[command.stackOp](state.commandStack, name);
state.atBOL = true;
return result;
}
var state = { // compilation state
commandStack: [], // stack of commands as they were nested
atBOL: true, // is the next character to process at BOL?
indentLevel: function() {
return Codie.indentStep * this.commandStack.length;
}
},
code = '', // generated template function code
vars = ['__p=[]'], // variables used by generated code
name, match, result, i;
/* Initialize state. */
for (name in Codie.commands) {
if (Codie.commands[name].init) { Codie.commands[name].init(state); }
}
/* Compile the template. */
while ((match = /^([ \t]*)#([a-zA-Z_][a-zA-Z0-9_]*)(?:[ \t]+([^ \t\n][^\n]*))?[ \t]*(?:\n|$)|#\{([^}]*)\}/m.exec(template)) !== null) {
code += pushRaw(template, match.index, state);
result = match[2] !== undefined && match[2] !== ""
? compileCommand(state, match[1], match[2], match[3] || "") // #-command
: compileExpr(state, match[4]); // #{...}
code += result[0];
vars = vars.concat(result[1]);
template = template.substring(match.index + match[0].length);
}
code += pushRaw(template, template.length, state);
/* Check the final state. */
if (state.commandStack.length > 0) { throw new Error("Missing #end."); }
/* Sanitize the list of variables used by commands. */
vars.sort();
for (i = 0; i < vars.length; i++) {
if (vars[i] === vars[i - 1]) { vars.splice(i--, 1); }
}
/* Create the resulting function. */
return new Function("__v", [
'__v=__v||{};',
'var ' + vars.join(',') + ';',
'with(__v){',
code,
'return __p.join("").replace(/^\\n+|\\n+$/g,"");};'
].join(''));
}
};
return Codie;
})();
function formatCode() {
var args = Array.prototype.slice.call(arguments);
var vars = args[args.length - 1] instanceof Object ? args.pop() : {};
return indentMultilineParts(interpolateVariablesInParts(args)).join("\n");
vars.string = quote;
return Codie.template(args.join('\n'))(vars);
}
function resultVar(index) { return "result" + index; }
@ -110,7 +269,7 @@ PEG.compiler.emitter = function(ast) {
' */',
' parse: function(input, startRule) {',
' var parseFunctions = {',
' ${parseFunctionTableItems}',
' #block parseFunctionTableItems',
' };',
' ',
' if (startRule !== undefined) {',
@ -118,7 +277,7 @@ PEG.compiler.emitter = function(ast) {
' throw new Error("Invalid rule name: " + quote(startRule) + ".");',
' }',
' } else {',
' startRule = ${startRule|string};',
' startRule = #{string(startRule)};',
' }',
' ',
' var pos = 0;',
@ -193,7 +352,7 @@ PEG.compiler.emitter = function(ast) {
' rightmostFailuresExpected.push(failure);',
' }',
' ',
' ${parseFunctionDefinitions}',
' #block parseFunctionDefinitions',
' ',
' function buildErrorMessage() {',
' function buildExpected(failuresExpected) {',
@ -260,7 +419,7 @@ PEG.compiler.emitter = function(ast) {
' return { line: line, column: column };',
' }',
' ',
' ${initializerCode}',
' #block initializerCode',
' ',
' var result = parseFunctions[startRule]();',
' ',
@ -354,8 +513,8 @@ PEG.compiler.emitter = function(ast) {
'reportFailures--;'
);
reportFailureCode = formatCode(
'if (reportFailures === 0 && ${resultVar} === null) {',
' matchFailed(${displayName|string});',
'if (reportFailures === 0 && #{resultVar} === null) {',
' matchFailed(#{string(displayName)});',
'}',
{
displayName: node.displayName,
@ -369,27 +528,27 @@ PEG.compiler.emitter = function(ast) {
}
return formatCode(
'function parse_${name}() {',
' var cacheKey = "${name}@" + pos;',
'function parse_#{name}() {',
' var cacheKey = "#{name}@" + pos;',
' var cachedResult = cache[cacheKey];',
' if (cachedResult) {',
' pos = cachedResult.nextPos;',
' return cachedResult.result;',
' }',
' ',
' ${resultVarsCode}',
' ${posVarsCode}',
' #block resultVarsCode',
' #block posVarsCode',
' ',
' ${setReportFailuresCode}',
' ${code}',
' ${restoreReportFailuresCode}',
' ${reportFailureCode}',
' #block setReportFailuresCode',
' #block code',
' #block restoreReportFailuresCode',
' #block reportFailureCode',
' ',
' cache[cacheKey] = {',
' nextPos: pos,',
' result: ${resultVar}',
' result: #{resultVar}',
' };',
' return ${resultVar};',
' return #{resultVar};',
'}',
{
name: node.name,
@ -440,8 +599,8 @@ PEG.compiler.emitter = function(ast) {
for (var i = node.alternatives.length - 1; i >= 0; i--) {
nextAlternativesCode = i !== node.alternatives.length - 1
? formatCode(
'if (${resultVar} === null) {',
' ${code}',
'if (#{resultVar} === null) {',
' #block code',
'}',
{
code: code,
@ -450,8 +609,8 @@ PEG.compiler.emitter = function(ast) {
)
: '';
code = formatCode(
'${currentAlternativeCode}',
'${nextAlternativesCode}',
'#block currentAlternativeCode',
'#block nextAlternativesCode',
{
currentAlternativeCode: emit(node.alternatives[i], context),
nextAlternativesCode: nextAlternativesCode
@ -468,7 +627,7 @@ PEG.compiler.emitter = function(ast) {
});
var code = formatCode(
'${resultVar} = ${elementResultVarArray};',
'#{resultVar} = #{elementResultVarArray};',
{
resultVar: resultVar(context.resultIndex),
elementResultVarArray: '[' + elementResultVars.join(', ') + ']'
@ -482,12 +641,12 @@ PEG.compiler.emitter = function(ast) {
posIndex: context.posIndex + 1
};
code = formatCode(
'${elementCode}',
'if (${elementResultVar} !== null) {',
' ${code}',
'#block elementCode',
'if (#{elementResultVar} !== null) {',
' #block code',
'} else {',
' ${resultVar} = null;',
' pos = ${posVar};',
' #{resultVar} = null;',
' pos = #{posVar};',
'}',
{
elementCode: emit(node.elements[i], elementContext),
@ -500,8 +659,8 @@ PEG.compiler.emitter = function(ast) {
}
return formatCode(
'${posVar} = pos;',
'${code}',
'#{posVar} = pos;',
'#block code',
{
code: code,
posVar: posVar(context.posIndex)
@ -520,15 +679,15 @@ PEG.compiler.emitter = function(ast) {
};
return formatCode(
'${posVar} = pos;',
'#{posVar} = pos;',
'reportFailures++;',
'${expressionCode}',
'#block expressionCode',
'reportFailures--;',
'if (${resultVar} !== null) {',
' ${resultVar} = "";',
' pos = ${posVar};',
'if (#{resultVar} !== null) {',
' #{resultVar} = "";',
' pos = #{posVar};',
'} else {',
' ${resultVar} = null;',
' #{resultVar} = null;',
'}',
{
expressionCode: emit(node.expression, expressionContext),
@ -545,15 +704,15 @@ PEG.compiler.emitter = function(ast) {
};
return formatCode(
'${posVar} = pos;',
'#{posVar} = pos;',
'reportFailures++;',
'${expressionCode}',
'#block expressionCode',
'reportFailures--;',
'if (${resultVar} === null) {',
' ${resultVar} = "";',
'if (#{resultVar} === null) {',
' #{resultVar} = "";',
'} else {',
' ${resultVar} = null;',
' pos = ${posVar};',
' #{resultVar} = null;',
' pos = #{posVar};',
'}',
{
expressionCode: emit(node.expression, expressionContext),
@ -565,7 +724,7 @@ PEG.compiler.emitter = function(ast) {
semantic_and: function(node, context) {
return formatCode(
'${resultVar} = (function() {${actionCode}})() ? "" : null;',
'#{resultVar} = (function() {#{actionCode}})() ? "" : null;',
{
actionCode: node.code,
resultVar: resultVar(context.resultIndex)
@ -575,7 +734,7 @@ PEG.compiler.emitter = function(ast) {
semantic_not: function(node, context) {
return formatCode(
'${resultVar} = (function() {${actionCode}})() ? null : "";',
'#{resultVar} = (function() {#{actionCode}})() ? null : "";',
{
actionCode: node.code,
resultVar: resultVar(context.resultIndex)
@ -585,8 +744,8 @@ PEG.compiler.emitter = function(ast) {
optional: function(node, context) {
return formatCode(
'${expressionCode}',
'${resultVar} = ${resultVar} !== null ? ${resultVar} : "";',
'#block expressionCode',
'#{resultVar} = #{resultVar} !== null ? #{resultVar} : "";',
{
expressionCode: emit(node.expression, context),
resultVar: resultVar(context.resultIndex)
@ -601,11 +760,11 @@ PEG.compiler.emitter = function(ast) {
};
return formatCode(
'${resultVar} = [];',
'${expressionCode}',
'while (${expressionResultVar} !== null) {',
' ${resultVar}.push(${expressionResultVar});',
' ${expressionCode}',
'#{resultVar} = [];',
'#block expressionCode',
'while (#{expressionResultVar} !== null) {',
' #{resultVar}.push(#{expressionResultVar});',
' #block expressionCode',
'}',
{
expressionCode: emit(node.expression, expressionContext),
@ -622,15 +781,15 @@ PEG.compiler.emitter = function(ast) {
};
return formatCode(
'${expressionCode}',
'if (${expressionResultVar} !== null) {',
' ${resultVar} = [];',
' while (${expressionResultVar} !== null) {',
' ${resultVar}.push(${expressionResultVar});',
' ${expressionCode}',
'#block expressionCode',
'if (#{expressionResultVar} !== null) {',
' #{resultVar} = [];',
' while (#{expressionResultVar} !== null) {',
' #{resultVar}.push(#{expressionResultVar});',
' #block expressionCode',
' }',
'} else {',
' ${resultVar} = null;',
' #{resultVar} = null;',
'}',
{
expressionCode: emit(node.expression, expressionContext),
@ -679,13 +838,13 @@ PEG.compiler.emitter = function(ast) {
}
return formatCode(
'${posVar} = pos;',
'${expressionCode}',
'if (${resultVar} !== null) {',
' ${resultVar} = (function(${formalParams}) {${actionCode}})(${actualParams});',
'#{posVar} = pos;',
'#block expressionCode',
'if (#{resultVar} !== null) {',
' #{resultVar} = (function(#{formalParams}) {#{actionCode}})(#{actualParams});',
'}',
'if (${resultVar} === null) {',
' pos = ${posVar};',
'if (#{resultVar} === null) {',
' pos = #{posVar};',
'}',
{
expressionCode: emit(node.expression, expressionContext),
@ -700,7 +859,7 @@ PEG.compiler.emitter = function(ast) {
rule_ref: function(node, context) {
return formatCode(
'${resultVar} = ${ruleMethod}();',
'#{resultVar} = #{ruleMethod}();',
{
ruleMethod: 'parse_' + node.name,
resultVar: resultVar(context.resultIndex)
@ -713,18 +872,18 @@ PEG.compiler.emitter = function(ast) {
if (length === 0) {
return formatCode(
'${resultVar} = "";',
'#{resultVar} = "";',
{ resultVar: resultVar(context.resultIndex) }
);
}
var testCode = length === 1
? formatCode(
'input.charCodeAt(pos) === ${valueCharCode}',
'input.charCodeAt(pos) === #{valueCharCode}',
{ valueCharCode: node.value.charCodeAt(0) }
)
: formatCode(
'input.substr(pos, ${length}) === ${value|string}',
'input.substr(pos, #{length}) === #{string(value)}',
{
value: node.value,
length: length
@ -732,13 +891,13 @@ PEG.compiler.emitter = function(ast) {
);
return formatCode(
'if (${testCode}) {',
' ${resultVar} = ${value|string};',
' pos += ${length};',
'if (#{testCode}) {',
' #{resultVar} = #{string(value)};',
' pos += #{length};',
'} else {',
' ${resultVar} = null;',
' #{resultVar} = null;',
' if (reportFailures === 0) {',
' matchFailed(${valueQuoted|string});',
' matchFailed(#{string(valueQuoted)});',
' }',
'}',
{
@ -754,10 +913,10 @@ PEG.compiler.emitter = function(ast) {
any: function(node, context) {
return formatCode(
'if (input.length > pos) {',
' ${resultVar} = input.charAt(pos);',
' #{resultVar} = input.charAt(pos);',
' pos++;',
'} else {',
' ${resultVar} = null;',
' #{resultVar} = null;',
' if (reportFailures === 0) {',
' matchFailed("any character");',
' }',
@ -789,13 +948,13 @@ PEG.compiler.emitter = function(ast) {
}
return formatCode(
'if (${regexp}.test(input.charAt(pos))) {',
' ${resultVar} = input.charAt(pos);',
'if (#{regexp}.test(input.charAt(pos))) {',
' #{resultVar} = input.charAt(pos);',
' pos++;',
'} else {',
' ${resultVar} = null;',
' #{resultVar} = null;',
' if (reportFailures === 0) {',
' matchFailed(${rawText|string});',
' matchFailed(#{string(rawText)});',
' }',
'}',
{

@ -189,16 +189,16 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(initializer, rules) {
var rulesConverted = {};
each(rules, function(rule) { rulesConverted[rule.name] = rule; });
return {
type: "grammar",
initializer: initializer !== "" ? initializer : null,
rules: rulesConverted,
startRule: rules[0].name
};
})(result0[1], result0[2]);
var rulesConverted = {};
each(rules, function(rule) { rulesConverted[rule.name] = rule; });
return {
type: "grammar",
initializer: initializer !== "" ? initializer : null,
rules: rulesConverted,
startRule: rules[0].name
};
})(result0[1], result0[2]);
}
if (result0 === null) {
pos = pos0;
@ -243,11 +243,11 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(code) {
return {
type: "initializer",
code: code
};
})(result0[0]);
return {
type: "initializer",
code: code
};
})(result0[0]);
}
if (result0 === null) {
pos = pos0;
@ -281,7 +281,6 @@ PEG.parser = (function(){
result1 = parse_literal();
if (result1 === null) {
result1 = "";
}
if (result1 !== null) {
result2 = parse_equals();
@ -314,13 +313,13 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(name, displayName, expression) {
return {
type: "rule",
name: name,
displayName: displayName !== "" ? displayName : null,
expression: expression
};
})(result0[0], result0[1], result0[3]);
return {
type: "rule",
name: name,
displayName: displayName !== "" ? displayName : null,
expression: expression
};
})(result0[0], result0[1], result0[3]);
}
if (result0 === null) {
pos = pos0;
@ -395,19 +394,19 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(head, tail) {
if (tail.length > 0) {
var alternatives = [head].concat(map(
tail,
function(element) { return element[1]; }
));
return {
type: "choice",
alternatives: alternatives
};
} else {
return head;
}
})(result0[0], result0[1]);
if (tail.length > 0) {
var alternatives = [head].concat(map(
tail,
function(element) { return element[1]; }
));
return {
type: "choice",
alternatives: alternatives
};
} else {
return head;
}
})(result0[0], result0[1]);
}
if (result0 === null) {
pos = pos0;
@ -456,18 +455,18 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(elements, code) {
var expression = elements.length !== 1
? {
type: "sequence",
elements: elements
}
: elements[0];
return {
type: "action",
expression: expression,
code: code
};
})(result0[0], result0[1]);
var expression = elements.length !== 1
? {
type: "sequence",
elements: elements
}
: elements[0];
return {
type: "action",
expression: expression,
code: code
};
})(result0[0], result0[1]);
}
if (result0 === null) {
pos = pos0;
@ -482,18 +481,17 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(elements) {
return elements.length !== 1
? {
type: "sequence",
elements: elements
}
: elements[0];
})(result0);
return elements.length !== 1
? {
type: "sequence",
elements: elements
}
: elements[0];
})(result0);
}
if (result0 === null) {
pos = pos0;
}
}
@ -540,19 +538,18 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(label, expression) {
return {
type: "labeled",
label: label,
expression: expression
};
})(result0[0], result0[2]);
return {
type: "labeled",
label: label,
expression: expression
};
})(result0[0], result0[2]);
}
if (result0 === null) {
pos = pos0;
}
if (result0 === null) {
result0 = parse_prefixed();
}
@ -593,11 +590,11 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(code) {
return {
type: "semantic_and",
code: code
};
})(result0[1]);
return {
type: "semantic_and",
code: code
};
})(result0[1]);
}
if (result0 === null) {
pos = pos0;
@ -620,11 +617,11 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(expression) {
return {
type: "simple_and",
expression: expression
};
})(result0[1]);
return {
type: "simple_and",
expression: expression
};
})(result0[1]);
}
if (result0 === null) {
pos = pos0;
@ -647,11 +644,11 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(code) {
return {
type: "semantic_not",
code: code
};
})(result0[1]);
return {
type: "semantic_not",
code: code
};
})(result0[1]);
}
if (result0 === null) {
pos = pos0;
@ -674,18 +671,17 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(expression) {
return {
type: "simple_not",
expression: expression
};
})(result0[1]);
return {
type: "simple_not",
expression: expression
};
})(result0[1]);
}
if (result0 === null) {
pos = pos0;
}
if (result0 === null) {
result0 = parse_suffixed();
}
}
}
@ -729,11 +725,11 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(expression) {
return {
type: "optional",
expression: expression
};
})(result0[0]);
return {
type: "optional",
expression: expression
};
})(result0[0]);
}
if (result0 === null) {
pos = pos0;
@ -756,11 +752,11 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(expression) {
return {
type: "zero_or_more",
expression: expression
};
})(result0[0]);
return {
type: "zero_or_more",
expression: expression
};
})(result0[0]);
}
if (result0 === null) {
pos = pos0;
@ -783,18 +779,17 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(expression) {
return {
type: "one_or_more",
expression: expression
};
})(result0[0]);
return {
type: "one_or_more",
expression: expression
};
})(result0[0]);
}
if (result0 === null) {
pos = pos0;
}
if (result0 === null) {
result0 = parse_primary();
}
}
}
@ -830,7 +825,6 @@ PEG.parser = (function(){
result1 = parse_literal();
if (result1 === null) {
result1 = "";
}
if (result1 !== null) {
result2 = parse_equals();
@ -863,11 +857,11 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(name) {
return {
type: "rule_ref",
name: name
};
})(result0[0]);
return {
type: "rule_ref",
name: name
};
})(result0[0]);
}
if (result0 === null) {
pos = pos0;
@ -877,11 +871,11 @@ PEG.parser = (function(){
result0 = parse_literal();
if (result0 !== null) {
result0 = (function(value) {
return {
type: "literal",
value: value
};
})(result0);
return {
type: "literal",
value: value
};
})(result0);
}
if (result0 === null) {
pos = pos0;
@ -925,7 +919,6 @@ PEG.parser = (function(){
if (result0 === null) {
pos = pos0;
}
}
}
}
@ -1013,14 +1006,12 @@ PEG.parser = (function(){
result2 = parse_braced();
if (result2 === null) {
result2 = parse_nonBraceCharacter();
}
while (result2 !== null) {
result1.push(result2);
result2 = parse_braced();
if (result2 === null) {
result2 = parse_nonBraceCharacter();
}
}
if (result1 !== null) {
@ -1049,8 +1040,8 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(parts) {
return "{" + parts.join("") + "}";
})(result0[1]);
return "{" + parts.join("") + "}";
})(result0[1]);
}
if (result0 === null) {
pos = pos0;
@ -1782,7 +1773,6 @@ PEG.parser = (function(){
matchFailed("\"$\"");
}
}
}
}
if (result0 !== null) {
@ -1810,7 +1800,6 @@ PEG.parser = (function(){
matchFailed("\"$\"");
}
}
}
}
}
@ -1839,7 +1828,6 @@ PEG.parser = (function(){
matchFailed("\"$\"");
}
}
}
}
}
@ -1862,8 +1850,8 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(head, tail) {
return head + tail.join("");
})(result0[0], result0[1]);
return head + tail.join("");
})(result0[0], result0[1]);
}
if (result0 === null) {
pos = pos0;
@ -1897,7 +1885,6 @@ PEG.parser = (function(){
result0 = parse_doubleQuotedLiteral();
if (result0 === null) {
result0 = parse_singleQuotedLiteral();
}
if (result0 !== null) {
result1 = parse___();
@ -2022,7 +2009,6 @@ PEG.parser = (function(){
result0 = parse_unicodeEscapeSequence();
if (result0 === null) {
result0 = parse_eolEscapeSequence();
}
}
}
@ -2075,7 +2061,6 @@ PEG.parser = (function(){
}
if (result0 === null) {
result0 = parse_eolChar();
}
}
reportFailures--;
@ -2214,7 +2199,6 @@ PEG.parser = (function(){
result0 = parse_unicodeEscapeSequence();
if (result0 === null) {
result0 = parse_eolEscapeSequence();
}
}
}
@ -2267,7 +2251,6 @@ PEG.parser = (function(){
}
if (result0 === null) {
result0 = parse_eolChar();
}
}
reportFailures--;
@ -2352,14 +2335,12 @@ PEG.parser = (function(){
result3 = parse_classCharacterRange();
if (result3 === null) {
result3 = parse_classCharacter();
}
while (result3 !== null) {
result2.push(result3);
result3 = parse_classCharacterRange();
if (result3 === null) {
result3 = parse_classCharacter();
}
}
if (result2 !== null) {
@ -2398,20 +2379,20 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(inverted, parts) {
var partsConverted = map(parts, function(part) { return part.data; });
var rawText = "["
+ inverted
+ map(parts, function(part) { return part.rawText; }).join("")
+ "]";
return {
type: "class",
inverted: inverted === "^",
parts: partsConverted,
// FIXME: Get the raw text from the input directly.
rawText: rawText
};
})(result0[1], result0[2]);
var partsConverted = map(parts, function(part) { return part.data; });
var rawText = "["
+ inverted
+ map(parts, function(part) { return part.rawText; }).join("")
+ "]";
return {
type: "class",
inverted: inverted === "^",
parts: partsConverted,
// FIXME: Get the raw text from the input directly.
rawText: rawText
};
})(result0[1], result0[2]);
}
if (result0 === null) {
pos = pos0;
@ -2471,18 +2452,18 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(begin, end) {
if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) {
throw new this.SyntaxError(
"Invalid character range: " + begin.rawText + "-" + end.rawText + "."
);
}
return {
data: [begin.data, end.data],
// FIXME: Get the raw text from the input directly.
rawText: begin.rawText + "-" + end.rawText
};
})(result0[0], result0[2]);
if (begin.data.charCodeAt(0) > end.data.charCodeAt(0)) {
throw new this.SyntaxError(
"Invalid character range: " + begin.rawText + "-" + end.rawText + "."
);
}
return {
data: [begin.data, end.data],
// FIXME: Get the raw text from the input directly.
rawText: begin.rawText + "-" + end.rawText
};
})(result0[0], result0[2]);
}
if (result0 === null) {
pos = pos0;
@ -2513,12 +2494,12 @@ PEG.parser = (function(){
result0 = parse_bracketDelimitedCharacter();
if (result0 !== null) {
result0 = (function(char_) {
return {
data: char_,
// FIXME: Get the raw text from the input directly.
rawText: quoteForRegexpClass(char_)
};
})(result0);
return {
data: char_,
// FIXME: Get the raw text from the input directly.
rawText: quoteForRegexpClass(char_)
};
})(result0);
}
if (result0 === null) {
pos = pos0;
@ -2556,7 +2537,6 @@ PEG.parser = (function(){
result0 = parse_unicodeEscapeSequence();
if (result0 === null) {
result0 = parse_eolEscapeSequence();
}
}
}
@ -2609,7 +2589,6 @@ PEG.parser = (function(){
}
if (result0 === null) {
result0 = parse_eolChar();
}
}
reportFailures--;
@ -2704,7 +2683,6 @@ PEG.parser = (function(){
}
if (result1 === null) {
result1 = parse_eolChar();
}
}
}
@ -2741,14 +2719,14 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(char_) {
return char_
.replace("b", "\b")
.replace("f", "\f")
.replace("n", "\n")
.replace("r", "\r")
.replace("t", "\t")
.replace("v", "\x0B"); // IE does not recognize "\v".
})(result0[2]);
return char_
.replace("b", "\b")
.replace("f", "\f")
.replace("n", "\n")
.replace("r", "\r")
.replace("t", "\t")
.replace("v", "\x0B"); // IE does not recognize "\v".
})(result0[2]);
}
if (result0 === null) {
pos = pos0;
@ -2866,8 +2844,8 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(h1, h2) {
return String.fromCharCode(parseInt(h1 + h2, 16));
})(result0[1], result0[2]);
return String.fromCharCode(parseInt(h1 + h2, 16));
})(result0[1], result0[2]);
}
if (result0 === null) {
pos = pos0;
@ -2937,8 +2915,8 @@ PEG.parser = (function(){
}
if (result0 !== null) {
result0 = (function(h1, h2, h3, h4) {
return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16));
})(result0[1], result0[2], result0[3], result0[4]);
return String.fromCharCode(parseInt(h1 + h2 + h3 + h4, 16));
})(result0[1], result0[2], result0[3], result0[4]);
}
if (result0 === null) {
pos = pos0;
@ -3081,7 +3059,6 @@ PEG.parser = (function(){
result0 = parse_lowerCaseLetter();
if (result0 === null) {
result0 = parse_upperCaseLetter();
}
@ -3173,7 +3150,6 @@ PEG.parser = (function(){
result1 = parse_eol();
if (result1 === null) {
result1 = parse_comment();
}
}
while (result1 !== null) {
@ -3183,7 +3159,6 @@ PEG.parser = (function(){
result1 = parse_eol();
if (result1 === null) {
result1 = parse_comment();
}
}
}
@ -3212,7 +3187,6 @@ PEG.parser = (function(){
result0 = parse_singleLineComment();
if (result0 === null) {
result0 = parse_multiLineComment();
}
reportFailures--;
if (reportFailures === 0 && result0 === null) {
@ -3535,7 +3509,6 @@ PEG.parser = (function(){
matchFailed("\"\\u2029\"");
}
}
}
}
}

Loading…
Cancel
Save