export function build(dictionaryString) { } export function buildTreeStruct(monoLineString) { //console.log('srcTree', monoLineString); const stringAsArray = monoLineString.split(''); const rawTree = leftParser(stringAsArray); //console.log('rawTree', JSON.stringify(rawTree)); const outOfScope = stringAsArray.length; if (outOfScope) throw `fail to build tree from : "${monoLineString}" parsed: ${JSON.stringify(rawTree)} unparsed/failed: ${stringAsArray.join('')}`; //return rawTree;//trivialDedup(flattenTree(rawTree)) return flattenTree(flattenTree(flattenTree(rawTree))); } /** * leftParser stuff */ function flushNoEmptyString(data) { if (data.str.length) data.tree[data.tree.length - 1].step.push(data.str); data.str = ''; } function appendToString(chr, data) { data.str += chr; } function nextAlt(data) { data.tree.push({step: []}); } function goIntoNewAlt(data) { data.tree[data.tree.length - 1].step.push(leftParser(data.input)); } function returnTrue() { return true; } function doTheses() { } const leftParserFunc = { ')': (chr, data) => returnTrue(flushNoEmptyString(data)), '|': (chr, data) => doTheses(flushNoEmptyString(data), nextAlt(data)), '(': (chr, data) => doTheses(flushNoEmptyString(data), goIntoNewAlt(data)), 'default': (chr, data) => appendToString(chr, data) } function leftParser(inputChrArray) { const data = { input: inputChrArray, str: '', tree: [{step: []}], }; while (data.input.length) { const chr = data.input.shift(); if (typeof leftParserFunc[chr] !== 'undefined') { const out = leftParserFunc[chr](chr, data); if (out) return data.tree; } else leftParserFunc['default'](chr, data); } flushNoEmptyString(data); return data.tree; } // end leftParser function concatStrings(array) { const data = { input: array, str: '', tree: [{step: []}], }; array.forEach(e => { if (typeof e === 'string') appendToString(e, data); else { flushNoEmptyString(data) data.tree[data.tree.length - 1].step.push(e); } }); flushNoEmptyString(data) return data.tree[data.tree.length - 1].step; } function flattenTree(tree) { if (typeof tree === 'string') return tree; if (Array.isArray(tree) && tree.length === 0) return ''; if (Array.isArray(tree) && tree.length === 1) return flattenTree(tree[0]); if (isStep(tree)) { tree.step = tree.step.map(flattenTree); if (!Array.isArray(tree.step)) return flattenTree(tree.step); if (tree.step.length === 1) return flattenTree(tree.step); if (tree.step.length === 0) return ''; if (!tree.step.reduce((acc, cur) => Array.isArray(cur) || acc, false)) return concatStrings(tree.step); return tree; } if (tree.length === 1) { //console.log('aloneChild', JSON.stringify(tree[0])); if (typeof tree[0] === 'string') return tree[0]; if (Array.isArray(tree[0])) return flattenTree(tree[0]); //return flattenTree(tree[0].step); } if (!Array.isArray(tree)) throw `Error : ${tree} should be an Array. ${JSON.stringify(tree)}`; //console.log('tree:', JSON.stringify(tree)); ///if(isStep(tree[0])) tree[0].step = flattenTree(tree[0].step); tree = trivialDedup(tree.map(flattenTree)); tree = [].concat(...tree.map(e => Array.isArray(e) ? e : [e])); return tree; } function isStep(element) { return typeof element === 'object' && typeof element.step !== 'undefined'; } function trivialDedup(tree) { if (typeof tree === 'string') return tree; if (isStep(tree)) return {step: tree.step.map(subTree => trivialDedup(subTree))}; if (Array.isArray(tree)) { const dedupKeys = {}; tree.forEach(v => dedupKeys[JSON.stringify(v)] = v); // eslint-disable-line no-return-assign return Object.keys(dedupKeys).map(json => trivialDedup(JSON.parse(json))); } throw `unknown case : ${tree}`; } export function serialize(treeStruct) { if (typeof treeStruct === 'string') return treeStruct; if (Array.isArray(treeStruct)) return `(${treeStruct.map(serialize).join('|')})`; if (isStep(treeStruct)) return treeStruct.step.map(serialize).join(''); throw new Error(`Error: how to serialize ${JSON.stringify(treeStruct)} RAW: ${treeStruct}`); } /* export function extract(treeNavArray,fromTreeWrapped){ if(!Array.isArray(treeNavArray)) throw new Error(`treeNav: ${JSON.stringify(treeNavArray)} should be an integer array.`); let extractedTree = ''; if(treeNavArray.length === 0) return fromTreeWrapped.pop(); if (typeof fromTreeWrapped[0] === 'string') throw new Error(`invalid treeNav pointer ${JSON.stringify(treeNavArray)} in ${serialize(fromTreeWrapped[0])} no branch ${treeNavArray[0]}.`); if (Array.isArray(fromTreeWrapped[0])) { const branch = treeNavArray.shift(); const extractedTree = fromTreeWrapped[0][branch]; // recursive here ? //fromTreeWrapped[0] = [].concat(branch>0?fromTreeWrapped[0].slice(0,branch-1):[],fromTreeWrapped[0].slice(branch+1,fromTreeWrapped[0].length)); return extractedTree; } if (isStep(fromTreeWrapped[0])) { const extractedTree = {step:[]}; fromTreeWrapped[0].step.forEach() f } return extractedTree; } */