四则运算式解释,并计算
语法分析
using
System;
using System.Collections;
namespace myChain
... {
/**//// <summary>
/// 自定义的CxyStack。
/// </summary>
public class cxyStack
...{
private Stack mystack;
public cxyStack()
...{
mystack=new Stack();
}
public void Push(object o)
...{
mystack.Push(o);
}
public object Pop()
...{
return mystack.Pop();
}
public bool IsEmpty()
...{
return mystack.Count==0;
}
public int Count
...{
get...{return mystack.Count;}
}
public object TopItem()
...{
return mystack.Peek();
}
}
/**//// <summary>
/// 处理四则表达式中Token的基础类
/// </summary>
public abstract class TreateToken
...{
//用来处理Token的临时堆栈
protected cxyStack st;
//用来保存结果的堆栈
protected cxyStack stOutput;
//Next构成职责链
protected TreateToken next;
public TreateToken Next
...{
get...{return next;}
set...{next=value;}
}
public TreateToken(cxyStack tst,cxyStack tstOut)
...{
this.st=tst;
this.stOutput=tstOut;
}
public abstract void Treat(string s);
}
/**//// <summary>
/// 处理数字
/// </summary>
public class NumberToToken:TreateToken
...{
public NumberToToken(cxyStack tst,cxyStack tstOut):base(tst,tstOut)
...{
}
public override void Treat(string s)
...{
if(Char.IsNumber(s,0))
...{
stOutput.Push(s);
}
else
...{
next.Treat(s);
}
}
}
/**//// <summary>
/// 处理字符串+-*/()
/// </summary>
public class OperatorToken:TreateToken
...{
private myOperator ope;
public OperatorToken(cxyStack tst,cxyStack tstOut,myOperator op):base(tst,tstOut)
...{
this.ope=op;
}
public override void Treat(string s)
...{
if(s==ope.Op)
...{
if(st.IsEmpty()||s=="(")
...{
st.Push(ope);
}
else
...{
myOperator o=(myOperator) st.TopItem();
while(o.Level>=ope.Level||ope.Op==")")
...{
myOperator ol=(myOperator)st.Pop();
if(ol.Op=="(") break;
this.stOutput.Push(ol);
if(st.IsEmpty()) break;
o=(myOperator)st.TopItem();
}
if(ope.Op!=")")
st.Push(ope);
}
}
else
next.Treat(s);
}
}
/**//// <summary>
/// 操作符与优先级
/// </summary>
public class myOperator
...{
private string ope;
private int level;
public myOperator(string o,int l)
...{
ope=o;level=l;
}
public string Op
...{
get...{return ope;}
set...{ope=value;}
}
public int Level
...{
get...{return level;}
}
public override string ToString()
...{
return ope;
}
}
/**//// <summary>
/// 处理除字符串和操作符之外的字符
/// </summary>
public class OtherToken:TreateToken
...{
public OtherToken():base(null,null)
...{
}
public override void Treat(string s)
...{
if(s!="")
throw new ArgumentException("无法识别的操作符"+s);
}
}
}
using System.Collections;
namespace myChain
... {
/**//// <summary>
/// 自定义的CxyStack。
/// </summary>
public class cxyStack
...{
private Stack mystack;
public cxyStack()
...{
mystack=new Stack();
}
public void Push(object o)
...{
mystack.Push(o);
}
public object Pop()
...{
return mystack.Pop();
}
public bool IsEmpty()
...{
return mystack.Count==0;
}
public int Count
...{
get...{return mystack.Count;}
}
public object TopItem()
...{
return mystack.Peek();
}
}
/**//// <summary>
/// 处理四则表达式中Token的基础类
/// </summary>
public abstract class TreateToken
...{
//用来处理Token的临时堆栈
protected cxyStack st;
//用来保存结果的堆栈
protected cxyStack stOutput;
//Next构成职责链
protected TreateToken next;
public TreateToken Next
...{
get...{return next;}
set...{next=value;}
}
public TreateToken(cxyStack tst,cxyStack tstOut)
...{
this.st=tst;
this.stOutput=tstOut;
}
public abstract void Treat(string s);
}
/**//// <summary>
/// 处理数字
/// </summary>
public class NumberToToken:TreateToken
...{
public NumberToToken(cxyStack tst,cxyStack tstOut):base(tst,tstOut)
...{
}
public override void Treat(string s)
...{
if(Char.IsNumber(s,0))
...{
stOutput.Push(s);
}
else
...{
next.Treat(s);
}
}
}
/**//// <summary>
/// 处理字符串+-*/()
/// </summary>
public class OperatorToken:TreateToken
...{
private myOperator ope;
public OperatorToken(cxyStack tst,cxyStack tstOut,myOperator op):base(tst,tstOut)
...{
this.ope=op;
}
public override void Treat(string s)
...{
if(s==ope.Op)
...{
if(st.IsEmpty()||s=="(")
...{
st.Push(ope);
}
else
...{
myOperator o=(myOperator) st.TopItem();
while(o.Level>=ope.Level||ope.Op==")")
...{
myOperator ol=(myOperator)st.Pop();
if(ol.Op=="(") break;
this.stOutput.Push(ol);
if(st.IsEmpty()) break;
o=(myOperator)st.TopItem();
}
if(ope.Op!=")")
st.Push(ope);
}
}
else
next.Treat(s);
}
}
/**//// <summary>
/// 操作符与优先级
/// </summary>
public class myOperator
...{
private string ope;
private int level;
public myOperator(string o,int l)
...{
ope=o;level=l;
}
public string Op
...{
get...{return ope;}
set...{ope=value;}
}
public int Level
...{
get...{return level;}
}
public override string ToString()
...{
return ope;
}
}
/**//// <summary>
/// 处理除字符串和操作符之外的字符
/// </summary>
public class OtherToken:TreateToken
...{
public OtherToken():base(null,null)
...{
}
public override void Treat(string s)
...{
if(s!="")
throw new ArgumentException("无法识别的操作符"+s);
}
}
}
计算机
using
System;
using System.Collections;
namespace myChain
... {
public abstract class CompToken:TreateToken
...{
protected string token=" ";
public CompToken(cxyStack sstemp,cxyStack soutput):base(sstemp,soutput)
...{
}
public override void Treat(string s)
...{
if(s==token) ...{
double b=Convert.ToDouble(stOutput.Pop().ToString());
double a=Convert.ToDouble(stOutput.Pop().ToString());
double c=Comp(a,b);
this.stOutput.Push(c.ToString());
}
else ...{
this.next.Treat(s);
}
}
public abstract double Comp(double a,double b);
}
public class AddToken:CompToken
...{
public AddToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="+";
}
public override double Comp(double a, double b)
...{
return a+b;
}
}
public class MinusToken:CompToken
...{
public MinusToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="-";
}
public override double Comp(double a, double b)
...{
return a-b;
}
}
public class ByToken:CompToken
...{
public ByToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="*";
}
public override double Comp(double a, double b)
...{
return a*b;
}
}
public class DivideToken:CompToken
...{
public DivideToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="/";
}
public override double Comp(double a, double b)
...{
return a/b;
}
}
public class ChangFange:CompToken
...{
public ChangFange(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="^";
}
public override double Comp(double a, double b)
...{
return Math.Pow(a,b);
}
}
public class Computer
...{
private cxyStack InStack;
private cxyStack OutStack=new cxyStack();
private TreateToken tk;
public Computer(cxyStack inStk)
...{
InStack=inStk;
tk=new NumberToToken(InStack,OutStack);
ArrayList configFile=new ArrayList();
MyConstruct addcon=new MyConstruct();
addcon.TypeStr= "myChain.AddToken";
MyConstruct minuscon=new MyConstruct();
minuscon.TypeStr="myChain.MinusToken";
MyConstruct bycon=new MyConstruct();
bycon.TypeStr="myChain.ByToken";
MyConstruct divecon=new MyConstruct();
divecon.TypeStr="myChain.DivideToken";
MyConstruct changfange=new MyConstruct();
changfange.TypeStr="myChain.ChangFange";
configFile.Add(addcon);
configFile.Add(minuscon);
configFile.Add(bycon);
configFile.Add(divecon);
configFile.Add(changfange);
ArrayList comar=ComputChainFactory.GetChain(InStack,OutStack,configFile);
tk.Next=(CompToken)comar[0];
}
public string Do()
...{
while(InStack.Count>0)
...{
string s=InStack.Pop().ToString();
tk.Treat(s);
}
return OutStack.Pop().ToString();
}
}
}
using System.Collections;
namespace myChain
... {
public abstract class CompToken:TreateToken
...{
protected string token=" ";
public CompToken(cxyStack sstemp,cxyStack soutput):base(sstemp,soutput)
...{
}
public override void Treat(string s)
...{
if(s==token) ...{
double b=Convert.ToDouble(stOutput.Pop().ToString());
double a=Convert.ToDouble(stOutput.Pop().ToString());
double c=Comp(a,b);
this.stOutput.Push(c.ToString());
}
else ...{
this.next.Treat(s);
}
}
public abstract double Comp(double a,double b);
}
public class AddToken:CompToken
...{
public AddToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="+";
}
public override double Comp(double a, double b)
...{
return a+b;
}
}
public class MinusToken:CompToken
...{
public MinusToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="-";
}
public override double Comp(double a, double b)
...{
return a-b;
}
}
public class ByToken:CompToken
...{
public ByToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="*";
}
public override double Comp(double a, double b)
...{
return a*b;
}
}
public class DivideToken:CompToken
...{
public DivideToken(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="/";
}
public override double Comp(double a, double b)
...{
return a/b;
}
}
public class ChangFange:CompToken
...{
public ChangFange(cxyStack sstemp,cxyStack stout):base(sstemp,stout)
...{
token="^";
}
public override double Comp(double a, double b)
...{
return Math.Pow(a,b);
}
}
public class Computer
...{
private cxyStack InStack;
private cxyStack OutStack=new cxyStack();
private TreateToken tk;
public Computer(cxyStack inStk)
...{
InStack=inStk;
tk=new NumberToToken(InStack,OutStack);
ArrayList configFile=new ArrayList();
MyConstruct addcon=new MyConstruct();
addcon.TypeStr= "myChain.AddToken";
MyConstruct minuscon=new MyConstruct();
minuscon.TypeStr="myChain.MinusToken";
MyConstruct bycon=new MyConstruct();
bycon.TypeStr="myChain.ByToken";
MyConstruct divecon=new MyConstruct();
divecon.TypeStr="myChain.DivideToken";
MyConstruct changfange=new MyConstruct();
changfange.TypeStr="myChain.ChangFange";
configFile.Add(addcon);
configFile.Add(minuscon);
configFile.Add(bycon);
configFile.Add(divecon);
configFile.Add(changfange);
ArrayList comar=ComputChainFactory.GetChain(InStack,OutStack,configFile);
tk.Next=(CompToken)comar[0];
}
public string Do()
...{
while(InStack.Count>0)
...{
string s=InStack.Pop().ToString();
tk.Treat(s);
}
return OutStack.Pop().ToString();
}
}
}