现在的位置: 首页 > 综合 > 正文

设计模式学习(1):解析器(Interpreter)模式

2013年10月08日 ⁄ 综合 ⁄ 共 4404字 ⁄ 字号 评论关闭

"这个Pattern用在Compiler的 Language Parser最合适。他可以反覆递归,最终分析好一个语言。语法就象下面一样

     算术表达式 = 算术表达式 +/-?*// 数字

然后构造一个算术表达式类和数字类,在算术表达式类中递归引用自己和数字类。最终能够解开任何的语言。在Gang Of
Four的网页上是通过LinkedList来处理这个例子。
LinkedList就是先准备好一堆Class,一个一个拿过来用在Context上。比较死板,只能处理很少的情况。在Compiler中最常用的是
递归。反复递归就是有一万层括号也能解开,但是用LinkedList就会受限制了。

 

Example:

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleTest
{

    class Program
    {
         public static void Main()
        {
            string roman = "五十七万六千四百五十二"; //==>576452

            Context context = new Context(roman);

            ArrayList tree = new ArrayList();
            tree.Add(new GeExpression());
            tree.Add(new ShiExpression());
            tree.Add(new BaiExpression());
            tree.Add(new QianExpression());
            tree.Add(new WanExpression());

            foreach (Expression exp in tree)
            {
                exp.Interpret(context);
            }

            Console.WriteLine("{0} = {1}",roman, context.Data);
            Console.Read();
        }

    }

    public abstract class Expression
    {
        protected Dictionary<string, int> table = new Dictionary<string, int>(9);
        public Expression()
        {
            table.Add("一", 1);
            table.Add("二", 2);
            table.Add("三", 3);
            table.Add("四", 4);
            table.Add("五", 5);
            table.Add("六", 6);
            table.Add("七", 7);
            table.Add("八", 8);
            table.Add("九", 9);
        }

        public virtual void Interpret(Context context)
        {
            if (context.Statement.Length == 0)
            {
                return;
            }

            foreach (string key in table.Keys)
            {
                int value = table[key];
               
                if (context.Statement.EndsWith(key + this.GetPostfix()))
                {
                    context.Data += value * this.Multiplier();
                    context.Statement = context.Statement.Substring(0, context.Statement.Length - this.GetLength());
                }

                if (context.Statement.EndsWith("零"))
                {
                    context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
                }
            }
        }

        public abstract string GetPostfix();
        public abstract int Multiplier();
        public virtual int GetLength()
        {
            return this.GetPostfix().Length + 1;
        }
    }

//变化部分:

public class GeExpression : Expression
    {
        public override string GetPostfix()
        {
            return "";
        }

        public override int Multiplier()
        {
            return 1;
        }
    }

    public class ShiExpression : Expression
    {
        public override string GetPostfix()
        {
            return "十";
        }

        public override int Multiplier()
        {
            return 10;
        }
    }
    public class BaiExpression : Expression
    {
        public override string GetPostfix()
        {
            return "百";
        }

        public override int Multiplier()
        {
            return 100;
        }
    }
    public class QianExpression : Expression
    {
        public override string GetPostfix()
        {
            return "千";
        }

        public override int Multiplier()
        {
            return 1000;
        }
    }

    public class WanExpression : Expression
    {
        public override string GetPostfix()
        {
            return "万";
        }

        public override int Multiplier()
        {
            return 10000;
        }

        //不能解释"万万"的情况
        public override void Interpret(Context context)
        {
            if (context.Statement.Length == 0)
                return;

            ArrayList tree = new ArrayList();
            tree.Add(new GeExpression());
            tree.Add(new ShiExpression());
            tree.Add(new BaiExpression());
            tree.Add(new QianExpression());
 
            if (context.Statement.EndsWith(this.GetPostfix()))
            {
                int temp = context.Data;
                context.Data = 0;
                context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);

                foreach (Expression exp in tree)
                {
                    exp.Interpret(context);
                }
                context.Data = temp + this.Multiplier() * context.Data;
            }
       
        }
    }

    public class Context
    {
        private string statement;
        private int data;

        public Context(string statement)
        {
            this.statement = statement;
        }

        public string Statement
        {
            get { return statement; }
            set { statement = value; }
        }

        public int Data
        {
            get { return data; }
            set { data = value; }
        }
    }
}

【上篇】
【下篇】

抱歉!评论已关闭.