public BrainfuckTokenSequence Parse(TextReader streamReader, BrainfuckMemoryTape memoryTape = null) { memoryTape = memoryTape ?? new BrainfuckMemoryTape(); var leftBracketStack = new Stack <LeftBracketToken>(); BrainfuckToken first = null; BrainfuckToken prev = null; var index = -1; while (0 <= streamReader.Peek()) { ++index; var c = (char)streamReader.Read(); BrainfuckToken current = null; switch (c) { case '>': current = new RightShiftToken(); break; case '<': current = new LeftShiftToken(); break; case '+': current = new PlusToken(); break; case '-': current = new MinusToken(); break; case '.': current = new DotToken(); break; case ',': current = new SemicolonToken(); break; case '[': { var leftBracket = new LeftBracketToken(); leftBracketStack.Push(leftBracket); current = leftBracket; } break; case ']': { if (leftBracketStack.Count == 0) { throw new InvalidOperationException(); } var leftBracket = leftBracketStack.Pop(); var rightBracket = new RightBracketToken(); leftBracket.RightBracketToken = rightBracket; rightBracket.LeftBracketToken = leftBracket; current = rightBracket; } break; default: break; } if (current == null) { continue; } current.MemoryTape = memoryTape; current.Index = index; if (prev != null && prev.Next == null) { prev.SetNextIndexToken(current); } prev = current; if (first != null) { continue; } first = current; } if (leftBracketStack.Count != 0) { throw new InvalidOperationException(); } return(new BrainfuckTokenSequence(first)); }
public IEnumerable <BrainfuckToken> Parse(TextReader streamReader) { var ret = new List <BrainfuckToken>(); var leftBracketStack = new Stack <LeftBracketToken>(); BrainfuckToken prev = null; var index = -1; while (0 <= streamReader.Peek()) { ++index; var c = (char)streamReader.Read(); BrainfuckToken current = null; switch (c) { case '>': current = new RightShiftToken(); break; case '<': current = new LeftShiftToken(); break; case '+': current = new PlusToken(); break; case '-': current = new MinusToken(); break; case '.': current = new DotToken(); break; case ',': current = new SemicolonToken(); break; case '[': { var leftBracket = new LeftBracketToken(); leftBracketStack.Push(leftBracket); current = leftBracket; } break; case ']': { if (leftBracketStack.Count == 0) { throw new InvalidOperationException(); } var leftBracket = leftBracketStack.Pop(); var rightBracket = new RightBracketToken(); leftBracket.RightBracketToken = rightBracket; rightBracket.LeftBracketToken = leftBracket; current = rightBracket; } break; } if (current == null) { continue; } current.Index = index; prev?.SetNextIndexToken(current); prev = current; ret.Add(current); } if (leftBracketStack.Count != 0) { throw new InvalidOperationException(); } return(ret); }
public List <Token> Convert(string regexString) { var result = new List <Token>(); var currentCharIndex = 0; var length = regexString.Length; while (currentCharIndex != length) { var currentChar = regexString[currentCharIndex]; Token toAdd; switch (currentChar) { case '(': toAdd = new LeftBracketToken(); break; case ')': toAdd = new RightBracketToken(); break; case '*': toAdd = new StarToken(); break; case '|': toAdd = new SumToken(); break; case '\\': currentCharIndex++; if (currentCharIndex == length) { throw new RegexParseException($"Backslash at the end of input escaping nothing."); } toAdd = new CharacterClassToken($"\\{regexString[currentCharIndex]}"); break; case '[': currentCharIndex++; var startingIndex = currentCharIndex; while (currentCharIndex != length && regexString[currentCharIndex] != ']') { // Escape inside character class if ('\\'.Equals(regexString[currentCharIndex])) { currentCharIndex++; } currentCharIndex++; } if (currentCharIndex == length) { throw new RegexParseException($"Character class not properly closed in {regexString}"); } var value = regexString.Substring(startingIndex, currentCharIndex - startingIndex); toAdd = new CharacterClassToken(value); break; default: toAdd = new CharacterClassToken($"\\{currentChar}"); break; } result.Add(toAdd); currentCharIndex++; } return(result); }