public IEnumerable<SemanticToken> ApplySemantics(IEnumerable<Token> tokenStream) { var tokens = tokenStream.ToList(); PreprocessSemantics(ref tokens); var rv = new List<SemanticToken>(tokens.Count()); foreach (var token in tokens) { if (token.OperationType == OperationType.Operator) { var t = OperatorToOpcode(token); rv.Add(t); } else { switch (token.TokenType) { case TokenType.FunctionCall: { var t = new SemanticToken { TokenType = token.TokenType, OperationType = OperationType.FunctionCall, Precedence = 9 }; var function = m_HostCallTable.GetFunctionByName(token.TokenValue); t.Data = function.Id; rv.Add(t); break; } case TokenType.FunctionArgumentSeperator: { rv.Add(new SemanticToken { TokenType = token.TokenType, OperationType = OperationType.Operand }); break; } case TokenType.Symbol: { var symbol = HostSymbolTable.GetSymbolByName(token.TokenValue); rv.Add(new SemanticToken { TokenType = token.TokenType, OperationType = OperationType.Operator, Data = symbol.SymbolId, Precedence = 9}); break; } default: { var t = new SemanticToken { TokenType = token.TokenType, OperationType = OperationType.Operand }; if (!t.IsBracket()) t.Data = Double.Parse(token.TokenValue); rv.Add(t); break; } } } } return rv; }
private static SemanticToken OperatorToOpcode(Token token) { var t = new SemanticToken() { TokenType = token.TokenType, OperationType = token.OperationType }; switch (t.TokenType) { case TokenType.Add: t.Precedence = 6; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.Subtract: t.Precedence = 6; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.Multiply: t.Precedence = 7; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.Divide: t.Precedence = 7; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.PowerOf: t.Precedence = 7; t.OperatorAssociativity = OperatorAssociativity.Right; break; case TokenType.UnaryMinus: t.Precedence = 8; t.OperatorAssociativity = OperatorAssociativity.Right; break; case TokenType.Negation: t.Precedence = 8; t.OperatorAssociativity = OperatorAssociativity.Right; break; case TokenType.Modulo: t.Precedence = 7; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.GreaterThan: t.Precedence = 5; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.GreaterThanOrEqualTo: t.Precedence = 5; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.LessThan: t.Precedence = 5; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.LessThanOrEqualTo: t.Precedence = 5; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.Equal: t.Precedence = 4; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.NotEqual: t.Precedence = 4; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.LogicalAnd: t.Precedence = 3; t.OperatorAssociativity = OperatorAssociativity.Left; break; case TokenType.LogicalOr: t.Precedence = 2; t.OperatorAssociativity = OperatorAssociativity.Left; break; default: throw new ExpressionParserException(String.Format("Unknown operator{0}", t)); break; } return t; }