文法分析与解释器模式(三)

这里把上两次内容作一个连接。
生成名为Parsing的类,它拥有一个名为Calculate()的方法,传入表达式字符串,返回double结果。
 public class Parsing
    
{
        
private Context ctx;
        
public Dictionary<stringdouble> _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 == 0return 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的表达式解析器发上来。
 一个类似简易的支持变量的表达式解析器例子

posted on 2007-04-22 19:45  刘霆  阅读(121)  评论(0)    收藏  举报

导航