public override ReadResult <Alternative> Read(ITextScanner scanner) { if (scanner == null) { throw new ArgumentNullException(nameof(scanner)); } var context = scanner.GetContext(); ILexer bestCandidate = null; var bestCandidateLength = -1; var ordinal = 0; IList <SyntaxError> errors = new List <SyntaxError>(lexers.Length); SyntaxError partialMatch = null; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < lexers.Length; i++) { var lexer = lexers[i]; var candidate = lexer.ReadElement(scanner); if (candidate.Success) { var alternative = candidate.Element; var length = alternative.Text.Length; if (length > bestCandidateLength) { bestCandidate = lexer; bestCandidateLength = length; ordinal = i + 1; } if (length != 0) { scanner.Unread(alternative.Text); } } else { errors.Add(candidate.Error); if (partialMatch == null || candidate.Text.Length > partialMatch.Text.Length) { partialMatch = candidate.Error; } } } if (bestCandidate == null) { Debug.Assert(partialMatch != null, "partialMatch != null"); return(ReadResult <Alternative> .FromSyntaxError(partialMatch)); } var readResult = bestCandidate.ReadElement(scanner); Debug.Assert(readResult.Success, "readResult.Success"); return(ReadResult <Alternative> .FromResult(new Alternative(readResult.Text, readResult.Element, context, ordinal))); }
public override ReadResult <Repetition> Read(ITextScanner scanner) { if (scanner == null) { throw new ArgumentNullException(nameof(scanner)); } var context = scanner.GetContext(); var stringBuilder = new StringBuilder(); IList <Element> elements = new List <Element>(lowerBound); // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < upperBound; i++) { var readResult = lexer.ReadElement(scanner); if (readResult.Success) { elements.Add(readResult.Element); stringBuilder.Append(readResult.Text); } else { if (elements.Count >= lowerBound) { return (ReadResult <Repetition> .FromResult( new Repetition(stringBuilder.ToString(), elements, context))); } var partialMatch = stringBuilder.ToString(); if (partialMatch.Length != 0) { scanner.Unread(partialMatch); } return (ReadResult <Repetition> .FromSyntaxError( new SyntaxError( readResult.EndOfInput, partialMatch, readResult.ErrorText, context, readResult.Error))); } } return(ReadResult <Repetition> .FromResult(new Repetition(stringBuilder.ToString(), elements, context))); }