private string CharRangeToString(CharRange c) { var textrange = new PInvoke.TextRange { chrg = c }; if (c.cpMax - c.cpMin <= 0) { return(string.Empty); } int characters = (c.cpMax - c.cpMin) + 1; // +1 for null termination var charBuffer = CharBuffer.CreateBuffer(characters); IntPtr unmanagedBuffer = charBuffer.AllocCoTaskMem(); if (unmanagedBuffer == IntPtr.Zero) { throw new OutOfMemoryException(); } textrange.lpstrText = unmanagedBuffer; NativeMethods.SendMessage(Handle, RichEditMessages.EM_GETTEXTRANGE, IntPtr.Zero, ref textrange); charBuffer.PutCoTaskMem(unmanagedBuffer); if (textrange.lpstrText != IntPtr.Zero) { Marshal.FreeCoTaskMem(unmanagedBuffer); } return(charBuffer.GetString()); }
public void Test() { //make pattern for whole numbers divisible by 3 //digits mod 3 var d0 = CharRange.AnyOf("0369"); var d1 = Pattern.Match(CharRange.AnyOf("147")).ThenMaybeRepeat(d0); var d2 = Pattern.Match(CharRange.AnyOf("258")).ThenMaybeRepeat(d0); var plus2 = Pattern.MaybeRepeat(d1.Then(d2)).Then(Pattern.AnyOf(d1.Then(d1), d2)); var minus2 = Pattern.MaybeRepeat(d2.Then(d1)).Then(Pattern.AnyOf(d2.Then(d2), d1)); var by3 = Pattern.MaybeRepeat(Pattern.AnyOf(d0, d1.Then(d2), plus2.Then(minus2))); var builder = new DfaBuilder <bool>(); builder.AddPattern(by3, true); var start = builder.Build(new HashSet <bool> { true }, null); Assert.Equal(3, CountStates(start)); CheckDfa(start, "By3Test.out.txt", false); }
public void SubsetConstruction_Label() { var nfaGraphBuilder = new Graph.Builder(); var lead = new CharRange[] { new CharRange('A', 'Z'), new CharRange('a', 'z') }; var tail = new CharRange[] { new CharRange('A', 'Z'), new CharRange('a', 'z'), new CharRange('0', '9'), new CharRange('_', '_') }; NFAHelper.Graph( nfaGraphBuilder, NFAHelper.Series( nfaGraphBuilder, NFAHelper.CreateSimplePath(nfaGraphBuilder, CharSet.New(lead)), NFAHelper.Optional( nfaGraphBuilder, NFAHelper.Repeat( nfaGraphBuilder, NFAHelper.CreateSimplePath(nfaGraphBuilder, CharSet.New(tail)))))); var dfaGraph = FATools.CreateDfa(nfaGraphBuilder.Graph); const string expected = "0 (S:S0) -- [A-Z,a-z] --> 1 (L:E0)\r\n" + "1 (L:E0) -- [0-9,A-Z,_,a-z] --> 1 (L:E0)\r\n" + ""; Assert.That(FARenderer.Render(dfaGraph), Is.EqualTo(expected)); }
// select the sentence that contains the current error private CharRange GetSentence(string text, CharRange err) { // find sentence start int start = -1; for (int i = err.Start; i > 0 && start < 0; i--) { switch (text[i]) { case '.': case '!': case '?': case '\n': case '\r': for (int j = i; j < err.Start; j++) { if (char.IsLetterOrDigit(text[j])) { start = j; break; } } break; } } if (start < 0) { start = 0; } // find sentence end int end = -1; for (int i = err.Start; i < text.Length && end < 0; i++) { switch (text[i]) { case '.': case '!': case '?': end = i; break; case '\n': case '\r': end = i - 1; break; } } if (end < 0) { end = text.Length - 1; } // done, return result string sentence = text.Substring(start, end - start + 1); return(new CharRange(sentence, start, false)); }
// STATIC CONSTRUCTOR static DMMLoader() { // A-Za-z0-9_/ ATOM_NAME_CHARS = CharRange.Build('A', 'Z') | CharRange.Build('a', 'z') | CharRange.Build('0', '9') | "_/"; WHITESPACE = new ConstCharMatcher("\r\n"); REGEX_FLOAT = new Regex(@"^[0-9\.]+([Ee][\+\-][0-9]+)?$"); REGEX_INTEGER = new Regex(@"^\d+$"); }
public static NFA Char(CharRange c) { NFA nfa = new NFA(); nfa.Start = new State(); nfa.Exit = new State() { IsFinal = true }; nfa.Start.AddTransition(c, nfa.Exit); return nfa; }
static void Render(StringBuilder builder, CharRange range) { builder.Append("new CharRange('"); AppendEscapedChar(builder, range.From); builder.Append("', '"); AppendEscapedChar(builder, range.To); builder.Append("')"); }
public void Contains_Case1(char start, char end, char checkTarget, bool result) { // Arrange var r = CharRange.Between(start, end); // Act // Assert Assert.That(r.Contains(checkTarget), Is.EqualTo(result)); }
public void Node_should_return_appropriate_node_associated_with_partition() { IEnumerable <string> nodes = new CharRange('A', 'C').ToStrings(); var ch = new PartitionedConsistentHash(nodes, 32); string node = ch.Node("foo"); node.Should().Be("B"); }
public void Intersects() { var bc = new CharRange[] { new CharRange('B', 'C') }; var cd = new CharRange[] { new CharRange('C', 'D') }; var de = new CharRange[] { new CharRange('D', 'E') }; Assert.That(CharSet.New(bc).Intersects(CharSet.New(bc)), Is.EqualTo(true)); Assert.That(CharSet.New(bc).Intersects(CharSet.New(cd)), Is.EqualTo(true)); Assert.That(CharSet.New(bc).Intersects(CharSet.New(de)), Is.EqualTo(false)); }
// update suggestion list with current content private void _btnSuggest_Click(object sender, EventArgs e) { _listSuggestions.Items.Clear(); CharRange replacement = GetReplacement(); if (replacement != null && replacement.Text.Length > 0) { ShowSuggestions(replacement.Text); } _btnSuggest.Enabled = false; }
public void Contains_Case2(char range0Start, char range0End, char range1Start, char range1End, char checkTarget, bool result) { // Arrange var range0 = CharRange.Between(range0Start, range0End); var range1 = CharRange.Between(range1Start, range1End); var clazz = new CharRangeCharClass(range0, range1); // Act // Assert Assert.That(clazz.Contains(checkTarget), Is.EqualTo(result)); Assert.That(clazz.Contains(checkTarget), Is.EqualTo(result)); }
public static bool AllChars(this string s, int from, int to, CharRange charRange) { for (int i = from; i <= to; i++) { if (!s[i].IsOneOf(CharRanges[charRange])) { return(false); } } return(true); }
public void PreferenceList() { IEnumerable <string> nodes = new CharRange('A', 'J').ToStrings(); var ch = new PartitionedConsistentHash(nodes, 32); string node = ch.Node("foo"); node.Should().Be("B"); var preferenceList = ch.PreferenceList("foo", 3); // belongs to node A preferenceList.Should().BeEquivalentTo(new[] { "B", "C", "D" }); }
public void Between_Case1(char start, char end) { // Arrange var less = start <= end ? start : end; var greater = start <= end ? end : start; // Act var r = CharRange.Between(start, end); // Assert Assert.That(r.Start, Is.EqualTo(less)); Assert.That(r.End, Is.EqualTo(greater)); }
public void Plus_Case2(char range0Start, char range0End, char range1Start, char range1End, char checkTarget) { // Arrange var range0 = CharRange.Between(range0Start, range0End); var range1 = CharRange.Between(range1Start, range1End); var clazz0 = new CharRangeCharClass(range0); // Act var clazz1 = clazz0.Plus(checkTarget); // Assert Assert.That(clazz1.Contains(checkTarget), Is.True); }
public void IsSuperSetOf() { var abcd = new CharRange[] { new CharRange('A', 'D') }; var abc = new CharRange[] { new CharRange('A', 'C') }; var bc = new CharRange[] { new CharRange('B', 'C') }; var cd = new CharRange[] { new CharRange('C', 'D') }; var de = new CharRange[] { new CharRange('D', 'E') }; Assert.That(CharSet.New(abc).IsSupersetOf(CharSet.New(abcd)), Is.EqualTo(false)); Assert.That(CharSet.New(abc).IsSupersetOf(CharSet.New(abc)), Is.EqualTo(true)); Assert.That(CharSet.New(abc).IsSupersetOf(CharSet.New(bc)), Is.EqualTo(true)); Assert.That(CharSet.New(abc).IsSupersetOf(CharSet.New(cd)), Is.EqualTo(false)); Assert.That(CharSet.New(abc).IsSupersetOf(CharSet.New(de)), Is.EqualTo(false)); }
public void Or_Case1(char range0Start, char range0End, char range1Start, char range1End, char checkTarget, bool result) { // Arrange var range0 = CharRange.Between(range0Start, range0End); var range1 = CharRange.Between(range1Start, range1End); var clazz0 = new CharRangeCharClass(range0); // Act var clazz1 = clazz0.Union(new CharRangeCharClass(range1)); // Assert Assert.That(clazz1.Contains(checkTarget), Is.EqualTo(result)); Assert.That(clazz1.Contains(checkTarget), Is.EqualTo(result)); }
public void TestThatSimpleRangeWithoutRightLimitFailed() { // Arrange var startSymbol = 'c'; var range = new CharRange(startSymbol, null); // Act var isContained = range.Contains((char)(startSymbol - 1)); // Assert Assert.IsFalse(isContained); }
public void TestThatSimpleRangeWithutLeftLimitFailed() { // Arrange var endSymbol = 'c'; var range = new CharRange(null, endSymbol); // Act var isContained = range.Contains((char)(endSymbol + 1)); // Assert Assert.IsFalse(isContained); }
int ISpellCheckableRichEditor.GetBaselineOffset(CharRange error) { LINERECT lr = new LINERECT(); lr.lineIndex = SendMessage(TX_LINEFROMCHAR, 0, error.Start) - 1; if (lr.lineIndex > -1) { SendMessage(this.Handle, TX_GETLINERECT, 0, ref lr); return((int)(lr.lineRect.height / 1440f * Dpi.Y * (this.ZoomFactor / 100f) - 2)); } else { return(this.Font.Height - 2); } }
public void TestThatSimpleRangeWorkSuccess() { // Arrange var startSymbol = 'a'; var endSymbol = 'c'; var range = new CharRange(startSymbol, endSymbol); // Act var isContained = range.Contains('b'); // Assert Assert.IsTrue(isContained); }
public void TestThatSimpleRangeFailed() { // Arrange var startSymbol = 'a'; var endSymbol = 'c'; var range = new CharRange(startSymbol, endSymbol); // Act var isContained = range.Contains('q'); // Assert Assert.IsFalse(isContained); }
public void Intersect() { var abc = new CharRange[] { new CharRange('A', 'C') }; var abd = new CharRange[] { new CharRange('A', 'B'), new CharRange('D', 'D') }; var acd = new CharRange[] { new CharRange('A', 'A'), new CharRange('C', 'D') }; var bcd = new CharRange[] { new CharRange('B', 'D') }; var set1 = CharSet.New(abc); var set2 = CharSet.New(abd); var set3 = CharSet.Universal.Subtract(CharSet.New(acd)); var set4 = CharSet.Universal.Subtract(CharSet.New(bcd)); Assert.That(set1.Intersection(set2).ToString(), Is.EqualTo("[A-B]")); Assert.That(set2.Intersection(set3).ToString(), Is.EqualTo("[B]")); Assert.That(set3.Intersection(set4).ToString(), Is.EqualTo("![A-D]")); Assert.That(set4.Intersection(set1).ToString(), Is.EqualTo("[A]")); }
public override ParseGraphNode BuildParseGraph(RuntimeState state) { string min = (string)((Base.String) this.min).text; string max = (string)((Base.String) this.max).text; min = TextEscape.Unquote(min); max = TextEscape.Unquote(max); if ((min.Length != 1) || (max.Length != 1)) { throw new Exception(); } CharRange range = new CharRange(min[0], max[0]); return(new CharNode(Source, range)); }
// ** private private void BuildCommentRangeList() { // clear old list _commentRanges.Clear(); // scan the string and save comments for (int index = 0; index < _text.Length; index++) { if (_text[index] == '/' && index < _text.Length - 1) { if (_text[index + 1] == '*') { // comments /* xxxx */ int end = _text.IndexOf("*/", index + 2); if (end > -1) { CharRange range = new CharRange(_text.Substring(index, end - index + 1), index, false); _commentRanges.Add(range); index = end + 1; } } else if (_text[index + 1] == '/') { // comments // xxxx \n int end = _text.IndexOf("\n", index + 2); if (end > -1) { CharRange range = new CharRange(_text.Substring(index, end - index + 1), index, false); _commentRanges.Add(range); index = end + 1; } } } // skip over strings in case they contain comment chars: "xxx // foo /* yyy */" if (_text[index] == '\"' && IsRealQuote(index)) { int end = FindNextQuote(index); if (end > -1) { index = end; } } } }
public void TestThatSimpleRangeWithEndEdgeSymbols() { // Arrange var startSymbol = 'a'; var endSymbol = 'c'; var range = new CharRange(startSymbol, endSymbol, isStartEqual: false, isEndEqual: true); // Act var isContained1 = range.Contains(startSymbol); var isContained2 = range.Contains(endSymbol); // Assert Assert.IsFalse(isContained1); Assert.IsTrue(isContained2); }
public void TestThatSimpleRangeWithoutEdgeSymbols() { // Arrange var startSymbol = 'a'; var endSymbol = 'c'; var range = new CharRange(startSymbol, endSymbol); // Act var isContained1 = range.Contains(startSymbol); var isContained2 = range.Contains(endSymbol); // Assert Assert.IsFalse(isContained1); Assert.IsFalse(isContained2); }
static void Main(string[] args) { var test = "abcdlmnorstuvwxz"; // get a list of ranges for the above var ranges = CharRange.GetRanges(test); // write them out (looks like regex) Console.Write("["); foreach (var range in ranges) { Console.Write(range); } Console.WriteLine("]"); // enumerate the characters in the ranges Console.Write("ranges chars: "); foreach (char ch in CharRange.ExpandRanges(ranges)) { Console.Write(ch); } Console.WriteLine(); // get a packed string - each char pair is one range Console.WriteLine("Packed string: " + CharRange.ToPackedString(ranges)); // write out the inverted set of ranges (will look ugly in the console) Console.Write("["); foreach (var range in CharRange.NotRanges(ranges)) { Console.Write(range); } Console.WriteLine("]"); // range [a-x] var a2x = new CharRange('a', 'x'); Console.WriteLine("[{0}]: Length = {1}", a2x, a2x.Length); // indexing into the range to get the character at the index Console.WriteLine("a2x[2] = " + a2x[2]); // enumerate the characters in the range Console.Write("a2x chars: "); foreach (var ch in a2x) { Console.Write(ch); } Console.WriteLine(); }
public int FormatRange(PrintPageEventArgs e, int charFrom, int charTo) { var range = new CharRange { cpMin = charFrom, cpMax = charTo }; var rect = new Rect { top = (int)(e.MarginBounds.Top * inch), bottom = (int)(e.MarginBounds.Bottom * inch), left = (int)(e.MarginBounds.Left * inch), right = (int)(e.MarginBounds.Right * inch) }; var rectPage = new Rect { top = (int)(e.PageBounds.Top * inch), bottom = (int)(e.PageBounds.Bottom * inch), left = (int)(e.PageBounds.Left * inch), right = (int)(e.PageBounds.Right * inch) }; IntPtr hdc = e.Graphics.GetHdc(); var formatRange = new FormatRange { chrg = range, hdc = hdc, hdcTarget = hdc, rc = rect, rcPage = rectPage }; IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(formatRange)); Marshal.StructureToPtr(formatRange, lParam, false); IntPtr result = NativeMethods.SendMessage(Handle, RichEditMessages.EM_FORMATRANGE, (IntPtr)1, lParam); Marshal.FreeCoTaskMem(lParam); e.Graphics.ReleaseHdc(hdc); return(result.ToInt32()); }
public void Date() { CharRange digit = new CharRange('0', '9'); CharRange dash = new CharRange('-'); // NFA nfa = NFA.Sequence(NFA.Repeat(NFA.Char(digit), 4), NFA.Char(dash), NFA.Repeat(NFA.Char(digit), 2), NFA.Char(dash), NFA.Repeat(NFA.Char(digit), 2)); NFA nfa = NFA.Sequence( NFA.Char(digit), NFA.Char(digit), NFA.Char(digit), NFA.Char(digit), NFA.Char(dash), NFA.Char(digit), NFA.Char(digit), NFA.Char(dash), NFA.Char(digit), NFA.Char(digit) ); DFA dfa = nfa.ToDfa(); Assert.IsTrue(dfa.IsMatch("2014-01-03")); Assert.IsTrue(dfa.IsMatch("0000-00-00")); }
// update dialog to show current error void UpdateCurrentError() { // design time if (_errors == null) { return; } // finished with this batch of errors if (ErrorIndex >= _errors.Count) { // check whether the editor has more text to check while (_editor.HasMoreText()) { _errors = _spell.CheckText(_editor.Text); if (_errors.Count > 0) { _errorCount += _errors.Count; ErrorIndex = 0; return; } } // editor has no more text... DialogResult = MessageBoxResult.OK; return; } // update current error CharRange err = CurrentError; // select word in editor _editor.Select(err.Start, err.Text.Length); // honor 'change all' list if (_changeAll.ContainsKey(err.Text)) { _textChangeTo = _changeAll[err.Text]; _btnChange_Click(this, new RoutedEventArgs()); return; } // raise 'BadWordFound' event BadWordEventArgs e = new BadWordEventArgs(this, _editor as Control, err, _errors); _spell.OnBadWordFound(e); if (e.Cancel) { DialogResult = MessageBoxResult.Cancel; return; } // show whole sentence, highlight bad word _updatingText = true; _sentence = GetSentence(_editor.Text, err); _originalText = _sentence.Text; _txtError.FontFamily = _editor.Control.FontFamily; _txtError.Text = _sentence.Text; _txtError.Select(err.Start - _sentence.Start, err.Length); _txtError.Selection.FontWeight = FontWeights.Bold; _txtError.Selection.Foreground = _errorForeground; _updatingText = false; // repeated word? if (err.Duplicate) { // adjust dialog _lblNotInDictionary.Visibility = Visibility.Collapsed; _lblRepeatedWord.Visibility = Visibility.Visible; _btnIgnoreAll.IsEnabled = false; _btnChangeAll.IsEnabled = false; _btnAdd.IsEnabled = false; // no suggestions _listSuggestions.Items.Clear(); } else { // adjust dialog _lblRepeatedWord.Visibility = Visibility.Collapsed; _lblNotInDictionary.Visibility = Visibility.Visible; _btnIgnoreAll.IsEnabled = true; _btnChangeAll.IsEnabled = true; _btnAdd.IsEnabled = true; // show suggestions UpdateSuggestions(err.Text); } // focus to new word _txtError.Focus(); _btnSuggest.IsEnabled = false; AcceptButton = _btnIgnore; // show 'Add' button only if user dictionary is enabled _btnAdd.Visibility = _spell.UserDictionary.Enabled ? Visibility.Visible : Visibility.Collapsed; // update button status UpdateButtonStatus(); // all ready, fire ErrorDisplayed event OnErrorDisplayed(EventArgs.Empty); }
public void Load(Stream stream) { Dictionary<int, State> states = new Dictionary<int, State>(); using (BinaryReader reader = new BinaryReader(stream, System.Text.Encoding.UTF8, leaveOpen: true)) { int stateCount = reader.ReadInt32(); for (int i = 0; i < stateCount; i++) { int id = reader.ReadInt32(); bool isFinal = reader.ReadBoolean(); int valueCount = reader.ReadInt32(); int[] values = new int[valueCount]; for (int v = 0; v < valueCount; v++) values[v] = reader.ReadInt32(); states[id] = new State { IsFinal = isFinal, Values = values }; } for (int i = 0; i < stateCount; i++) { int transitionCount = reader.ReadInt32(); for (int t = 0; t < transitionCount; t++) { CharRange input = new CharRange(reader.ReadChar(), reader.ReadChar()); int fromState = reader.ReadInt32(); int toState = reader.ReadInt32(); states[fromState].AddTransition(input, states[toState]); } } int startState = reader.ReadInt32(); if (startState != -1) Start = states[startState]; } }
public void AddTransition(CharRange input, State to) { if (!transitions.ContainsKey(input)) transitions[input] = new HashSet<State>(); transitions[input].Add(to); }
public void RemoveTransition(CharRange input) { // overlaps // doesn't overlap // throw new NotImplementedException(); transitions.Remove(input); Minimize(); }
// not used by NFA.ToDfa() public void SetTransition(CharRange input, State to) { CharRange overlaping = transitions.Keys.SingleOrDefault(range => range.Overlaps(input)); if (overlaping == CharRange.Empty) // [a..c -> 1] + [d..f -> 2] { transitions[input] = to; } else // [a..z -> 1] + [c..f -> 2] = [a..b -> 1] + [c..f -> 2] + [g..z -> 1] { State overlapingState = transitions[overlaping]; transitions.Remove(overlaping); CharRange[] ranges = overlaping.Split(input); foreach (CharRange range in ranges) transitions[range] = range.Overlaps(input) ? to : overlapingState; } Minimize(); }
public void AddTransition(CharRange input, State to) { if (transitions.Keys.Any(range => range.Overlaps(input))) throw new ArgumentOutOfRangeException("Already have a transition for this input or it's overlapping", "input"); transitions[input] = to; Minimize(); }
public void Minimize() { // todo: join ranges, maybe? // this makes it so much faster!!!!! var sorted = transitions.OrderBy(kp => kp.Key).ToArray(); ranges = sorted.Select(kp => kp.Key).ToArray(); states = sorted.Select(kp => kp.Value).ToArray(); count = ranges.Length; if (count > 0) firstRange = ranges[0]; }
public State this[CharRange input] { get { foreach (CharRange range in transitions.Keys.OrderBy(r => r)) if (range.Contains(input)) return transitions[range]; return null; } }
// select the sentence that contains the current error private CharRange GetSentence(string text, CharRange err) { // find sentence start int start = -1; for (int i = err.Start; i > 0 && start < 0; i--) { switch (text[i]) { case '.': case '!': case '?': case '\n': case '\r': for (int j = i; j < err.Start; j++) { if (char.IsLetterOrDigit(text[j])) { start = j; break; } } break; } } if (start < 0) start = 0; // find sentence end int end = -1; for (int i = err.Start; i < text.Length && end < 0; i++) { switch (text[i]) { case '.': case '!': case '?': end = i; break; case '\n': case '\r': end = i - 1; break; } } if (end < 0) end = text.Length - 1; // done, return result string sentence = text.Substring(start, end - start + 1); return new CharRange(sentence, start, false); }
public bool Equals(CharRange other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return other.From == From && other.To == To; }
public void DateTime() { CharRange digit = new CharRange('0', '9'); CharRange dash = new CharRange('-'); CharRange colon = new CharRange(':'); CharRange seperator = new CharRange(' '); // NFA date = NFA.Sequence(NFA.Repeat(NFA.Char(digit), 4), NFA.Char(dash), NFA.Repeat(NFA.Char(digit), 2), NFA.Char(dash), NFA.Repeat(NFA.Char(digit), 2)); // NFA time = NFA.Sequence(NFA.Repeat(NFA.Char(digit), 2), NFA.Char(colon), NFA.Repeat(NFA.Char(digit), 2)); NFA date = NFA.Sequence( NFA.Char(digit), NFA.Char(digit), NFA.Char(digit), NFA.Char(digit), NFA.Char(dash), NFA.Char(digit), NFA.Char(digit), NFA.Char(dash), NFA.Char(digit), NFA.Char(digit) ); NFA time = NFA.Sequence( NFA.Char(digit), NFA.Char(digit), NFA.Char(colon), NFA.Char(digit), NFA.Char(digit) ); NFA datetime = NFA.Sequence(date, NFA.Char(seperator), time); NFA nfa = NFA.Or(date, time, datetime); DFA dfa = nfa.ToDfa(); Assert.IsTrue(dfa.IsMatch("00:00")); Assert.IsTrue(dfa.IsMatch("23:15")); Assert.IsTrue(dfa.IsMatch("23:59")); Assert.IsTrue(dfa.IsMatch("2014-01-03")); Assert.IsTrue(dfa.IsMatch("0000-00-00")); Assert.IsTrue(dfa.IsMatch("2014-01-03 23:15")); }
private static void AppendRange(List<CharRange> list, CharRange range) { if (list.Count == 0) { list.Add(range); } else { CharRange lastRange = list[list.Count - 1]; char last = lastRange.Last; if (last != c_lastChar) { if (range.First > last + 1) { list.Add(range); } else if (last < range.Last) { lastRange.Last = range.Last; } } } }
private static extern void Internal_SetCharRanges(IntPtr thisPtr, CharRange[] value);
public void Time() { CharRange d09 = new CharRange('0', '9'); CharRange d05 = new CharRange('0', '5'); CharRange d03 = new CharRange('0', '3'); CharRange colon = new CharRange(':'); NFA a = NFA.Sequence(NFA.Or(NFA.Char('0'), NFA.Char('1')), NFA.Char(d09), NFA.Char(colon), NFA.Char(d05), NFA.Char(d09)); // [01][0-9]:[0-5][0-9] NFA b = NFA.Sequence(NFA.Char('2'), NFA.Char(d03), NFA.Char(colon), NFA.Char(d05), NFA.Char(d09)); // [2][0-3]:[0-5][0-9] NFA c = NFA.Sequence(NFA.Char('2'), NFA.Char('4'), NFA.Char(colon), NFA.Char('0'), NFA.Char('0')); // [2][4]:[0][0] NFA nfa = NFA.Or(a, b, c); DFA dfa = nfa.ToDfa(); Assert.IsTrue(dfa.IsMatch("00:00")); Assert.IsTrue(dfa.IsMatch("01:50")); Assert.IsTrue(dfa.IsMatch("23:15")); Assert.IsTrue(dfa.IsMatch("23:59")); Assert.IsTrue(dfa.IsMatch("24:00")); Assert.IsFalse(dfa.IsMatch("14:78")); Assert.IsFalse(dfa.IsMatch("24:59")); }