1
16
17 import org.as2lib.regexp.Pattern;
18 import org.as2lib.regexp.node.Node;
19 import org.as2lib.regexp.node.TreeInfo;
20
21
28
29 class org.as2lib.regexp.node.Curly extends Node {
30
31 private var atom:Node;
32 private var type:Number;
33 private var cmin:Number;
34 private var cmax:Number;
35
36 public function Curly(node:Node, cmin:Number, cmax:Number, type:Number) {
37 this.atom = node;
38 this.type = type;
39 this.cmin = cmin;
40 this.cmax = cmax;
41 }
42
43 public function match(matcher:Object, i:Number, seq:String):Boolean {
44 var j:Number;
45 for (j = 0; j < cmin; j++) {
46 if (atom.match(matcher, i, seq)) {
47 i = matcher.last;
48 continue;
49 }
50 return false;
51 }
52 if (type == Pattern.GREEDY)
53 return match0(matcher, i, j, seq);
54 else if (type == Pattern.LAZY)
55 return match1(matcher, i, j, seq);
56 else
57 return match2(matcher, i, j, seq);
58 }
59
60
61
62
63 private function match0(matcher:Object, i:Number, j:Number, seq:String):Boolean {
64 if (j >= cmax) {
65
66
67 return next.match(matcher, i, seq);
68 }
69 var backLimit:Number = j;
70 while (atom.match(matcher, i, seq)) {
71
72 var k:Number = matcher.last - i;
73
74
75 if (k == 0) break;
76
77
78 i = matcher.last;
79 j++;
80
81
82 while (j < cmax) {
83 if (!atom.match(matcher, i, seq)) break;
84 if (i + k != matcher.last) {
85 if (match0(matcher, matcher.last, j+1, seq)) return true;
86 break;
87 }
88 i += k;
89 j++;
90 }
91
92
93 while (j >= backLimit) {
94 if (next.match(matcher, i, seq))
95 return true;
96 i -= k;
97 j--;
98 }
99 return false;
100 }
101 return next.match(matcher, i, seq);
102 }
103
104
105
106
107 private function match1(matcher:Object, i:Number, j:Number, seq:String):Boolean {
108 while (true) {
109
110 if (next.match(matcher, i, seq))
111 return true;
112
113 if (j >= cmax)
114 return false;
115
116 if (!atom.match(matcher, i, seq))
117 return false;
118
119 if (i == matcher.last)
120 return false;
121
122 i = matcher.last;
123 j++;
124 }
125 }
126
127 private function match2(matcher:Object, i:Number, j:Number, seq:String):Boolean {
128 for (; j < cmax; j++) {
129 if (!atom.match(matcher, i, seq))
130 break;
131 if (i == matcher.last)
132 break;
133 i = matcher.last;
134 }
135 return next.match(matcher, i, seq);
136 }
137
138 public function study(info:TreeInfo):Boolean {
139
140 var minL:Number = info.minLength;
141 var maxL:Number = info.maxLength;
142 var maxV:Boolean = info.maxValid;
143 var detm:Boolean = info.deterministic;
144 info.reset();
145
146 atom.study(info);
147
148 var temp:Number = info.minLength * cmin + minL;
149 if (temp < minL) {
150 temp = 0xFFFFFFF;
151 }
152 info.minLength = temp;
153
154 if (maxV && info.maxValid) {
155 temp = info.maxLength * cmax + maxL;
156 info.maxLength = temp;
157 if (temp < maxL) {
158 info.maxValid = false;
159 }
160 } else {
161 info.maxValid = false;
162 }
163
164 if (info.deterministic && cmin == cmax)
165 info.deterministic = detm;
166 else
167 info.deterministic = false;
168
169 return next.study(info);
170 }
171
172 public function getType(Void):Number {
173 return type;
174 }
175
176 public function getAtom(Void):Node {
177 return atom;
178 }
179
180 public function getCmin(Void):Number {
181 return cmin;
182 }
183
184 public function getCmax(Void):Number {
185 return cmax;
186 }
187
188 }
189
190