UNPKG

yyel-engine

Version:
369 lines (314 loc) 11.3 kB
function str2Object(commonStr) { let oper1 = ['+', '-', '*', '/', '!=', '==', '(', ')', '<', '>', '<=', '>=']; let oper2 = ['7', '8', '9', '0', '4', '5', '6', '.', '1', '2', '3', '00']; let regOper1 = oper1.concat(oper2).filter(v => v.length > 1); let regOper2 = oper1.concat(oper2).filter(v => v.length <= 1); let reg = regOper => { let specialCharList = "[]-\\^"; let simpleOperArray = regOper.filter(v => v.length == 1); let complexOperArray = regOper.filter(v => v.length > 1); let simpleReg = simpleOperArray.length > 0 ? `[${simpleOperArray.map((v, k) => /[0-9]/.test(v) ? `${v}` : `\\${v}`).join('')}]` : ''; let complexReg = complexOperArray.map((v, k) => { return k == complexOperArray.length - 1 ? `(?:${v})` : `(?:${v})|`; }).join(''); return new RegExp(simpleReg.length > 0 && complexReg.length > 0 ? simpleReg + '|' + complexReg : simpleReg.length > 0 ? simpleReg : complexReg.length > 0 ? complexReg : ""); }; function getNumber(str) { var arr = []; for (let i = 0; i < str.length; i++) { if (parseInt(str[i]).toString() == 'NaN') { arr.push({ type: 'oper', value: str[i] }); } else { let newV = str.substring(i).replace(/[<>+-]/g, '*').split('*').concat(); for (let j = 0; j < newV.length; j++) { if (parseInt(str[i]).toString() != 'NaN') { arr.push({ type: 'number', value: newV[j] }); i += newV[j].length - 1; break; } } } } return arr; } let isString = commonStr.match(/[\"\“\'\’]/); if (!isString) { return getNumber(commonStr); } else { function divideStr(str) { let divideList = []; let divideReg = /(?:(\"(.*?)\")|(\“(.*?)\”)|(\'(.*?)\')|(\‘(.*?)\’))/; for (let i = 0; i < str.length; i++) { let tempStr = str.slice(i); let hasChar = tempStr.match(divideReg); if (!hasChar) { divideList.push(tempStr); break; } else { let startIndex = hasChar.index || 0; let length = hasChar[0].length; if (startIndex >= 0) { if (startIndex != 0) { divideList.push(tempStr.slice(0, startIndex)); } divideList.push({ type: 'string', code: hasChar[0] || '' }); i = i + startIndex + length - 1; } } } return divideList; } return divideStr(commonStr).reduce((prev, v) => { if (typeof v == 'string') { prev = prev.concat(getNumber(v)); return prev; } else { prev.push(v); return prev; } }, []); } } export function parseFormulaExpression(formulaExpression, isParamStr) { let formulaArray = []; if (isParamStr) { if (formulaExpression.length === 0) { return []; } let dotIndex = [], degree = 0; for (let i in formulaExpression) { if (degree == 0 && formulaExpression[i] == ',') { dotIndex.push(parseInt(i)); } if (formulaExpression[i] == '(') { degree++; } if (formulaExpression[i] == ')') { degree--; } } if (dotIndex.length > 0) { let paramList = dotIndex.reduce((prev, v, k) => { let item = null, item2 = null; if (k == 0) { item = formulaExpression.slice(0, v); prev.push(item); if (k == dotIndex.length - 1) { prev.push(formulaExpression.slice(v + 1)); } return prev; } else if (k < dotIndex.length - 1) { item = formulaExpression.slice(dotIndex[k - 1] + 1, v); prev.push(item); return prev; } else { item = formulaExpression.slice(dotIndex[k - 1] + 1, v); item2 = formulaExpression.slice(v + 1); prev.push(item, item2); return prev; } }, []); return paramList.map(v => v.length >= 1 ? parseFormulaExpression(v) : null); } else { return [parseFormulaExpression(formulaExpression)]; } } let inUriReg = /(\".*?#.*?\")|(\“.*?#.*?\”)/; let firstIndex = -1; for (let i = 0; i < formulaExpression.length; i++) { let tempStr = formulaExpression.slice(i); let charPosition = tempStr.indexOf('#'); let hasChar = tempStr.match(inUriReg); if (!hasChar) { firstIndex = charPosition; break; } else { let startIndex = hasChar.index || 0; let length = hasChar[0].length; if (charPosition > startIndex && charPosition < startIndex + length) { i = i + startIndex + length - 1; } else { firstIndex = charPosition; break; } } } if (firstIndex == -1) { return str2Object(formulaExpression); } let firstSubstr = formulaExpression.slice(0, firstIndex); if (firstSubstr.length > 0) { formulaArray = formulaArray.concat(parseFormulaExpression(firstSubstr)); } let regVerify = formulaExpression.slice(firstIndex).match(/[\(\@\$]/); if (!regVerify) { return str2Object(formulaExpression); } let type = regVerify ? regVerify[0] == '(' ? 'func' : regVerify[0] == '@' ? 'variable' : regVerify[0] == '$' ? 'uri' : '' : ''; let endIndex = regVerify && regVerify.index || -1; let paramEndIndex = -1; if (type == 'func') { let count = 1; let countStr = formulaExpression.slice(firstIndex + endIndex + 1); for (let i in countStr) { if (countStr[i] == '(') { count++; } if (countStr[i] == ')') { count--; if (count == 0) { paramEndIndex = parseInt(i) + firstIndex + endIndex + 1; break; } } } if (paramEndIndex == -1) { formulaArray.push({ type: 'func', code: formulaExpression.slice(firstIndex + 1, firstIndex + endIndex), params: parseFormulaExpression(formulaExpression.slice(firstIndex + endIndex + 1), true) }); } else { formulaArray.push({ type: 'func', code: formulaExpression.slice(firstIndex + 1, firstIndex + endIndex), params: parseFormulaExpression(formulaExpression.slice(firstIndex + endIndex + 1, paramEndIndex), true) }); } } else if (type == 'variable') { paramEndIndex = firstIndex + endIndex; formulaArray.push({ type: 'variable', code: formulaExpression.slice(firstIndex + 1, paramEndIndex) }); } else if (type == 'uri') { if (formulaExpression.slice(firstIndex + 1, firstIndex + endIndex).match(/^\{[^\}]*\}$/)) { paramEndIndex = firstIndex + endIndex; formulaArray.push({ type: 'const', code: formulaExpression.slice(firstIndex + 2, paramEndIndex - 1).replace(/"/g, '') }); } else { paramEndIndex = firstIndex + endIndex; formulaArray.push({ type: 'uri', code: formulaExpression.slice(firstIndex + 1, paramEndIndex).replace(/"/g, '') }); } } let tailSubstr = paramEndIndex == -1 ? "" : formulaExpression.slice(paramEndIndex + 1); if (tailSubstr.length > 0) { formulaArray = formulaArray.concat(parseFormulaExpression(tailSubstr)); } return formulaArray; } export function createMathExpressWithError(formulaList, paramList) { let _mathExpress = ''; try { _mathExpress = createMathExpress(formulaList, paramList); } catch (err) { throw Error('公式自动计算错误:' + err); } return _mathExpress; } function createMathExpress(formulaList, paramList) { const OPER_LIST = new Set(['-', '+', '/', '*', '(', ')', '>', '<', '&&', '||', '>=', '<=', '==', '%']); const MATH_LIST = new Set(['sin', 'cos', 'exp', 'sqrt', 'log', 'tan', 'cot', 'asin', 'acos', 'atan', 'max', 'min', 'abs', 'ln', 'PI', 'E']); const MATH_LIST_EXP = new Set(['PI', 'E']); const STRING_LIST = new Set(['contains', 'endsWith', 'startsWith', 'indexOf', 'lastIndexOf', 'length', 'lowerCase', 'upperCase', 'equalsIgnoreCase', 'left', 'right']); const STRING_LIST_OBJ = { contains: (s1, s2) => s1.includes(s2), endsWith: (s1, s2) => s1.endsWith(s2), startsWith: (s1, s2) => s1.startsWith(s2), indexOf: (s1, s2) => s1.indexOf(s2), lastIndexOf: (s1, s2) => s1.lastIndexOf(s2), length: s1 => s1.length, lowerCase: s1 => s1.toLowerCase(), upperCase: s1 => s1.toUpperCase(), equalsIgnoreCase: (s1, s2) => s1.toLowerCase() === s2.toLowerCase(), left: (s1, num) => s1.slice(0, num), right: (s1, num) => s1.slice(-num) }; let express = "", calcExpress = true; function handleFactory(record) { if (record.type == 'func') { if (STRING_LIST.has(record.functionName || record.code)) { let strParamList = []; let params = "paramCount" in record ? record.params.slice(0, record.paramCount) : record.params; params.forEach(v => { strParamList.push(createMathExpress(v, paramList)); }); let returnType = typeof STRING_LIST_OBJ[record.code](...strParamList); if (returnType == 'string' && isNaN(STRING_LIST_OBJ[record.code](...strParamList))) { calcExpress = false; } if (!express) { express = STRING_LIST_OBJ[record.code](...strParamList); } else { express += STRING_LIST_OBJ[record.code](...strParamList); } } if (MATH_LIST.has(record.functionName || record.code)) { let _funcExpress = ''; if (MATH_LIST_EXP.has(record.functionName || record.code)) { _funcExpress += `${record.functionName}`; } else { _funcExpress += `${record.functionName}(`; let params = "paramCount" in record ? record.params.slice(0, record.paramCount) : record.params; _funcExpress += params && params.map((v, index) => { return createMathExpress(v, paramList) + (index < params.length - 1 ? ',' : ''); }).join('') || ''; _funcExpress += ")"; } express += eval(_funcExpress); } } if (record.type == 'variable') { if (record.code && record.code in paramList) { if (paramList[record.code] === '') { if (record.paramType) { express += ['DOUBLE', 'FLOAT', 'INT'].includes(record.paramType) ? 0 : ''; } else { express += ''; } } else { express += paramList[record.code]; } } else { express += record.code; throw Error('选中变量不在当前提供变量列表中!'); } } if (record.type == 'oper' || record.type == 'number') { calcExpress = isNaN(record.value) && !OPER_LIST.has(record.value) ? false : calcExpress; express += record.value; } if (record.type == 'uri' || record.type == 'string') { calcExpress = isNaN(record.code) ? false : calcExpress; express += record.code; } } if (formulaList) { if (Array.isArray(formulaList) && formulaList.length > 0) { for (let record of formulaList) { handleFactory(record); } } else if (typeof formulaList == "object") { handleFactory(formulaList); } } return calcExpress ? eval(express) : express; } //# sourceMappingURL=index.js.map