Beispiel #1
0
        private PathRegexElement ParseItemSequence(ref int pos, bool startsWithItem)
        {
            // Syntax: { element }
            int startPos = pos;
            var list     = new List <PathRegexElement>();

            for (;;)
            {
                string peekSym = PeekSymbol(pos, eofOk: true);
                if (Matches(peekSym, "", ")", "|"))
                {
                    break;
                }
                else
                {
                    PathRegexElement element = ParseItemElement(ref pos, startsWithItem);
                    list.Add(element);
                    startsWithItem = !element.EndsWithItem;
                }
            }
            switch (list.Count)
            {
            case 0:
                return(new Sequence(startsWithItem, !startsWithItem, startPos, list));

            case 1:
                return(list.Single());

            default:
                return(new Sequence(startsWithItem, list.Last().EndsWithItem, startPos, list));
            }
        }
Beispiel #2
0
        private PathRegexElement ParseItemAlternatives(ref int pos, bool startsWithItem)
        {
            // Syntax: sequence { '|' sequence }
            int startPos           = pos;
            PathRegexElement first = ParseItemSequence(ref pos, startsWithItem);
            var elements           = new List <PathRegexElement> {
                first
            };

            while (Matches(PeekSymbol(pos, eofOk: true), "|"))
            {
                AdvanceSymbolPos(ref pos);
                elements.Add(ParseItemSequence(ref pos, startsWithItem));
            }

            bool endsWithItem = first.EndsWithItem;

            foreach (var e in elements)
            {
                if (e.EndsWithItem != endsWithItem)
                {
                    throw new RegexSyntaxException(_definition, e.TextPos,
                                                   "Element in Regex does not end with " + ItemOrDependency(endsWithItem) + " like others");
                }
            }

            return(elements.Count > 1
                ? new Alternatives(startsWithItem: startsWithItem, endsWithItem: endsWithItem, textPos: startPos,
                                   elements: elements)
                : first);
        }
Beispiel #3
0
        protected PathRegex([NotNull] string definition, [NotNull] Dictionary <string, TItemMatch> definedItemMatches,
                            [NotNull] Dictionary <string, TDependencyMatch> definedDependencyMatches, bool ignoreCase)
        {
            _definedItemMatches       = definedItemMatches;
            _definedDependencyMatches = definedDependencyMatches;
            _ignoreCase = ignoreCase;

            int pos = 0;

            _definition = definition;
            PathRegexElement regex = ParseItemAlternatives(ref pos, startsWithItem: true);

            _graph = regex.CreateGraphken();
            _graph.EndNode.IsEnd = true;
        }
Beispiel #4
0
        private PathRegexElement ParseItemElement(ref int pos, bool startsWithItem)
        {
            // Syntax:
            //     /!startsWithItem/ .
            //   | /startsWithItem/  :
            //   | '(' alternative ')' ( ? | * | + )?
            //   | '[' ( '^' )? NAME { NAME } ']'
            //   | NAME
            int    startPos = pos;
            string peekSym  = PeekSymbol(startPos);

            if (Matches(peekSym, "("))
            {
                AdvanceSymbolPos(ref pos);

                PathRegexElement inner = ParseItemAlternatives(ref pos, startsWithItem);
                peekSym = PeekSymbol(pos);
                if (!Matches(peekSym, ")"))
                {
                    throw new RegexSyntaxException(_definition, pos, ") expected");
                }
                AdvanceSymbolPos(ref pos);

                peekSym = PeekSymbol(pos, eofOk: true);
                if (Matches(peekSym, "?"))
                {
                    AdvanceSymbolPos(ref pos);
                    return(new Optional(startPos, inner));
                }
                else if (Matches(peekSym, "*"))
                {
                    AdvanceSymbolPos(ref pos);
                    _containsLoops = true;
                    return(new ZeroOrMore(startPos, inner));
                }
                else if (Matches(peekSym, "+"))
                {
                    AdvanceSymbolPos(ref pos);
                    _containsLoops = true;
                    return(new OneOrMore(startPos, inner));
                }
                else
                {
                    return(inner);
                }
            }
            else if (Matches(peekSym, "["))
            {
                AdvanceSymbolPos(ref pos);

                bool invert = false;
                if (Matches(PeekSymbol(pos), "^"))
                {
                    invert = true;
                    AdvanceSymbolPos(ref pos);
                }

                var matches = new SortedDictionary <int, string> {
                    { pos, PeekName(pos) }
                };
                AdvanceSymbolPos(ref pos);
                while (!Matches(PeekSymbol(pos), "]"))
                {
                    matches.Add(pos, PeekName(pos));
                    AdvanceSymbolPos(ref pos);
                }
                AdvanceSymbolPos(ref pos);
                bool isCount = ParseOptionalCount(ref pos);
                if (startsWithItem)
                {
                    return(new ItemMatchAnyElement(invert, isCount, startPos,
                                                   matches.Select(kvp => CreateItemMatch(kvp.Key, kvp.Value))));
                }
                else
                {
                    return(new DependencyMatchAnyElement(invert, isCount, startPos,
                                                         matches.Select(kvp => CreateDependencyMatch(kvp.Key, kvp.Value))));
                }
            }
            else if (Matches(peekSym, NAME_REGEX))
            {
                AdvanceSymbolPos(ref pos);

                bool isCount = ParseOptionalCount(ref pos);
                if (startsWithItem)
                {
                    return(new ItemMatchAnyElement(false, isCount, startPos,
                                                   new[] { CreateItemMatch(startPos, peekSym) }));
                }
                else
                {
                    return(new DependencyMatchAnyElement(false, isCount, startPos,
                                                         new[] { CreateDependencyMatch(startPos, peekSym) }));
                }
            }
            else if (Matches(peekSym, "."))
            {
                AdvanceSymbolPos(ref pos);
                if (startsWithItem)
                {
                    throw new RegexSyntaxException(_definition, startPos, ". cannot be used at item position");
                }
                bool isCount = ParseOptionalCount(ref pos);
                return(new DependencyMatchAnyElement(false, isCount, startPos, null));
            }
            else if (Matches(peekSym, ":"))
            {
                AdvanceSymbolPos(ref pos);
                if (!startsWithItem)
                {
                    throw new RegexSyntaxException(_definition, startPos, ": cannot be used at dependency position");
                }
                bool isCount = ParseOptionalCount(ref pos);
                return(new ItemMatchAnyElement(false, isCount, startPos, null));
            }
            else
            {
                throw new RegexSyntaxException(_definition, startPos,
                                               "Unexpected element - [, ( or " + (startsWithItem ? ":" : ".") + " expected");
            }
        }
Beispiel #5
0
 public OneOrMore(int textPos, PathRegexElement inner) : base(textPos)
 {
     Inner = inner;
 }
Beispiel #6
0
 public Optional(int textPos, PathRegexElement inner) : base(textPos)
 {
     Inner = inner;
 }