1 using System;
2 using System.Collections;
3
4
5
6
7
8 namespace System.RegularExpressions
9 {
10 public const uchar eps = '\0';
11 public abstract class Symbol
12 {
13 public virtual ~Symbol()
14 {
15 }
16 public abstract bool Match(uchar c);
17 public abstract string ToString() const;
18 }
19 public class Char : Symbol
20 {
21 public Char(uchar chr_) :
22 chr(chr_)
23 {
24 }
25 public uchar Chr() const
26 {
27 return chr;
28 }
29 public override bool Match(uchar c)
30 {
31 return c == chr;
32 }
33 public override string ToString() const
34 {
35 if (chr == eps)
36 {
37 return "<eps>";
38 }
39 else
40 {
41 return "char(" + ToString(chr) + ")";
42 }
43 }
44 private uchar chr;
45 }
46 public class Any : Symbol
47 {
48 public override bool Match(uchar c)
49 {
50 return true;
51 }
52 public override string ToString() const
53 {
54 return "<any>";
55 }
56 }
57 public class Range : Symbol
58 {
59 public Range(uchar start_, uchar end_) :
60 start(start_), end(end_)
61 {
62 }
63 public uchar Start() const
64 {
65 return start;
66 }
67 public uchar End() const
68 {
69 return end;
70 }
71 public override bool Match(uchar c)
72 {
73 return c >= start && c <= end;
74 }
75 public override string ToString() const
76 {
77 return "range(" + ToString(start) + "-" + ToString(end) + ")";
78 }
79 private uchar start;
80 private uchar end;
81 }
82 public inline bool operator==(const Range& left, const Range& right)
83 {
84 return left.Start() == right.Start() && left.End() == right.End();
85 }
86 public inline bool operator<(const Range& left, const Range& right)
87 {
88 if (left.Start() < right.Start()) return true;
89 if (left.Start() > right.Start()) return false;
90 return left.End() < right.End();
91 }
92 public class Class : Symbol
93 {
94 public Class() :
95 inverse(false)
96 {
97 }
98 public void SetInverse()
99 {
100 inverse = true;
101 }
102 public void AddSymbol(Symbol* symbol)
103 {
104 symbols.Add(symbol);
105 }
106 public override bool Match(uchar c)
107 {
108 bool match = false;
109 for (Symbol* symbol : symbols)
110 {
111 if (symbol->Match(c))
112 {
113 match = true;
114 break;
115 }
116 }
117 return match != inverse;
118 }
119 public override string ToString() const
120 {
121 string s = '[';
122 if (inverse)
123 {
124 s.Append('^');
125 }
126 for (Symbol* symbol : symbols)
127 {
128 s.Append(symbol->ToString());
129 }
130 s.Append(']');
131 return s;
132 }
133 private bool inverse;
134 private List<Symbol*> symbols;
135 }
136 }