Porting invRegex.py to Javascript (Node.js)

后端 未结 6 1907
余生分开走
余生分开走 2020-12-16 03:16

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

6条回答
  •  我在风中等你
    2020-12-16 04:16

    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

提交回复
热议问题