Exemplo n.º 1
0
        public List <ExpressionToken> ConvertToReversePolishNotation(ScriptVariableTable variableTable, List <InputToken> tokenstream)
        {
            // TODO Probably returns an expression object
            // That contains a list<semantictokens> but also a list of the variable lookups referenced in the list.


            var rv      = new List <ExpressionToken>();
            var opcodes = m_SemanticAnalyser.ApplySemantics(variableTable, tokenstream);
            var stack   = new Stack <ExpressionToken>(tokenstream.Count);

            // Shunting Yard Algorithm
            // http://en.wikipedia.org/wiki/Shunting-yard_algorithm
            foreach (var opcode in opcodes)
            {
                if (opcode.IsNumber() || opcode.IsVariableNumberType())
                {
                    rv.Add(opcode);
                }
                else
                {
                    if (opcode.IsFunction())
                    {
                        stack.Push(opcode);
                    }
                    else
                    {
                        if (opcode.IsFunctionArgumentSeperator())
                        {
                            while (stack.Count > 0)
                            {
                                var o = stack.Peek();
                                if (o.TokenType == SemanticTokenType.OpenBracket)
                                {
                                    break;
                                }

                                rv.Add(o);
                            }
                        }
                        else
                        {
                            if (opcode.IsOperator())
                            {
                                while (stack.Count > 0)
                                {
                                    var peek = stack.Peek();
                                    if ((opcode.Precedence < peek.Precedence) ||
                                        opcode.OperatorAssociativity == OperatorAssociativity.Left && opcode.Precedence == peek.Precedence)
                                    {
                                        rv.Add(stack.Pop());
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                stack.Push(opcode);
                            }
                            else
                            {
                                // Left Bracket
                                if (opcode.TokenType == SemanticTokenType.OpenBracket)
                                {
                                    stack.Push(opcode);
                                }

                                if (opcode.TokenType == SemanticTokenType.CloseBracket)
                                {
                                    var token = stack.Pop();
                                    while (stack.Count > 0 && token.TokenType != SemanticTokenType.OpenBracket)
                                    {
                                        rv.Add(token);
                                        token = stack.Pop();
                                    }

                                    if (token.TokenType != SemanticTokenType.OpenBracket)
                                    {
                                        throw new ExpressionParserException("Mismatched brackets");
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // When there are no more tokens to read
            while (stack.Count > 0)
            {
                var op = stack.Pop();
                if (op.IsBracket())
                {
                    throw new ExpressionParserException("Mismatched brackets");
                }

                rv.Add(op);
            }

            return(rv);
        }
Exemplo n.º 2
0
        public IEnumerable <ExpressionToken> ApplySemantics(ScriptVariableTable variableTable, IEnumerable <InputToken> tokenStream)
        {
            var tokens = tokenStream.ToList();

            PreprocessSemantics(ref tokens);

            var rv = new List <ExpressionToken>(tokens.Count());

            foreach (var token in tokens)
            {
                if (token.OperationType == TranspileTest.OperationType.Operator)
                {
                    var t = OperatorToOpcode(token);
                    rv.Add(t);
                }
                else
                {
                    switch (token.TokenType)
                    {
                    // TODO Add variable lookups for this we might want some kind of index?
                    // To be stored with the expression?

                    case SemanticTokenType.FunctionCall:
                    {
                        var t = new ExpressionToken
                        {
                            TokenType     = token.TokenType,
                            OperationType = OperationType.FunctionCall,
                            Precedence    = 9
                        };

                        var function = m_HostCallTable.GetFunctionByName(token.TokenValue);
                        t.Data.Int = function.Id;

                        rv.Add(t);
                        break;
                    }

                    case SemanticTokenType.FunctionArgumentSeperator:
                    {
                        rv.Add(new ExpressionToken {
                                TokenType = token.TokenType, OperationType = OperationType.Operand
                            });
                        break;
                    }

                    case SemanticTokenType.Symbol:
                    {
                        var symbol         = HostSymbolTable.GetSymbolByName(token.TokenValue);
                        var expressionData = new ExpressionData()
                        {
                            Int = symbol.SymbolId
                        };
                        rv.Add(new ExpressionToken {
                                TokenType = token.TokenType, OperationType = OperationType.Operator, Data = expressionData, Precedence = 9
                            });
                        break;
                    }

                    default:
                    {
                        var t = new ExpressionToken
                        {
                            TokenType     = token.TokenType,
                            OperationType = OperationType.Operand
                        };

                        if (!t.IsBracket())
                        {
                            if (t.TokenType == SemanticTokenType.VariableName)
                            {
                                t.Data.Guid = variableTable.GetGuid(token.TokenValue);
                            }
                            else
                            {
                                t.Data.Float = float.Parse(token.TokenValue);
                            }
                        }

                        rv.Add(t);
                        break;
                    }
                    }
                }
            }
            return(rv);
        }