Парсер скобок

Продолжая цикл задач с собеседований, выкладываю задачу с собеседования с Hola.

Нужно написать функцию, которая парсит строку и выдает вот такой результат


check("a(b)") // true
check("[{}]") // true
check("[(]") // false
check("}{") // false
check("z([{}-()]{a})") // true
check("") // true

Сначала я подумал, что это все json и хватит обертки на JSON.parse и хотя я жестоко ошибся продолжал упорствовать и парсить уже как js код при помощи eval, но и тут я понял что парсер лох, и надо не искать легких путей, а использовать конечные автоматы.


function check(string) {
	var open = ["[", "{", "("];
	var close = ["]", "}", ")"];

	var current = [];
	try {
		for (var i = 0, j = string.length; i < j; i++) {
			if (open.indexOf(string[i]) !== -1) {
				current.push(string[i]);
			} else {
				var index = close.indexOf(string[i]);
				if (index !== -1) {
					if (!current.length) {
						throw new Error("illegal close `" + string[i] + "`");
					} else if (current[current.length - 1] !== open[index]) {
						throw new Error("mismatch close `" + string[i] + "`");
					} else {
						current.pop();
					}
				}
			}
		}
		if (current.length) {
			throw new Error("not closed `" + current + "`");
		}
	} catch (e) {
		console.error(e);
		return false;
	}
	return true;
}

Можно еще почистить строку регулярками от всех "не скобок", но по хорошему, на коротких строках это даст только минуса


string.replace(new RegExp("[^\\\\" + open.concat(close).join("\\\\") + "]", "g"), "") 

А можно пробовать сделать быстрый выход из цикла, но надо выделять память на одну лишнюю переменную и выполнять поис по массиву, который можно было бы не делать.


var oIndex = open.indexOf(char); 
var cIndex = close.indexOf(char); 
if (oIndex === -1 && cIndex === -1) { 
	return; 
}

Что имели ввиду в Hola, будет видно :)