Вы можете взять массив для индекса каждого открывающего символа и вытолкнуть его, если найден соответствующий закрывающий символ.
Если завершено, и в стеке нет элемента, синтаксис в порядке, в противном случае возвращаетиндекс или индекс последнего нажатого открывающего символа.
Пример:
code comment
----------- ---------------------------
[][[[]][][]
[] balanced
[ error, this returns later 2
[[]] balanced
[] balanced
[] balanced
finally a missing ]
function syntaxError(syntax) {
const
isOpening = c => /[<[{(]/.test(c),
isClosing = c => /[>\]})]/.test(c),
open = { '>': '<', ']': '[', '}': '{', ')': '(' };
var stack = [],
index,
finished = Array
.from(syntax)
.every((c, i) => {
var temp = stack[stack.length - 1];
if (isOpening(c)) {
if (temp && temp.c === c) {
temp.indices.push(i);
} else {
stack.push({ c, indices: [i] });
}
return true;
}
if (isClosing(c)) {
if (temp && temp.c === open[c]) {
temp.indices.pop();
if (!temp.indices.length) stack.pop();
} else {
index = stack.length ? stack.pop().indices.pop() : i;
return false;
}
}
return true;
});
return finished && !stack.length
? 'ok'
: index === undefined
? stack.pop().indices.pop()
: index;
}
console.log(syntaxError('[][][[{}]]')); // ok
console.log(syntaxError(')'));
// 0
console.log(syntaxError('[][][[{<}]]'));
// 01234567
console.log(syntaxError('[][[[]][][]'));
// 012
console.log(syntaxError('[[[[[[[[[[[[[[]]]]]]]]<<<<<<<<<<<>>>>>>>>>>>]]]]]]'+'[[[[[[[[[[[[[[]]]]]]]<<<<<<<<<<<>>>>>>>>>>>]}]]]]' + '>'));