Mercurial > ~dholland > hg > ag > index.cgi
comparison anagram/agcore/csexp.cpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 /* | |
2 * AnaGram, A System for Syntax Directed Programming | |
3 * Copyright 1993-2002 Parsifal Software. All Rights Reserved. | |
4 * See the file COPYING for license and usage terms. | |
5 * | |
6 * csexp.cpp | |
7 */ | |
8 | |
9 #include "config.h" | |
10 #include "cs.h" | |
11 #include "csexp.h" | |
12 #include "error.h" | |
13 #include "symbol.h" | |
14 | |
15 //#define INCLUDE_LOGGING | |
16 #include "log.h" | |
17 | |
18 | |
19 #define MAX_N_CHARS 0x10001 | |
20 | |
21 static char caseTable[32] = { | |
22 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
23 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
24 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0, | |
25 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0 | |
26 }; | |
27 | |
28 unsigned char agToUpper(unsigned char c) { | |
29 if (c >= 'a' && c <= 'z') { | |
30 return c ^= 0x20; | |
31 } | |
32 if (iso_latin_1 && (unsigned) c >= 0xe0) { | |
33 c ^= caseTable[c-0xe0]; | |
34 } | |
35 return c; | |
36 } | |
37 | |
38 | |
39 //asString | |
40 | |
41 AgString CharSetExpression::asString(Precedence p) const { | |
42 LOGSECTION_OFF("CharSetExpression::asString(Precedence)"); | |
43 //LOGSECTION("CharSetExpression::asString(Precedence)"); | |
44 LOGV(p) LCV(precedence); | |
45 if (p < precedence) { | |
46 return asString(); | |
47 } | |
48 AgString value = AgString("(").concat(asString()).concat(")"); | |
49 LOGV(value) LCV((int) p); | |
50 return value; | |
51 } | |
52 | |
53 AgString CharRange::asString() const { | |
54 LOGSECTION_OFF("CharRange::asString"); | |
55 char buf[20]; | |
56 sprintf(buf, "'%c-%c'", first, last); | |
57 LOGV(first) LCV(last) LCV(buf); | |
58 return AgString(buf); | |
59 } | |
60 | |
61 AgString CodeRange::asString() const { | |
62 LOGSECTION_OFF("CodeRange::asString"); | |
63 char buf[20]; | |
64 sprintf(buf, "%d..%d", first, last); | |
65 LOGV(first) LCV(last) LCV(buf); | |
66 return AgString(buf); | |
67 } | |
68 | |
69 AgString IndividualChar::asString() const { | |
70 LOGSECTION_OFF("IndividualChar::asString"); | |
71 LOGV(asciiValue); | |
72 char buf[10]; | |
73 if (asciiValue < ' ') { | |
74 switch (asciiValue) { | |
75 case '\a': sprintf(buf, "'\\a'"); break; | |
76 case '\b': sprintf(buf, "'\\b'"); break; | |
77 case '\f': sprintf(buf, "'\\f'"); break; | |
78 case '\n': sprintf(buf, "'\\n'"); break; | |
79 case '\r': sprintf(buf, "'\\r'"); break; | |
80 case '\t': sprintf(buf, "'\\t'"); break; | |
81 case '\v': sprintf(buf, "'\\v'"); break; | |
82 default: sprintf(buf, "'\\%03o'", asciiValue); break; | |
83 } | |
84 } | |
85 else { | |
86 switch (asciiValue) { | |
87 case '\\': sprintf(buf, "'\\\\'"); break; | |
88 case '\?': sprintf(buf, "'\\?'"); break; | |
89 case '\'': sprintf(buf, "'\\''"); break; | |
90 case '\"': sprintf(buf, "'\\\"'"); break; | |
91 default: sprintf(buf, "'%c'", asciiValue); break; | |
92 } | |
93 } | |
94 LOGV(asciiValue) LCV(buf); | |
95 return AgString(buf); | |
96 } | |
97 | |
98 AgString IndividualCode::asString() const { | |
99 LOGSECTION_OFF("IndividualCode::asString"); | |
100 LOGV(value); | |
101 char buf[20]; | |
102 sprintf(buf, "%d", value); | |
103 LOGV(value) LCV(buf); | |
104 return AgString(buf); | |
105 } | |
106 | |
107 AgString NamedCharSet::asString() const { | |
108 LOGSECTION_OFF("NamedCharSet::asString"); | |
109 return Symbol(name)->string; | |
110 //return AgString(dict_str(tkn_dict, name)); | |
111 } | |
112 | |
113 AgString CharSetUnion::asString() const { | |
114 LOGSECTION_OFF("CharSetUnion::asString"); | |
115 //LOGSECTION("CharSetUnion::asString"); | |
116 return left->asString().concat(" + ").concat(right->asString()); | |
117 } | |
118 | |
119 AgString CharSetIntersection::asString() const { | |
120 LOGSECTION_OFF("CharSetIntersection::asString"); | |
121 return left->asString(multiplicative).concat(" * "). | |
122 concat(right->asString(multiplicative)); | |
123 } | |
124 | |
125 AgString CharSetDifference::asString() const { | |
126 LOGSECTION_OFF("CharSetDifference::asString"); | |
127 AgString value = left->asString().concat(" - "). | |
128 concat(right->asString(additive)); | |
129 LOGV(value); | |
130 return value; | |
131 } | |
132 | |
133 AgString CharSetComplement::asString() const { | |
134 LOGSECTION_OFF("CharSetComplement::asString"); | |
135 //LOGSECTION_ON("CharSetComplement::asString"); | |
136 AgString value("~"); | |
137 LOGV(value); | |
138 value = value.concat(operand->asString(unary)); | |
139 LOGV(value); | |
140 return value; | |
141 } | |
142 | |
143 //bitmap | |
144 | |
145 CharBitmap CharRange::bitmap() const { | |
146 LOGSECTION("CharRange::bitmap"); | |
147 LOGV(asString()); | |
148 int i = first; | |
149 CharBitmap returnValue; | |
150 while (i <= last) { | |
151 returnValue.setBit(translateTable[i]); | |
152 if (!case_sensitive) { | |
153 returnValue.setBit(translateTable[agToUpper((char) i)]); | |
154 } | |
155 i++; | |
156 } | |
157 return returnValue; | |
158 } | |
159 | |
160 CharBitmap CodeRange::bitmap() const { | |
161 LOGSECTION("CodeRange::bitmap"); | |
162 LOGV(asString()); | |
163 LOGV(first) LCV(last); | |
164 return CharBitmap().setRange(first, last); | |
165 } | |
166 | |
167 CharBitmap IndividualChar::bitmap() const { | |
168 LOGSECTION("IndividualChar::bitmap"); | |
169 LOGV(asString()); | |
170 CharBitmap map; | |
171 map.setBit(translateTable[asciiValue]); | |
172 if (!case_sensitive) { | |
173 map.setBit(translateTable[agToUpper((char) asciiValue)]); | |
174 } | |
175 return map; | |
176 } | |
177 | |
178 CharBitmap IndividualCode::bitmap() const { | |
179 LOGSECTION("IndividualCode::bitmap"); | |
180 LOGV(asString()); | |
181 CharBitmap map; | |
182 map.setBit(value); | |
183 return map; | |
184 } | |
185 | |
186 CharBitmap NamedCharSet::bitmap() const { | |
187 LOGSECTION("NamedCharSet::bitmap"); | |
188 LOGV(asString()); | |
189 int parseTree = getParseTree(name); | |
190 LOGV(parseTree); | |
191 if (parseTree == 0) { | |
192 return CharBitmap(); | |
193 } | |
194 LOGV((int)(map_parse_tree[parseTree].expression)); | |
195 CharSetExpression *expression = map_parse_tree[parseTree].expression; | |
196 | |
197 return expression->bitmap(); | |
198 } | |
199 | |
200 CharBitmap CharSetUnion::bitmap() const { | |
201 LOGSECTION("CharSetUnion::bitmap"); | |
202 LOGV(asString()); | |
203 CharBitmap returnValue = left->bitmap(); | |
204 returnValue |= right->bitmap(); | |
205 return returnValue; | |
206 } | |
207 | |
208 CharBitmap CharSetIntersection::bitmap() const { | |
209 LOGSECTION("CharSetIntersection::bitmap"); | |
210 LOGV(asString()); | |
211 CharBitmap returnValue = left->bitmap(); | |
212 returnValue &= right->bitmap(); | |
213 return returnValue; | |
214 } | |
215 | |
216 CharBitmap CharSetDifference::bitmap() const { | |
217 LOGSECTION("CharSetDifference::bitmap"); | |
218 LOGV(asString()); | |
219 CharBitmap returnValue = left->bitmap(); | |
220 returnValue -= right->bitmap(); | |
221 return returnValue; | |
222 } | |
223 | |
224 CharBitmap CharSetComplement::bitmap() const { | |
225 LOGSECTION("CharSetComplement::bitmap"); | |
226 LOGV(asString()); | |
227 return ~operand->bitmap(); | |
228 } | |
229 | |
230 // checkMinimum | |
231 | |
232 void CharSetExpression::checkMinimum(int c) { | |
233 if (!negativeCharDiagnostic && c < 0 && pointer_input) { | |
234 // would be nice to dig up the line on which it was defined | |
235 errorList.push(Error("Negative character code in pointer mode")); | |
236 negativeCharDiagnostic = 1; | |
237 } | |
238 } | |
239 | |
240 // checkRange() | |
241 | |
242 void CharRange::checkRange() { | |
243 LOGSECTION("CharRange::checkRange"); | |
244 LOGV(asString()); | |
245 for (int i = first; i < last; i++) { | |
246 LOGV(i) LCV(translateTable[i]); | |
247 if (min_char_number > translateTable[i]) { | |
248 min_char_number = translateTable[i]; | |
249 } | |
250 if (max_char_number < translateTable[i]) { | |
251 max_char_number = translateTable[i]; | |
252 } | |
253 } | |
254 n_chars = max_char_number - min_char_number + 1; | |
255 LOGV(first) LCV(last); | |
256 LOGV(min_char_number) LCV(max_char_number); | |
257 } | |
258 | |
259 void CodeRange::checkRange() { | |
260 LOGSECTION("CodeRange::checkRange"); | |
261 LOGV(asString()); | |
262 | |
263 if (min_char_number > first) { | |
264 min_char_number = first; | |
265 } | |
266 if (max_char_number < last) { | |
267 max_char_number = last; | |
268 } | |
269 | |
270 n_chars = max_char_number - min_char_number + 1; | |
271 LOGV(first) LCV(last); | |
272 LOGV(min_char_number) LCV(max_char_number); | |
273 } | |
274 | |
275 void IndividualChar::checkRange() { | |
276 LOGSECTION("IndividualChar::checkRange"); | |
277 LOGV(asString()); | |
278 | |
279 if (min_char_number > translateTable[asciiValue]) { | |
280 min_char_number = translateTable[asciiValue]; | |
281 } | |
282 if (max_char_number < translateTable[asciiValue]) { | |
283 max_char_number = translateTable[asciiValue]; | |
284 } | |
285 | |
286 n_chars = max_char_number - min_char_number + 1; | |
287 LOGV(asciiValue); | |
288 LOGV(min_char_number) LCV(max_char_number); | |
289 } | |
290 | |
291 void IndividualCode::checkRange() { | |
292 LOGSECTION("IndividualCode::checkRange"); | |
293 LOGV(asString()); | |
294 | |
295 if (value > 0xffff) { | |
296 value = 0xffff; | |
297 log_error("Only 16 bit characters supported"); | |
298 } | |
299 | |
300 if (min_char_number > value) { | |
301 min_char_number = value; | |
302 } | |
303 if (max_char_number < value) { | |
304 max_char_number = value; | |
305 } | |
306 | |
307 n_chars = max_char_number - min_char_number + 1; | |
308 LOGV(value); | |
309 LOGV(min_char_number) LCV(max_char_number); | |
310 } | |
311 | |
312 void CharSetUnion::checkRange() { | |
313 LOGSECTION("CharSetUnion::checkRange"); | |
314 LOGV(asString()); | |
315 left->checkRange(); | |
316 right->checkRange(); | |
317 LOGV(min_char_number) LCV(max_char_number); | |
318 } | |
319 | |
320 void CharSetIntersection::checkRange() { | |
321 LOGSECTION("CharSetIntersection::checkRange"); | |
322 LOGV(asString()); | |
323 left->checkRange(); | |
324 right->checkRange(); | |
325 LOGV(min_char_number) LCV(max_char_number); | |
326 } | |
327 | |
328 void CharSetDifference::checkRange() { | |
329 LOGSECTION("CharSetDifference::checkRange"); | |
330 LOGV(asString()); | |
331 left->checkRange(); | |
332 right->checkRange(); | |
333 LOGV(min_char_number) LCV(max_char_number); | |
334 } | |
335 | |
336 void CharSetComplement::checkRange() { | |
337 LOGSECTION("CharSetComplement::checkRange"); | |
338 LOGV(asString()); | |
339 operand->checkRange(); | |
340 LOGV(min_char_number) LCV(max_char_number); | |
341 } | |
342 | |
343 //translate table | |
344 | |
345 CharSetExpression::TranslateTable CharSetExpression::translateTable; | |
346 | |
347 | |
348 // Comparisons | |
349 | |
350 int CharRange::operator == (const CharSetExpression &x) const { | |
351 LOGSECTION_OFF("CharRange::operator==(CharSetExpression &)"); | |
352 //if (typeid(*this) != typeid(x)) return 0; | |
353 if (!sameType(x)) { | |
354 return 0; | |
355 } | |
356 //const CharRange &arg = dynamic_cast<const CharRange &>(x); | |
357 const CharRange &arg = (const CharRange &) x; | |
358 return first == arg.first && last == arg.last; | |
359 } | |
360 | |
361 int CharRange::operator < (const CharSetExpression &x) const { | |
362 LOGSECTION_OFF("CharRange::operator <"); | |
363 LOGV(asString()) LCV(x.asString()); | |
364 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
365 if (!sameType(x)) { | |
366 return CharSetExpression::operator < (x); | |
367 } | |
368 //const CharRange &arg = dynamic_cast<const CharRange &>(x); | |
369 const CharRange &arg = (const CharRange &) x; | |
370 int flag = (first == arg.first) ? last < arg.last : first < arg.first; | |
371 LOGV(flag); | |
372 return flag; | |
373 } | |
374 | |
375 int CodeRange::operator == (const CharSetExpression &x) const { | |
376 LOGSECTION("CodeRange::operator==(CharSetExpression &)"); | |
377 //if (typeid(*this) != typeid(x)) return 0; | |
378 if (!sameType(x)) { | |
379 return 0; | |
380 } | |
381 //const CodeRange &arg = dynamic_cast<const CodeRange &>(x); | |
382 const CodeRange &arg = (const CodeRange &) x; | |
383 return first == arg.first && last == arg.last; | |
384 } | |
385 | |
386 int CodeRange::operator < (const CharSetExpression &x) const { | |
387 LOGSECTION("CodeRange::operator <"); | |
388 LOGV(asString()) LCV(x.asString()); | |
389 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
390 if (!sameType(x)) { | |
391 return CharSetExpression::operator < (x); | |
392 } | |
393 //const CodeRange &arg = dynamic_cast<const CodeRange &>(x); | |
394 const CodeRange &arg = (const CodeRange &) x; | |
395 int flag = first == arg.first ? last < arg.last : first < arg.first; | |
396 LOGV(flag); | |
397 return flag; | |
398 } | |
399 | |
400 int IndividualChar::operator == (const CharSetExpression &x) const { | |
401 LOGSECTION("IndividualChar::operator==(CharSetExpression &)"); | |
402 //if (typeid(*this) != typeid(x)) return 0; | |
403 if (!sameType(x)) { | |
404 return 0; | |
405 } | |
406 //const IndividualChar &arg = dynamic_cast<const IndividualChar &>(x); | |
407 const IndividualChar &arg = (const IndividualChar &) x; | |
408 return asciiValue == arg.asciiValue; | |
409 } | |
410 int IndividualChar::operator < (const CharSetExpression &x) const { | |
411 LOGSECTION("IndividualChar::operator <"); | |
412 LOGV(asString()) LCV(x.asString()); | |
413 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
414 if (!sameType(x)) { | |
415 return CharSetExpression::operator < (x); | |
416 } | |
417 //const IndividualChar &arg = dynamic_cast<const IndividualChar &>(x); | |
418 const IndividualChar &arg = (const IndividualChar &) x; | |
419 int flag = asciiValue < arg.asciiValue; | |
420 LOGV(flag); | |
421 return flag; | |
422 } | |
423 | |
424 int IndividualCode::operator == (const CharSetExpression &x) const { | |
425 LOGSECTION("IndividualCode::operator==(CharSetExpression &)"); | |
426 //if (typeid(*this) != typeid(x)) return 0; | |
427 if (!sameType(x)) { | |
428 return 0; | |
429 } | |
430 //const IndividualCode &arg = dynamic_cast<const IndividualCode &>(x); | |
431 const IndividualCode &arg = (const IndividualCode &) x; | |
432 return value == arg.value; | |
433 } | |
434 | |
435 int IndividualCode::operator < (const CharSetExpression &x) const { | |
436 LOGSECTION("IndividualCode::operator <"); | |
437 LOGV(asString()) LCV(x.asString()); | |
438 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
439 if (!sameType(x)) { | |
440 return CharSetExpression::operator < (x); | |
441 } | |
442 //const IndividualCode &arg = dynamic_cast<const IndividualCode &>(x); | |
443 const IndividualCode &arg = (const IndividualCode &) x; | |
444 int flag = value < arg.value; | |
445 LOGV(flag); | |
446 return flag; | |
447 } | |
448 | |
449 int NamedCharSet::operator == (const CharSetExpression &x) const { | |
450 LOGSECTION("NamedCharSet::operator==(CharSetExpression &)"); | |
451 //if (typeid(*this) != typeid(x)) return 0; | |
452 if (!sameType(x)) { | |
453 return 0; | |
454 } | |
455 //const NamedCharSet &arg = dynamic_cast<const NamedCharSet &>(x); | |
456 const NamedCharSet &arg = (const NamedCharSet &) x; | |
457 return name == arg.name; | |
458 } | |
459 | |
460 int NamedCharSet::operator < (const CharSetExpression &x) const { | |
461 LOGSECTION("NamedCharSet::operator <"); | |
462 LOGV(asString()) LCV(x.asString()); | |
463 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
464 if (!sameType(x)) { | |
465 return CharSetExpression::operator < (x); | |
466 } | |
467 //const NamedCharSet &arg = dynamic_cast<const NamedCharSet &>(x); | |
468 const NamedCharSet &arg = (const NamedCharSet &) x; | |
469 int flag = name < arg.name; | |
470 LOGV(flag); | |
471 return flag; | |
472 } | |
473 | |
474 int CharSetUnion::operator == (const CharSetExpression &x) const { | |
475 LOGSECTION("CharSetUnion::operator==(CharSetExpression &)"); | |
476 //if (typeid(*this) != typeid(x)) return 0; | |
477 if (!sameType(x)) { | |
478 return 0; | |
479 } | |
480 //const CharSetUnion &arg = dynamic_cast<const CharSetUnion &>(x); | |
481 const CharSetUnion &arg = (const CharSetUnion &) x; | |
482 return (*left == *arg.left && *right == *arg.right) || | |
483 (*left == *arg.right && *right == *arg.left); | |
484 } | |
485 | |
486 int CharSetUnion::operator < (const CharSetExpression &x) const { | |
487 LOGSECTION("CharSetUnion::operator <"); | |
488 LOGV(asString()) LCV(x.asString()); | |
489 //if (typeid(*this) != typeid(x)) { | |
490 if (!sameType(x)) { | |
491 return CharSetExpression::operator < (x); | |
492 } | |
493 LOGS("Same type"); | |
494 //const CharSetUnion &arg = dynamic_cast<const CharSetUnion &>(x); | |
495 const CharSetUnion &arg = (const CharSetUnion &) x; | |
496 LOGS("Dynamic cast successful"); | |
497 int flag = (*this == arg) ? 0 : | |
498 (*left == *arg.left ? *right < *arg.right : *left < *arg.left); | |
499 LOGV(flag); | |
500 return flag; | |
501 } | |
502 | |
503 int CharSetIntersection::operator == (const CharSetExpression &x) const { | |
504 LOGSECTION("CharSetIntersection::operator==(CharSetExpression &)"); | |
505 //if (typeid(*this) != typeid(x)) return 0; | |
506 if (!sameType(x)) { | |
507 return 0; | |
508 } | |
509 //const CharSetIntersection &arg = dynamic_cast<const CharSetIntersection &>(x); | |
510 const CharSetIntersection &arg = (const CharSetIntersection &) x; | |
511 return (*left == *arg.left && *right == *arg.right) | |
512 || (*left == *arg.right && *right == *arg.left); | |
513 } | |
514 | |
515 int CharSetIntersection::operator < (const CharSetExpression &x) const { | |
516 LOGSECTION("CharSetIntersection::operator <"); | |
517 LOGV(asString()) LCV(x.asString()); | |
518 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
519 if (!sameType(x)) { | |
520 return CharSetExpression::operator < (x); | |
521 } | |
522 //const CharSetIntersection &arg = dynamic_cast<const CharSetIntersection &>(x); | |
523 const CharSetIntersection &arg = (const CharSetIntersection &) x; | |
524 int flag = (*this == arg) ? 0 : | |
525 (*left == *arg.left ? *right < *arg.right : *left < *arg.left); | |
526 LOGV(flag); | |
527 return flag; | |
528 } | |
529 | |
530 int CharSetDifference::operator == (const CharSetExpression &x) const { | |
531 LOGSECTION("CharSetDifference::operator==(CharSetExpression &)"); | |
532 //if (typeid(*this) != typeid(x)) return 0; | |
533 if (!sameType(x)) { | |
534 return 0; | |
535 } | |
536 //const CharSetDifference &arg = dynamic_cast<const CharSetDifference &>(x); | |
537 const CharSetDifference &arg = (const CharSetDifference &) x; | |
538 return (*left == *arg.left && *right == *arg.right); | |
539 } | |
540 int CharSetDifference::operator < (const CharSetExpression &x) const { | |
541 LOGSECTION("CharSetDifference::operator <"); | |
542 LOGV(asString()) LCV(x.asString()); | |
543 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
544 if (!sameType(x)) { | |
545 return CharSetExpression::operator < (x); | |
546 } | |
547 //const CharSetDifference &arg = dynamic_cast<const CharSetDifference &>(x); | |
548 const CharSetDifference &arg = (const CharSetDifference &) x; | |
549 int flag = (*this == arg) ? 0 : | |
550 (*left == *arg.left ? *right < *arg.right : *left < *arg.left); | |
551 LOGV(flag); | |
552 return flag; | |
553 } | |
554 | |
555 int CharSetComplement::operator == (const CharSetExpression &x) const { | |
556 LOGSECTION("CharSetComplement::operator==(CharSetExpression &)"); | |
557 //if (typeid(*this) != typeid(x)) return 0; | |
558 if (!sameType(x)) { | |
559 return 0; | |
560 } | |
561 //const CharSetComplement &arg = dynamic_cast<const CharSetComplement &>(x); | |
562 const CharSetComplement &arg = (const CharSetComplement &) x; | |
563 return *operand == *arg.operand; | |
564 } | |
565 | |
566 int CharSetComplement::operator < (const CharSetExpression &x) const { | |
567 LOGSECTION("CharSetComplement::operator <"); | |
568 LOGV(asString()) LCV(x.asString()); | |
569 //if (typeid(*this) != typeid(x)) return CharSetExpression::operator < (x); | |
570 if (!sameType(x)) { | |
571 return CharSetExpression::operator < (x); | |
572 } | |
573 //const CharSetComplement &arg = dynamic_cast<const CharSetComplement &>(x); | |
574 const CharSetComplement &arg = (const CharSetComplement &) x; | |
575 int flag = *operand < *arg.operand; | |
576 LOGV(flag); | |
577 return flag; | |
578 } |