Skip to content

Commit

Permalink
Also compact objects with not all identical values.
Browse files Browse the repository at this point in the history
  • Loading branch information
RubenVerborgh committed Aug 18, 2014
1 parent 031056f commit cff2053
Showing 1 changed file with 32 additions and 16 deletions.
48 changes: 32 additions & 16 deletions lib/jison.js
Expand Up @@ -1173,17 +1173,33 @@ lrGeneratorMixin.generateTableCode = function (table) {
// Don't surround numerical property name numbers in quotes
moduleCode = moduleCode.replace(/"([0-9]+)"(?=:)/g, "$1");

// Replace objects with identical values for all keys by function calls
// e.g., { 1: [6,7]; 3: [6,7], 4: [6,7] } = o([6,7], [1, 3, 4])
moduleCode = moduleCode.replace(/\{\d+:(\[[^\]]+\]),\d+:\1[^\}]*\}/g, function (object, value) {
// Check if all values in this object are identical, and collect its keys
var keyValue, keys = [], keyValueMatcher = /(\d+):([^:]+)(?=,\d+:|\})/g;
while (keyValue = keyValueMatcher.exec(object))
// Only continue if the keys are identical
if (value !== keyValue[2]) return object;
else keys.push(keyValue[1])
// Create a function call with the value and all keys
return 'o(' + value + ',[' + keys.join(',') + '])';
// Replace objects with several identical values by function calls
// e.g., { 1: [6, 7]; 3: [6, 7], 4: [6, 7], 5: 8 } = o([1, 3, 4], [6, 7], { 5: 8 })
moduleCode = moduleCode.replace(/\{\d+:[^\}]+,\d+:[^\}]+\}/g, function (object) {
// Find the value that occurs with the highest number of keys
var value, frequentValue, key, keys = {}, keyCount, maxKeyCount = 0,
keyValue, keyValues = [], keyValueMatcher = /(\d+):([^:]+)(?=,\d+:|\})/g;
while ((keyValue = keyValueMatcher.exec(object))) {
// For each value, store the keys where that value occurs
key = keyValue[1], value = keyValue[2], keyCount = 1;
if (!(value in keys)) keys[value] = [key];
else keyCount = keys[value].push(key);
// Remember this value if it is the most frequent one
if (keyCount > maxKeyCount)
maxKeyCount = keyCount, frequentValue = value;
}
// Construct the object with a function call if the most frequent value occurs multiple times
if (maxKeyCount > 1) {
// Collect all non-frequent values into a remainder object
for (value in keys)
if (value !== frequentValue)
for (k = keys[value], i = 0, l = k.length; i < l; i++)
keyValues.push(k[i] + ':' + value);
keyValues = keyValues.length ? ',{' + keyValues.join(',') + '}' : '';
// Create the function call `o(keys, value, remainder)`
object = 'o([' + keys[frequentValue].join(',') + '],' + frequentValue + keyValues + ')';
}
return object;
});

// Count occurrences of number lists
Expand Down Expand Up @@ -1214,11 +1230,11 @@ lrGeneratorMixin.generateTableCode = function (table) {
moduleCode: moduleCode
};
};
// Function that creates an object with the given value for all given keys
// e.g., o([6,7], [1, 3, 4]) = { 1: [6,7]; 3: [6,7], 4: [6,7] }
var createObjectCode = 'o=function(v,a,l,r){' +
'for(l=a.length,r={};l--;r[a[l]]=v);' +
'return r}';
// Function that extends an object with the given value for all given keys
// e.g., o([1, 3, 4], [6, 7], { x: 1, y: 2 }) = { 1: [6, 7]; 3: [6, 7], 4: [6, 7], x: 1, y: 2 }
var createObjectCode = 'o=function(k,v,o,l){' +
'for(o=o||{},l=k.length;l--;o[k[l]]=v);' +
'return o}';

// Creates a variable with a unique name
function createVariable() {
Expand Down

0 comments on commit cff2053

Please sign in to comment.