Portierung von invRegex.py nach Javascript (Node.js)

Ich habe versucht zu portiereninvRegex.py für eine Weile auf eine node.js-Implementierung, aber ich habe immer noch Probleme damit. Ich habe bereits den regulären Ausdruck parse tree dank derret.js Tokenizer und es funktioniert ziemlich gut, aber die tatsächliche Erzeugung und Verkettung aller einzelnen Elemente auf eine Weise, die speichereffizient ist, ist für mich eine große Herausforderung. Nehmen wir an, ich habe den folgenden regulären Ausdruck, um es einfach zu halten:

[01]{1,2}@[a-f]

Füttere dasinvRegex.py erzeugt die folgende Ausgabe (tabbifiziert um weniger Platz einzunehmen):

 0@a     0@b     0@c     0@d     0@e     0@f
00@a    00@b    00@c    00@d    00@e    00@f
01@a    01@b    01@c    01@d    01@e    01@f
 1@a     1@b     1@c     1@d     1@e     1@f
10@a    10@b    10@c    10@d    10@e    10@f
11@a    11@b    11@c    11@d    11@e    11@f

In Anbetracht der Tatsache, dass ich in der Lage bin, jedes einzelne Token abzurufen und ein Array aller gültigen Einzelausgaben zu erstellen:

[01]{1,2} = function () {
    return ['0', '00', '01', '1', '10', '11'];
};

@ = function () {
    return ['@'];
};

[a-f] = function () {
    return ['a', 'b', 'c', 'd', 'e', 'f'];
};

Ich kann das berechnenkartesisches Produkt von allen Arrays und erhalten die gleiche erwartete Ausgabe:

var _ = require('underscore');

function cartesianProductOf() {
    return _.reduce(arguments, function(a, b) {
        return _.flatten(_.map(a, function(x) {
            return _.map(b, function(y) {
                return x.concat([y]);
            });
        }), true);
    }, [ [] ]);
};

var tokens = [
    ['0', '00', '01', '1', '10', '11'],
    ['@'],
    ['a', 'b', 'c', 'd', 'e', 'f'],
];

var result = cartesianProductOf(tokens[0], tokens[1], tokens[2]);

_.each(result, function (value, key) {
    console.log(value.join(''));
});

Das Problem dabei ist, dass es alle 36 Werte im Speicher hält, wenn ich einen etwas komplizierteren regulären Ausdruck hatte, wie z[a-z]{0,10} es würde halten146813779479511 Werte im Speicher, was völlig unmöglich ist. Ich möchte diese große Liste asynchron verarbeiten, jede generierte Kombination an einen Rückruf übergeben und den Prozess an jedem sinnvollen Punkt unterbrechen, den ich für richtig halte, ähnlich wie invRegex.py oderdieses Haskell-Paket - Leider kann ich Haskell nicht verstehen und ich weiß auch nicht, wie ich das Generatorverhalten in Python mit Javascript nachahmen kann.

Ich habe versucht, ein paar einfache Generatorexperimente in Knoten 0.11.9 (mit--harmony) wie dieser:

function* alpha() {
    yield 'a'; yield 'b'; yield 'c';
}

function* numeric() {
    yield '0'; yield '1';
}

function* alphanumeric() {
    yield* alpha() + numeric(); // what's the diff between yield and yield*?
}

for (var i of alphanumeric()) {
    console.log(i);
}

Unnötig zu sagen, dass e oben nicht funktioniert. = /

Wenn ich meinen Kopf hier gegen die Wand stoße, wäre jede Hilfe bei der Lösung dieses Problems sehr willkommen.

AKTUALISIEREN: Hier ist ein Beispiel für einen Analysebaum für ret.jsb[a-z]{3}:

{
    "type": ret.types.ROOT,
    "stack": [
            {
                "type": ret.types.CHAR,
                "value": 98 // b
            },
            {
                "type": ret.types.REPETITION,
                "max": 3,
                "min": 3,
                "value": {
                    "type": ret.types.SET,
                    "not": false,
                    "set": [
                        {
                            "type": ret.types.RANGE,
                            "from": 97, // a
                            "to": 122   // z
                        }
                    ]
                }
            }
        ]
    ]
}

DasSET / RANGE Typ sollte 26 verschiedene Werte ergeben, und der ElternteilREPETITION type sollte diesen vorherigen Wert hoch 3 setzen, was 17576 verschiedene Kombinationen ergibt. Wenn ich ein abgeflachtes generieren würdetokens Array wie ich zuvor fürcartesianProductOfnehmen die abgeflachten Zwischenwerte so viel Platz ein wie das eigentliche kartesische Produkt.

Ich hoffe, dieses Beispiel erklärt das Problem, mit dem ich konfrontiert bin, besser.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage