class Lexer { string ExprStr; List() tokens; int tokType = Token.Type_Number; int tokBegin = 0; int i = 0; Token() TokBracketOpen; Token() TokBracketClose; Token() TokPow; Token() TokMul; Token() TokMod; Token() TokDiv; Token() TokAdd; Token() TokSub; public Lexer(){ TokBracketOpen = Token.Create("(", 0, 1, Token.Type_BracketOpen); TokBracketClose = Token.Create(")", 0, 1, Token.Type_BracketClose); TokPow = Token.Create("^", 0, 1, Token.Type_OperatorPow); TokMul = Token.Create("*", 0, 1, Token.Type_OperatorMul); TokMod = Token.Create("%", 0, 1, Token.Type_OperatorMod); TokDiv = Token.Create("/", 0, 1, Token.Type_OperatorDiv); TokAdd = Token.Create("+", 0, 1, Token.Type_OperatorAdd); TokSub = Token.Create("-", 0, 1, Token.Type_OperatorSub); } internal List Lex!() { while (i < ExprStr.Length) { switch (ExprStr[i]) { // end token, add new predifined token and move next case '(': AddStaticToken(TokBracketOpen); break; case ')': AddStaticToken(TokBracketClose); break; case '^': AddStaticToken(TokPow); break; case '*': AddStaticToken(TokMul); break; case '%': AddStaticToken(TokMod); break; case '/': AddStaticToken(TokDiv); break; case '+': AddStaticToken(TokAdd); break; case '-': AddStaticToken(TokSub); break; // try end token and skip current char case ' ': case '\t': case '\n': case '\r': TryEndToken(); i++; break; // move next case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': i++; break; // set type from Numeric to Literal default: tokType = Token.Type_Literal; i++; break; } } // end last token TryEndToken(); return tokens; } void TryEndToken!() { if (tokBegin != i) { Token() tok = Token.Create(ExprStr, tokBegin, i - tokBegin, tokType); tokens.Add(); tokens[tokens.Count-1] = tok; tokType = Token.Type_Number; tokBegin = i; } } void AddStaticToken!(Token() tok) { TryEndToken(); tokens.Add(); tokens[tokens.Count-1] = tok; tokType = Token.Type_Number; tokBegin = ++i; } }