syntax.cs

来自「没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没的 没」· CS 代码 · 共 977 行 · 第 1/2 页

CS
977
字号
//// assembly:	System// namespace:	System.Text.RegularExpressions// file:	syntax.cs//// author:	Dan Lewis (dlewis@gmx.co.uk)// 		(c) 2002using System;using System.Collections;namespace System.Text.RegularExpressions.Syntax {	// collection classes		class ExpressionCollection : CollectionBase {		public void Add (Expression e) {			List.Add (e);		}		public Expression this[int i] {			get { return (Expression)List[i]; }			set { List[i] = value; }		}		protected override void OnValidate (object o) {			// allow null elements		}	}	// abstract classes		abstract class Expression {		public abstract void Compile (ICompiler cmp, bool reverse);		public abstract void GetWidth (out int min, out int max);		public int GetFixedWidth () {			int min, max;			GetWidth (out min, out max);			if (min == max)				return min;			return -1;		}		public virtual AnchorInfo GetAnchorInfo () {			return new AnchorInfo (this, GetFixedWidth ());		}		public virtual bool IsComplex () {			return true;		}	}	// composite expressions		abstract class CompositeExpression : Expression {		public CompositeExpression () {			expressions = new ExpressionCollection ();		}		protected ExpressionCollection Expressions {			get { return expressions; }		}		protected void GetWidth (out int min, out int max, int count) {			min = Int32.MaxValue;			max = 0;			bool empty = true;			for (int i = 0; i < count; ++ i) {				Expression e = Expressions[i];				if (e == null)					continue;							empty = false;				int a, b;				e.GetWidth (out a, out b);				if (a < min) min = a;				if (b > max) max = b;			}			if (empty)				min = max = 0;		}		private ExpressionCollection expressions;	}	// groups		class Group : CompositeExpression {		public Group () {		}		public Expression Expression {			get { return Expressions[0]; }			set { Expressions[0] = value; }		}		public void AppendExpression (Expression e) {			Expressions.Add (e);		}		public override void Compile (ICompiler cmp, bool reverse) {			int count = Expressions.Count;			for (int i = 0; i < count; ++ i) {				Expression e;				if (reverse)					e = Expressions[count - i - 1];				else					e = Expressions[i];				e.Compile (cmp, reverse);			}		}		public override void GetWidth (out int min, out int max) {			min = 0;			max = 0;			foreach (Expression e in Expressions) {				int a, b;				e.GetWidth (out a, out b);				min += a;				if (max == Int32.MaxValue || b == Int32.MaxValue)					max = Int32.MaxValue;				else					max += b;			}		}		public override AnchorInfo GetAnchorInfo () {			int ptr;			int width = GetFixedWidth ();			ArrayList infos = new ArrayList ();			IntervalCollection segments = new IntervalCollection ();			// accumulate segments			ptr = 0;			foreach (Expression e in Expressions) {				AnchorInfo info = e.GetAnchorInfo ();				infos.Add (info);				if (info.IsPosition)					return new AnchorInfo (this, ptr + info.Offset, width, info.Position);				if (info.IsSubstring)					segments.Add (info.GetInterval (ptr));				if (info.IsUnknownWidth)					break;				ptr += info.Width;			}			// normalize and find the longest segment			segments.Normalize ();			Interval longest = Interval.Empty;			foreach (Interval segment in segments) {				if (segment.Size > longest.Size)					longest = segment;			}			// now chain the substrings that made this segment together			if (!longest.IsEmpty) {				string str = "";				bool ignore = false;				ptr = 0;				foreach (AnchorInfo info in infos) {					if (info.IsSubstring && longest.Contains (info.GetInterval (ptr))) {						str += info.Substring;	// TODO mark subexpressions						ignore |= info.IgnoreCase;					}					if (info.IsUnknownWidth)						break;					ptr += info.Width;				}				return new AnchorInfo (this, longest.low, width, str, ignore);			}			return new AnchorInfo (this, width);		}		public override bool IsComplex () {			bool comp = false;			foreach (Expression e in Expressions) {				comp |= e.IsComplex ();			}			return comp | GetFixedWidth () <= 0;		}	}	class RegularExpression : Group {		public RegularExpression () {			group_count = 0;		}		public int GroupCount {			get { return group_count; }			set { group_count = value; }		}		public override void Compile (ICompiler cmp, bool reverse) {			// info block			int min, max;			GetWidth (out min, out max);			cmp.EmitInfo (group_count, min, max);			// anchoring expression			AnchorInfo info = GetAnchorInfo ();			if (reverse)				info = new AnchorInfo (this, GetFixedWidth ());	// FIXME			LinkRef pattern = cmp.NewLink ();			cmp.EmitAnchor (info.Offset, pattern);			if (info.IsPosition)				cmp.EmitPosition (info.Position);			else if (info.IsSubstring)				cmp.EmitString (info.Substring, info.IgnoreCase, reverse);						cmp.EmitTrue ();						// pattern			cmp.ResolveLink (pattern);			base.Compile (cmp, reverse);			cmp.EmitTrue ();		}		private int group_count;	}	class CapturingGroup : Group {		public CapturingGroup () {			this.gid = 0;			this.name = null;		}		public int Number {			get { return gid; }			set { gid = value; }		}		public string Name {			get { return name; }			set { name = value; }		}		public bool IsNamed {			get { return name != null; }		}		public override void Compile (ICompiler cmp, bool reverse) {			cmp.EmitOpen (gid);			base.Compile (cmp, reverse);			cmp.EmitClose (gid);		}		public override bool IsComplex () {			return true;		}		private int gid;		private string name;	}	class BalancingGroup : CapturingGroup {		public BalancingGroup () {			this.balance = null;		}		public CapturingGroup Balance {			get { return balance; }			set { balance = value; }		}		public override void Compile (ICompiler cmp, bool reverse) {			// can't invoke Group.Compile from here :(			// so I'll just repeat the code					int count = Expressions.Count;			for (int i = 0; i < count; ++ i) {				Expression e;				if (reverse)					e = Expressions[count - i - 1];				else					e = Expressions[i];				e.Compile (cmp, reverse);			}			cmp.EmitBalance (this.Number, balance.Number);		}		private CapturingGroup balance;	}	class NonBacktrackingGroup : Group {		public NonBacktrackingGroup () {		}		public override void Compile (ICompiler cmp, bool reverse) {			LinkRef tail = cmp.NewLink ();			cmp.EmitSub (tail);			base.Compile (cmp, reverse);			cmp.EmitTrue ();			cmp.ResolveLink (tail);		}		public override bool IsComplex () {			return true;		}	}	// repetition	class Repetition : CompositeExpression {		public Repetition (int min, int max, bool lazy) {			Expressions.Add (null);						this.min = min;			this.max = max;			this.lazy = lazy;		}		public Expression Expression {			get { return Expressions[0]; }			set { Expressions[0] = value; }		}		public int Minimum {			get { return min; }			set { min = value; }		}		public int Maximum {			get { return max; }			set { max = value; }		}		public bool Lazy {			get { return lazy; }			set { lazy = value; }		}		public override void Compile (ICompiler cmp, bool reverse) {			if (Expression.IsComplex ()) {				LinkRef until = cmp.NewLink ();								cmp.EmitRepeat (min, max, lazy, until);				Expression.Compile (cmp, reverse);				cmp.EmitUntil (until);			}			else {				LinkRef tail = cmp.NewLink ();				cmp.EmitFastRepeat (min, max, lazy, tail);				Expression.Compile (cmp, reverse);				cmp.EmitTrue ();				cmp.ResolveLink (tail);			}		}		public override void GetWidth (out int min, out int max) {			Expression.GetWidth (out min, out max);			min = min * this.min;			if (max == Int32.MaxValue || this.max == 0xffff)				max = Int32.MaxValue;			else				max = max * this.max;		}		public override AnchorInfo GetAnchorInfo () {			int width = GetFixedWidth ();			if (Minimum == 0)				return new AnchorInfo (this, width);						AnchorInfo info = Expression.GetAnchorInfo ();			if (info.IsPosition)				return new AnchorInfo (this, info.Offset, width, info.Position);						if (info.IsSubstring) {				if (info.IsComplete) {					string str = "";					for (int i = 0; i < Minimum; ++ i)						str += info.Substring;					return new AnchorInfo (this, 0, width, str, info.IgnoreCase);				}				return new AnchorInfo (this, info.Offset, width, info.Substring, info.IgnoreCase);			}			return new AnchorInfo (this, width);		}		private int min, max;		private bool lazy;	}	// assertions	abstract class Assertion : CompositeExpression {		public Assertion () {			Expressions.Add (null);		// true expression			Expressions.Add (null);		// false expression		}		public Expression TrueExpression {			get { return Expressions[0]; }			set { Expressions[0] = value; }		}		public Expression FalseExpression {			get { return Expressions[1]; }			set { Expressions[1] = value; }		}		public override void GetWidth (out int min, out int max) {			GetWidth (out min, out max, 2);			if (TrueExpression == null || FalseExpression == null)				min = 0;		}	}	class CaptureAssertion : Assertion {		public CaptureAssertion () {		}		public CapturingGroup CapturingGroup {			get { return group; }			set { group = value; }		}		public override void Compile (ICompiler cmp, bool reverse) {			int gid = group.Number;			LinkRef tail = cmp.NewLink ();			if (FalseExpression == null) {				//    IfDefined :1				//      <yes_exp>				// 1: <tail>							cmp.EmitIfDefined (gid, tail);				TrueExpression.Compile (cmp, reverse);			}			else {				//    IfDefined :1				//      <yes_expr>				//      Jump :2				// 1:   <no_expr>				// 2: <tail>							LinkRef false_expr = cmp.NewLink ();				cmp.EmitIfDefined (gid, false_expr);				TrueExpression.Compile (cmp, reverse);				cmp.EmitJump (tail);				cmp.ResolveLink (false_expr);				FalseExpression.Compile (cmp, reverse);			}			cmp.ResolveLink (tail);		}		public override bool IsComplex () {			bool comp = false;			if (TrueExpression != null)				comp |= TrueExpression.IsComplex ();			if (FalseExpression != null)				comp |= FalseExpression.IsComplex ();			return comp | GetFixedWidth () <= 0;		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?