Skip to content

Instantly share code, notes, and snippets.

@fronterior
Last active February 25, 2022 22:29
Show Gist options
  • Save fronterior/ca86350163975764f9e72bde06b90a4c to your computer and use it in GitHub Desktop.
Save fronterior/ca86350163975764f9e72bde06b90a4c to your computer and use it in GitHub Desktop.
parenthesis parser.
export type ParenthesisPosition = [number, number, ParenthesisPosition[]];
export const parenthesisParse = (str: string) => {
let cursor = -1;
const result: ParenthesisPosition[] = [];
const stack: ParenthesisPosition[] = [];
let error = '';
while (!error) {
if (!stack.length) {
const startIndex = str.indexOf('(', cursor + 1);
if (startIndex !== -1) {
cursor = startIndex;
stack.push([startIndex, -1, []]);
} else {
if (str.indexOf(')', cursor + 1) !== -1) error = 'Invalid parenthesis';
break;
}
} else if (stack.length) {
const nestedStartIndex = str.indexOf('(', cursor + 1);
const endIndex = str.indexOf(')', cursor + 1);
if (endIndex < nestedStartIndex || (endIndex !== -1 && nestedStartIndex === -1)) {
cursor = endIndex;
if (endIndex === -1) {
error = 'Invalid parenthesis';
break;
}
const target = stack.pop() as ParenthesisPosition;
target[1] = endIndex;
if (!stack.length) result.push(target);
} else {
cursor = nestedStartIndex;
if (nestedStartIndex === -1) {
error = 'Invalid parenthesis';
break;
}
const target = [nestedStartIndex, -1, []] as ParenthesisPosition;
stack[stack.length - 1][2].push(target);
stack.push(target);
}
}
}
if (error) throw new Error(error);
return result;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment