Skip to content

Instantly share code, notes, and snippets.

@e-neko
Created April 26, 2020 20:36
Show Gist options
  • Save e-neko/8638c76f70e37905adcb22251f27234e to your computer and use it in GitHub Desktop.
Save e-neko/8638c76f70e37905adcb22251f27234e to your computer and use it in GitHub Desktop.
An exercise in parsing
// input format
let input = '2x(1m:5s) 2x(3x(2m:1s) 3m:2s 4x(2m:2s)) 20s 3m 3s';
// recursive splitter/parser
let splitter = s=>s.split('').reduce((parse, char, idx, arr)=>{
if (parse.depth>0){
if (char==')'){
parse.depth--;
if (parse.depth)
parse.group+=char;
else{
let inner = splitter(parse.group).groups;
for(;parse.grouptimes--;parse.grouptimes>0)
parse.groups = parse.groups.concat(inner);
parse.group='';
parse.grouptimes=0;
}
}
else {
parse.group+=char;
if (char=='(')
parse.depth++;
}
}
else if (char=='('){
parse.depth++;
parse.group = '';
parse.grouptimes = parseInt(parse.accum);
parse.accum = '';
}
else if (char==')')
throw 'unbalanced parentheses';
else {
if (char!=' ')
parse.accum+=char;
if (char==' ' || idx==arr.length-1){
if (parse.accum.length){
let group = /^(?:(\d+m):?)?(\d+s)?$/i.exec(parse.accum);
parse.groups.push({min: parseInt(group[1]||0), sec: parseInt(group[2]||0)});
parse.accum = '';
}
}
}
return parse;
}, {groups: [], accum: '', group: '', grouptimes: 0, depth: 0});
// test
console.log(splitter(input).groups.map(entry=>`${entry.min}m:${entry.sec}s`).join(' '))
// should return
// 1m:5s 1m:5s 2m:1s 2m:1s 2m:1s 3m:2s 2m:2s 2m:2s 2m:2s 2m:2s 2m:1s 2m:1s 2m:1s 3m:2s 2m:2s 2m:2s 2m:2s 2m:2s 0m:20s 3m:0s 0m:3s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment