JSFiddle - React, Tailwind, and code Playground
HTML
<h2>Javascript port of invRegex.py</h2>
<p>Generates a list of strings that match a regex.</p>
<form name="input">
Regex: <input type="text" name="regex" value="b[a-n]{3}" />
Delay: <input type="text" name="delay" value="0" />
<input type="submit" />
</form>
<ol id="matches"></ol>
JavaScript
var timer = null;
input.onsubmit = function() {
if (timer) {
window.clearTimeout(timer);
timer = null;
}
var matches = document.getElementById('matches');
matches.innerHTML = '';
var show = function(match) {
var li = document.createElement('li');
li.appendChild(document.createTextNode(match));
matches.appendChild(li);
};
var iterator = new ParseTreeMapper().mapToIterator(ret(this.regex.value));
var delay = parseInt(this.delay.value);
if (delay > 0) {
iterator.first();
var step = function() {
timer = null;
if (iterator.ok()) {
show(iterator.get());
iterator.next();
timer = window.setTimeout(step, delay);
}
};
step();
}
else {
new Enumerator(iterator).each(show);
}
return false;
};
function Enumerator(iterator) {
this.iterator = iterator;
this.each = function(callback) {
for (this.iterator.first(); this.iterator.ok(); this.iterator.next()) {
callback(this.iterator.get());
}
};
}
//--------------------------------------------------
// map parse tree to iterator
//--------------------------------------------------
function ParseTreeMapper() {
this.capturingGroups = [];
}
ParseTreeMapper.prototype.mapToIterator = function(parseTree) {
switch (parseTree.type) {
case ret.types.ROOT:
case ret.types.GROUP:
var me = this;
var mapToSequence = function(parseTrees) {
return new Sequence(parseTrees.map(function(t) {
return me.mapToIterator(t);
}));
};
var group = parseTree.options ?
new Choice(parseTree.options.map(mapToSequence)) :
mapToSequence(parseTree.stack);
if (parseTree.remember) {
this.capturingGroups.push(group);
}
return group;
...