表达式解析及自动解析

using System;
using System.Collections;
using System.Reflection;
using System.Collections.Generic;
using System.CodeDom.Compiler;

namespace ConsolidationReport
{
    public enum ExpressionTypes { NONE, DELIMITER, VARIABLE, NUMBER, FUNCTION };
    public class MyParser
    {
        // 枚举计算单元类型.
        

        string exp;       // 计算表达式
        int expIdx;       // 当前表达式解析位置    
        string token;  // 当前记号
        ExpressionTypes tokType; // 当前记号类型

        public MyParser()
        {
 
        }

        // 解析器程序入口.
        public ExpressionNodes Evaluate(string expstr)
        {

            exp = expstr;
            expIdx = 0;
            ExpressionNodes nodes = new ExpressionNodes();
            while (expIdx<expstr.Length)
            {
                GetToken();
                if (tokType == ExpressionTypes.NONE && token == "") throw new Exception("No Expression Present!");
                ExpressionNode node = new ExpressionNode(token,tokType,expIdx-token.Length,expIdx-1);
                nodes.Add(node);
            }

            return nodes;
        }

        // 取计算单元标记
        void GetToken()
        {
            tokType = ExpressionTypes.NONE;
            token = "";

            if (expIdx == exp.Length) return; //    到了表达式末端

            // 忽略前置空格    
            while (expIdx < exp.Length && Char.IsWhiteSpace(exp[expIdx])) expIdx++;

            if (expIdx == exp.Length) return; //    到了表达式末端

            if (IsDelim(exp[expIdx]))
            { // 分隔符    
                token += exp[expIdx];
                expIdx++;
                tokType = ExpressionTypes.DELIMITER;
                return;
            }
            if (Char.IsLetter(exp[expIdx]))
            { // 变量
                token += exp[expIdx];
                expIdx++;
                if (expIdx == exp.Length) return;
                bool isfunction = false;
                while (Char.IsLetter(exp[expIdx]) || Char.IsDigit(exp[expIdx]) || exp[expIdx] == '.' || isfunction)
                {
                    token += exp[expIdx];
                    expIdx++;
                    if (expIdx == exp.Length) break;
                    if (exp[expIdx] == '(') isfunction = true;
                }
                if (isfunction)
                {
                    tokType = ExpressionTypes.FUNCTION;
                }
                else
                {
                    tokType = ExpressionTypes.VARIABLE;
                }

                return;
            }
            if (Char.IsDigit(exp[expIdx]))
            { // 数字
                while (!IsDelim(exp[expIdx]))
                {
                    token += exp[expIdx];
                    expIdx++;
                    if (expIdx >= exp.Length) break;
                }
                tokType = ExpressionTypes.NUMBER;
                return;
            }
        }

        // 检验是否指定分隔符.    
        bool IsDelim(char c)
        {
            if ((" +-/*&()=".IndexOf(c) != -1))
                return true;
            return false;
        }
    }

    public class MyParserF
    {
        // 枚举计算单元类型.


        string exp;       // 计算表达式
        int expIdx;       // 当前表达式解析位置    
        string token;  // 当前记号
        ExpressionTypes tokType; // 当前记号类型

        public MyParserF()
        {

        }

        // 解析器程序入口.
        public ExpressionNodes Evaluate(string expstr, string funcName)
        {
            if (funcName == null || funcName == "") return new ExpressionNodes();
            if (expstr.IndexOf(funcName) != 0) return new ExpressionNodes();
            ExpressionNodes nodes = new ExpressionNodes();
            ExpressionNode nodeName = new ExpressionNode(funcName, ExpressionTypes.FUNCTION, 0, funcName.Length - 1);
            nodes.Add(nodeName);
            exp = expstr;
            expIdx = funcName.Length;
            while (expIdx < expstr.Length)
            {
                GetToken();
                if (tokType == ExpressionTypes.NONE && token == "") throw new Exception("No Expression Present!");
                ExpressionNode node = new ExpressionNode(token, tokType, expIdx - token.Length, expIdx - 1);
                nodes.Add(node);
            }

            return nodes;
        }

        // 取计算单元标记
        void GetToken()
        {
            tokType = ExpressionTypes.NONE;
            token = "";

            if (expIdx == exp.Length) return; //    到了表达式末端

            // 忽略前置空格    
            while (expIdx < exp.Length && Char.IsWhiteSpace(exp[expIdx])) expIdx++;

            if (expIdx == exp.Length) return; //    到了表达式末端

            if (IsDelim(exp[expIdx]))
            { // 分隔符    
                token += exp[expIdx];
                expIdx++;
                tokType = ExpressionTypes.DELIMITER;
                return;
            }
            if (Char.IsLetter(exp[expIdx]))
            { // 变量
                token += exp[expIdx];
                expIdx++;
                if (expIdx == exp.Length) return;
                while (Char.IsLetter(exp[expIdx]) || Char.IsDigit(exp[expIdx]) || exp[expIdx] == '.')
                {
                    token += exp[expIdx];
                    expIdx++;
                    if (expIdx == exp.Length) break;
                }
                tokType = ExpressionTypes.VARIABLE;

                return;
            }
            if (Char.IsDigit(exp[expIdx]))
            { // 数字
                while (!IsDelim(exp[expIdx]))
                {
                    token += exp[expIdx];
                    expIdx++;
                    if (expIdx >= exp.Length) break;
                }
                tokType = ExpressionTypes.NUMBER;
                return;
            }
        }

        // 检验是否指定分隔符.    
        bool IsDelim(char c)
        {
            if ((" ():,".IndexOf(c) != -1))
                return true;
            return false;
        }
    }

    public class ExpressionNode
    {
        public ExpressionNode()
        {
 
        }

        public ExpressionNode(string expression, ExpressionTypes expressiontypes,int startindex,int endindex)
        {
            this.expression = expression;
            this.expressionTypes = expressiontypes;
            this.startIndex = startindex;
            this.endIndex = endindex;
        }

        private int startIndex;

        public int StartIndex
        {
            get { return startIndex; }
            set { startIndex = value; }
        }
        private int endIndex;

        public int EndIndex
        {
            get { return endIndex; }
            set { endIndex = value; }
        }

        private string expression;

        public string Expression
        {
            get { return expression; }
            set { expression = value; }
        }
        private ExpressionTypes expressionTypes;

        public ExpressionTypes ExpressionTypes
        {
            get { return expressionTypes; }
            set { expressionTypes = value; }
        }

    }

    public class ExpressionNodes : List<ExpressionNode>
    {
        public ExpressionNodes(){}
    }

    public class Evaluator
    {

        private static object _evaluator = null;
        private static Type _evaluatorType = null;

        private static readonly string _jscriptSource =

            @"class Evaluator
              {
                  public function Eval(expr : String) : String
                  {
                     return eval(expr);
                  }
              }";

        static Evaluator()
        {

            CodeDomProvider provider = CodeDomProvider.CreateProvider("JScript");
            CompilerParameters parameters;
            parameters = new CompilerParameters();
            parameters.GenerateInMemory = true;
            parameters.IncludeDebugInformation = false;

            CompilerResults results = provider.CompileAssemblyFromSource(parameters, _jscriptSource);
            Assembly assembly = results.CompiledAssembly;
            _evaluatorType = assembly.GetType("Evaluator");

            _evaluator = Activator.CreateInstance(_evaluatorType);
        }

        public static object Eval(string statement)
        {
            return _evaluatorType.InvokeMember(
                        "Eval",
                        BindingFlags.InvokeMethod,
                        null,
                        _evaluator,
                        new object[] { statement }
                     );
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值