I have been trying to port invRegex.py to a node.js implementation for a while, but I\'m still struggling with it. I already have the regular expression parse tree thanks to
Here's a version that makes a function for each part of the input and composes all of them to produce a function that'll generate each regex result and feed it into that argument:
//Takes in a list of things, returns a function that takes a function and applies it to
// each Cartesian product. then composes all of the functions to create an
// inverse regex generator.
function CartesianProductOf() {
var args = arguments;
return function(callback) {
Array.prototype.map.call(args, function(vals) {
return function(c, val) {
vals.forEach(function(v) {
c(val + v);
});
};
}).reduce(function(prev, cur) {
return function(c, val) {
prev(function(v){cur(c, v)}, val);
};
})(callback, "");
};
}
Modified to work off a parse tree (copied a litte code from here):
//Takes in a list of things, returns a function that takes a function and applies it to
// each Cartesian product.
function CartesianProductOf(tree) {
var args = (tree.type == ret.types.ROOT)? tree.stack :
((tree.type == ret.types.SET)? tree.set : []);
return function(callback) {
var funs = args.map(function(vals) {
switch(vals.type) {
case ret.types.CHAR:
return function(c, val) {
c(val + vals.value);
};
case ret.types.RANGE:
return function(c, val) {
for(var i=vals.from; i<=vals.to; i++) {
c(val+String.fromCharCode(i));
}
};
case ret.types.SET:
return function(c, val) {
CartesianProductOf(vals)(function(i) {c(val+i)});
};
/* return function(c, val) {
vals.set.forEach(function(v) {
c(val + v);
});
}; */
case ret.types.REPETITION:
var tmp = CartesianProductOf(vals.value);
if(vals.max == vals.min) {
return fillArray(function(c, val) {
tmp(function(i){c(val+i);}); //Probably works?
}, vals.max);
} else {
return fillArray(function(c, val) {
tmp(function(i){c(val+i);});
}, vals.min).concat(fillArray(function(c, val) {
c(val);
tmp(function(i){c(val+i);});
}, vals.max-vals.min));
}
default:
return function(c, val) {
c(val);
};
}
}).reduce(function(prev, cur) { //Flatten array.
return prev.concat(cur);
}, []);
if(tree.type == rets.type.ROOT) //If it's a full tree combine all the functions.
funs.reduce(function(prev, cur) { //Compose!
return function(c, val) {
prev(function(v){cur(c, v)}, val);
};
})(callback, "");
else //If it's a set call each function.
funs.forEach(function(f) {f(callback, "")});
};
}
function fillArray(value, len) {
var arr = [];
for (var i = 0; i < len; i++) {
arr.push(value);
}
return arr;
}
If you're alright with a less functionalish, more C-esque solution:
function helper(callme, cur, stuff, pos) {
if(pos == stuff.length) {
callme(cur);
} else
for(var i=0; i