namespace XUnitConsole.Compiler; internal class MyCompiler { static MyCompiler() { TokenTypeDictionary.Add("begin", TokenType.BEGIN); TokenTypeDictionary.Add("if", TokenType.IF); TokenTypeDictionary.Add("then", TokenType.THEN); TokenTypeDictionary.Add("while", TokenType.WHILE); TokenTypeDictionary.Add("do", TokenType.DO); TokenTypeDictionary.Add("end", TokenType.END); TokenTypeDictionary.Add("main", TokenType.MAIN); TokenTypeDictionary.Add("int", TokenType.INT); TokenTypeDictionary.Add("float", TokenType.FLOAT); TokenTypeDictionary.Add("for", TokenType.FOR); TokenTypeDictionary.Add("else", TokenType.ELSE); TokenTypeDictionary.Add("double", TokenType.DOUBLE); TokenTypeDictionary.Add("char", TokenType.CHAR); TokenTypeDictionary.Add("break", TokenType.BREAK); TokenTypeDictionary.Add("continue", TokenType.CONTINUE); } bool isEnd = false; bool isIgnore = false; char currentChar; string currentString = string.Empty; int currentPosition; public const string EndKeyWord = "..."; public static Dictionary TokenTypeDictionary { get; } = []; public string TargetString { get; set; } = string.Empty; public List Analyze() { currentPosition = -1; var tokenList = new List(); while (!isEnd) { MoveNext(); MoveUntilNext(); if (AnalyzeNextWord() is Token token) tokenList.Add(token); } return tokenList; } public Token? AnalyzeNextWord() { if (currentString == EndKeyWord) { isEnd = true; return null; } else if (char.IsLetter(currentChar)) { while (char.IsLetter(currentChar) || char.IsDigit(currentChar)) { currentString += currentChar; MoveNext(); } Retract(); if (!Reserve(out var tokenType)) tokenType = TokenType.LETTER; var token = new Token { Type = tokenType, Word = currentString }; Clear(); return token; } else if (char.IsDigit(currentChar)) { while (char.IsDigit(currentChar)) { currentString += currentChar; MoveNext(); } Retract(); var token = new Token { Type = TokenType.DIGIT, Word = currentString }; Clear(); return token; } else if (isIgnore) { isIgnore = !JudgeAnnotationEnd(); return null; } else { switch (currentChar) { case '=': MoveNext(); if (currentChar == '=') { Clear(); return new() { Type = TokenType.EQUAL, Word = "==" }; } Retract(); Clear(); return new() { Type = TokenType.APPLY, Word = "=" }; case '/': MoveNext(); if (currentChar == '*') isIgnore = true; return null; case '+': Clear(); return new() { Type = TokenType.PLUS, Word = "+" }; case '-': Clear(); return new() { Type = TokenType.DASH, Word = "-" }; case '*': Clear(); return new() { Type = TokenType.MULTIPLE, Word = "*" }; case '#': Clear(); return new() { Type = TokenType.SHARP, Word = "#" }; case '%': Clear(); return new() { Type = TokenType.PERCENTAGE, Word = "%" }; case '!': { MoveNext(); if (currentChar == '=') { Clear(); return new() { Type = TokenType.NOTEQUAL, Word = "!=" }; } Retract(); Clear(); isEnd = true; return new() { Type = TokenType.END, Word = "!" }; } case '<': { MoveNext(); if (currentChar == '>') { Clear(); return new() { Type = TokenType.LESSANDGREATERTHAN, Word = "<>" }; } if (currentChar == '=') { Clear(); return new() { Type = TokenType.LESSOREQUALTHAN, Word = "<=" }; } Retract(); Clear(); return new() { Type = TokenType.LESSTHAN, Word = "<" }; } case '>': { MoveNext(); if (currentChar == '=') { Clear(); return new() { Type = TokenType.GREATEROREQUALTHAN, Word = ">=" }; } Retract(); Clear(); return new() { Type = TokenType.GREATERTHAN, Word = ">" }; } case ';': Clear(); return new() { Type = TokenType.SEMICOLON, Word = ";" }; case '(': Clear(); return new() { Type = TokenType.LEFTPARENTHESE, Word = "(" }; case ')': Clear(); return new() { Type = TokenType.RIGHTPARETHESE, Word = ")" }; default: currentString += currentChar; MoveNext(); return AnalyzeNextWord(); } } } bool JudgeAnnotationEnd() { switch (currentChar) { case '*': MoveNext(); if (currentChar == '/') return true; return false; default: return false; } } void Retract() => currentChar = TargetString[--currentPosition]; void Clear() => currentString = string.Empty; bool Reserve(out TokenType type) { if (TokenTypeDictionary.TryGetValue(currentString, out type)) { return true; } return false; } void MoveNext() { if (currentPosition < TargetString.Length - 1) currentChar = TargetString[++currentPosition]; else isEnd = true; } void MoveUntilNext() { while (currentChar == ' ' || currentPosition == TargetString.Length - 1) MoveNext(); } }