Serialize arithmetic expression-tree

2019-09-14 06:14发布

问题:

I'm doing a simple task for investigation purposes. The problem is as follows:

  1. Create an arithmetic expression with variables.
  2. Build an AST for the expression.
  3. Send it to the server (using Sockets)
  4. Calculate an result of the server side and return the results.

Now I can to build a tree. This method doing it:

    private readonly Stack<Expression> expressionStack = new Stack<Expression>();
    private readonly Stack<Symbol> operatorStack = new Stack<Symbol>();
    private readonly List<string> parameters = new List<string>();
    public Expression<Func<decimal[], decimal>> Parse(string expression)
    {
        if (string.IsNullOrWhiteSpace(expression))
        {
            return s => 0;
        }

        var arrayParameter = Expression.Parameter(typeof(decimal[]), "args");

        parameters.Clear();
        operatorStack.Clear();
        expressionStack.Clear();

        using (var reader = new StringReader(expression))
        {
            int peek;
            while ((peek = reader.Peek()) > -1)
            {
                var next = (char)peek;

                if (char.IsDigit(next))
                {
                    expressionStack.Push(ReadOperand(reader));
                    continue;
                }

                if (char.IsLetter(next))
                {
                    expressionStack.Push(ReadParameter(reader, arrayParameter));
                    continue;
                }

                if (Operation.IsDefined(next))
                {
                    if (next == '-' && expressionStack.Count == 0)
                    {
                        reader.Read();
                        operatorStack.Push(Operation.UnaryMinus);
                        continue;
                    }

                    var currentOperation = ReadOperation(reader);

                    EvaluateWhile(() => operatorStack.Count > 0 && operatorStack.Peek() != Parentheses.Left &&
                        currentOperation.Precedence <= ((Operation)operatorStack.Peek()).Precedence);

                    operatorStack.Push(currentOperation);
                    continue;
                }

                if (next == '(')
                {
                    reader.Read();
                    operatorStack.Push(Parentheses.Left);

                    if (reader.Peek() == '-')
                    {
                        reader.Read();
                        operatorStack.Push(Operation.UnaryMinus);
                    }

                    continue;
                }

                if (next == ')')
                {
                    reader.Read();
                    EvaluateWhile(() => operatorStack.Count > 0 && operatorStack.Peek() != Parentheses.Left);
                    operatorStack.Pop();
                    continue;
                }

                if (next == ' ')
                {
                    reader.Read();
                }
                else
                {
                    throw new ArgumentException(string.Format("Encountered invalid character {0}", next),
                        "expression");
                }
            }
        }

        EvaluateWhile(() => operatorStack.Count > 0);

        return Expression.Lambda<Func<decimal[], decimal>>(expressionStack.Pop(), arrayParameter);
    }

This method works, and returns the expected result.
Before being sent to the server I want to serialize a tree to binary type. My question is as follows. Which is the simplest way I can apply for this?
I found a lot of solutions for LINQ serialization, but they are too big. I don't need the full functionality of these solutions. In addition, usually, they provide the JSON or XML-serialization, but I need a binary serialization. Can somebody suggest a simple and easy solution for this problem?