文法分析与解释器模式(三)
这里把上两次内容作一个连接。
生成名为Parsing的类,它拥有一个名为Calculate()的方法,传入表达式字符串,返回double结果。
public class Parsing
{
private Context ctx;
public Dictionary<string, double> _src;
public Parsing(Dictionary<string,double> source)
{
this._src = source;
ctx = new Context();
foreach (string key in _src.Keys)
{
ctx.Assign(new Variable(key), _src[key]);
}
}
public void Update()
{
ctx.Clear();
foreach (string key in _src.Keys)
{
ctx.Assign(new Variable(key), _src[key]);
}
}
public double Calculate(string expression)
{
InToPost post = new InToPost(expression);
Queue<string> q;
int err=post.Trans(out q);
if (err == 0) return double.MaxValue;
Stack<Expression> se = new Stack<Expression>();
string str;
while (q.Count != 0)
{
str=q.Dequeue();
switch (str)
{
case"":
case"(":
case")":
break;
case"+":
se.Push(new Add(se.Pop(), se.Pop()));
break;
case "-":
se.Push(new Dec(se.Pop(), se.Pop()));
break;
case "*":
se.Push(new Mul(se.Pop(), se.Pop()));
break;
case "/":
se.Push(new Div(se.Pop(), se.Pop()));
break;
case "^":
se.Push(new Pow(se.Pop(), se.Pop()));
break;
default:
if (char.IsLetter(str[0]))
se.Push(new Variable(str));
else
se.Push(new Number(double.Parse(str)));
break;
}
}
double result;
if (se.Count == 1)
result = se.Pop().Interpret(ctx);
else
throw new Exception("Expression is not correct");
return result;
}
}
大家可能注意到这个类中有一个Dictionary类型的变量和一条new Variable(str)的语句,这其实就是可以对支持变量进行扩展^_^.
有时间我会写一个近似于MathCAD的RichEditBox的表达式解析器发上来。
一个类似简易的支持变量的表达式解析器例子
生成名为Parsing的类,它拥有一个名为Calculate()的方法,传入表达式字符串,返回double结果。
public class Parsing
{
private Context ctx;
public Dictionary<string, double> _src;
public Parsing(Dictionary<string,double> source)
{
this._src = source;
ctx = new Context();
foreach (string key in _src.Keys)
{
ctx.Assign(new Variable(key), _src[key]);
}
}
public void Update()
{
ctx.Clear();
foreach (string key in _src.Keys)
{
ctx.Assign(new Variable(key), _src[key]);
}
}
public double Calculate(string expression)
{
InToPost post = new InToPost(expression);
Queue<string> q;
int err=post.Trans(out q);
if (err == 0) return double.MaxValue;
Stack<Expression> se = new Stack<Expression>();
string str;
while (q.Count != 0)
{
str=q.Dequeue();
switch (str)
{
case"":
case"(":
case")":
break;
case"+":
se.Push(new Add(se.Pop(), se.Pop()));
break;
case "-":
se.Push(new Dec(se.Pop(), se.Pop()));
break;
case "*":
se.Push(new Mul(se.Pop(), se.Pop()));
break;
case "/":
se.Push(new Div(se.Pop(), se.Pop()));
break;
case "^":
se.Push(new Pow(se.Pop(), se.Pop()));
break;
default:
if (char.IsLetter(str[0]))
se.Push(new Variable(str));
else
se.Push(new Number(double.Parse(str)));
break;
}
}
double result;
if (se.Count == 1)
result = se.Pop().Interpret(ctx);
else
throw new Exception("Expression is not correct");
return result;
}
}有时间我会写一个近似于MathCAD的RichEditBox的表达式解析器发上来。
一个类似简易的支持变量的表达式解析器例子

浙公网安备 33010602011771号