/// <summary>
		/// 使用内部正则表达式初始化 <see cref="AnchorExp"/> 类的新实例。
		/// </summary>
		/// <param name="innerExp">包含的内部正则表达式。</param>
		internal AnchorExp(Regex innerExp)
		{
			ExceptionHelper.CheckArgumentNull(innerExp, "innerExp");
			CheckRegex(innerExp);
			this.innerExp = innerExp;
			this.BeginningOfLine = false;
			this.TrailingExpression = null;
		}
		/// <summary>
		/// 使用要连接的正则表达式初始化 <see cref="ConcatenationExp"/> 类的新实例。
		/// </summary>
		/// <param name="left">要连接的第一个正则表达式。</param>
		/// <param name="right">要连接的第二个正则表达式。</param>
		internal ConcatenationExp(Regex left, Regex right)
		{
			ExceptionHelper.CheckArgumentNull(left, "left");
			ExceptionHelper.CheckArgumentNull(right, "right");
			CheckRegex(left);
			CheckRegex(right);
			this.left = left;
			this.right = right;
		}
Beispiel #3
0
		/// <summary>
		/// 使用内部正则表达式初始化 <see cref="AnchorExp"/> 类的新实例。
		/// </summary>
		/// <param name="innerExp">包含的内部正则表达式。</param>
		internal AnchorExp(Regex innerExp)
		{
			if (innerExp == null)
			{
				throw CommonExceptions.ArgumentNull("innerExp");
			}
			CheckRegex(innerExp);
			this.innerExp = innerExp;
			this.BeginningOfLine = false;
			this.TrailingExpression = null;
		}
		/// <summary>
		/// 使用要连接的正则表达式初始化 <see cref="ConcatenationExp"/> 类的新实例。
		/// </summary>
		/// <param name="left">要连接的第一个正则表达式。</param>
		/// <param name="right">要连接的第二个正则表达式。</param>
		internal ConcatenationExp(Regex left, Regex right)
		{
			if (left == null)
			{
				throw CommonExceptions.ArgumentNull("left");
			}
			if (right == null)
			{
				throw CommonExceptions.ArgumentNull("right");
			}
			CheckRegex(left);
			CheckRegex(right);
			this.left = left;
			this.right = right;
		}
Beispiel #5
0
		/// <summary>
		/// 检查正则表达式是否可以被嵌套。
		/// </summary>
		/// <param name="regex">要检查的正则表达式。</param>
		protected static void CheckRegex(Regex regex)
		{
			AnchorExp anchor = regex as AnchorExp;
			if (anchor != null)
			{
				if (anchor.BeginningOfLine)
				{
					throw CompilerCommonExceptions.NestedBeginningOfLine("regex");
				}
				if (anchor.TrailingExpression == AnchorExp.EndOfLine)
				{
					throw CompilerCommonExceptions.NestedEndOfLine("regex");
				}
				throw CompilerCommonExceptions.NestedTrailing("regex");
			}
			if (regex is EndOfFileExp)
			{
				throw CompilerCommonExceptions.NestedEndOfFile("regex");
			}
		}
		/// <summary>
		/// 使用内部正则表达式和重复次数初始化 <see cref="RepeatExp"/> 类的新实例。
		/// </summary>
		/// <param name="innerExp">包含的内部正则表达式。</param>
		/// <param name="minTimes">内部正则表达式的最少重复次数。</param>
		/// <param name="maxTimes">内部正则表达式的最多重复次数。</param>
		internal RepeatExp(Regex innerExp, int minTimes, int maxTimes)
		{
			if (minTimes < 0)
			{
				ExceptionHelper.ArgumentNegative("minTimes");
			}
			if (maxTimes < 0)
			{
				ExceptionHelper.ArgumentNegative("maxTimes");
			}
			if (minTimes > maxTimes)
			{
				ExceptionHelper.ReversedArgument("minTimes", "maxTimes");
			}
			ExceptionHelper.CheckArgumentNull(innerExp, "innerExp");
			CheckRegex(innerExp);
			this.innerExp = innerExp;
			this.minTimes = minTimes;
			this.maxTimes = maxTimes;
		}
Beispiel #7
0
		/// <summary>
		/// 使用内部正则表达式和重复次数初始化 <see cref="RepeatExp"/> 类的新实例。
		/// </summary>
		/// <param name="innerExp">包含的内部正则表达式。</param>
		/// <param name="minTimes">内部正则表达式的最少重复次数。</param>
		/// <param name="maxTimes">内部正则表达式的最多重复次数。</param>
		internal RepeatExp(Regex innerExp, int minTimes, int maxTimes)
		{
			if (minTimes < 0)
			{
				CommonExceptions.ArgumentNegative("minTimes", minTimes);
			}
			if (maxTimes < 0)
			{
				CommonExceptions.ArgumentNegative("maxTimes", maxTimes);
			}
			if (minTimes > maxTimes)
			{
				CommonExceptions.ReversedArgument("minTimes", "maxTimes");
			}
			if (innerExp == null)
			{
				throw CommonExceptions.ArgumentNull("innerExp");
			}
			CheckRegex(innerExp);
			this.innerExp = innerExp;
			this.minTimes = minTimes;
			this.maxTimes = maxTimes;
		}
Beispiel #8
0
		/// <summary>
		/// 返回表示可选的正则表达式。
		/// </summary>
		/// <param name="innerExp">可选的内部正则表达式。</param>
		/// <returns>表示可选的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示可选的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex Optional(Regex innerExp)
		{
			return new RepeatExp(innerExp, 0, 1);
		}
Beispiel #9
0
		/// <summary>
		/// 返回表示正闭包的正则表达式。
		/// </summary>
		/// <param name="innerExp">正闭包的内部正则表达式。</param>
		/// <returns>表示正闭包的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示正闭包的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex Positive(Regex innerExp)
		{
			return new RepeatExp(innerExp, 1, int.MaxValue);
		}
Beispiel #10
0
		/// <summary>
		/// 返回表示 Kleene 闭包的正则表达式。
		/// </summary>
		/// <param name="innerExp">Kleene 闭包的内部正则表达式。</param>
		/// <returns>表示 Kleene 闭包的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示 Kleene 闭包的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex Star(Regex innerExp)
		{
			return new RepeatExp(innerExp, 0, int.MaxValue);
		}
Beispiel #11
0
		/// <summary>
		/// 设置当前的正则表达式。
		/// </summary>
		/// <param name="regex">要设置的正则表达式。</param>
		private void AddRegex(Regex regex)
		{
			current = regex;
		}
Beispiel #12
0
		/// <summary>
		/// 返回表示当前正则表达式要向前看指定内容的正则表达式。
		/// </summary>
		/// <param name="regex">要向前看的正则表达式。</param>
		/// <returns>表示当前正则表达式要向前看指定内容的正则表达式。</returns>
		public Regex Trailing(Regex regex)
		{
			return Trailing(this, regex);
		}
Beispiel #13
0
		/// <summary>
		/// 返回表示两个正则表达式连接的正则表达式。
		/// </summary>
		/// <param name="left">要连接的第一个正则表达式。</param>
		/// <param name="right">要连接的第二个正则表达式。</param>
		/// <returns>表示两个正则表达式连接的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示两个正则表达式连接的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex Concat(Regex left, Regex right)
		{
			return new ConcatenationExp(left, right);
		}
Beispiel #14
0
		/// <summary>
		/// 返回表示至少重复 <paramref name="minTimes"/> 次的正则表达式。
		/// </summary>
		/// <param name="innerExp">重复的的内部正则表达式。</param>
		/// <param name="minTimes">最少的重复次数。</param>
		/// <returns>表示至少重复 <paramref name="minTimes"/> 次的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示至少重复 <paramref name="minTimes"/> 次的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex RepeatMinTimes(Regex innerExp, int minTimes)
		{
			return new RepeatExp(innerExp, minTimes, int.MaxValue);
		}
Beispiel #15
0
		/// <summary>
		/// 结束当前的正则表达式单元(找到数量词)。
		/// </summary>
		/// <param name="min">最小重复次数。</param>
		/// <param name="max">最大重复次数。</param>
		private void AddConcatenate(int min, int max)
		{
			Debug.Assert(current != null);
			concatenate.Add(current.Repeat(min, max));
			current = null;
		}
Beispiel #16
0
		/// <summary>
		/// 设置当前的正则表达式为一个单独的字符。
		/// </summary>
		/// <param name="ch">正则表达式包含的字符。</param>
		private void AddSymbol(char ch)
		{
			if (UseOptionIgnoreCase)
			{
				current = Regex.SymbolIgnoreCase(ch, culture);
			}
			else
			{
				current = Regex.Symbol(ch);
			}
		}
Beispiel #17
0
		private Regex ScanRegex()
		{
			// 是否需要读取向前看符号。
			bool readTrailing = false;
			// 非特殊的字符,标识开始。
			int ich = '@';
			// 是否是数量词。
			bool isQuantifier = false;
			while (!EndOfPattern)
			{
				bool wasPrevQuantifier = isQuantifier;
				isQuantifier = false;
				ScanBlank();
				string normalChars = ScanNormalChars();
				ScanBlank();
				if (EndOfPattern)
				{
					// 非特殊的字符,表示结束。
					ich = '!';
				}
				else if (IsSpecial(ich = reader.Peek()))
				{
					isQuantifier = IsQuantifier(ich);
					// 排除 {name} 情况。
					if (isQuantifier && ich == '{' && !IsTrueQuantifier())
					{
						isQuantifier = false;
					}
					reader.Read();
				}
				else
				{
					// 非特殊的字符,表示普通的字符。
					ich = ' ';
				}
				if (normalChars.Length > 0)
				{
					wasPrevQuantifier = false;
					// 如果之后是量词的话,量词只针对最后一个字符。
					if (isQuantifier)
					{
						if (normalChars.Length > 1)
						{
							AddLiteral(normalChars.Substring(0, normalChars.Length - 1));
						}
						AddSymbol(normalChars[normalChars.Length - 1]);
					}
					else
					{
						AddLiteral(normalChars);
					}
				}
				switch (ich)
				{
					case '!':
						goto BreakOuterScan;
					case ' ':
						goto ContinueOuterScan;
					case '[':
						AddCharClass(ScanCharClass(true).ToStringClass());
						break;
					case '(':
						PushOptions();
						if (ScanGroupOpen())
						{
							PushGroup();
						}
						else
						{
							PopKeepOptions();
						}
						continue;
					case '|':
						AddAlternate();
						goto ContinueOuterScan;
					case ')':
						if (EmptyStack)
						{
							ThrowTooManyParens();
						}
						AddGroup();
						PopGroup();
						if (current == null)
						{
							goto ContinueOuterScan;
						}
						break;
					case '\\':
						AddRegex(ScanBackslash());
						break;
					case '/':
						if (inTrailing)
						{
							ThrowNestedTrailing();
						}
						readTrailing = true;
						goto BreakOuterScan;
					case '$':
						// $ 仅在结尾表示行结尾,否则表示普通的符号。
						// 在 Trailing 中,最后的 $ 不再认为是行结束符。
						if (EndOfPattern && !inTrailing)
						{
							trailing = AnchorExp.EndOfLine;
							goto BreakOuterScan;
						}
						else
						{
							AddSymbol('$');
						}
						break;
					case '.':
						AddRegex(Regex.AnyChar(UseOptionSingleLine));
						break;
					case '{':
					case '*':
					case '+':
					case '?':
						if (current == null)
						{
							if (ich == '{')
							{
								// {regexName} 情况。
								reader.Drop();
								SourcePosition start = reader.StartPosition;
								string name = ScanCapname();
								SourcePosition end = reader.StartPosition;
								if (reader.Read() == '}')
								{
									if (!regexDefinition.TryGetValue(name, out current))
									{
										ThrowUndefinedRegex(name, start, end);
									}
									break;
								}
								else
								{
									ThrowIncompleteRegexReference();
								}
							}
							else if (wasPrevQuantifier)
							{
								ThrowNestedQuantify(((char)ich).ToString());
							}
							else
							{
								ThrowQuantifyAfterNothing();
							}
						}
						reader.Unget();
						break;
					case '"':
						// 字符串。
						string str = ScanLiteral();
						if (UseOptionIgnoreCase)
						{
							AddRegex(Regex.LiteralIgnoreCase(str, culture));
						}
						else
						{
							AddRegex(Regex.Literal(str));
						}
						break;
					default:
						Debug.Fail("内部的 ScanRegex 错误");
						break;
				}
				ScanBlank();
				if (EndOfPattern || !(isQuantifier = IsTrueQuantifier()))
				{
					AddConcatenate();
					goto ContinueOuterScan;
				}
				ScanRepeat();
			ContinueOuterScan:
				;
			}
		BreakOuterScan:
			if (!EmptyStack)
			{
				ThrowNotEnoughParens();
			}
			AddGroup();
			Regex tempRegex = current;
			current = null;
			if (readTrailing)
			{
				inTrailing = true;
				trailing = ScanRegex();
				inTrailing = false;
			}
			if (trailing != null)
			{
				tempRegex = tempRegex.Trailing(trailing);
			}
			return tempRegex;
		}
Beispiel #18
0
		/// <summary>
		/// 结束当前的组(例如 ) 或到达模式结尾)。
		/// </summary>
		private void AddGroup()
		{
			AddAlternate();
			int cnt = alternation.Count;
			if (cnt > 0)
			{
				Regex regex = alternation[0];
				for (int i = 1; i < cnt; i++)
				{
					regex = regex.Union(alternation[i]);
				}
				alternation.Clear();
				current = regex;
			}
			else
			{
				current = null;
			}
		}
Beispiel #19
0
		/// <summary>
		/// 返回表示重复多次的正则表达式。
		/// </summary>
		/// <param name="innerExp">重复的的内部正则表达式。</param>
		/// <param name="times">重复次数。</param>
		/// <returns>表示重复多次的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示重复多次的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex Repeat(Regex innerExp, int times)
		{
			return new RepeatExp(innerExp, times, times);
		}
Beispiel #20
0
		/// <summary>
		/// 返回表示行的起始位置的正则表达式。
		/// </summary>
		/// <param name="innerExp">内部的正则表达式。</param>
		/// <returns>表示行的起始位置的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示行的起始位置的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex BeginningOfLine(Regex innerExp)
		{
			AnchorExp anchorExp = innerExp as AnchorExp;
			if (anchorExp == null)
			{
				anchorExp = new AnchorExp(innerExp);
			}
			anchorExp.BeginningOfLine = true;
			return anchorExp;
		}
Beispiel #21
0
		/// <summary>
		/// 返回表示重复多次的正则表达式。
		/// </summary>
		/// <param name="innerExp">重复的的内部正则表达式。</param>
		/// <param name="minTimes">最少的重复次数。</param>
		/// <param name="maxTimes">最多的重复次数。</param>
		/// <returns>表示重复多次的正则表达式。</returns>
		public static Regex Repeat(Regex innerExp, int minTimes, int maxTimes)
		{
			return new RepeatExp(innerExp, minTimes, maxTimes);
		}
Beispiel #22
0
		/// <summary>
		/// 返回表示当前正则表达式与指定的正则表达式并联的正则表达式。
		/// </summary>
		/// <param name="right">要并联的个正则表达式。</param>
		/// <returns>表示两个正则表达式并联的正则表达式。</returns>
		public Regex Union(Regex right)
		{
			return Union(this, right);
		}
Beispiel #23
0
		/// <summary>
		/// 返回表示至多重复 <paramref name="maxTimes"/> 次的正则表达式。
		/// </summary>
		/// <param name="innerExp">重复的的内部正则表达式。</param>
		/// <param name="maxTimes">最多的重复次数。</param>
		/// <returns>表示至多重复 <paramref name="maxTimes"/> 次的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示至多重复 <paramref name="maxTimes"/> 次的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex RepeatMaxTimes(Regex innerExp, int maxTimes)
		{
			return new RepeatExp(innerExp, 0, maxTimes);
		}
Beispiel #24
0
		/// <summary>
		/// 结束当前的正则表达式单元(没有找到数量词)。
		/// </summary>
		private void AddConcatenate()
		{
			if (current != null)
			{
				concatenate.Add(current);
				current = null;
			}
		}
Beispiel #25
0
		/// <summary>
		/// 返回表示两个正则表达式并联的正则表达式。
		/// </summary>
		/// <param name="left">要并联的第一个正则表达式。</param>
		/// <param name="right">要并联的第二个正则表达式。</param>
		/// <returns>表示两个正则表达式并联的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示两个正则表达式并联的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex Union(Regex left, Regex right)
		{
			return new AlternationExp(left, right);
		}
Beispiel #26
0
		/// <summary>
		/// 返回表示向前看的正则表达式。
		/// </summary>
		/// <param name="innerExp">内部的正则表达式。</param>
		/// <param name="regex">要向前看的正则表达式。</param>
		/// <returns>表示向前看的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示向前看的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex Trailing(Regex innerExp, Regex regex)
		{
			AnchorExp anchorExp = innerExp as AnchorExp;
			if (anchorExp == null)
			{
				anchorExp = new AnchorExp(innerExp);
			}
			anchorExp.TrailingExpression = regex;
			return anchorExp;
		}
Beispiel #27
0
		/// <summary>
		/// 返回表示当前正则表达式与指定的正则表达式连接的正则表达式。
		/// </summary>
		/// <param name="right">要连接的正则表达式。</param>
		/// <returns>表示两个正则表达式连接的正则表达式。</returns>
		public Regex Concat(Regex right)
		{
			return Concat(this, right);
		}
Beispiel #28
0
		/// <summary>
		/// 设置当前的正则表达式为一个字符类。
		/// </summary>
		/// <param name="cc">正则表达式包含的字符类。</param>
		private void AddCharClass(string cc)
		{
			current = Regex.CharClass(cc);
		}
Beispiel #29
0
		/// <summary>
		/// 返回表示当前正则表达式与指定的正则表达式并联的正则表达式。
		/// </summary>
		/// <param name="right">要并联的个正则表达式。</param>
		/// <returns>表示两个正则表达式并联的正则表达式。</returns>
		public Regex BitwiseOr(Regex right)
		{
			return Union(this, right);
		}
Beispiel #30
0
		/// <summary>
		/// 返回表示行的结束位置的正则表达式。
		/// </summary>
		/// <param name="innerExp">内部的正则表达式。</param>
		/// <returns>表示行的结束位置的正则表达式。</returns>
		/// <overloads>
		/// <summary>
		/// 返回表示行的结束位置的正则表达式。
		/// </summary>
		/// </overloads>
		public static Regex EndOfLine(Regex innerExp)
		{
			return Trailing(innerExp, AnchorExp.EndOfLine);
		}