예제 #1
0
        /// <summary>
        /// Appends a regular expression representation of the language described by the node to a given string builder,
        /// adding brackets if the parent operation has higher priority.
        /// </summary>
        /// <param name="resultBuilder">The string builder.</param>
        /// <param name="parentType">The type of the parent node.</param>
        /// <param name="formattingSettings">The formatting settings used for conversion from an automaton to a string.</param>
        /// <param name="useCache">Whether the value caching should be used (see <see cref="AppendToString(StringBuilder, RegexpFormattingSettings, bool)"/>).</param>
        /// <returns>Returns true if successful, false otherwise.</returns>
        private bool AppendRegexpWithBrackets(
            StringBuilder resultBuilder, RegexpTreeNodeType parentType, RegexpFormattingSettings formattingSettings, bool useCache)
        {
            Debug.Assert(formattingSettings != null, "A valid formatting settings description must be provided.");

            bool addBrackets = this.Type < parentType && !(formattingSettings.PutOptionalInSquareBrackets && this.IsOptional());

            if (addBrackets)
            {
                resultBuilder.Append('(');
            }

            if (!this.AppendToString(resultBuilder, formattingSettings, useCache))
            {
                return(false);
            }

            if (addBrackets)
            {
                resultBuilder.Append(')');
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Returns a string representation of the language described by the node.
        /// </summary>
        /// <param name="builder">The string builder to append to.</param>
        /// <param name="formattingSettings">The formatting settings used for conversion from an automaton to a string.</param>
        /// <returns>False if the string was truncated.</returns>
        public bool AppendToString(StringBuilder builder, RegexpFormattingSettings formattingSettings)
        {
            Argument.CheckIfNotNull(formattingSettings, "formattingSettings");

            return(this.AppendToString(builder, formattingSettings, false));
        }
예제 #3
0
        /// <summary>
        /// Returns a string representation of the language described by the node.
        /// </summary>
        /// <param name="resultBuilder">The string builder to append to.</param>
        /// <param name="formattingSettings">The formatting settings used for conversion from an automaton to a string.</param>
        /// <param name="useCache">Whether the value caching should be used.</param>
        /// <returns>False if the max length was reached, true otherwise.</returns>
        /// <remarks>
        /// Value caching must be used with care: once cached, a value would never be invalidated.
        /// That is why this method should be called with value caching only on those nodes that have already been simplified.
        /// <see cref="SimplifyUnion"/> uses this method in exactly this way.
        /// </remarks>
        private bool AppendToString(StringBuilder resultBuilder, RegexpFormattingSettings formattingSettings, bool useCache)
        {
            Debug.Assert(formattingSettings != null, "Valid formatting settings must be provided.");
            Debug.Assert(!useCache || this.simplified, "Caching must not be used for non-simplified nodes.");

            int lengthAtStart = resultBuilder.Length;

            if (lengthAtStart > formattingSettings.TruncationLength)
            {
                return(false);
            }

            if (useCache && this.toStringVerboseCached != null && formattingSettings.Equals(VerboseFormattingSettings))
            {
                resultBuilder.Append(this.toStringVerboseCached);
                return(true);
            }

            ////var resultBuilder = new StringBuilder();
            switch (this.Type)
            {
            case RegexpTreeNodeType.Empty:
                break;

            case RegexpTreeNodeType.Nothing:
                resultBuilder.Append('Ø');
                break;

            case RegexpTreeNodeType.ElementSet:
                if (typeof(TElement) == typeof(string))
                {
                    resultBuilder.Append("<");
                    if (this.elementSet is DiscreteChar)
                    {
                        ((DiscreteChar)(object)this.elementSet).AppendToString(resultBuilder);
                    }
                    else
                    {
                        var stringForm = this.elementSet.ToString();
                        ////if (stringForm.Contains('?')) stringForm = "?";
                        resultBuilder.Append(stringForm);
                    }

                    resultBuilder.Append(">");
                }
                else
                {
                    if (this.elementSet.IsPointMass)
                    {
                        if (this.elementSet is DiscreteChar)
                        {
                            var dc = (DiscreteChar)(object)this.elementSet;
                            dc.AppendRegex(resultBuilder);
                        }
                        else
                        {
                            resultBuilder.Append(this.elementSet.Point);
                        }
                    }
                    else if (this.elementSet.IsUniform() || formattingSettings.IgnoreElementDistributionDetails)
                    {
                        resultBuilder.Append(formattingSettings.ShowAnyElementAsQuestionMark ? '?' : '.');
                    }
                    else
                    {
                        if (this.elementSet is DiscreteChar)
                        {
                            var dc = (DiscreteChar)(object)this.elementSet;
                            dc.AppendRegex(resultBuilder);
                        }
                        else
                        {
                            // not a discrete char... What to do here?
                            resultBuilder.Append(this.elementSet);
                        }
                    }
                }

                break;

            case RegexpTreeNodeType.Union:
                bool withSquareBrackets = formattingSettings.PutOptionalInSquareBrackets && this.IsOptional();
                if (withSquareBrackets)
                {
                    resultBuilder.Append('[');
                }

                bool hasPrevious = false;
                for (int i = 0; i < this.children.Count; ++i)
                {
                    if (!withSquareBrackets || this.children[i].Type != RegexpTreeNodeType.Empty)
                    {
                        if (hasPrevious)
                        {
                            resultBuilder.Append('|');
                        }

                        if (!this.children[i].AppendRegexpWithBrackets(resultBuilder, RegexpTreeNodeType.Union, formattingSettings, useCache))
                        {
                            return(false);
                        }

                        hasPrevious = true;
                    }
                }

                if (withSquareBrackets)
                {
                    resultBuilder.Append(']');
                }

                break;

            case RegexpTreeNodeType.Concat:
                for (int i = 0; i < this.children.Count; ++i)
                {
                    if (!this.children[i].AppendRegexpWithBrackets(resultBuilder, RegexpTreeNodeType.Concat, formattingSettings, useCache))
                    {
                        return(false);
                    }
                }

                break;

            case RegexpTreeNodeType.Star:
                if (!this.children[0].AppendRegexpWithBrackets(resultBuilder, RegexpTreeNodeType.Star, formattingSettings, useCache))
                {
                    return(false);
                }

                resultBuilder.Append(formattingSettings.UseLazyQuantifier ? "*?" : "*");
                break;

            default:
                Debug.Fail("Unhandled operation!");
                break;
            }

            if (useCache && formattingSettings.Equals(VerboseFormattingSettings))
            {
                ////    this.toStringVerboseCached = resultBuilder.ToString(lengthAtStart, resultBuilder.Length-lengthAtStart);
            }

            return(true);
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RegexpAutomatonFormat"/> class.
        /// </summary>
        /// <param name="formattingSettings">The formatting settings used for conversion from an automaton to a string.</param>
        public RegexpAutomatonFormat(RegexpFormattingSettings formattingSettings)
        {
            Argument.CheckIfNotNull(formattingSettings, "formattingSettings");

            this.FormattingSettings = formattingSettings;
        }