I am trying to write a function that checks if a syntax is correct or not. If it is correct it returns \'ok\' else it returns the index of the error. So far my code works if
An algorithm for doing this is, find an opening symbol, push it to a stack (or array, whatever). Find another opening symbol, push it to a stack. Find a closing symbol that matches the top of the stack, pop the opening symbol off the stack. Find a closing symbol that doesn't match the top of the stack, you found an error. Find a closing symbol and there's nothing on the stack, you found an error. Get to the end and still have symbols on the stack, you found an error.
You could take a an array for the index of each opening character and pop this if the related closing character is found.
If finished and the stack has no item, the syntax is ok, otherwise return an index or the index of the last pushed opening character.
Example:
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('[[[[[[[[[[[[[[]]]]]]]]<<<<<<<<<<<>>>>>>>>>>>]]]]]]'+'[[[[[[[[[[[[[[]]]]]]]<<<<<<<<<<<>>>>>>>>>>>]}]]]]' + '>'));