コード例 #1
0
        protected override bool CompareAndAdvanceImp(
            string str,
            int firstIndex,
            int depth,
            RunState runState,
            out int index)
        {
            if (EndComparison == null && !MaxLength.HasValue)
            {
                Parser.ThrowParseError(string.Format("Invalid combination of parameters. " +
                                                     "Both the end comparison and max length values have not been specified. " +
                                                     "How can we tell when the pattern match has completed?"));
            }

            index = -1;
            // If the minimum value is less than the length of the input string then it can never match
            int numCharsLeftInStr = str.Length - firstIndex;

            if (MinLength.HasValue && MinLength.Value > numCharsLeftInStr)
            {
                return(false);
            }

            // Sort the ranges
            if (!m_SortedRanges)
            {
                // A speedup by only doing it once
                m_SortedRanges = true;
                m_ComparisonRange.Sort(tComparisonRange.CompareByRange);
            }

            //// Iterate the string
            // The relevant range
            tComparisonRange range = null;
            // The index of the relevant range
            int rangeIndex = 0;
            // The index into the input string
            int i;

            int depthPlusOne = depth + 1;

            bool matched = true;

            for (i = firstIndex; matched && i < str.Length;)
            {
                // The current length
                int thisIndex1Based = i - firstIndex + 1;

                // Check the maximum length
                if (EndComparison != null)
                {
                    // If the end comparison has been specified but we've exceeded the maximum length then this is not a match
                    if (MaxLength.HasValue && thisIndex1Based > MaxLength.Value)
                    {
                        matched = false;
                    }
                }
                else
                {
                    // If there is no end comparison and we've reached the maximum length then this is a successful match
                    //  and stop trying to match any further
                    if (thisIndex1Based > MaxLength.Value)
                    {
                        break;
                    }
                }

                if (matched)
                {
                    // Check the current range is still relevant
                    if (range != null)
                    {
                        if (!range.Range.IsInRange(thisIndex1Based))
                        {
                            rangeIndex += 1;
                            range       = null;
                        }
                    }

                    // Find/update the appropriate range
                    if (range == null)
                    {
                        for (int iRange = rangeIndex; iRange < m_ComparisonRange.Count; ++iRange)
                        {
                            // Is it in range?
                            tComparisonRange iterRange = m_ComparisonRange[iRange];
                            if (iterRange.Range.IsInRange(thisIndex1Based))
                            {
                                // Update the range in use
                                range      = iterRange;
                                rangeIndex = iRange;
                                break;
                            }
                        }

                        if (range == null)
                        {
                            string text = string.Format("No range specified for character at index {0}.", i);
                            Parser.ThrowParseError(text);
                        }
                    }

                    // Do the comparison
                    // If the comparison is not specified then simply advance by 1 if we have not reached the end.
                    // Can be used to specify match on everything
                    bool endMatches;
                    if (EndComparison != null)
                    {
                        endMatches = EndComparison.Compare(str, i, depthPlusOne, runState);
                    }
                    else
                    {
                        endMatches = false;
                    }
                    if (range.Comparison != null)
                    {
                        int afterMatch;
                        matched = range.Comparison.CompareAndAdvance(str, i, depthPlusOne, runState, out afterMatch);
                        // This is a key nuance with the way this works. DO NOT STOP if both the end comparisons and range
                        //  comparisons succeed. This is a design decision to make it behave in this manner
                        if (endMatches && !matched)
                        {
                            matched = true;
                            break;
                        }

                        // Advance to after the successful match
                        i = afterMatch;
                    }
                    else
                    {
                        if (endMatches)
                        {
                            // Stop if we found the end
                            break;
                        }
                        ++i;
                    }
                }
            }

            if (matched)
            {
                index = i;
                // Check the length
                int  length          = i - firstIndex;
                bool isMinimumLength = (!MinLength.HasValue || (MinLength.HasValue && length >= MinLength.Value));
                matched = (isMinimumLength);
            }
            return(matched);
        }
コード例 #2
0
ファイル: ComparisonBase.cs プロジェクト: sidfishus/TextParse
 abstract protected bool CompareImp(
     string input,
     int pos,
     int depth,
     RunState runState);
コード例 #3
0
        private string Process(
            string input,
            string replaceWith,
            IComparisonWithAdvance mainComparison,
            Dictionary <string, Capture> capturing,
            List <State> stateList,
            bool replace,
            out int numMatches,
            Func <RunState, string, int, string> ReplaceFunc = null,
            Action <RunState> InitRunState = null)
        {
            // The replaced string
            StringBuilder replaced = new StringBuilder();

            var runState = new RunState();

            if (InitRunState != null)
            {
                InitRunState(runState);
            }
            numMatches = 0;

            // Iterate the input string character by character
            for (int outerIndex = 0; outerIndex < input.Length;)
            {
                runState.Clear();
                runState.BeginPos = outerIndex;
#if DEBUG
                int dbgInitialOuterIndex = outerIndex;
                if (dbgInitialOuterIndex == 1374)
                {
                    Misc.Break();
                }
                string dbgInputPortion = input.Substring(dbgInitialOuterIndex,
                                                         Math.Min(20, input.Length - dbgInitialOuterIndex));
#endif
                //// All states enabled?
                int  afterState = outerIndex;
                bool stateEnabled;
                if (stateList != null)
                {
                    for (; ;)
                    {
                        // If the state becomes enabled, check that directly afterwards we don't encounter a close state
                        // Imagine we have a state which opens on '<%' and closes on '%>' and the input string is '<%%> ...'
                        // We enable then instantly disable again. We only stop trying to update the state when updating the
                        //  state doesn't advance the position
                        int curIndex = afterState;
                        stateEnabled = UpdateState(stateList, input, afterState, runState, out afterState);
                        if (curIndex == afterState)
                        {
                            // Updating the state did not advance the position - continue with the replace
                            break;
                        }
                    }
                }
                else
                {
                    stateEnabled = true;
                }

                // Copy the state string (if any)
                if (afterState != outerIndex)
                {
                    string stateString = input.Substring(outerIndex, afterState - outerIndex);
                    replaced.Append(stateString);
                }

                // Update the main index
                outerIndex = afterState;

                if (outerIndex < input.Length)
                {
                    bool matched = stateEnabled;
                    if (stateEnabled)
                    {
                        // Run the statements beginning from 'afterState'
                        int innerIndex = outerIndex;
                        int afterMatch;
                        matched = mainComparison.CompareAndAdvance(input, innerIndex, 0, runState, out afterMatch);
                        if (matched)
                        {
                            // The begin of the matching string
                            runState.BeginPos = outerIndex;

                            ++numMatches;

                            // This is a match! :)
                            // Do the replace
                            string iterReplaced = ReplaceMatch(replaceWith, ReplaceFunc, capturing, runState, input, afterMatch);
                            replaced.Append(iterReplaced);
                            LogMatchReplace(
                                input,
                                innerIndex,
                                afterMatch,
                                iterReplaced,
                                capturing);

                            // Update the outer index and continue iterating from there
                            outerIndex = afterMatch;
                        }
                    }

                    if (!matched)
                    {
                        if (replace)
                        {
                            // Match failed: copy this character to the output string and move on to the next one (if this is replace mode)
                            replaced.Append(input[outerIndex]);
                        }
                        ++outerIndex;
                    }
                }
            }
            return(replaced.ToString());
        }
コード例 #4
0
ファイル: OperationBase.cs プロジェクト: sidfishus/TextParse
 abstract protected void PerformImp(
     string input,
     int pos,
     int depth,
     RunState runState,
     out int index);