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 }