Пример #1
0
            public Expression Pop(ExpressionT type)
            {
                var expression = Peek(type);

                expressions.RemoveAt(expressions.Count - 1);
                types.RemoveAt(types.Count - 1);
                return(expression);
            }
Пример #2
0
            public Expression Peek(ExpressionT toType)
            {
                var fromType   = types[types.Count - 1];
                var expression = expressions[expressions.Count - 1];

                if (toType == fromType)
                {
                    return(expression);
                }

                switch (toType)
                {
                case ExpressionT.Bool:
                    return(IfThenElse(AsBool(expression), True, False));

                case ExpressionT.Int:
                    return(IfThenElse(expression, One, Zero));
                }

                throw new InvalidProgramException("Unable to convert ExpressionType.{0} to ExpressionType.{1}".F(Enum <ExpressionT> .GetValues()[(int)fromType], Enum <ExpressionT> .GetValues()[(int)toType]));
            }
Пример #3
0
            public Expression Build(Token[] postfix, ExpressionT resultType)
            {
                foreach (var t in postfix)
                {
                    switch (t.Type)
                    {
                    case TokenType.And:
                    {
                        var y = ast.Pop(ExpressionT.Bool);
                        var x = ast.Pop(ExpressionT.Bool);
                        ast.Push(Expressions.Expression.And(x, y));
                        continue;
                    }

                    case TokenType.Or:
                    {
                        var y = ast.Pop(ExpressionT.Bool);
                        var x = ast.Pop(ExpressionT.Bool);
                        ast.Push(Expressions.Expression.Or(x, y));
                        continue;
                    }

                    case TokenType.Add:
                    {
                        var y = ast.Pop(ExpressionT.Bool);
                        var x = ast.Pop(ExpressionT.Bool);
                        ast.Push(Expressions.Expression.Add(x, y));
                        continue;
                    }

                    case TokenType.GreaterThan:
                    {
                        var y = ast.Pop(ExpressionT.Int);
                        var x = ast.Pop(ExpressionT.Int);
                        ast.Push(Expressions.Expression.GreaterThan(x, y));
                        continue;
                    }

                    case TokenType.GreaterThanOrEqual:
                    {
                        var y = ast.Pop(ExpressionT.Int);
                        var x = ast.Pop(ExpressionT.Int);
                        ast.Push(Expressions.Expression.GreaterThanOrEqual(x, y));
                        continue;
                    }

                    case TokenType.LessThan:
                    {
                        var y = ast.Pop(ExpressionT.Int);
                        var x = ast.Pop(ExpressionT.Int);
                        ast.Push(Expressions.Expression.LessThan(x, y));
                        continue;
                    }

                    case TokenType.LessThanOrEqual:
                    {
                        var y = ast.Pop(ExpressionT.Int);
                        var x = ast.Pop(ExpressionT.Int);
                        ast.Push(Expressions.Expression.LessThanOrEqual(x, y));
                        continue;
                    }

                    case TokenType.False:
                    {
                        ast.Push(False);
                        continue;
                    }

                    case TokenType.True:
                    {
                        ast.Push(True);
                        continue;
                    }

                    case TokenType.Number:
                    {
                        ast.Push(Expressions.Expression.Constant(((NumberToken)t).Value));
                        continue;
                    }

                    case TokenType.Variable:
                    {
                        var symbol = Expressions.Expression.Constant(((VariableToken)t).Symbol);
                        Func <string, IReadOnlyDictionary <string, int>, int> parseSymbol = ParseSymbol;
                        ast.Push(Expressions.Expression.Call(parseSymbol.Method, symbol, SymbolsParam));
                        continue;
                    }

                    case TokenType.Not:
                    {
                        ast.Push(Expressions.Expression.Not(ast.Pop(ExpressionT.Bool)));
                        continue;
                    }

                    case TokenType.NotEquals:
                    {
                        var y = ast.Pop(ExpressionT.Int);
                        var x = ast.Pop(ExpressionT.Int);
                        ast.Push(Expressions.Expression.NotEqual(x, y));
                        continue;
                    }

                    case TokenType.Equals:
                    {
                        var y = ast.Pop(ExpressionT.Int);
                        var x = ast.Pop(ExpressionT.Int);
                        ast.Push(Expressions.Expression.Equal(x, y));
                        continue;
                    }

                    default:
                        throw new InvalidProgramException("ConditionExpression.Compile() is missing an expression builder for TokenType.{0}".F(Enum <TokenType> .GetValues()[(int)t.Type]));
                    }
                }
                return(ast.Pop(resultType));
            }
Пример #4
0
        Expression Build(ExpressionT resultType)
        {
            var   tokens         = new List <Token>();
            var   currentOpeners = new Stack <Token>();
            Token lastToken      = null;

            for (var i = 0; ;)
            {
                var token = Token.GetNext(Expression, ref i, lastToken != null ? lastToken.Type : TokenType.Invalid);
                if (token == null)
                {
                    //Sanity check parsed tree
                    if (lastToken == null)
                    {
                        throw new InvalidDataException("Empty expression");
                    }
                    //Expressions can't end with a binary or unary prefix operation
                    //表达式不能以二进制或一元前缀操作结束
                    if (lastToken.RightOperand)
                    {
                        throw new InvalidDataException("Missing value or sub-expression at end for '{0}' operator".F(lastToken.Symbol));
                    }
                    break;
                }

                if (token.Closes != Grouping.None)
                {
                    if (currentOpeners.Count == 0)
                    {
                        throw new InvalidDataException("Unmatched closing parenthesis at index  {0}".F(token.Index));
                    }

                    currentOpeners.Pop();
                }

                if (token.Opens != Grouping.None)
                {
                    currentOpeners.Push(token);
                }

                if (lastToken == null)
                {
                    //Expressions can't end with a binary or unary prefix operation
                    if (token.LeftOperand)
                    {
                        throw new InvalidDataException("Missing value or sub-expression at beginning for '{0}' operator".F(token.Symbol));
                    }
                }
                else
                {
                    if (lastToken.Opens != Grouping.None && token.Closes != Grouping.None)
                    {
                        throw new InvalidDataException("Empty parenthesis at index {0}".F(lastToken.Index));
                    }

                    if (lastToken.RightOperand == token.LeftOperand)
                    {
                        if (lastToken.RightOperand)
                        {
                            throw new InvalidDataException("Missing value or sub-expression or there is an extra operator '{0}' at index {1} or '{2}' at  index {3}".F(
                                                               lastToken.Symbol, lastToken.Index, token.Symbol, token.Index
                                                               ));
                        }
                        throw new InvalidDataException("Missing binary operation before '{0}' at index {1}".F(token.Symbol, token.Index));
                    }
                }
                if (token.Type == TokenType.Variable)
                {
                    variables.Add(token.Symbol);
                }

                tokens.Add(token);
                lastToken = token;
            }

            if (currentOpeners.Count > 0)
            {
                throw new InvalidDataException("Unclosed opening parenthesis at index {0}".F(currentOpeners.Peek().Index));
            }

            return(new Compiler().Build(ToPostfix(tokens).ToArray(), resultType));
        }