internal override sealed IEnumerable <ParseStep> Parse(IRegexEngine engine) { yield return(ParseStep.BeginParse(this, engine.State)); var initialState = engine.State; var matchedText = new StringBuilder(); foreach (var parseStep in ParseRequired(engine, matchedText, initialState)) { yield return(parseStep); } // If min equals max, we're done. if (Min == Max) { yield return(ParseStep.Pass(this, matchedText.ToString(), initialState, engine.State)); yield return(ParseStep.Break(this)); yield break; } foreach (var specific in ParseSpecific(engine, initialState, matchedText)) { if (ReferenceEquals(specific.Node, this) && specific.Type == ParseStepType.Break) { yield return(ParseStep.Break(this)); } else { yield return(specific); } } }
internal override IEnumerable <ParseStep> Parse(IRegexEngine engine) { yield return(ParseStep.BeginParse(this, engine.State)); if (engine.State.Index >= engine.Input.Length) { yield return(ParseStep.Fail(this, engine.State, engine.State)); yield return(ParseStep.Break(this)); yield break; } if (Matches(engine.Input[engine.State.Index])) { var match = engine.Input.Substring(engine.State.Index, 1); var initialState = engine.State; engine.State = engine.State.Advance(); yield return(ParseStep.Pass(this, match, initialState, engine.State)); yield return(ParseStep.AdvanceIndex(this, engine.State)); yield return(ParseStep.Break(this)); } else { yield return(ParseStep.Fail(this, engine.State, engine.State)); yield return(ParseStep.Break(this)); } }
internal override IEnumerable <ParseStep> Parse(IRegexEngine engine) { yield return(ParseStep.BeginParse(this, engine.State)); var initialState = engine.State; var capture = engine.GetCaptures(Number).FirstOrDefault(); if (capture == null || string.IsNullOrEmpty(capture.Value)) { yield return(ParseStep.Fail(this, initialState, engine.State, "No backreference value found")); yield return(ParseStep.Break(this)); } else { var literals = capture.Value.Select((c, i) => new CharacterLiteral(c, _ignoreCase, capture.Index + i, new string(new[] { c }))); foreach (var literal in literals) { var success = false; foreach (var result in literal.Parse(engine)) { if (result.Type == ParseStepType.Break) { break; } if (result.Type == ParseStepType.Pass) { success = true; } } if (!success) { yield return(ParseStep.Fail(this, initialState, engine.State)); yield return(ParseStep.Break(this)); yield break; } } yield return(ParseStep.Pass(this, capture.Value, initialState, engine.State)); yield return(ParseStep.Break(this)); } }
internal override sealed IEnumerable <ParseStep> Parse(IRegexEngine engine) { yield return(ParseStep.BeginParse(this, engine.State)); if (Matches(engine.State)) { yield return(ParseStep.Pass(this, "", engine.State, engine.State)); } else { yield return(ParseStep.Fail(this, engine.State, engine.State)); } yield return(ParseStep.Break(this)); }
internal override IEnumerable <ParseStep> Parse(IRegexEngine engine) { yield return(ParseStep.BeginParse(this, engine.State)); var initialState = engine.State; var choiceIndex = 0; foreach (var choice in Choices) { var matchedText = ""; var choicePassed = false; foreach (var result in choice.Parse(engine)) { if (ReferenceEquals(choice, result.Node) && result.Type == ParseStepType.Break) { break; } yield return(result); if (ReferenceEquals(choice, result.Node)) { if (result.Type == ParseStepType.Pass) { matchedText = result.MatchedText; choicePassed = true; if (choiceIndex < Choices.Count - 1) { // Only save state if we're not the last choice... yield return(ParseStep.StateSaved(this, initialState, string.Format("Saving state - index {0}", engine.State.Index))); } } } } if (choicePassed) { yield return(ParseStep.Pass(this, matchedText, initialState, engine.State)); yield return(ParseStep.Break(this)); // TODO: lazy quantifiers might act in a similar manner as alternation here... yield return(ParseStep.Backtrack(this, initialState, engine.State)); } else { if (engine.State.Index != initialState.Index) { yield return(ParseStep.ResetIndex(this, initialState, engine.State)); engine.State = initialState; } } choiceIndex++; } yield return(ParseStep.Fail(this, initialState, engine.State)); yield return(ParseStep.Break(this)); }