Construct expectations using functions

Until now, expectations were constructed using object literals. This
commit changes the construction to use factory functions.

This change makes generated parsers slightly smaller because property
names don't have to be repeated many times and factory function calls
are more amenable to minifying.

Some numbers based on the aggregate size of parsers generated from
examples/*.pegjs:

  Optimization   Minified?   Size before   Size after   Saving
  ------------------------------------------------------------
  speed          no               719066       716063    0.42%
  speed          yes              188998       180202    4.65%
  size           no               194810       197813    1.52%
  size           yes              108782        99947    8.12%

(Minification was done using "uglify --mangle --compress" with
uglify-js 2.4.24.)
redux
David Majda 8 years ago
parent e7d03825e0
commit 5a4d04fa90

@ -297,7 +297,7 @@ function generateBytecode(ast) {
named: function(node, context) {
var nameIndex = addConst(
'{ type: "other", description: "' + js.stringEscape(node.name) + '" }'
'peg$otherExpectation("' + js.stringEscape(node.name) + '")'
);
/*
@ -540,13 +540,12 @@ function generateBytecode(ast) {
)
+ '"'
);
expectedIndex = addConst([
'{',
'type: "literal",',
'text: "' + js.stringEscape(node.value) + '",',
'ignoreCase: ' + node.ignoreCase,
'}'
].join(' '));
expectedIndex = addConst(
'peg$literalExpectation('
+ '"' + js.stringEscape(node.value) + '", '
+ node.ignoreCase
+ ')'
);
/*
* For case-sensitive strings the value must match the beginning of the
@ -600,14 +599,13 @@ function generateBytecode(ast) {
+ ']';
regexpIndex = addConst(regexp);
expectedIndex = addConst([
'{',
'type: "class",',
'parts: ' + parts + ',',
'inverted: ' + node.inverted + ',',
'ignoreCase: ' + node.ignoreCase,
'}'
].join(' '));
expectedIndex = addConst(
'peg$classExpectation('
+ parts + ', '
+ node.inverted + ', '
+ node.ignoreCase
+ ')'
);
return buildCondition(
[op.MATCH_REGEXP, regexpIndex],
@ -617,7 +615,7 @@ function generateBytecode(ast) {
},
any: function() {
var expectedIndex = addConst('{ type: "any" }');
var expectedIndex = addConst('peg$anyExpectation()');
return buildCondition(
[op.MATCH_ANY],

@ -1065,7 +1065,7 @@ function generateJS(ast, options) {
'',
' throw peg$buildException(',
' null,',
' [{ type: "other", description: description }],',
' [peg$otherExpectation(description)],',
' input.substring(peg$savedPos, peg$currPos),',
' location',
' );',
@ -1082,6 +1082,26 @@ function generateJS(ast, options) {
' );',
' }',
'',
' function peg$literalExpectation(text, ignoreCase) {',
' return { type: "literal", text: text, ignoreCase: ignoreCase };',
' }',
'',
' function peg$classExpectation(parts, inverted, ignoreCase) {',
' return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };',
' }',
'',
' function peg$anyExpectation() {',
' return { type: "any" };',
' }',
'',
' function peg$endExpectation() {',
' return { type: "end" };',
' }',
'',
' function peg$otherExpectation(description) {',
' return { type: "other", description: description };',
' }',
'',
' function peg$computePosDetails(pos) {',
' var details = peg$posDetailsCache[pos], p;',
'',
@ -1182,7 +1202,7 @@ function generateJS(ast, options) {
' return peg$result;',
' } else {',
' if (peg$result !== peg$FAILED && peg$currPos < input.length) {',
' peg$fail({ type: "end" });',
' peg$fail(peg$endExpectation());',
' }',
'',
' throw peg$buildException(',

File diff suppressed because one or more lines are too long

@ -35,11 +35,11 @@ describe("compiler pass |generateBytecode|", function() {
'c = "c"'
].join("\n"), constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }',
'peg$literalExpectation("a", false)',
'"b"',
'{ type: "literal", text: "b", ignoreCase: false }',
'peg$literalExpectation("b", false)',
'"c"',
'{ type: "literal", text: "c", ignoreCase: false }'
'peg$literalExpectation("c", false)'
]));
});
});
@ -67,9 +67,9 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'{ type: "other", description: "start" }',
'peg$otherExpectation("start")',
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }'
'peg$literalExpectation("a", false)'
]));
});
});
@ -106,7 +106,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }',
'peg$literalExpectation("a", false)',
'function() { code }'
]));
});
@ -129,7 +129,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }',
'peg$literalExpectation("a", false)',
'function(a) { code }'
]));
});
@ -165,11 +165,11 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }',
'peg$literalExpectation("a", false)',
'"b"',
'{ type: "literal", text: "b", ignoreCase: false }',
'peg$literalExpectation("b", false)',
'"c"',
'{ type: "literal", text: "c", ignoreCase: false }',
'peg$literalExpectation("c", false)',
'function(a, b, c) { code }'
]));
});
@ -205,11 +205,11 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }',
'peg$literalExpectation("a", false)',
'"b"',
'{ type: "literal", text: "b", ignoreCase: false }',
'peg$literalExpectation("b", false)',
'"c"',
'{ type: "literal", text: "c", ignoreCase: false }'
'peg$literalExpectation("c", false)'
]));
});
});
@ -257,7 +257,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }'
'peg$literalExpectation("a", false)'
]));
});
});
@ -284,7 +284,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }'
'peg$literalExpectation("a", false)'
]));
});
});
@ -304,7 +304,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }'
'peg$literalExpectation("a", false)'
]));
});
});
@ -326,7 +326,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }'
'peg$literalExpectation("a", false)'
]));
});
});
@ -352,7 +352,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }'
'peg$literalExpectation("a", false)'
]));
});
});
@ -429,11 +429,11 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }',
'peg$literalExpectation("a", false)',
'"b"',
'{ type: "literal", text: "b", ignoreCase: false }',
'peg$literalExpectation("b", false)',
'"c"',
'{ type: "literal", text: "c", ignoreCase: false }',
'peg$literalExpectation("c", false)',
'function(a, b, c) { code }'
]));
});
@ -504,11 +504,11 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }',
'peg$literalExpectation("a", false)',
'"b"',
'{ type: "literal", text: "b", ignoreCase: false }',
'peg$literalExpectation("b", false)',
'"c"',
'{ type: "literal", text: "c", ignoreCase: false }',
'peg$literalExpectation("c", false)',
'function(a, b, c) { code }'
]));
});
@ -560,7 +560,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "a", ignoreCase: false }'
'peg$literalExpectation("a", false)'
]));
});
});
@ -579,7 +579,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(grammar, constsDetails([
'"a"',
'{ type: "literal", text: "A", ignoreCase: true }'
'peg$literalExpectation("A", true)'
]));
});
});
@ -598,7 +598,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST('start = [a]', constsDetails([
'/^[a]/',
'{ type: "class", parts: ["a"], inverted: false, ignoreCase: false }'
'peg$classExpectation(["a"], false, false)'
]));
});
});
@ -607,7 +607,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST('start = [^a]', constsDetails([
'/^[^a]/',
'{ type: "class", parts: ["a"], inverted: true, ignoreCase: false }'
'peg$classExpectation(["a"], true, false)'
]));
});
});
@ -616,7 +616,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST('start = [a]i', constsDetails([
'/^[a]/i',
'{ type: "class", parts: ["a"], inverted: false, ignoreCase: true }'
'peg$classExpectation(["a"], false, true)'
]));
});
});
@ -625,7 +625,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST('start = [ab-def-hij-l]', constsDetails([
'/^[ab-def-hij-l]/',
'{ type: "class", parts: ["a", ["b", "d"], "e", ["f", "h"], "i", ["j", "l"]], inverted: false, ignoreCase: false }'
'peg$classExpectation(["a", ["b", "d"], "e", ["f", "h"], "i", ["j", "l"]], false, false)'
]));
});
});
@ -634,7 +634,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST('start = []', constsDetails([
'/^(?!)/',
'{ type: "class", parts: [], inverted: false, ignoreCase: false }'
'peg$classExpectation([], false, false)'
]));
});
});
@ -643,7 +643,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST('start = [^]', constsDetails([
'/^[\\S\\s]/',
'{ type: "class", parts: [], inverted: true, ignoreCase: false }'
'peg$classExpectation([], true, false)'
]));
});
});
@ -663,7 +663,7 @@ describe("compiler pass |generateBytecode|", function() {
it("defines correct constants", function() {
expect(pass).toChangeAST(
grammar,
constsDetails(['{ type: "any" }'])
constsDetails(['peg$anyExpectation()'])
);
});
});

Loading…
Cancel
Save