示例#1
0
        /// <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));
                        }
                    }
                }
            }
        }
示例#2
0
        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);
                }
            }
        }
示例#3
0
        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));
            }
        }
示例#4
0
        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));
        }
示例#5
0
 public CachedStep(ParseStep step, int stepIndex, int currentIndex, int currentLookaroundIndex, IEnumerable<int> savedStatesIndexes)
 {
     Step = step;
     StepIndex = stepIndex;
     CurrentIndex = currentIndex;
     CurrentLookaroundIndex = currentLookaroundIndex;
     SavedStatesIndexes = savedStatesIndexes;
 }
示例#6
0
 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);
 }
示例#7
0
 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;
 }
示例#8
0
        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));
        }
示例#9
0
        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));
            }
        }
示例#10
0
        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));
        }
示例#11
0
        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));
        }
示例#12
0
        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);
        }
示例#14
0
 public object PartOne(string input)
 {
     return(ParseStep(input)("abcdefghijklmnop"));
 }
示例#15
0
 protected override void OnBegin()
 {
     Step = ParseStep.Idle;
 }
示例#16
0
        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;
                }
            }
        }
示例#17
0
        protected override IEnumerable <ParseStep> GetEndOfStringSteps(IRegexEngine engine)
        {
            yield return(ParseStep.EndOfString(this, engine.State));

            yield return(ParseStep.Break(this));
        }
示例#18
0
        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));
        }
示例#19
0
        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);
        }
示例#21
0
        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));
        }
示例#22
0
        /// <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);
        }