formulaStringToArray.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. function parseFormula(arr,resultFormula,processFormula,isAllFun){
  2. let tmpArr = [];//放置这一层的数组
  3. for (let i = 0; i < arr.length; i++) {
  4. tmpArr.push(arr[i]);
  5. if(arr[i].type != "Function"){
  6. isAllFun = false;
  7. }
  8. }
  9. if(isAllFun){
  10. for (let i = 0; i < tmpArr.length; i++) {
  11. parseArguments(resultFormula[0],tmpArr[i]);
  12. parseFormula(arr[i].children,resultFormula,processFormula,isAllFun);
  13. }
  14. }else{
  15. for (let i = 0; i < tmpArr.length; i++) {
  16. if(tmpArr[i].type == 'Function'){
  17. let obj = {
  18. children:[],
  19. name:"临时占位",
  20. selected:false,
  21. type:"Element",
  22. }
  23. parseProcessFormula(arr[i],obj);
  24. processFormula.push(Object.assign({},obj))
  25. delete obj.children;
  26. }else if(tmpArr[i].name){
  27. processFormula.push(tmpArr[i]);
  28. }
  29. }
  30. }
  31. }
  32. //解析方法里面的参数
  33. function parseArguments(ele,funObj){
  34. let fcReg = /(FC\.\S+\()(.+)\)/;
  35. let fun = {
  36. example:funObj.example,
  37. name:funObj.name,
  38. template:funObj.template,
  39. };
  40. let argTextArr = funObj.children;//放参数文本的数组
  41. //根据逗号位置分割参数
  42. let index = 0;
  43. let argSpliceArr = [[]];
  44. while (index < argTextArr.length) {
  45. if(argTextArr[index].type =='Comma'){
  46. argSpliceArr.push([]);
  47. }else{
  48. argSpliceArr[argSpliceArr.length-1].push(argTextArr[index])
  49. }
  50. index++
  51. }
  52. fun.arguments = [];
  53. let tmpArr = fcReg.exec(funObj.template.ft);
  54. let argList = tmpArr[2].split(",");//括号里面参数部分#1,#2..
  55. argList.forEach((argText,index)=>{
  56. //只用动态的
  57. if(argText.indexOf('#')>-1){
  58. if(argSpliceArr[index].length>1){
  59. //是前面的计算结果
  60. fun.arguments.push(ele)
  61. }else{
  62. let arg = argSpliceArr[index][0];
  63. if(arg.type == 'Element'){
  64. fun.arguments.push(arg)
  65. }else if(arg.type == 'Function'){
  66. fun.arguments.push(ele)
  67. }else if(arg.type == 'Text'){
  68. fun.arguments.push(arg.tag)
  69. }else{
  70. fun.arguments.push(undefined)
  71. }
  72. }
  73. }
  74. })
  75. ele.children.push(fun);
  76. }
  77. function parseProcessFormula(funObj,ele){
  78. parseArguments(ele,funObj);
  79. let inFun = false;//是不是有Function
  80. let endEle = null;//认为最下面一层第一个元素是显示的元素
  81. for (let i = 0; i < funObj.children.length; i++) {
  82. if(funObj.children[i].type == 'Function'){
  83. parseProcessFormula(funObj.children[i],ele);
  84. inFun = true;
  85. }else if(funObj.children[i].type == "Element" && !endEle){
  86. endEle = funObj.children[i];
  87. }
  88. }
  89. if(!inFun){
  90. //把临时的属性改为最终找到的
  91. ele.id = endEle.id;
  92. ele.name = endEle.name;
  93. ele.tableElementKey = endEle.tableElementKey;
  94. }
  95. }
  96. export const formulaStringToArray = (text,elemap,formulaMap) => {
  97. // 匹配开始的FC.xxx(
  98. const startFCRegExp = /^FC\.([a-zA-Z]+)\(/;
  99. const startBracketsReg = /^\(/;//左括号
  100. const endBracketsReg = /^\)/;//右括号
  101. const elementReg = /^E\[(.[^\]]+_.[^\]]+)\]/;//元素
  102. const commaReg = /^,/;//逗号
  103. const operatorReg = /^(\+|-|\*|%)/;//加减乘除
  104. const wordReg = /^[\u4e00-\u9fa5\w0-9'"-]+/;//文本
  105. let elementMap = JSON.parse(elemap);//元素字典
  106. //console.log(formulaMap)
  107. let resArr = [];//结果数组
  108. let strIndex = 0;//位置索引
  109. let nuText = text;//未处理的字符串
  110. //let startStack = [];//方法体开始部分和左括号 放进来的栈
  111. let contentStack = [];//内容放进来的栈
  112. while (strIndex < text.length) {
  113. nuText = text.substring(strIndex);
  114. if(startFCRegExp.test(nuText)){
  115. //console.log('匹配FC开始部分')
  116. //匹配FC开始部分FC.xxx(
  117. let regRes = nuText.match(startFCRegExp);
  118. let startText = regRes[0];//匹配到的文本
  119. let obj = {};
  120. if(formulaMap[startText]){
  121. Object.assign(obj,formulaMap[startText]);
  122. Object.assign(obj,{
  123. type:'Function',
  124. children:[],
  125. tag:startText
  126. });
  127. }else{
  128. obj = {
  129. type:'Function',
  130. children:[],
  131. tag:startText
  132. }
  133. }
  134. //startStack.push(startText);
  135. contentStack.push(obj);
  136. strIndex += startText.length;//索引移动
  137. }else if(endBracketsReg.test(nuText)){
  138. //console.log('匹配右括号')
  139. //匹配右括号
  140. let endBrackets = nuText.match(endBracketsReg)[0];
  141. let popObj = contentStack.pop();
  142. let arrType = [];
  143. if(contentStack.length > 0){
  144. let content =contentStack[contentStack.length - 1];
  145. content.children.push(popObj);
  146. arrType = content.children;
  147. }else{
  148. //匹配完成最顶层的一整个方法体,或括号
  149. resArr.push(popObj);
  150. arrType = resArr;
  151. }
  152. if(popObj.type =='Brackets'){
  153. let brackArr = [];
  154. //如果是括号,把括号里面的提出一层
  155. popObj.children.forEach((ele)=>{
  156. brackArr.push(ele);
  157. })
  158. //补个右括号
  159. brackArr.push({
  160. type:'Brackets',
  161. selected:false,
  162. name:')',
  163. });
  164. arrType.push(...brackArr);
  165. delete popObj.children
  166. }
  167. //console.log(popObj,'pop')
  168. strIndex += endBrackets.length;//索引移动
  169. }else if(startBracketsReg.test(nuText)){
  170. //console.log('匹配左括号')
  171. //匹配左括号
  172. let startBrackets = nuText.match(startBracketsReg)[0];
  173. contentStack.push({
  174. type:'Brackets',
  175. children:[],
  176. selected:false,
  177. name:startBrackets,
  178. tag:startBrackets
  179. });
  180. strIndex += startBrackets.length;//索引移动
  181. }else if(elementReg.test(nuText)){
  182. //console.log('匹配元素')
  183. //匹配元素
  184. let eleArr = nuText.match(elementReg);
  185. let obj = {};
  186. if(elementMap[eleArr[1]]){
  187. Object.assign(obj,elementMap[eleArr[1]]);
  188. Object.assign(obj,{
  189. selected:false,
  190. children:[],
  191. tag:eleArr[0]
  192. });
  193. }else{
  194. obj = {
  195. type:'Element',
  196. name:eleArr[1].split('_')[1],
  197. tableElementKey:eleArr[1],
  198. children:[],
  199. selected:false,
  200. tag:eleArr[0]
  201. }
  202. }
  203. let content =contentStack[contentStack.length - 1];
  204. content.children.push(obj);
  205. strIndex += eleArr[0].length;//索引移动
  206. }else if(commaReg.test(nuText)){
  207. //console.log('匹配逗号')
  208. //匹配逗号
  209. let comma = nuText.match(commaReg)[0];
  210. contentStack[contentStack.length - 1].children.push({
  211. type:'Comma',
  212. tag:comma
  213. });
  214. strIndex += comma.length;//索引移动
  215. }else if(operatorReg.test(nuText)){
  216. //console.log('匹配加减乘除')
  217. //匹配加减乘除
  218. let operator = nuText.match(operatorReg)[0];
  219. let obj = {
  220. type:'Operator',
  221. name:operator,
  222. selected:false,
  223. tag:operator,
  224. };
  225. if(formulaMap[operator]){
  226. obj.example = formulaMap[operator].example;
  227. obj.template = formulaMap[operator].template;
  228. }
  229. if(contentStack.length > 0){
  230. //不然就在方法体或括号里面
  231. contentStack[contentStack.length - 1].children.push(obj);
  232. }else{
  233. //如果没有,那就是在最上层
  234. resArr.push(obj);
  235. }
  236. strIndex += operator.length;//索引移动
  237. }else if(wordReg.test(nuText)){
  238. //匹配文本
  239. let word = nuText.match(wordReg)[0];
  240. console.log('匹配文本',word)
  241. contentStack[contentStack.length - 1].children.push({
  242. type:'Text',
  243. tag:word
  244. });
  245. strIndex += word.length;//索引移动
  246. }
  247. else{
  248. console.log('匹配不到:',nuText)
  249. //匹配不到
  250. strIndex++
  251. }
  252. }
  253. let resultFormula = [{
  254. children:[],
  255. name:"临时占位",
  256. selected:false,
  257. type:"Element",
  258. }]
  259. let processFormula = []
  260. let isAllFun = true;//一层全是方法,有其他说明到了显示层
  261. //从顶层开始
  262. parseFormula(resArr,resultFormula,processFormula,isAllFun);
  263. //console.log(contentStack)
  264. console.log(resArr);
  265. console.log(resultFormula);
  266. console.log(processFormula);
  267. return {
  268. processFormula:processFormula,
  269. resultFormula:resultFormula,
  270. };
  271. }