为了完成java的作业,先拿js写了一个。暂时只完成了一些简单的运算
效果:
expression.calcExpression('1%+1');//1.01 expression.calcExpression('.1%+1');//1.001 expression.calcExpression('(5-2)%/0');//Infinity expression.calcExpression('(4+3)(4-3)');//7 expression.calcExpression('3(4+5)');//27 expression.calcExpression('-3(4+5)');//-27
/* Copyright luojia@luojia.me (https://luojia.me) */ class expression{ static throwError(index){ throw(`expression error @${index}`); } static compItem(value,index){ return [value,index]; } static isNumber(item){ return typeof item[0]==='number'; } static calcExpression(exp){ let rawcomps=[], comps=[]; let signs=new RegExp(/[\(\)\-\+\*\/\%]/y), space=new RegExp(/\s+/y), number=new RegExp(/(\d+\.*\d*)|(\.\d+)/y); let lastIndex=0,match; do{ if(((space.lastIndex=lastIndex),true)&&(match=space.exec(exp))){//spaces rawcomps.push(match[0]); lastIndex=space.lastIndex; }else if(((signs.lastIndex=lastIndex),true)&&(match=signs.exec(exp))){//signs rawcomps.push(match[0]); comps.push(expression.compItem(match[0],match.index)); if(match[0]==='('){ if(comps.length>1){ let last=comps[comps.length-2][0]; if(last===')'|| expression.isNumber(comps[comps.length-2])){ comps.splice(comps.length-1,0,expression.compItem('*',-1)); } } } lastIndex=signs.lastIndex; }else if(((number.lastIndex=lastIndex),true)&&(match=number.exec(exp))){//number rawcomps.push(match[0]); if(match[0][0]==='.')match[0]='0'+match[0];//添加0 comps.push(expression.compItem(Number(match[0]),match.index)); lastIndex=number.lastIndex; }else{ expression.throwError(lastIndex); } }while(lastIndex!==exp.length); return expression.expressionParser(comps)[0]; } static expressionParser(comps){//return a compItem let groupStack=[],lastWasNumber=false; for(let i=0;i<comps.length;i++){//() if(expression.isNumber(comps[i])){ if(lastWasNumber)expression.throwError(comps[i][1]); lastWasNumber=true; continue; } lastWasNumber=false; if(comps[i][0]==='('){ groupStack.push(i); }else if(comps[i][0]===')'){ if(groupStack.length===0) expression.throwError(comps[i][1]); else if(groupStack.length===1){//use a new parser let newgroup=comps.splice(groupStack[0],i-groupStack[0]+1); newgroup.pop();newgroup.shift(); comps.splice(groupStack[0],0,expression.expressionParser(newgroup)); i=groupStack[0]; } groupStack.pop(); } } if(groupStack.length)expression.throwError(comps[groupStack[groupStack.length-1]][1]); for(let i=0;i<comps.length;i++){// n% if(expression.isNumber(comps[i])){continue;} let exp=comps[i][0]; if(exp==='%'){ if(!comps[i-1] || !expression.isNumber(comps[i-1]))expression.throwError(comps[i][1]); comps.splice(i-1,2,expression.compItem(comps[i-1][0]/100,comps[i-1][1])); i--; } } for(let i=0;i<comps.length;i++){// * / if(expression.isNumber(comps[i])){continue;} let exp=comps[i][0]; if(exp==='*'||exp==='/'){ if(i===comps.length || !comps[i-1] || !expression.isNumber(comps[i-1]) || !expression.isNumber(comps[i+1])) expression.throwError(comps[i][1]); //calc let result; if(exp==='*'){ result=comps[i-1][0]*comps[i+1][0]; }else{ result=comps[i-1][0]/comps[i+1][0]; } comps.splice(i-1,3,expression.compItem(result,comps[i-1][1])); i--; } } for(let i=0;i<comps.length;i++){// + - if(expression.isNumber(comps[i])){continue;} let exp=comps[i][0]; if(exp==='+'||exp==='-'){ if(i===comps.length || !expression.isNumber(comps[i+1])) expression.throwError(comps[i][1]); if(i===0||!expression.isNumber(comps[i-1])){//当做正负符号 if(exp==='-')comps[i+1][0]=-comps[i+1][0]; comps.splice(i,1); i--; }else{//计算表达式 let result; if(exp==='+'){ result=comps[i-1][0]+comps[i+1][0]; }else{ result=comps[i-1][0]-comps[i+1][0]; } comps.splice(i-1,3,expression.compItem(result,comps[i-1][1])); i--; } } } if(comps.length!==1){ console.error([...comps]); throw('something wrong'); } return comps[0];//return the value } }
本文发布于 https://luojia.me
本站文章未经文下加注授权不得拷贝发布。