Click here to Skip to main content
15,891,937 members
Articles / Programming Languages / C#

Script Engine Implemented by C# and Regular Expression

Rate me:
Please Sign up or sign in to vote.
4.60/5 (4 votes)
21 Nov 2009CPOL2 min read 24.8K   853   24  
Script engine to execute script codes, which is built by C# and regular expression
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Zadesoft.Library.Script
{
    public class Expression
    {
        protected List<Expression> _subExpressions;

        public virtual string Name
        {
            get
            {
                return "Common";
            }
        }

        public virtual int RequiredOperandNum
        {
            get
            {
                return 0;
            }
        }

        public bool HasAnySubExpression
        {
            get
            {
                return _subExpressions.Count > 0;
            }
        }

        public virtual bool HasDirectValueObject
        {
            get
            {
                return false;
            }
        }

        public virtual object DirectValueObject
        {
            get
            {
                throw new ExpressionException(this, "no DirectValueObject");
            }
        }

        public Expression()
        {
            _subExpressions = new List<Expression>();
        }

        public virtual Expression Evaluate(ScriptContext context)
        {
            try
            {
                Expression r = null;

                foreach (Expression expr in _subExpressions)
                {
                    r = expr.Evaluate(context);
                }

                return r;
            }
            catch (Exception e)
            {
                throw new ExpressionException(this, "expression evaluate failed", e);
            }
        }

        protected virtual object[] EvaluateSubExpressionsAsObjects(ScriptContext context)
        {
            List<object> objects = new List<object>(_subExpressions.Count);

            try
            {
                foreach (Expression expr in _subExpressions)
                {
                    Expression r = expr.Evaluate(context);

                    objects.Add(r.HasDirectValueObject ? r.DirectValueObject : null);
                }
            }
            catch (Exception e)
            {
                throw new ExpressionException(this, "expression evaluate failed", e);
            }

            return objects.ToArray();
        }

        public virtual string ToStringExpression()
        {
            StringBuilder sb = new StringBuilder();

            foreach (Expression exp in _subExpressions)
            {
                sb.Append(exp.ToStringExpression()).Append(";").Append("\n");
            }

            return sb.ToString();
        }

        public override string ToString()
        {
            return ToStringExpression();
        }

        public static Expression Null
        {
            get
            {
                return new Expression();
            }
        }

        public static IExpressionParser Parser
        {
            get
            {
                return new ExpressionParser();
            }
        }

        internal class ExpressionParser
            : IExpressionParser
        {
            //public const string PRFIX = "(";
            //public const string POSFIX = ")";
            //public const string REGX = @"^\((.*)\)$";
            //public const string REGX_PART = @"\((.*)\)";
            //public const string REGX_ATOM = @"\(([^\(^\).]*)\)";
            //public const string REGEX = @"^([A-Za-z]+\(@[A-Za-z0-9_]+\))([ ]?(\|\||&&)[ ]?([A-Za-z]+\(@[A-Za-z0-9_]+\)))*[;]?$";
            public const string REGEX = @"^([A-Za-z]+\(@[A-Za-z0-9_]+\))([ ]?(\|\||&&)[ ]?([A-Za-z]+\(@[A-Za-z0-9_]+\)))*[;]?$";

            #region IExpressionParser Members

            public ExpressionPriority Priority { get { return ExpressionPriority.Block; } }

            public virtual Expression Parse(string code)
            {
                if (string.IsNullOrEmpty(code))
                {
                    return Expression.Null;
                }

                //get lines
                string[] lines = code.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

                if (lines.Length > 1)
                {
                    Expression expression = new Expression();

                    foreach (string line in lines)
                    {
                        expression._subExpressions.Add(ParseLine(line));
                    }

                    return expression;
                }
                else if (lines.Length == 1)
                {
                    return ParseLine(lines[0]);
                }
                else
                {
                    return Expression.Null;
                }
            }

            private Expression ParseLine(string seg)
            {
                if (string.IsNullOrEmpty(seg))
                {
                    return Expression.Null; 
                }

                seg = seg.Trim();

                IExpressionParser[] parsers = ScriptParser.GetSortedParsers();

                foreach (IExpressionParser parser in parsers)
                {
                    if (parser.CheckGrammar(seg))
                    {
                        return parser.Parse(seg);
                    }
                }

                return Expression.Null;
            }

            public virtual Expression Parse(string[] words)
            {
                throw new NotImplementedException();
            }

            public virtual bool CheckGrammar(string code)
            {
                return Regex.IsMatch(code, REGEX);
            }

            public virtual bool CheckGrammar(string[] words)
            {
                throw new NotImplementedException();
            }

            #endregion
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Totaldata Web Data Mining(extractweb.com)
China China
Just develop simple softwares. C# is my favorite prgramming languare, though I hope to create a new one...

Comments and Discussions