Exemplo n.º 1
0
		private Expression ParseGroupingConstruct (ref RegexOptions options) {
			if (pattern[ptr] != '?') {
				Group group;

				if (IsExplicitCapture (options))
					group = new Group ();
				else {
					group = new CapturingGroup ();
					caps.Add (group);
				}

				ParseGroup (group, options, null);
				return group;
			}
			else
				++ ptr;

			switch (pattern[ptr]) {
			case ':': {						// non-capturing group
				++ ptr;
				Group group = new Group ();
				ParseGroup (group, options, null);

				return group;
			}

			case '>': {						// non-backtracking group
				++ ptr;
				Group group = new NonBacktrackingGroup ();
				ParseGroup (group, options, null);
				
				return group;
			}

			case 'i': case 'm': case 'n':
			case 's': case 'x': case '-': {				// options
				RegexOptions o = options;
				ParseOptions (ref o, false);
				if (pattern[ptr] == '-') {
					++ ptr;
					ParseOptions (ref o, true);
				}

				if (pattern[ptr] == ':') {			// pass options to child group
					++ ptr;
					Group group = new Group ();
					ParseGroup (group, o, null);
					return group;
				}
				else if (pattern[ptr] == ')') {			// change options of enclosing group
					++ ptr;
					options = o;
					return null;
				}
				else
					throw NewParseException ("Bad options");
			}

			case '<': case '=': case '!': {				// lookahead/lookbehind
				ExpressionAssertion asn = new ExpressionAssertion ();
				if (!ParseAssertionType (asn))
					goto case '\'';				// it's a (?<name> ) construct

				Group test = new Group ();
				ParseGroup (test, options, null);

				asn.TestExpression = test;
				return asn;
			}

			case '\'': {						// named/balancing group
				char delim;
				if (pattern[ptr] == '<')
					delim = '>';
				else
					delim = '\'';

				++ ptr;
				string name = ParseName ();

				if (pattern[ptr] == delim) {
					// capturing group

					if (name == null)
						throw NewParseException ("Bad group name.");

					++ ptr;
					CapturingGroup cap = new CapturingGroup ();
					cap.Name = name;
					caps.Add (cap);
					ParseGroup (cap, options, null);

					return cap;
				}
				else if (pattern[ptr] == '-') {
					// balancing group

					++ ptr;
					string balance_name = ParseName ();
					if (balance_name == null || pattern[ptr] != delim)
						throw NewParseException ("Bad balancing group name.");

					++ ptr;
					BalancingGroup bal = new BalancingGroup ();
					bal.Name = name;
					
					if(bal.IsNamed) {
						caps.Add (bal);
					}

					refs.Add (bal, balance_name);

					ParseGroup (bal, options, null);

					return bal;
				}
				else
					throw NewParseException ("Bad group name.");
			}

			case '(': {						// expression/capture test
				Assertion asn;
			
				++ ptr;
				int p = ptr;
				string name = ParseName ();
				if (name == null || pattern[ptr] != ')') {	// expression test
					// FIXME MS implementation doesn't seem to
					// implement this version of (?(x) ...)

					ptr = p;
					ExpressionAssertion expr_asn = new ExpressionAssertion ();

					if (pattern[ptr] == '?') {
						++ ptr;
						if (!ParseAssertionType (expr_asn))
							throw NewParseException ("Bad conditional.");
					}
					else {
						expr_asn.Negate = false;
						expr_asn.Reverse = false;
					}

					Group test = new Group ();
					ParseGroup (test, options, null);
					expr_asn.TestExpression = test;
					asn = expr_asn;
				}
				else {						// capture test
					++ ptr;
					asn = new CaptureAssertion (new Literal (name, IsIgnoreCase (options)));
					refs.Add (asn, name);
				}

				Group group = new Group ();
				ParseGroup (group, options, asn);
				return group;
			}

			case '#': {						// comment
				++ ptr;
				while (pattern[ptr ++] != ')') {
					if (ptr >= pattern.Length)
						throw NewParseException ("Unterminated (?#...) comment.");
				}
				return null;
			}

			default: 						// error
				throw NewParseException ("Bad grouping construct.");
			}
		}
Exemplo n.º 2
0
        private Expression ParseGroupingConstruct(ref RegexOptions options)
        {
            if (pattern[ptr] != '?')
            {
                Group group;

                if (IsExplicitCapture(options))
                {
                    group = new Group();
                }
                else
                {
                    group = new CapturingGroup();
                    caps.Add(group);
                }

                ParseGroup(group, options, null);
                return(group);
            }
            else
            {
                ++ptr;
            }

            switch (pattern[ptr])
            {
            case ':': {                                                         // non-capturing group
                ++ptr;
                Group group = new Group();
                ParseGroup(group, options, null);

                return(group);
            }

            case '>': {                                                         // non-backtracking group
                ++ptr;
                Group group = new NonBacktrackingGroup();
                ParseGroup(group, options, null);

                return(group);
            }

            case 'i':
            case 'm':
            case 'n':
            case 's':
            case 'x':
            case '-': {                                                         // options
                RegexOptions o = options;
                ParseOptions(ref o, false);
                if (pattern[ptr] == '-')
                {
                    ++ptr;
                    ParseOptions(ref o, true);
                }

                if (pattern[ptr] == ':')                                        // pass options to child group
                {
                    ++ptr;
                    Group group = new Group();
                    ParseGroup(group, o, null);
                    return(group);
                }
                else if (pattern[ptr] == ')')                                   // change options of enclosing group
                {
                    ++ptr;
                    options = o;
                    return(null);
                }
                else
                {
                    throw NewParseException("Bad options");
                }
            }

            case '<':
            case '=':
            case '!': {                                                         // lookahead/lookbehind
                ExpressionAssertion asn = new ExpressionAssertion();
                if (!ParseAssertionType(asn))
                {
                    goto case '\'';                                             // it's a (?<name> ) construct
                }
                Group test = new Group();
                ParseGroup(test, options, null);

                asn.TestExpression = test;
                return(asn);
            }

            case '\'': {                                                        // named/balancing group
                char delim;
                if (pattern[ptr] == '<')
                {
                    delim = '>';
                }
                else
                {
                    delim = '\'';
                }

                ++ptr;
                string name = ParseName();

                if (pattern[ptr] == delim)
                {
                    // capturing group

                    if (name == null)
                    {
                        throw NewParseException("Bad group name.");
                    }

                    ++ptr;
                    CapturingGroup cap = new CapturingGroup();
                    cap.Name = name;
                    caps.Add(cap);
                    ParseGroup(cap, options, null);

                    return(cap);
                }
                else if (pattern[ptr] == '-')
                {
                    // balancing group

                    ++ptr;
                    string balance_name = ParseName();
                    if (balance_name == null || pattern[ptr] != delim)
                    {
                        throw NewParseException("Bad balancing group name.");
                    }

                    ++ptr;
                    BalancingGroup bal = new BalancingGroup();
                    bal.Name = name;

                    if (bal.IsNamed)
                    {
                        caps.Add(bal);
                    }

                    refs.Add(bal, balance_name);

                    ParseGroup(bal, options, null);

                    return(bal);
                }
                else
                {
                    throw NewParseException("Bad group name.");
                }
            }

            case '(': {                                                         // expression/capture test
                Assertion asn;

                ++ptr;
                int    p    = ptr;
                string name = ParseName();
                if (name == null || pattern[ptr] != ')')                        // expression test
                // FIXME MS implementation doesn't seem to
                // implement this version of (?(x) ...)

                {
                    ptr = p;
                    ExpressionAssertion expr_asn = new ExpressionAssertion();

                    if (pattern[ptr] == '?')
                    {
                        ++ptr;
                        if (!ParseAssertionType(expr_asn))
                        {
                            throw NewParseException("Bad conditional.");
                        }
                    }
                    else
                    {
                        expr_asn.Negate  = false;
                        expr_asn.Reverse = false;
                    }

                    Group test = new Group();
                    ParseGroup(test, options, null);
                    expr_asn.TestExpression = test;
                    asn = expr_asn;
                }
                else                                                            // capture test
                {
                    ++ptr;
                    asn = new CaptureAssertion(new Literal(name, IsIgnoreCase(options)));
                    refs.Add(asn, name);
                }

                Group group = new Group();
                ParseGroup(group, options, asn);
                return(group);
            }

            case '#': {                                                         // comment
                ++ptr;
                while (pattern[ptr++] != ')')
                {
                    if (ptr >= pattern.Length)
                    {
                        throw NewParseException("Unterminated (?#...) comment.");
                    }
                }
                return(null);
            }

            default:                                                            // error
                throw NewParseException("Bad grouping construct.");
            }
        }
Exemplo n.º 3
0
        private Expression ParseGroupingConstruct(ref RegexOptions options)
        {
            if (pattern[ptr] != '?')
            {
                Group group;
                if (IsExplicitCapture(options))
                {
                    group = new Group();
                }
                else
                {
                    group = new CapturingGroup();
                    caps.Add(group);
                }
                ParseGroup(group, options, null);
                return(group);
            }
            ptr++;
            switch (pattern[ptr])
            {
            case ':':
            {
                ptr++;
                Group group6 = new Group();
                ParseGroup(group6, options, null);
                return(group6);
            }

            case '>':
            {
                ptr++;
                Group group2 = new NonBacktrackingGroup();
                ParseGroup(group2, options, null);
                return(group2);
            }

            case '-':
            case 'i':
            case 'm':
            case 'n':
            case 's':
            case 'x':
            {
                RegexOptions options2 = options;
                ParseOptions(ref options2, negate: false);
                if (pattern[ptr] == '-')
                {
                    ptr++;
                    ParseOptions(ref options2, negate: true);
                }
                if (pattern[ptr] == ':')
                {
                    ptr++;
                    Group group3 = new Group();
                    ParseGroup(group3, options2, null);
                    return(group3);
                }
                if (pattern[ptr] == ')')
                {
                    ptr++;
                    options = options2;
                    return(null);
                }
                throw NewParseException("Bad options");
            }

            case '!':
            case '<':
            case '=':
            {
                ExpressionAssertion expressionAssertion2 = new ExpressionAssertion();
                if (!ParseAssertionType(expressionAssertion2))
                {
                    goto case '\'';
                }
                Group group7 = new Group();
                ParseGroup(group7, options, null);
                expressionAssertion2.TestExpression = group7;
                return(expressionAssertion2);
            }

            case '\'':
            {
                char c = (pattern[ptr] != '<') ? '\'' : '>';
                ptr++;
                string text2 = ParseName();
                if (pattern[ptr] == c)
                {
                    if (text2 == null)
                    {
                        throw NewParseException("Bad group name.");
                    }
                    ptr++;
                    CapturingGroup capturingGroup = new CapturingGroup();
                    capturingGroup.Name = text2;
                    caps.Add(capturingGroup);
                    ParseGroup(capturingGroup, options, null);
                    return(capturingGroup);
                }
                if (pattern[ptr] == '-')
                {
                    ptr++;
                    string text3 = ParseName();
                    if (text3 == null || pattern[ptr] != c)
                    {
                        throw NewParseException("Bad balancing group name.");
                    }
                    ptr++;
                    BalancingGroup balancingGroup = new BalancingGroup();
                    balancingGroup.Name = text2;
                    if (balancingGroup.IsNamed)
                    {
                        caps.Add(balancingGroup);
                    }
                    refs.Add(balancingGroup, text3);
                    ParseGroup(balancingGroup, options, null);
                    return(balancingGroup);
                }
                throw NewParseException("Bad group name.");
            }

            case '(':
            {
                ptr++;
                int       num  = ptr;
                string    text = ParseName();
                Assertion assertion;
                if (text == null || pattern[ptr] != ')')
                {
                    ptr = num;
                    ExpressionAssertion expressionAssertion = new ExpressionAssertion();
                    if (pattern[ptr] == '?')
                    {
                        ptr++;
                        if (!ParseAssertionType(expressionAssertion))
                        {
                            throw NewParseException("Bad conditional.");
                        }
                    }
                    else
                    {
                        expressionAssertion.Negate  = false;
                        expressionAssertion.Reverse = false;
                    }
                    Group group4 = new Group();
                    ParseGroup(group4, options, null);
                    expressionAssertion.TestExpression = group4;
                    assertion = expressionAssertion;
                }
                else
                {
                    ptr++;
                    assertion = new CaptureAssertion(new Literal(text, IsIgnoreCase(options)));
                    refs.Add(assertion, text);
                }
                Group group5 = new Group();
                ParseGroup(group5, options, assertion);
                return(group5);
            }

            case '#':
                ptr++;
                while (pattern[ptr++] != ')')
                {
                    if (ptr >= pattern.Length)
                    {
                        throw NewParseException("Unterminated (?#...) comment.");
                    }
                }
                return(null);

            default:
                throw NewParseException("Bad grouping construct.");
            }
        }