- 论坛徽章:
- 0
|
呵呵,如果加sin log...的话,用一棵expression binary tree 来分析比较好。
更新链接
- #! /usr/bin/awk
- # expression evaluator awk version
- # author : dbcat at chinaunix
- # email: deeperbluecat@gmail.com
- # 用法:
- # echo "4*arctan(sin(1))+sqrt(1.2)*(1-23*exp(3))-log(2+cos(3))"| awk -f eval
- # echo "PI+E^sin(32.1%3.1)"|awk -f eval
- # awk -f eval <( seq 1 100|tr "\n" "+"|sed 's/+//100' )
- # echo '1!=2&1|0'|awk -f eval
- # echo '1<=2+3>=(!2-1.1)+sin(1.2*(PI!=E))' | awk -f eval
- # 支持的算术运算符号 : + - * / % ^ ( )
- # 支持的函数运算 : sin cos tg log exp arctan sqrt int
- # 支持的逻辑运算符号 : < > ! != <= >= & |
- # 内置的常数 : PI E
- # 运行环境 : GNU Awk 3.1.4
- # have fun
- BEGIN{
- # 运算符集合
- symbol="+-*%<=!=>==|&>^SCLAEQTI/()@";
- # 构造运算符优先级关系
- consop(oppr);
- }
- #主函数
- {
- split(funclib($0"@"),Ex," ");
- print evaluate(Ex);
- }
- # 表达式求值函数
- function evaluate(Ex,OP,OF,c,k,t,x,str,y,r)
- {
- k=1;
- push(OP,"@");
- c=Ex[k];
- while(c!="@" || gettop(OP)!="@")
- {
- if(index(symbol,c)==0)
- {
- push(OF,c);
- k=k+1;
- c=Ex[k];
- }else
- {
- t=priority(oppr,gettop(OP),c);
- if(t=="<")
- {
- push(OP,c);
- k=k+1;
- c=Ex[k];
- }else if(t=="=")
- {
- pop(OP);
- k=k+1;
- c=Ex[k];
- }else{
- str=pop(OP);
- y=pop(OF);
- x=pop(OF);
- r=calculate(x,str,y);
- push(OF,calculate(x,str,y));
- }
- }
- }
- return gettop(OF);
- }
- # 二元运算函数
- function calculate(x,st,y)
- {
- if(st=="+")
- return x+y;
- else if(st=="-")
- return x-y;
- else if(st=="*")
- return x*y;
- else if(st=="%")
- return x%y;
- else if(st=="/")
- return x/y;
- else if(st=="^")
- return x^y;
- else if(st=="S")
- return sin(y);
- else if(st=="C")
- return cos(y);
- else if(st=="L")
- return log(y);
- else if(st=="E")
- return exp(y);
- else if(st=="Q")
- return sqrt(y);
- else if(st=="A")
- return atan2(y,1);
- else if(st=="T")
- return sin(y)/cos(y);
- else if(st=="I")
- return int(y);
- else if(st=="<")
- return x<y;
- else if(st==">")
- return x>y;
- else if(st=="<=")
- return x<=y;
- else if(st==">=")
- return x>=y;
- else if(st=="==")
- return x==y;
- else if(st=="!=")
- return x!=y;
- else if(st=="&")
- return x&&y;
- else if(st=="|")
- return x||y;
- else if(st=="!")
- return !y;
- }
- # 算符优先关系函数
- function consop(oppr,t,x,y,z,i,k,j,xl,yl,zl,tl)
- {
- xl="+-";
- yl=" * / % ^ < <= ! & | > >= == != ";
- zl="SCALEQTI";
- tl="+ - * / % ^ < > ! != == >= <= & | S C A L E Q T I";
- split(tl,t," ");
- split(xl,x,"");
- split(yl,y," ");
- split(zl,z,"");
- for(k=1;k<=length(xl);k++)
- {
- for(j=1;j<=length(xl);j++)
- {
- oppr[x[k]""x[j]]=">";
- oppr[x[j]""x[j]]=">";
- }
- for(j=1;j<=length(yl);j++)
- {
- oppr[x[k]""y[j]]="<";
- oppr[y[j]""x[k]]=">";
- for(i=1;i<=length(yl);i++)
- {
- oppr[y[j]""y[i]]=">";
- oppr[y[i]""y[j]]=">";
- }
- for(i=1;i<=length(zl);i++)
- {
- oppr[y[j]""z[i]]="<";
- oppr[z[i]""y[j]]=">";
- }
- }
- for(j=1;j<=length(zl);j++)
- {
- oppr[x[k]""z[j]]="<";
- oppr[z[j]""x[k]]=">";
- for(i=1;i<=length(zl);i++)
- {
- oppr[z[j]""z[i]]=">";
- oppr[z[i]""z[j]]=">";
- }
- }
- }
- for(j=1;j<=length(tl);j++)
- {
- oppr[t[j]"("]="<";
- oppr[t[j]")"]=">"
- oppr[t[j]"@"]=">";
- oppr[")"t[j]]=">";
- oppr["("t[j]]="<";
- oppr["@"t[j]]="<";
- }
- for(j=1;j<=length(yl);j++)
- {
- oppr[y[j]"^"]="<";
- }
- oppr["(("]="<";oppr["()"]="=";
- oppr["))"]=">";oppr[")@"]=">";
- oppr["@("]="<";oppr["@@"]="=";
- }
- # 优先级别比较
- function priority(oppr,op1,op2)
- {
- return oppr[op1""op2];
- }
- # 分解表达式
- function funclib(expr)
- {
- gsub(/PI/,"3.141592653589793238460",expr);
- gsub(/E/,"2.718281828459045235360",expr);
- gsub(/sin/," & S ",expr);
- gsub(/cos/," & C ",expr);
- gsub(/log/," & L ",expr);
- gsub(/exp/," & E ",expr);
- gsub(/arctan/," & A ",expr);
- gsub(/sqrt/," & Q ",expr);
- gsub(/tg/," & T ",expr);
- gsub(/int/," & I ",expr);
- gsub(/[-*%+>=!&|<^()SCLAEQTI/@]/," & ",expr);
- gsub(/<[ ]*=/,"<=",expr);
- gsub(/>[ ]*=/,">=",expr);
- gsub(/=[ ]*=/,"==",expr);
- gsub(/![ ]*=/,"!=",expr);
- gsub(/&/," & ",expr);
- gsub(/[|]/," & ",expr);
- gsub(/![^=]/," N ! ",expr);
- return expr;
- }
- # 取栈顶
- function gettop(arr,k,t)
- {
- k=0;
- for(t in arr)
- {
- k++;
- }
- return arr[k-1];
- }
- # 进栈函数
- function push(arr,x,t,k)
- {
- k=0;
- for(t in arr)
- {
- k++;
- }
- arr[k]=x;
- }
- # 出栈函数
- function pop(arr,va,t,u)
- {
- u=0;
- for(t in arr)
- {
- u++;
- }
- va=arr[u-1];
- delete arr[u-1];
- return va;
- }
复制代码
[ 本帖最后由 dbcat 于 2006-4-25 11:08 编辑 ] |
|