public Evaluator(Instructions instructions, Tokens tokens = null) { Memory = new double[instructions.Count]; Variables = new Dictionary<char, double>(30); Variables.Add('p', Math.PI); Variables.Add('e', Math.E); Instructions = instructions; IsConstantExpression = true; if (tokens == null) { foreach (var token in tokens) { if (token == TokenType.Variable) { IsConstantExpression = false; break; } } if (IsConstantExpression) { IsConstantExpression = false; Evaluate(); IsConstantExpression = true; } } else { IsConstantExpression = false; } }
public Tokens GenerateTokens() { int N = Expression.Length; Tokens tokens = new Tokens(N); StringBuilder tokenValue = new StringBuilder(N); State currentState = State.BEGIN; int position = 0; while (position <= N && !LexicalError) { char symbol = position < N ? Expression[position] : EndOfExpression; switch (currentState) { case State.BEGIN: if (Char.IsLetter(symbol)) { tokenValue.Append(symbol); currentState = State.VAR; } else if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); currentState = State.NUM1; } else if ("+-*/^()".Contains(symbol)) { tokenValue.Append(symbol); currentState = State.OK; } else if (symbol != EndOfExpression) { if (position < N) { var error = String.Format("Invalid symbol {0}", symbol); TokenError = new Token(TerminalSymbolType.UnRecognized, position, error); tokens.Add(TokenError); LexicalError = true; } } position++; break; case State.VAR: if (Char.IsLetter(symbol)) { tokenValue.Append(symbol); position++; currentState = State.FUNC; } else { tokens.Add(new Token(TokenType.Variable, position, tokenValue.ToString())); tokenValue.Clear(); currentState = State.BEGIN; } break; case State.FUNC: if (Char.IsLetter(symbol)) { tokenValue.Append(symbol); position++; } else { var str = tokenValue.ToString(); if (IsFunction(str)) { tokens.Add(new Token(TokenType.Function, position, str)); tokenValue.Clear(); currentState = State.BEGIN; } else { var error = String.Format("Unrecognized {0}", str); TokenError = new Token(TokenType.UnRecognized, position, error); tokens.Add(TokenError); LexicalError = true; } } break; case State.OK: tokens.Add(makeOneCharToken(tokenValue.ToString(), position)); tokenValue.Clear(); currentState = State.BEGIN; break; case State.NUM1: if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); position++; } else if (symbol == '.') { tokenValue.Append(symbol); position++; currentState = State.TRANS; } else { tokens.Add(new Token(TokenType.Value, position, tokenValue.ToString())); tokenValue.Clear(); currentState = State.BEGIN; } break; case State.TRANS: if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); position++; currentState = State.NUM2; } else { var error = String.Format("Invalid number format {0}", tokenValue.Append(symbol)); TokenError = new Token(TokenType.UnRecognized, position, error); tokens.Add(TokenError); LexicalError = true; } break; case State.NUM2: if (Char.IsDigit(symbol)) { tokenValue.Append(symbol); position++; } else { tokens.Add(new Token(TokenType.Value, position, tokenValue.ToString())); tokenValue.Clear(); currentState = State.BEGIN; } break; } } return tokens; }