using System.Diagnostics.CodeAnalysis; using CanonSharp.Common.Abstractions; namespace CanonSharp.Common.LexicalAnalyzer; public class LexicalScanner( DeterministicState startState, Dictionary finalStateMap, HashSet skippedTokens, ISourceReader reader) { private readonly DeterministicState _startState = startState; private readonly List _readHistory = []; private DeterministicState _currentState = startState; public bool TryRead([NotNullWhen(true)] out LexicalToken? token) { while (TryReadInternal(out token)) { if (!skippedTokens.Contains(token)) { return true; } } return false; } private bool TryReadInternal([NotNullWhen(true)] out LexicalToken? token) { while (reader.TryPeek(out char c)) { if (_currentState.Transaction.TryGetValue(c, out DeterministicState? nextState)) { // 可以迁移到下一个状态 _currentState = nextState; _readHistory.Add(reader.Read()); } else { // 无法迁移到下一个状态 if (!finalStateMap.TryGetValue(_currentState, out LexicalToken? possibleToken)) { throw new InvalidOperationException(); } // 当前状态是终止状态 token = new LexicalToken(possibleToken, new string(_readHistory.ToArray())); // 重置状态 _readHistory.Clear(); _currentState = _startState; return true; } } // 当前状态是终止状态 if (finalStateMap.TryGetValue(_currentState, out LexicalToken? possibleToken2)) { token = new LexicalToken(possibleToken2, new string(_readHistory.ToArray())); _readHistory.Clear(); _currentState = _startState; return true; } if (!_currentState.Equals(_startState)) { throw new InvalidOperationException(); } token = null; return false; } public static LexicalScannerBuilder CreateDefaultBuilder() { LexicalScannerBuilder builder = new(); builder.DefineToken(LexicalToken.LineBreaker); builder.DefineToken(LexicalToken.WhiteSpace); builder.AddSkippedToken(LexicalToken.LineBreaker); builder.AddSkippedToken(LexicalToken.WhiteSpace); return builder; } public static LexicalScannerBuilder CreateEmptyBuilder() => new(); }