static void DemoEvalToken() { // Token[] tokens = { // Token.Create(Token.EXPRESSION_TOKEN, null), // Token.Create(Token.VARIABLE_TOKEN, "A"), // Token.Create(Token.OPERATION_TOKEN, "=="), // Token.Create(Token.VARIABLE_TOKEN, "B"), // Token.Create(Token.OPERATION_TOKEN, "||"), // Token.Create(Token.VARIABLE_TOKEN, "C"), // Token.Create(Token.OPERATION_TOKEN, "+"), // Token.Create(Token.VARIABLE_TOKEN, "D"), // Token.Create(Token.OPERATION_TOKEN, "*"), // Token.Create(Token.VARIABLE_TOKEN, "E"), // Token.Create(Token.OPERATION_TOKEN, "-"), // Token.Create(Token.VARIABLE_TOKEN, "F"), // Token.Create(Token.OPERATION_TOKEN, ">="), // Token.Create(Token.VARIABLE_TOKEN, "G"), // Token.Create(Token.OPERATION_TOKEN, "+"), // Token.Create(Token.PREFIX_TOKEN, "-"), // Token.Create(Token.VARIABLE_TOKEN, "H"), // Token.Create(Token.END_EXPRESSION_TOKEN, null), // Token.Create(Token.OPERATION_TOKEN, "?"), // Token.Create(Token.VARIABLE_TOKEN, "I"), // }; Token[] tokens = { Token.CreatePrefix("!"), Token.Create(TokenType.Expression, null), (Token)10, Token.CreateOperator(">="), (Token)15, Token.CreateOperator("||"), (Token)6, Token.CreateOperator("+"), (Token)3, Token.CreateOperator("*"), (Token)11, Token.CreateOperator("-"), (Token)4, Token.CreateOperator("=="), (Token)12, Token.CreateOperator("+"), Token.CreatePrefix("-"), (Token)5, Token.Create(TokenType.EndExpression,null), Token.CreateOperator("?"), (Token)"Got It!!!", }; // tokens = new Token[] { // 12, // Token.Create(Token.OPERATION_TOKEN, "+"), // Token.Create(Token.PREFIX_TOKEN, "-"), // 5, // }; Stopwatch watch = new Stopwatch(); watch.Start(); ParseTree tree = null; int i = 0; for (; i < 1; i++) { tree = new ParseTree(); foreach (Token token in tokens) { if (!tree.Append(token)) { Console.WriteLine(token.Lexeme); break; } //Console.WriteLine(token); } switch (i) { case 1000: case 5000: Console.WriteLine("run {0,-8} {1,5}ms", i, watch.ElapsedMilliseconds); break; } //Console.WriteLine(tree.Root.Token.Lexeme); } watch.Stop(); Console.WriteLine("run {0,-8} {1,5}ms", i, watch.ElapsedMilliseconds); Console.WriteLine(ParseTree.Evaluate(tree).ToString()); Console.WriteLine(); }
static private ParseTree Parse(string expression, IResolver resolver) { if (expression == null) { throw new ArgumentNullException("expression"); } ParseTree tokenTree = new ParseTree(); StringBuilder literal = new StringBuilder(); CharReader reader = new CharReader(expression); Token last = Token.Null; while (reader.Next()) { Debug.Assert(literal.Length == 0); char c = reader.Read(); switch (c) { case '(': { switch (last.Type) { case TokenType.Prefix: case TokenType.Operation: case TokenType.Expression: case TokenType.None: last = Token.Create(TokenType.Expression, null); tokenTree.Append(last); break; default: throw ThrowSyntaxError(reader.Position); } } break; case ')': { switch (last.Type) { case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.EndExpression: last = Token.Create(TokenType.EndExpression, null); tokenTree.Append(last); break; default: throw ThrowSyntaxError(reader.Position); } } break; case '?': switch (last.Type) { case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.EndExpression: last = Token.CreateOperator(c.ToString()); tokenTree.Append(last); break; default: throw ThrowSyntaxError(reader.Position); } break; case '|': case '&': switch (last.Type) { case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.Expression: literal.Append(c); if (!reader.Next()) { throw ThrowSyntaxError(reader.Position); } if (reader.Current != c) { throw ThrowSyntaxError(reader.Position); } literal.Append(reader.Read()); last = Token.CreateOperator(literal.ToString()); tokenTree.Append(last); literal.Length = 0; break; default: throw ThrowSyntaxError(reader.Position); } break; case '!': switch (last.Type) { case TokenType.Operation: case TokenType.Expression: case TokenType.None: // prefix last = Token.CreatePrefix(c.ToString()); tokenTree.Append(last); break; case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.EndExpression: // operator literal.Append(c); if (!reader.Next()) { throw ThrowSyntaxError(reader.Position); } if (reader.Current != '=') { throw ThrowSyntaxError(reader.Position); } literal.Append(reader.Read()); last = Token.CreateOperator(literal.ToString()); tokenTree.Append(last); literal.Length = 0; break; default: throw ThrowSyntaxError(reader.Position); } break; case '-': switch (last.Type) { case TokenType.Operation: case TokenType.Expression: case TokenType.None: // prefix last = Token.CreatePrefix(c.ToString()); tokenTree.Append(last); break; case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.EndExpression: // operator last = Token.CreateOperator(c.ToString()); tokenTree.Append(last); break; default: throw ThrowSyntaxError(reader.Position); } break; case '+': case '*': case '/': case '%': switch (last.Type) { case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.EndExpression: last = Token.CreateOperator(c.ToString()); tokenTree.Append(last); break; default: throw ThrowSyntaxError(reader.Position); } break; case '>': case '<': switch (last.Type) { case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.EndExpression: literal.Append(c); if (!reader.Next()) { throw ThrowSyntaxError(reader.Position); } if (reader.Current == '=') { literal.Append(reader.Read()); } last = Token.CreateOperator(literal.ToString()); tokenTree.Append(last); literal.Length = 0; break; default: throw ThrowSyntaxError(reader.Position); } break; case '=': switch (last.Type) { case TokenType.Boolean: case TokenType.Number: case TokenType.String: case TokenType.Variable: case TokenType.Function: case TokenType.EndExpression: literal.Append(c); if (!reader.Next()) { throw ThrowSyntaxError(reader.Position); } if (reader.Current != '=') { throw ThrowSyntaxError(reader.Position); } literal.Append(reader.Read()); last = Token.CreateOperator(literal.ToString()); tokenTree.Append(last); literal.Length = 0; break; default: throw ThrowSyntaxError(reader.Position); } break; case '\'': switch (last.Type) { case TokenType.Operation: case TokenType.Expression: case TokenType.None: last = ExpandString(reader, literal); tokenTree.Append(last); literal.Length = 0; break; default: throw ThrowSyntaxError(reader.Position); } break; default: if (char.IsLetter(c)) { switch (last.Type) { case TokenType.Prefix: case TokenType.Operation: case TokenType.Expression: case TokenType.None: literal.Append(c); last = ExpandVariable(reader, literal, resolver); tokenTree.Append(last); literal.Length = 0; break; default: throw ThrowSyntaxError(reader.Position); } } else if (char.IsDigit(c)) { switch (last.Type) { case TokenType.Prefix: case TokenType.Operation: case TokenType.Expression: case TokenType.None: literal.Append(c); last = ExpandNumber(reader, literal); tokenTree.Append(last); literal.Length = 0; break; default: throw ThrowSyntaxError(reader.Position); } } else { // it is whitespace or newline, to do nothing... } break; } } return(tokenTree); }