コード例 #1
0
ファイル: Parser.cs プロジェクト: PimRheiter/regex-parser
        /// <summary>
        /// Remove a group from the top of the group stack and create a GroupNode from it in response to a closing ')'.
        /// </summary>
        private void CloseGroup()
        {
            if (_groupStack.Count == 0)
            {
                throw MakeException(RegexParseError.TooManyParentheses);
            }

            RegexNode outerNode        = CreateOuterNode();
            GroupUnit currentGroup     = _groupStack.Pop();
            var       currentGroupNode = currentGroup.Node.AddNode(outerNode);

            _group = _groupStack.FirstOrDefault();


            // The first group "(...)" inside a conditional group goes directly to the condition group as it's condition.
            // TODO: "(...)" should be a reference node "(1)" without "\" or a named reference "(name)" without "?<>" if this is the name of a named group or a lookahead without "?=" otherwise.
            if (_group?.Node is ConditionalGroupNode && !_group.Node.ChildNodes.Any())
            {
                _group.Node = _group.Node.AddNode(currentGroupNode);
                return;
            }

            // No more than two alternates allowed in a conditional group
            if (_group?.Node is ConditionalGroupNode &&
                outerNode is AlternationNode &&
                outerNode.ChildNodes.Count() > MaxAlternatesInConditionalGroup)
            {
                throw MakeException(RegexParseError.TooManyAlternates);
            }

            AddNode(currentGroupNode);
        }
コード例 #2
0
ファイル: Parser.cs プロジェクト: PimRheiter/regex-parser
        /// <summary>
        /// Sets a new GroupUnit with a ModeModifierGroupNode as the current group
        /// </summary>
        private void StartModeModifierGroup()
        {
            string options = ScanOptions();

            // Invalid grouping construct
            if (string.IsNullOrEmpty(options))
            {
                throw MakeException(RegexParseError.UnrecognizedGroupingConstruct);
            }

            // Mode modifier group "(?imnsx-imnsx)" or "(?imnsx-imnsx:...)"
            _group = new GroupUnit(new ModeModifierGroupNode(options));
        }
コード例 #3
0
ファイル: Parser.cs プロジェクト: PimRheiter/regex-parser
        private void StartNamedOrLookbehindGroup()
        {
            if (CharsRight() > 0)
            {
                char ch = RightChar();

                // Possitive lookbehind "(?<=...)" or negative lookbehind "(?<!...)"
                if (ch == '=' || ch == '!')
                {
                    // Consume both the '<' and the '=' or '!' characters.
                    MoveRight();
                    _group = new GroupUnit(new LookaroundGroupNode(false, ch == '='));
                    return;
                }
            }

            // Named capturing group "(?<name>...)" or balancing group "(?<name-balancedGroupName>...)"
            _group = new GroupUnit(CreateNamedGroup('>'));
        }
コード例 #4
0
ファイル: Parser.cs プロジェクト: PimRheiter/regex-parser
        /// <summary>
        /// Adds a new GroupUnit to the group stack and sets it as the current group in response to an opening '('.
        /// </summary>
        private void StartGroup()
        {
            // Regular capturing group "(...)"
            if (IsCaptureGroup())
            {
                _group = new GroupUnit(new CaptureGroupNode());
            }

            // "(?...)" is a special group.
            else
            {
                MoveRight();
                char ch = RightCharMoveRight();

                switch (ch)
                {
                // Noncapturing group "(?:...)"
                case ':':
                    _group = new GroupUnit(new NonCaptureGroupNode());
                    break;

                // Atomic group "(?>...)"
                case '>':
                    _group = new GroupUnit(new AtomicGroupNode());
                    break;

                // Conditional group (?(condition)then|else)
                case '(':
                    MoveLeft();
                    _group = new GroupUnit(new ConditionalGroupNode());
                    break;

                // Possitive lookahead "(?=...)" or negative lookahead "(?!...)"
                case '=':
                case '!':
                    _group = new GroupUnit(new LookaroundGroupNode(true, ch == '='));
                    break;

                // Named capturing group "(?'name'...)" or balancing group "(?'name-balancedGroupName'...)"
                case '\'':
                    _group = new GroupUnit(CreateNamedGroup(ch));
                    break;


                // Named capturing group "(?<name>...)" or possitive lookbehind "(?<=...)" or negative lookbehind "(?<!...)"
                case '<':
                    StartNamedOrLookbehindGroup();
                    break;

                // Comment group "(?#...)" is not added to the group stack. It will be the prefix for the next node instead.
                case '#':
                    string comment = ScanComment();
                    _prefix = new CommentGroupNode(comment)
                    {
                        Prefix = _prefix
                    };
                    // Return here, so nothing gets pushed to the group stack.
                    return;

                // Could be inline mode modifier group "(?imnsx-imnsx)" or "(?imnsx-imnsx:...)". Invalid grouping construct otherwise.
                default:
                    MoveLeft();
                    StartModeModifierGroup();
                    break;
                }
            }
            _groupStack.Push(_group);
        }