/// <summary> /// Parse the required quantities - we must match at least the minimum. /// </summary> private IEnumerable <ParseStep> ParseRequired(IRegexEngine engine, StringBuilder matchedText, State initialState) { for (int i = 0; i < Min; i++) { foreach (var result in Child.Parse(engine)) { if (result.Type == ParseStepType.Break && ReferenceEquals(Child, result.Node)) { break; } yield return(result); if (ReferenceEquals(Child, result.Node)) { if (result.Type == ParseStepType.Pass) { matchedText.Append(result.MatchedText); } else if (result.Type == ParseStepType.Fail) { yield return(ParseStep.Fail( this, initialState, engine.State, string.Format("Greedy quantifier was required to match at least {0} times, but matched {1} times", Min, i))); yield return(ParseStep.Break(this)); } } } } }
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)); } }
protected override IEnumerable <ParseStep> GetSuccessParseStep(IRegexEngine engine, State initialState) { var matchedText = engine.Input.Substring(initialState.Index, engine.State.Index - initialState.Index); yield return(ParseStep.Pass(this, matchedText, initialState, engine.State)); yield return(ParseStep.Break(this)); }
public CachedStep(ParseStep step, int stepIndex, int currentIndex, int currentLookaroundIndex, IEnumerable<int> savedStatesIndexes) { Step = step; StepIndex = stepIndex; CurrentIndex = currentIndex; CurrentLookaroundIndex = currentLookaroundIndex; SavedStatesIndexes = savedStatesIndexes; }
public Steps(ICoreConfigSection coreConfigSection, SDBuildStrings sdBuildStrings, IConfigController configController, BuildMessenger buildMessenger, IExporter[] allExporters = null) { PreBuildStep = new PreBuildStep(coreConfigSection, allExporters, buildMessenger, sdBuildStrings); LoadStep = new LoadStep(coreConfigSection, sdBuildStrings, buildMessenger); ParseStep = new ParseStep(sdBuildStrings, coreConfigSection, buildMessenger); StructureParseStep = new StructureParseStep(sdBuildStrings, buildMessenger); ExportStep = new ExportStep(coreConfigSection, sdBuildStrings, buildMessenger, allExporters); EndStep = new EndStep(configController, coreConfigSection); }
public CachedStep(ParseStep step, int stepIndex, int regexIndex, int currentIndex, int currentLookaroundIndex, IEnumerable <int> savedStatesIndexes) { Step = step; StepIndex = stepIndex; RegexIndex = regexIndex; CurrentIndex = currentIndex; CurrentLookaroundIndex = currentLookaroundIndex; SavedStatesIndexes = savedStatesIndexes; }
private IEnumerable <ParseStep> Backtrack(IRegexEngine engine, State initialState, Stack <SavedState> savedStates) { var savedState = savedStates.Pop(); engine.State = savedState.State; yield return(ParseStep.Backtrack(this, initialState, engine.State)); yield return(ParseStep.Pass(this, savedState.MatchedText, initialState, 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)); }
protected override IEnumerable <ParseStep> ParseSpecific(IRegexEngine engine, State initialState, StringBuilder matchedText) { for (int i = Min; Max == null || i <= Max; i++) { // We're lazy - we've already matched what was required of us, so declare that we're done. yield return(ParseStep.StateSaved(this, initialState, string.Format("Saving state - index {0}", engine.State.Index))); yield return(ParseStep.Pass(this, matchedText.ToString(), initialState, engine.State)); yield return(ParseStep.Break(this)); // However, if we make it to here, it indicates that we need to match more, in order to (attempt to) get the overall regex to match. // According to the parlance of regex people smarter than me, this is a backtrack, even though it's forward. yield return(ParseStep.Backtrack(this, initialState, engine.State)); var childSuccess = false; foreach (var result in Child.Parse(engine)) { if (result.Type == ParseStepType.Break && ReferenceEquals(Child, result.Node)) { break; } yield return(result); if (ReferenceEquals(Child, result.Node)) { if (result.Type == ParseStepType.Pass) { matchedText.Append(result.MatchedText); childSuccess = true; } } } if (!childSuccess) { break; } } // If we ever make it outside the loop, it means either we were asked to backtrack and our child didn't pass, // or, we were asked to backtrack more than the Max allowed matches yield return(ParseStep.Fail(this, initialState, engine.State, "Exceeded max allowled quantities")); yield return(ParseStep.Break(this)); }
internal override IEnumerable <ParseStep> Parse(IRegexEngine outerEngine) { var engine = new RegexEngine.RegexEngineInternal(GetEngineInput(outerEngine)); foreach (var capture in outerEngine.GetAllDefinedCaptures().SelectMany(kvp => kvp.Value)) { engine.AddCapture(capture.Number, capture.Index, capture.Value); } var modifier = GetModifier(outerEngine); bool match = false; yield return(ParseStep.StartLookaround(this, engine.State.Plus(modifier)).WithSkipAdvanceOnFail(ShouldSkipAdvance)); foreach (var result in _regex.Parse(engine)) { // Don't report the results of the non-reporting start of string element. if (ReferenceEquals(result.Node, _nonReportingNode)) { continue; } if (ReferenceEquals(result.Node, _regex)) { if (result.Type == ParseStepType.Match) { match = true; break; } if (result.Type == ParseStepType.Fail) { continue; } if (result.Type == ParseStepType.Break) { break; } } if (result.Type != ParseStepType.Break && engine.State.Index <= engine.Input.Length) { yield return(result .ConvertToOuterContext(outerEngine.Input, modifier, this, n => ReferenceEquals(n, _regex), message => message.Replace(_regex.NodeType, NodeType)) .AsLookaround() .WithSkipAdvanceOnFail(ShouldSkipAdvance)); } } if (match) { if (!Negative) { // TODO: we need to forward any captures from the look-around to the outer engine. yield return(ParseStep.Pass(this, "", outerEngine.State, engine.State.Plus(modifier)).WithSkipAdvanceOnFail(ShouldSkipAdvance)); } else { yield return(ParseStep.Fail(this, outerEngine.State, engine.State.Plus(modifier)).WithSkipAdvanceOnFail(ShouldSkipAdvance)); } } else { if (!Negative) { yield return(ParseStep.Fail(this, outerEngine.State, engine.State.Plus(modifier)).WithSkipAdvanceOnFail(ShouldSkipAdvance)); } else { // TODO: we need to forward any captures from the look-around to the outer engine. yield return(ParseStep.Pass(this, "", outerEngine.State, engine.State.Plus(modifier)).WithSkipAdvanceOnFail(ShouldSkipAdvance)); } } yield return(ParseStep.EndLookaround(this).WithSkipAdvanceOnFail(ShouldSkipAdvance)); yield return(ParseStep.Break(this).WithSkipAdvanceOnFail(ShouldSkipAdvance)); }
/// <summary> /// Parses the AWL Text and returns the S7Blocks /// </summary> /// <param name="AWL"></param> /// <param name="SymbolTable">Can be null</param> /// <returns></returns> public static List <S7Block> ParseAWL(string AWL, string SymbolTable) { var retVal = new List <S7Block>(); string txt = ""; string blockType = ""; string blockNumberOrName = ""; string blockRetValType = ""; bool startOfQuote = false; ParseStep step = ParseStep.ReadBlockType; S7DataRow akDataRow = null; S7Block akBlock = null; foreach (char c in AWL) { if (!startOfQuote && (c == ' ' || c == '\n' || c == '\r' || c == '=' || c == ':') || c == '"') { if (c == '"' && !startOfQuote) { startOfQuote = true; } else if (startOfQuote) { startOfQuote = false; } if (step == ParseStep.ReadBlockRetVal && txt != "" && txt != ":") //Header ohne RetVal { blockRetValType = ""; akBlock = CreateBlock(blockType, blockNumberOrName, blockRetValType); step = ParseStep.ParseHeaderRow; } if (step == ParseStep.ParseTitle && (c == '\n' || c == '\r')) { step = ParseStep.ParseHeaderRow; } if (txt != "") { switch (step) { case ParseStep.ReadBlockType: { blockType = txt.ToUpper(); step = ParseStep.ReadBlockNumberOrName; break; } case ParseStep.ReadBlockNumberOrName: { blockNumberOrName = txt; step = ParseStep.ReadBlockRetVal; break; } case ParseStep.ReadBlockRetVal: { step = ParseStep.ReadBlockRetValType; break; } case ParseStep.ReadBlockRetValType: { blockRetValType = txt; akBlock = CreateBlock(blockType, blockNumberOrName, blockRetValType); step = ParseStep.ParseHeaderRow; break; } case ParseStep.ParseHeaderRow: { switch (txt.ToUpper()) { case ("TITLE"): { step = ParseStep.ParseTitle; break; } case ("VERSION"): { step = ParseStep.ParseVersion; break; } case ("STRUCT"): { step = ParseStep.ParseStructure; break; } case ("BEGIN"): { step = ParseStep.ParseAWLCode; break; } case ("VAR_INPUT"): case ("VAR_OUTPUT"): case ("VAR_IN_OUT"): case ("VAR_TEMP"): { step = ParseStep.ParsePara; break; } default: { if (txt.StartsWith("{") && txt.EndsWith("}")) { akBlock.Attributes = ParseStep7Attribute(txt); } break; } } break; } case ParseStep.ParseTitle: { akBlock.Title = txt; step = ParseStep.ParseHeaderRow; break; } case ParseStep.ParseVersion: { akBlock.Version = txt; step = ParseStep.ParseHeaderRow; break; } } } txt = ""; } else { txt = txt + c; } } return(retVal); }
public object PartOne(string input) { return(ParseStep(input)("abcdefghijklmnop")); }
protected override void OnBegin() { Step = ParseStep.Idle; }
protected override void Read() { if (ByteValue == -1) { EndSymbol(); return; } var ch = (char)ByteValue; if (char.IsWhiteSpace(ch)) { switch (Step) { case ParseStep.Idle: return; case ParseStep.WaitForSymbol: EndSymbol(); Step = ParseStep.Idle; return; } } else if (ch == '(') { switch (Step) { case ParseStep.Idle: PushToken(MetaTokenType.LP); return; case ParseStep.WaitForSymbol: EndSymbol(); PushToken(MetaTokenType.LP); Step = ParseStep.Idle; return; } } else if (ch == ')') { switch (Step) { case ParseStep.Idle: PushToken(MetaTokenType.RP); return; case ParseStep.WaitForSymbol: EndSymbol(); PushToken(MetaTokenType.RP); Step = ParseStep.Idle; return; } } else if (ch == '+') { switch (Step) { case ParseStep.Idle: PushToken(MetaTokenType.OneOrMore); return; case ParseStep.WaitForSymbol: EndSymbol(); PushToken(MetaTokenType.OneOrMore); Step = ParseStep.Idle; return; } } else if (ch == '|') { switch (Step) { case ParseStep.Idle: PushToken(MetaTokenType.Or); return; case ParseStep.WaitForSymbol: EndSymbol(); PushToken(MetaTokenType.Or); Step = ParseStep.Idle; return; } } else if (ch == '*') { switch (Step) { case ParseStep.Idle: PushToken(MetaTokenType.ZeroOrMore); return; case ParseStep.WaitForSymbol: EndSymbol(); PushToken(MetaTokenType.ZeroOrMore); Step = ParseStep.Idle; return; } } else { switch (Step) { case ParseStep.Idle: PushBuffer(); Step = ParseStep.WaitForSymbol; break; case ParseStep.WaitForSymbol: PushBuffer(); break; } } }
protected override IEnumerable <ParseStep> GetEndOfStringSteps(IRegexEngine engine) { yield return(ParseStep.EndOfString(this, engine.State)); yield return(ParseStep.Break(this)); }
protected override IEnumerable <ParseStep> GetFailParseSteps(IRegexEngine engine, State initialState, State currentState, bool skipAdvance) { yield return(ParseStep.Fail(this, initialState, currentState)); yield return(ParseStep.Break(this)); }
protected override IEnumerable <ParseStep> ParseSpecific(IRegexEngine engine, State initialState, StringBuilder matchedText) { // At this point, we know we'll match. Attempt to match everything else, until we hit max, a non-match, or the end of the string. // We need to save states as we go, in case we're asked to backtrack. var savedStates = new Stack <SavedState>(); int matchedQuantity = Min; for (; Max == null || matchedQuantity < Max; matchedQuantity++) { // If the last state we saved was at the end of the string, there's no point in going any further... if (savedStates.Count > 0 && savedStates.Peek().State.Index >= engine.Input.Length) { // Should we ever get here??? savedStates.Pop(); break; } if (engine.State.Index < engine.Input.Length) { // We're not at the end of the string, so save state before attempting a match - since we're greedy, we leave breadcrumbs before doing anything. savedStates.Push(new SavedState(engine.State, matchedText.ToString())); yield return(ParseStep.StateSaved(this, engine.State, string.Format("Saving state - index {0}", engine.State.Index))); } else { // It looks like we're at the end of the string - which means we're done. Time to report as such. yield return(ParseStep.EndOfString(this, engine.State)); yield return(ParseStep.Pass(this, matchedText.ToString(), initialState, engine.State)); yield return(ParseStep.Break(this)); break; } var endOfMatch = false; // TODO: I think that we're going to need to use an enumerator here so we can initiate backtracking in our child and its descendants. foreach (var result in Child.Parse(engine)) { if (result.Type == ParseStepType.Break && ReferenceEquals(Child, result.Node)) { break; } yield return(result); if (ReferenceEquals(Child, result.Node)) { if (result.Type == ParseStepType.Pass) { matchedText.Append(result.MatchedText); } else if (result.Type == ParseStepType.Fail) { endOfMatch = true; foreach (var backtrackStep in Backtrack(engine, initialState, savedStates)) { yield return(backtrackStep); } break; } } } if (endOfMatch) { break; } } if (matchedQuantity >= Max) { // We've reached the maximum allowed quantity of repetitions, time to break; yield return(ParseStep.Pass(this, matchedText.ToString(), initialState, engine.State)); yield return(ParseStep.Break(this)); } // If we get here, it means that we're backtracking while (savedStates.Count > 0) { foreach (var backtrackStep in Backtrack(engine, initialState, savedStates)) { yield return(backtrackStep); } } // If we get here, we ran out of saved states to backtrack to - report failure. yield return(ParseStep.Fail(this, initialState, engine.State, "No backtrack is available")); if (engine.State.Index != initialState.Index) { yield return(ParseStep.ResetIndex(this, initialState, engine.State)); engine.State = initialState; } yield return(ParseStep.Break(this)); }
public void CommonCases() { var _builder = new StringParserBuilder { PreSteps = { NullableParseStep.Default, }, Steps = { EnumParseStep.Ordinal, CustomParseStep.Define <ushort>(_s => { ushort _value; return(ushort.TryParse(_s, out _value) ? ParseStep.Valid((ushort)(_value + 1)) : ParseStep.InvalidString()); }), }, PostSteps = { ConvertibleParseStep.Default, }, }; var _stringParser = _builder.Build(); Assert.Equal(true, _stringParser.Parse <bool?>("True")); Assert.Equal(false, _stringParser.Parse <bool>("False")); Assert.Equal(null, _stringParser.Parse <bool?>(null)); Assert.Equal("Test", _stringParser.Parse <string>("Test")); Assert.Equal(22, _stringParser.Parse <int>("22")); Assert.Equal('@', _stringParser.Parse <char>("@")); Assert.Equal(null, _stringParser.Parse <int?>(string.Empty)); Assert.Equal(UriKind.RelativeOrAbsolute, _stringParser.Parse <UriKind>("RelativeOrAbsolute")); Assert.Equal(UriKind.Absolute, _stringParser.Parse <UriKind?>("Absolute")); Assert.Equal(null, _stringParser.Parse <UriKind?>(string.Empty)); Assert.Equal(NumberStyles.AllowExponent | NumberStyles.AllowParentheses, _stringParser.Parse <NumberStyles?>("AllowExponent , AllowParentheses ")); Assert.Equal((ushort?)1, _stringParser.Parse <ushort?>("0")); Assert.NotEqual(null, _stringParser.Parse <UriKind?>("Absolute")); Assert.True(_stringParser.TryParse <bool?>("True").IsValid); Assert.True(_stringParser.TryParse <UriKind?>(string.Empty).IsValid); Assert.True(_stringParser.TryParse <int?>(string.Empty).IsValid); Assert.True(_stringParser.TryParse <string>("Nope!").IsValid); Assert.True(_stringParser.TryParse <char>("!").IsValid); Assert.True(_stringParser.TryParse <NumberStyles>("AllowExponent , AllowParentheses ").IsValid); Assert.False(_stringParser.TryParse <UriKind>("Absolute!").IsValid); Assert.False(_stringParser.TryParse <UriKind>(string.Empty).IsValid); Assert.False(_stringParser.TryParse <int>(string.Empty).IsValid); Assert.False(_stringParser.TryParse <int?>("Nope!").IsValid); Assert.False(_stringParser.TryParse <int>("Nope!").IsValid); Assert.False(_stringParser.TryParse <int>("Nope!").IsValid); Assert.False(_stringParser.TryParse <char>("!!").IsValid); Assert.False(_stringParser.TryParse <Type>(GetType().FullName).IsValid); Assert.False(_stringParser.TryParse <Type>("System.String").IsValid); Assert.False(_stringParser.TryParse <Type>("!!").IsValid); Assert.False(_stringParser.TryParse <object>("Test").IsValid); }
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)); }
/// <summary> /// Parse the subtitle file and return a list of lines. /// </summary> public override List <InfoLine> parse() { List <InfoLine> lineInfos = new List <InfoLine>(2000); StreamReader subFile = new StreamReader(File, SubsEncoding); string rawLine; ParseStep parseStep = ParseStep.LineNum; string rawStartTime = ""; string rawEndTime = ""; string lineText = ""; // Fill in lineInfos while ((rawLine = subFile.ReadLine()) != null) { Match match; switch (parseStep) { case ParseStep.LineNum: // Skip past line number and anything before it match = Regex.Match(rawLine, @"^\d+$", RegexOptions.IgnoreCase | RegexOptions.Compiled); if (match.Success) { parseStep = ParseStep.Time; } continue; case ParseStep.Time: // Match time match = Regex.Match(rawLine, @"^(?<StartTime>.*?)\s-->\s(?<EndTime>.*)$", RegexOptions.IgnoreCase | RegexOptions.Compiled); if (!match.Success) { // Something went wrong - there's something between line number and time info continue; } rawStartTime = match.Groups["StartTime"].ToString().Trim(); rawEndTime = match.Groups["EndTime"].ToString().Trim(); parseStep = ParseStep.Text; continue; case ParseStep.Text: // Match text match = Regex.Match(rawLine, @"^(?<Text>.*)$", RegexOptions.IgnoreCase | RegexOptions.Compiled); string text = match.Groups["Text"].ToString().Trim(); // Keep parsing subs until a blank line is encountered if (text == "") { parseStep = ParseStep.LineNum; lineInfos.Add(createLineInfo(lineText, rawStartTime, rawEndTime)); lineText = ""; } else { // Add space between each line of a multiline subtitle lineText += text + " "; } continue; } } // Handle the last line in the file if (lineText.Trim().Length > 0) { lineInfos.Add(createLineInfo(lineText, rawStartTime, rawEndTime)); } lineInfos.Sort(); return(lineInfos); }