function parseFormula(arr,resultFormula,processFormula,isAllFun){ let tmpArr = [];//放置这一层的数组 for (let i = 0; i < arr.length; i++) { tmpArr.push(arr[i]); if(arr[i].type != "Function"){ isAllFun = false; } } if(isAllFun){ for (let i = 0; i < tmpArr.length; i++) { parseArguments(resultFormula[0],tmpArr[i]); parseFormula(arr[i].children,resultFormula,processFormula,isAllFun); } }else{ for (let i = 0; i < tmpArr.length; i++) { if(tmpArr[i].type == 'Function'){ let obj = { children:[], name:"临时占位", selected:false, type:"Element", } parseProcessFormula(arr[i],obj); processFormula.push(Object.assign({},obj)) delete obj.children; }else if(tmpArr[i].name){ processFormula.push(tmpArr[i]); } } } } //解析方法里面的参数 function parseArguments(ele,funObj){ let fcReg = /(FC\.\S+\()(.+)\)/; let fun = { example:funObj.example, name:funObj.name, template:funObj.template, }; let argTextArr = funObj.children;//放参数文本的数组 //根据逗号位置分割参数 let index = 0; let argSpliceArr = [[]]; while (index < argTextArr.length) { if(argTextArr[index].type =='Comma'){ argSpliceArr.push([]); }else{ argSpliceArr[argSpliceArr.length-1].push(argTextArr[index]) } index++ } fun.arguments = []; let tmpArr = fcReg.exec(funObj.template.ft); let argList = tmpArr[2].split(",");//括号里面参数部分#1,#2.. argList.forEach((argText,index)=>{ //只用动态的 if(argText.indexOf('#')>-1){ if(argSpliceArr[index].length>1){ //是前面的计算结果 fun.arguments.push(ele) }else{ let arg = argSpliceArr[index][0]; if(arg.type == 'Element'){ fun.arguments.push(arg) }else if(arg.type == 'Function'){ fun.arguments.push(ele) }else if(arg.type == 'Text'){ fun.arguments.push(arg.tag) }else{ fun.arguments.push(undefined) } } } }) ele.children.push(fun); } function parseProcessFormula(funObj,ele){ parseArguments(ele,funObj); let inFun = false;//是不是有Function let endEle = null;//认为最下面一层第一个元素是显示的元素 for (let i = 0; i < funObj.children.length; i++) { if(funObj.children[i].type == 'Function'){ parseProcessFormula(funObj.children[i],ele); inFun = true; }else if(funObj.children[i].type == "Element" && !endEle){ endEle = funObj.children[i]; } } if(!inFun){ //把临时的属性改为最终找到的 ele.id = endEle.id; ele.name = endEle.name; ele.tableElementKey = endEle.tableElementKey; } } export const formulaStringToArray = (text,elemap,formulaMap) => { // 匹配开始的FC.xxx( const startFCRegExp = /^FC\.([a-zA-Z]+)\(/; const startBracketsReg = /^\(/;//左括号 const endBracketsReg = /^\)/;//右括号 const elementReg = /^E\[(.[^\]]+_.[^\]]+)\]/;//元素 const commaReg = /^,/;//逗号 const operatorReg = /^(\+|-|\*|%)/;//加减乘除 const wordReg = /^[\u4e00-\u9fa5\w0-9'"-]+/;//文本 let elementMap = JSON.parse(elemap);//元素字典 //console.log(formulaMap) let resArr = [];//结果数组 let strIndex = 0;//位置索引 let nuText = text;//未处理的字符串 //let startStack = [];//方法体开始部分和左括号 放进来的栈 let contentStack = [];//内容放进来的栈 while (strIndex < text.length) { nuText = text.substring(strIndex); if(startFCRegExp.test(nuText)){ //console.log('匹配FC开始部分') //匹配FC开始部分FC.xxx( let regRes = nuText.match(startFCRegExp); let startText = regRes[0];//匹配到的文本 let obj = {}; if(formulaMap[startText]){ Object.assign(obj,formulaMap[startText]); Object.assign(obj,{ type:'Function', children:[], tag:startText }); }else{ obj = { type:'Function', children:[], tag:startText } } //startStack.push(startText); contentStack.push(obj); strIndex += startText.length;//索引移动 }else if(endBracketsReg.test(nuText)){ //console.log('匹配右括号') //匹配右括号 let endBrackets = nuText.match(endBracketsReg)[0]; let popObj = contentStack.pop(); let arrType = []; if(contentStack.length > 0){ let content =contentStack[contentStack.length - 1]; content.children.push(popObj); arrType = content.children; }else{ //匹配完成最顶层的一整个方法体,或括号 resArr.push(popObj); arrType = resArr; } if(popObj.type =='Brackets'){ let brackArr = []; //如果是括号,把括号里面的提出一层 popObj.children.forEach((ele)=>{ brackArr.push(ele); }) //补个右括号 brackArr.push({ type:'Brackets', selected:false, name:')', }); arrType.push(...brackArr); delete popObj.children } //console.log(popObj,'pop') strIndex += endBrackets.length;//索引移动 }else if(startBracketsReg.test(nuText)){ //console.log('匹配左括号') //匹配左括号 let startBrackets = nuText.match(startBracketsReg)[0]; contentStack.push({ type:'Brackets', children:[], selected:false, name:startBrackets, tag:startBrackets }); strIndex += startBrackets.length;//索引移动 }else if(elementReg.test(nuText)){ //console.log('匹配元素') //匹配元素 let eleArr = nuText.match(elementReg); let obj = {}; if(elementMap[eleArr[1]]){ Object.assign(obj,elementMap[eleArr[1]]); Object.assign(obj,{ selected:false, children:[], tag:eleArr[0] }); }else{ obj = { type:'Element', name:eleArr[1].split('_')[1], tableElementKey:eleArr[1], children:[], selected:false, tag:eleArr[0] } } let content =contentStack[contentStack.length - 1]; if(content){ content.children.push(obj); }else{ //如果没有,那就是在最上层 resArr.push(obj); } strIndex += eleArr[0].length;//索引移动 }else if(commaReg.test(nuText)){ //console.log('匹配逗号') //匹配逗号 let comma = nuText.match(commaReg)[0]; contentStack[contentStack.length - 1].children.push({ type:'Comma', tag:comma }); strIndex += comma.length;//索引移动 }else if(operatorReg.test(nuText)){ //console.log('匹配加减乘除') //匹配加减乘除 let operator = nuText.match(operatorReg)[0]; let obj = { type:'Operator', name:operator, selected:false, tag:operator, }; if(formulaMap[operator]){ obj.example = formulaMap[operator].example; obj.template = formulaMap[operator].template; } if(contentStack.length > 0){ //不然就在方法体或括号里面 contentStack[contentStack.length - 1].children.push(obj); }else{ //如果没有,那就是在最上层 resArr.push(obj); } strIndex += operator.length;//索引移动 }else if(wordReg.test(nuText)){ //匹配文本 let word = nuText.match(wordReg)[0]; console.log('匹配文本',word) contentStack[contentStack.length - 1].children.push({ type:'Text', tag:word }); strIndex += word.length;//索引移动 } else{ console.log('匹配不到:',nuText) //匹配不到 strIndex++ } } let resultFormula = [{ children:[], name:"临时占位", selected:false, type:"Element", }] let processFormula = [] let isAllFun = true;//一层全是方法,有其他说明到了显示层 //从顶层开始 parseFormula(resArr,resultFormula,processFormula,isAllFun); //console.log(contentStack) console.log(resArr); console.log(resultFormula); console.log(processFormula); return { processFormula:processFormula, resultFormula:resultFormula, }; }