00001
00002
00003 #include <stdio.h>
00004 #include <iostream.h>
00005 #include <ctype.h>
00006 #include <string.h>
00007
00008 #include "../HeapStats.h"
00009 #include "../Type.h"
00010 #include "../String.h"
00011 #include "../Collection/RefList.h"
00012 #include "../Collection/Iterator.h"
00013 #include "../macros.h"
00014 #include "../utilities/switches_util.h"
00015 #include "../Symbol/Symbol.h"
00016 #include "../Symbol/VariableSymbol.h"
00017 #include "../Symbol/FunctionSymbol.h"
00018 #include "../Symtab.h"
00019 #include "../p-setjmp.h"
00020 #include "../debug.h"
00021 #include "../Info.h"
00022 #include "../OmegaInfo.h"
00023
00024 #include "Expression.h"
00025 #include "Expression.all.h"
00026 #include "../Wildcard/Wildcard.all.h"
00027 #include "expr.h"
00028 #include "ExprSignature.h"
00029
00030 void test_expr_str(char *);
00031 Expression *parse_expr (char *&, Symtab &);
00032 void skip_whitespace(char *&);
00033 Symbol *parse_symbol(char *&, Symtab &);
00034 long parse_int(char *&);
00035 Expression *parse_real(char *&);
00036 Expression *parse_op(char *&, Symtab &);
00037 Expression *parse_wildcard_op(char *&, Symtab &);
00038 Expression *parse_unary_expr(char *&, OP_TYPE, EXPR_TYPE, Symtab &);
00039 Expression *parse_binary_expr(char *&, OP_TYPE, EXPR_TYPE, Symtab &);
00040 Expression *parse_nonbinary_expr(char *&, OP_TYPE, EXPR_TYPE, Symtab &);
00041 Expression *parse_no_arg_wildcard_expr(char *&, OP_TYPE, Symtab &);
00042 Expression *parse_unary_wildcard_expr(char *&, OP_TYPE, Symtab &);
00043 Expression *parse_binary_wildcard_expr(char *&, OP_TYPE, Symtab &);
00044 Expression *parse_array_ref(char *&, Symtab &);
00045 Expression *parse_intrinsic_call(char *&, const String &, Symtab &);
00046 Expression *parse_function_call(char *&, const String &, Symtab &);
00047 Expression *parse_phi_expr(char *&, OP_TYPE, Symtab &);
00048 void parse_non_binary_args(char *&, Symtab &, Expression *);
00049 void parse_close_paren(char *&);
00050 void parse_close_angle_bracket(char *&);
00051 Expression * do_fold(Expression *, ExtraInfo &);
00052 struct fold_info { Wildcard *hook1, *hook2; };
00053 Boolean do_funny_check(const Expression &, ExtraInfo &);
00054 Expression * do_funny(Expression *, ExtraInfo &);
00055 struct funny2_info { Wildcard *hook1; };
00056 Expression * do_funny2(Expression *, ExtraInfo &);
00057 Boolean do_funny2_check(const Expression &, ExtraInfo &);
00058 Expression * do_funny3(Expression *, ExtraInfo &);
00059 void print_wildcard_matches(Expression &e);
00060 void traverse_action1(const Expression &subexpr, ExtraInfo &other_args);
00061
00062 template class Info<funny2_info>;
00063 template class Info<fold_info>;
00064
00065
00066
00067 int main(int argc, char *argv[])
00068 {
00069 FILE *infile;
00070 char expr_str[255];
00071 char *version = "1.0-35.5 May 24, 1995";
00072
00073 char *intrin_file_name;
00074
00075 int index = parse_switches( argc, argv, version, &intrin_file_name );
00076
00077 if (index < 0) {
00078 cerr << "Error: can not open switches database, aborting.\n";
00079 exit(1);
00080 }
00081
00082 dbx_full_parenthesization = 1;
00083 dbx_wildcards_debug_level = 1;
00084
00085 if (index == argc)
00086 infile = stdin;
00087 else if (index == argc - 1) {
00088 infile = fopen(argv[index], "r");
00089
00090 if (infile == 0)
00091 {
00092 cerr << "Error: Couldn't open file " << argv[1] << endl;
00093 exit(1);
00094 }
00095 }
00096 else {
00097 cerr << "Usage: " << argv[0] << " [file]\n";
00098 exit(1);
00099 }
00100
00101
00102
00103
00104 Expression *dummy = omega();
00105 (void) dummy->arg_list();
00106 delete dummy;
00107
00108 HeapStats::restart();
00109
00110 SETJUMP() {
00111 while (fgets(expr_str, 255, infile) != 0)
00112 if (expr_str[0] == ';')
00113 cout << expr_str;
00114 else
00115 test_expr_str(expr_str);
00116 }
00117
00118 HeapStats::report(cout);
00119 HeapStats::print_memory_leaks(cout);
00120 }
00121
00122 void
00123 test_expr_str(char *expr_str)
00124 {
00125 char *e_str = expr_str;
00126 HeapStats::reset();
00127 Symtab *symtab = new Symtab;
00128
00129 if (e_str[0] == '=' && e_str[1] == '=') {
00130 e_str += 2;
00131 Expression *e1 = parse_expr(e_str, *symtab);
00132 Expression *e2 = parse_expr(e_str, *symtab);
00133
00134 if (e1 && e2) {
00135 cout << "Comparing (" << *e1 << ") with (" << *e2 << ")\n";
00136 HeapStats::report(cout);
00137
00138 if (*e1 == *e2)
00139 cout << "**Expressions are EQUAL.\n";
00140 else
00141 cout << "**Expressions are NOT equal.\n";
00142 }
00143
00144 if (e1) delete e1;
00145 if (e2) delete e2;
00146 delete symtab;
00147 HeapStats::report(cout);
00148 HeapStats::print_memory_leaks(cout);
00149 }
00150 else if (strncmp(e_str, "backup ", 7) == 0) {
00151 e_str += 7;
00152
00153
00154
00155
00156
00157 Expression *e1 = parse_expr(e_str, *symtab);
00158 Expression *e2 = parse_expr(e_str, *symtab);
00159
00160 if (e1 && e2) {
00161 cout << "Comparing (" << *e1 << ") with (" << *e2 << ")\n";
00162
00163 e1->standardize();
00164 e2->standardize();
00165
00166 cout << "Before:\n";
00167 print_wildcard_matches(*e1);
00168 print_wildcard_matches(*e2);
00169
00170 HeapStats::report(cout);
00171
00172 if (*e1 == *e2)
00173 cout << "**Expressions are EQUAL.\n";
00174 else
00175 cout << "**Expressions are NOT equal.\n";
00176
00177 cout << "After:\n";
00178 print_wildcard_matches(*e1);
00179 print_wildcard_matches(*e2);
00180 }
00181
00182 if (e1) delete e1;
00183 if (e2) delete e2;
00184 delete symtab;
00185 HeapStats::report(cout);
00186 HeapStats::print_memory_leaks(cout);
00187 }
00188 else if (strncmp(e_str, "constant ", 9) == 0) {
00189 e_str += 9;
00190
00191
00192
00193
00194 while (e_str[strlen(e_str) - 1] == '\n') {
00195 e_str[strlen(e_str) - 1] = '\000';
00196 }
00197
00198 if (*e_str) {
00199 cout << "Calling constant(const char *) with input: "
00200 << e_str << endl;
00201 }
00202
00203 HeapStats::report(cout);
00204
00205 Expression *e1 = ::constant(e_str);
00206
00207 if (e1) {
00208 cout << "** Returned expression: " << *e1 << endl;
00209 delete e1;
00210 }
00211 else {
00212 cout << "** Returned ERROR **" << endl;
00213 }
00214
00215 delete symtab;
00216 HeapStats::report(cout);
00217 HeapStats::print_memory_leaks(cout);
00218 }
00219 else if (strncmp(e_str, "sort ", 5) == 0) {
00220 e_str += 5;
00221 Expression *e1 = parse_expr(e_str, *symtab);
00222
00223 if (e1) {
00224 cout << "Sorting (" << *e1 << ")\n";
00225 HeapStats::report(cout);
00226
00227 e1->create_signature();
00228 cout << "**After creating signature: " << *e1 << endl;
00229
00230 _sort_expr_list(e1->arg_list());
00231 cout << "**Result: " << *e1 << endl;
00232 }
00233
00234 if (e1) delete e1;
00235 delete symtab;
00236 HeapStats::report(cout);
00237 HeapStats::print_memory_leaks(cout);
00238 }
00239 else if (strncmp(e_str, "match ", 6) == 0) {
00240 e_str += 6;
00241 Expression *e1 = parse_expr(e_str, *symtab);
00242 Expression *e2 = parse_expr(e_str, *symtab);
00243
00244 if (e1 && e2) {
00245 cout << "Matching (" << *e1 << ") with (" << *e2 << ")\n";
00246 HeapStats::report(cout);
00247
00248 if (e1->match(*e2))
00249 cout << "**Expressions MATCH.\n";
00250 else
00251 cout << "**Expressions do NOT match.\n";
00252 }
00253
00254 if (e1) delete e1;
00255 if (e2) delete e2;
00256 delete symtab;
00257 HeapStats::report(cout);
00258 HeapStats::print_memory_leaks(cout);
00259 }
00260 else if (strncmp(e_str, "sum ", 4) == 0) {
00261 e_str += 4;
00262 Expression *e1 = parse_expr(e_str, *symtab);
00263 Expression *e2 = parse_expr(e_str, *symtab);
00264 Expression *e3 = parse_expr(e_str, *symtab);
00265 Expression *e4 = parse_expr(e_str, *symtab);
00266
00267 if (e1 && e2 && e3 && e4) {
00268 cout << "SUM(" << *e1 << ", " << *e2 << ", " <<
00269 *e3 << ", " << *e4 << ") " << endl;
00270
00271 HeapStats::report(cout);
00272
00273 e1 = sum( e1, *e2, *e3, *e4 );
00274
00275 if (e1 != 0) {
00276 cout << "**Result: " << *e1 << endl;
00277 }
00278 else {
00279 cout << "**Result: UNKNOWN" << endl;
00280 }
00281 }
00282
00283 if (e1) delete e1;
00284 if (e2) delete e2;
00285 if (e3) delete e3;
00286 if (e4) delete e4;
00287
00288 delete symtab;
00289 HeapStats::report(cout);
00290 HeapStats::print_memory_leaks(cout);
00291 }
00292 else if (strncmp(e_str, "traverse ", 9) == 0) {
00293 e_str += 9;
00294 Expression *e = parse_expr(e_str, *symtab);
00295 Expression *pattern = parse_expr(e_str, *symtab);
00296
00297
00298 REPLACE_OPTION option = NON_RECURSIVE_REPLACE;
00299 skip_whitespace(e_str);
00300 if (strncmp(e_str, "non-recursive", 13) == 0) {
00301 option = NON_RECURSIVE_REPLACE;
00302 e_str += 13;
00303 }
00304 else if (strncmp(e_str, "recursive", 9) == 0) {
00305 option = RECURSIVE_REPLACE;
00306 e_str += 9;
00307 }
00308 else cout << "Missing REPLACE_OPTION: Assuming non-recursive\n";
00309
00310
00311 REPLACE_ORDER order = POSTORDER_REPLACE;
00312 skip_whitespace(e_str);
00313 if (strncmp(e_str, "post", 4) == 0) {
00314 order = POSTORDER_REPLACE; e_str += 4; }
00315 else if (strncmp(e_str, "pre", 3) == 0) {
00316 order = PREORDER_REPLACE; e_str += 3; }
00317 else cout << "Missing REPLACE_ORDER: Assuming post\n";
00318
00319 if (e && pattern) {
00320 cout << "Traversing (" << *e
00321 << ") using pattern ("
00322 << *pattern << ")\n";
00323 HeapStats::report(cout);
00324
00325 cout << "**Results:\n";
00326
00327 traverse(*e, *pattern, traverse_action1, (ExtraInfo &)* new Info<int>(0),
00328 option, order);
00329 }
00330
00331 delete e;
00332 delete pattern;
00333 delete symtab;
00334
00335 HeapStats::report(cout);
00336 HeapStats::print_memory_leaks(cout);
00337 }
00338 else if (strncmp(e_str, "subst ", 6) == 0) {
00339 e_str += 6;
00340 Expression *e = parse_expr(e_str, *symtab);
00341 skip_whitespace(e_str);
00342 Symbol *var = parse_symbol(e_str, *symtab);
00343 Expression *value = parse_expr(e_str, *symtab);
00344
00345 if (e && var && value) {
00346 cout << "Substituting " << var->name_ref() << "=" << *value
00347 << " into " << *e << endl;
00348 HeapStats::report(cout);
00349 e = substitute_var(e, *var, *value);
00350 cout << "**Result: " << *e << endl;
00351 }
00352
00353 if (e) delete e;
00354 if (value) delete value;
00355 delete symtab;
00356 HeapStats::report(cout);
00357 HeapStats::print_memory_leaks(cout);
00358 }
00359 else if (strncmp(e_str, "replace ", 8) == 0) {
00360 e_str += 8;
00361 Expression *e = parse_expr(e_str, *symtab);
00362 skip_whitespace(e_str);
00363 Expression *pattern = parse_expr(e_str, *symtab);
00364 skip_whitespace(e_str);
00365 Expression *replacement = parse_expr(e_str, *symtab);
00366
00367
00368 REPLACE_OPTION option = NON_RECURSIVE_REPLACE;
00369 skip_whitespace(e_str);
00370 if (strncmp(e_str, "non-recursive", 13) == 0) {
00371 option = NON_RECURSIVE_REPLACE;
00372 e_str += 13;
00373 }
00374 else if (strncmp(e_str, "recursive", 9) == 0) {
00375 option = RECURSIVE_REPLACE;
00376 e_str += 9;
00377 }
00378 else cout << "Missing REPLACE_OPTION: Assuming non-recursive\n";
00379
00380
00381 REPLACE_ORDER order = POSTORDER_REPLACE;
00382 skip_whitespace(e_str);
00383 if (strncmp(e_str, "post", 4) == 0) {
00384 order = POSTORDER_REPLACE; e_str += 4; }
00385 else if (strncmp(e_str, "pre", 3) == 0) {
00386 order = PREORDER_REPLACE; e_str += 3; }
00387 else cout << "Missing REPLACE_ORDER: Assuming post\n";
00388
00389 if (e && pattern && replacement) {
00390 cout << "Replacing:\n expr = "
00391 << *e << "\n pattern = "
00392 << *pattern << "\n replacement = "
00393 << *replacement << "\n options: "
00394 << (option == NON_RECURSIVE_REPLACE ? "non-recursive "
00395 : "recursive")
00396 << ", "
00397 << (order == PREORDER_REPLACE ? "pre-order" : "post-order")
00398 << endl;
00399 HeapStats::report(cout);
00400 e = replace(e, *pattern, *replacement, option, order);
00401 cout << "**Result: " << *e << endl;
00402 }
00403
00404 if (e) delete e;
00405 if (pattern) delete pattern;
00406 if (replacement) delete replacement;
00407 delete symtab;
00408 HeapStats::report(cout);
00409 HeapStats::print_memory_leaks(cout);
00410 }
00411 else if (strncmp(e_str, "fold ", 5) == 0) {
00412 e_str += 5;
00413 Expression *e = parse_expr(e_str, *symtab);
00414 skip_whitespace(e_str);
00415
00416 fold_info my_fold_info;
00417
00418 Expression *pattern =
00419 add(my_fold_info.hook1 = any_int_const(),
00420 my_fold_info.hook2 = any_int_const());
00421
00422
00423 REPLACE_OPTION option = NON_RECURSIVE_REPLACE;
00424 skip_whitespace(e_str);
00425 if (strncmp(e_str, "non-recursive", 13) == 0) {
00426 option = NON_RECURSIVE_REPLACE;
00427 e_str += 13;
00428 }
00429 else if (strncmp(e_str, "recursive", 9) == 0) {
00430 option = RECURSIVE_REPLACE;
00431 e_str += 9;
00432 }
00433 else cout << "Missing REPLACE_OPTION: Assuming non-recursive\n";
00434
00435
00436 REPLACE_ORDER order = POSTORDER_REPLACE;
00437 skip_whitespace(e_str);
00438 if (strncmp(e_str, "post", 4) == 0) {
00439 order = POSTORDER_REPLACE; e_str += 4; }
00440 else if (strncmp(e_str, "pre", 3) == 0) {
00441 order = PREORDER_REPLACE; e_str += 3; }
00442 else cout << "Missing REPLACE_ORDER: Assuming post\n";
00443
00444 if (e && pattern) {
00445 cout << "Folding:\n expr = "
00446 << *e << "\n pattern = "
00447 << *pattern << "\n options: "
00448 << (option == NON_RECURSIVE_REPLACE ? "non-recursive "
00449 : "recursive")
00450 << ", "
00451 << (order == PREORDER_REPLACE ? "pre-order" : "post-order")
00452 << endl;
00453 HeapStats::report(cout);
00454 e = replace(e, *pattern,
00455 do_fold, (ExtraInfo &)*new Info<fold_info>(my_fold_info),
00456 option, order);
00457 cout << "**Result: " << *e << endl;
00458 }
00459
00460 if (e) delete e;
00461 if (pattern) delete pattern;
00462 delete symtab;
00463 HeapStats::report(cout);
00464 HeapStats::print_memory_leaks(cout);
00465 }
00466 else if (strncmp(e_str, "funny ", 6) == 0) {
00467 e_str += 6;
00468 Expression *e = parse_expr(e_str, *symtab);
00469 skip_whitespace(e_str);
00470
00471 Expression *pattern = any_int_const();
00472
00473
00474 REPLACE_OPTION option = NON_RECURSIVE_REPLACE;
00475 skip_whitespace(e_str);
00476 if (strncmp(e_str, "non-recursive", 13) == 0) {
00477 option = NON_RECURSIVE_REPLACE;
00478 e_str += 13;
00479 }
00480 else if (strncmp(e_str, "recursive", 9) == 0) {
00481 option = RECURSIVE_REPLACE;
00482 e_str += 9;
00483 }
00484 else cout << "Missing REPLACE_OPTION: Assuming non-recursive\n";
00485
00486
00487 REPLACE_ORDER order = POSTORDER_REPLACE;
00488 skip_whitespace(e_str);
00489 if (strncmp(e_str, "post", 4) == 0) {
00490 order = POSTORDER_REPLACE; e_str += 4; }
00491 else if (strncmp(e_str, "pre", 3) == 0) {
00492 order = PREORDER_REPLACE; e_str += 3; }
00493 else cout << "Missing REPLACE_ORDER: Assuming post\n";
00494
00495 if (e && pattern) {
00496 cout << "Funny:\n expr = "
00497 << *e << "\n pattern = "
00498 << *pattern << "\n options: "
00499 << (option == NON_RECURSIVE_REPLACE ? "non-recursive "
00500 : "recursive")
00501 << ", "
00502 << (order == PREORDER_REPLACE ? "pre-order" : "post-order")
00503 << endl;
00504 HeapStats::report(cout);
00505 e = replace(e, *pattern,
00506 do_funny_check, do_funny, (ExtraInfo &)*new OmegaInfo(),
00507 option, order);
00508 cout << "**Result: " << *e << endl;
00509 }
00510
00511 if (e) delete e;
00512 if (pattern) delete pattern;
00513 delete symtab;
00514 HeapStats::report(cout);
00515 HeapStats::print_memory_leaks(cout);
00516 }
00517 else if (strncmp(e_str, "funny2 ", 7) == 0) {
00518 e_str += 7;
00519 Expression *e = parse_expr(e_str, *symtab);
00520 skip_whitespace(e_str);
00521
00522 struct funny2_info info;
00523
00524 Expression *pattern =
00525 add(
00526 info.hook1 = any_int_const(),
00527 constant(-1));
00528
00529
00530 REPLACE_OPTION option = NON_RECURSIVE_REPLACE;
00531 skip_whitespace(e_str);
00532 if (strncmp(e_str, "non-recursive", 13) == 0) {
00533 option = NON_RECURSIVE_REPLACE;
00534 e_str += 13;
00535 }
00536 else if (strncmp(e_str, "recursive", 9) == 0) {
00537 option = RECURSIVE_REPLACE;
00538 e_str += 9;
00539 }
00540 else cout << "Missing REPLACE_OPTION: Assuming non-recursive\n";
00541
00542
00543 REPLACE_ORDER order = POSTORDER_REPLACE;
00544 skip_whitespace(e_str);
00545 if (strncmp(e_str, "post", 4) == 0) {
00546 order = POSTORDER_REPLACE; e_str += 4; }
00547 else if (strncmp(e_str, "pre", 3) == 0) {
00548 order = PREORDER_REPLACE; e_str += 3; }
00549 else cout << "Missing REPLACE_ORDER: Assuming post\n";
00550
00551 if (e && pattern) {
00552 cout << "Funny2:\n expr = "
00553 << *e << "\n pattern = "
00554 << *pattern << "\n options: "
00555 << (option == NON_RECURSIVE_REPLACE ? "non-recursive "
00556 : "recursive")
00557 << ", "
00558 << (order == PREORDER_REPLACE ? "pre-order" : "post-order")
00559 << endl;
00560 HeapStats::report(cout);
00561 e = replace(e, *pattern,
00562 do_funny2_check, do_funny2, (ExtraInfo &)*new Info<funny2_info>(info),
00563 option, order);
00564 cout << "**Result: " << *e << endl;
00565 }
00566
00567 if (e) delete e;
00568 if (pattern) delete pattern;
00569 delete symtab;
00570 HeapStats::report(cout);
00571 HeapStats::print_memory_leaks(cout);
00572 }
00573 else if (strncmp(e_str, "funny3 ", 7) == 0) {
00574 e_str += 7;
00575 Expression *e = parse_expr(e_str, *symtab);
00576 skip_whitespace(e_str);
00577
00578
00579
00580
00581
00582
00583
00584 Expression *pattern =
00585 wildcard_or(any_int_const(),
00586 any_array_ref());
00587
00588 REPLACE_OPTION option = NON_RECURSIVE_REPLACE;
00589 REPLACE_ORDER order = PREORDER_REPLACE;
00590
00591 if (e && pattern) {
00592 cout << "Funny3:\n expr = "
00593 << *e << "\n pattern = "
00594 << *pattern << "\n";
00595
00596 HeapStats::report(cout);
00597 e = replace(e, *pattern,
00598 do_funny3, (ExtraInfo &)*new OmegaInfo(),
00599 option, order);
00600 cout << "**Result: " << *e << endl;
00601 }
00602
00603 if (e) delete e;
00604 if (pattern) delete pattern;
00605 delete symtab;
00606 HeapStats::report(cout);
00607 HeapStats::print_memory_leaks(cout);
00608 }
00609 else if (strncmp(e_str, "clone ", 6) == 0) {
00610 e_str += 6;
00611 Expression *e = parse_expr(e_str, *symtab);
00612 Expression *clone = 0;
00613
00614 if (e) {
00615 cout << "Cloning Expression " << *e << endl;
00616 HeapStats::report(cout);
00617 clone = e->clone();
00618 cout << "**Result: " << *clone << endl;
00619 }
00620
00621 if (e) delete e;
00622 if (clone) delete clone;
00623 delete symtab;
00624 HeapStats::report(cout);
00625 HeapStats::print_memory_leaks(cout);
00626 }
00627 else if (strncmp(e_str, "arg_refs ", 9) == 0) {
00628 e_str += 9;
00629 Expression *e = parse_expr(e_str, *symtab);
00630
00631 if (e) {
00632 cout << "**Arg refs for: " << *e << endl;
00633 HeapStats::report(cout);
00634 const RefList<Expression> *args = e->arg_refs();
00635 Iterator<Expression> iter(*args);
00636
00637 for ( ; iter.valid(); iter.next())
00638 cout << " " << iter.current() << endl;
00639
00640
00641 delete e;
00642 }
00643
00644 delete symtab;
00645
00646 if (e) {
00647 HeapStats::report(cout);
00648 HeapStats::print_memory_leaks(cout);
00649 }
00650 }
00651 else {
00652 Expression *e = parse_expr(e_str, *symtab);
00653
00654 if (e) {
00655 cout << "**Before: " << *e << endl;
00656 HeapStats::report(cout);
00657 e = simplify(e);
00658 cout << "**After: " << *e << endl;
00659 ExprSignature old_signature = e->signature();
00660 e->standardize();
00661
00662 if (old_signature.hash_value() != e->signature().hash_value()) {
00663 cout << "WARNING: Expr signature is not correct: ";
00664 cout << "(" << e->signature();
00665 cout << " should be " << old_signature << ")\n";
00666 }
00667
00668 delete e;
00669 }
00670 else
00671 cout << endl;
00672
00673 delete symtab;
00674
00675 if (e) {
00676 HeapStats::report(cout);
00677 HeapStats::print_memory_leaks(cout);
00678 }
00679 }
00680 }
00681
00682 Expression *
00683 parse_expr (char *& expr_str, Symtab &symtab)
00684 {
00685 char ch;
00686
00687 skip_whitespace(expr_str);
00688
00689 if (! *expr_str)
00690 return 0;
00691
00692 if (isalpha(*expr_str)) {
00693 Symbol *sym = parse_symbol(expr_str, symtab);
00694
00695 if (strcmp(sym->name_ref(), "TRUE") == 0)
00696 return constant(".TRUE.");
00697 else if (strcmp(sym->name_ref(), "FALSE") == 0)
00698 return constant(".FALSE.");
00699 else if (strcmp(sym->name_ref(), "NULL") == 0)
00700 return 0;
00701 else if (strcmp(sym->name_ref(), "OM") == 0)
00702 return omega();
00703 else if (strcmp(sym->name_ref(), "INF") == 0)
00704 return infinity();
00705 else
00706 return id(*sym);
00707 }
00708 else if (isdigit(*expr_str) || *expr_str == '-')
00709 return constant(parse_int(expr_str));
00710 else if (*expr_str == '#')
00711 return parse_real(expr_str);
00712 else if (*expr_str == '(')
00713 return parse_op(expr_str, symtab);
00714 else if (*expr_str == '<')
00715 return parse_wildcard_op(expr_str, symtab);
00716 else {
00717 cerr << "Expression Parser Error: Unrecognized char " << *expr_str
00718 << endl;
00719 ++expr_str;
00720 return 0;
00721 }
00722 }
00723
00724 void
00725 skip_whitespace(char *& expr_str)
00726 {
00727 while (*expr_str && isspace(*expr_str))
00728 ++expr_str;
00729 }
00730
00731 Symbol *
00732 parse_name(char *& expr_str, char buf[])
00733 {
00734 int i = 0;
00735
00736 while (*expr_str && isalnum(*expr_str))
00737 buf[i++] = *(expr_str++);
00738
00739 buf[i] = '\0';
00740
00741 for (i = 0; buf[i] != '\0'; i++)
00742 if (islower(buf[i]))
00743 buf[i] = toupper(buf[i]);
00744 }
00745
00746 Symbol *
00747 parse_symbol(char *& expr_str, Symtab &symtab)
00748 {
00749 Symbol *sym;
00750 char buf[100];
00751
00752 parse_name(expr_str, buf);
00753 sym = symtab.find_ref(buf);
00754
00755 if (! sym) {
00756 sym = new VariableSymbol(buf, make_type(INTEGER_TYPE),
00757 NOT_FORMAL, NOT_SAVED);
00758 symtab.ins(sym);
00759 }
00760
00761 p_assert(sym->sym_class() == VARIABLE_CLASS,
00762 "Symbol is not a variable symbol.");
00763
00764 return sym;
00765 }
00766
00767 Symbol *
00768 parse_function_symbol(char *expr_str, Symtab &symtab)
00769 {
00770 Symbol *sym;
00771 char buf[100];
00772
00773 parse_name(expr_str, buf);
00774 sym = symtab.find_ref(buf);
00775
00776 if (! sym) {
00777 sym = new FunctionSymbol(buf, make_type(INTEGER_TYPE),
00778 NOT_EXTERNAL, IS_INTRINSIC, NOT_FORMAL);
00779 symtab.ins(sym);
00780 }
00781
00782 p_assert(sym->sym_class() == FUNCTION_CLASS,
00783 "Symbol is not a function symbol.");
00784
00785 return sym;
00786 }
00787
00788 long
00789 parse_int(char *& expr_str)
00790 {
00791 char buf[100];
00792 int i = 0;
00793
00794 if (*expr_str == '-')
00795 buf[i++] = *(expr_str++);
00796
00797 while (*expr_str && isdigit(*expr_str))
00798 buf[i++] = *(expr_str++);
00799
00800 buf[i] = '\0';
00801
00802 return (long) atoi(buf);
00803 }
00804
00805 Expression *
00806 parse_real(char *& expr_str)
00807 {
00808 char buf[100];
00809 int i = 0;
00810
00811 if (*expr_str == '#')
00812 ++expr_str;
00813
00814 if (*expr_str == '-')
00815 buf[i++] = *(expr_str++);
00816
00817 while (*expr_str && (isdigit(*expr_str) || *expr_str == '.'))
00818 buf[i++] = *(expr_str++);
00819
00820 buf[i] = '\0';
00821
00822 return constant(buf);
00823 }
00824
00825 Expression *
00826 parse_op(char *& expr_str, Symtab &symtab)
00827 {
00828 char buf[100];
00829 int i = 0;
00830
00831 if (*expr_str == '(')
00832 ++expr_str;
00833
00834 skip_whitespace(expr_str);
00835
00836 while (*expr_str && ! isspace(*expr_str)
00837 && *expr_str != '(' && *expr_str != ')')
00838 buf[i++] = *(expr_str++);
00839
00840 buf[i] = '\0';
00841
00842 String op(buf);
00843
00844 if (op == "+")
00845 return parse_nonbinary_expr(expr_str, ADD_OP, INTEGER_TYPE, symtab);
00846 else if (op == "*")
00847 return parse_nonbinary_expr(expr_str, MULT_OP, INTEGER_TYPE, symtab);
00848 else if (op == "-")
00849 return parse_binary_expr(expr_str, SUB_OP, INTEGER_TYPE, symtab);
00850 else if (op == "/")
00851 return parse_binary_expr(expr_str, DIV_OP, INTEGER_TYPE, symtab);
00852 else if (op == "**")
00853 return parse_binary_expr(expr_str, EXP_OP, INTEGER_TYPE, symtab);
00854 else if (op == "[]")
00855 return parse_array_ref(expr_str, symtab);
00856 else if (op == "U-")
00857 return parse_unary_expr(expr_str, U_MINUS_OP, INTEGER_TYPE, symtab);
00858 else if (op == "U+")
00859 return parse_unary_expr(expr_str, U_PLUS_OP, INTEGER_TYPE, symtab);
00860 else if (op == "not")
00861 return parse_unary_expr(expr_str, NOT_OP, LOGICAL_TYPE, symtab);
00862 else if (op == "<")
00863 return parse_binary_expr(expr_str, LT_OP, LOGICAL_TYPE, symtab);
00864 else if (op == "<=")
00865 return parse_binary_expr(expr_str, LE_OP, LOGICAL_TYPE, symtab);
00866 else if (op == ">")
00867 return parse_binary_expr(expr_str, GT_OP, LOGICAL_TYPE, symtab);
00868 else if (op == ">=")
00869 return parse_binary_expr(expr_str, GE_OP, LOGICAL_TYPE, symtab);
00870 else if (op == "==")
00871 return parse_binary_expr(expr_str, EQ_OP, LOGICAL_TYPE, symtab);
00872 else if (op == "!=")
00873 return parse_binary_expr(expr_str, NE_OP, LOGICAL_TYPE, symtab);
00874 else if (op == "and")
00875 return parse_nonbinary_expr(expr_str, AND_OP, LOGICAL_TYPE, symtab);
00876 else if (op == "or")
00877 return parse_nonbinary_expr(expr_str, OR_OP, LOGICAL_TYPE, symtab);
00878 else if (op == "eqv")
00879 return parse_nonbinary_expr(expr_str, EQV_OP, LOGICAL_TYPE, symtab);
00880 else if (op == "neqv")
00881 return parse_nonbinary_expr(expr_str, NEQV_OP, LOGICAL_TYPE, symtab);
00882 else if (op == "gamma")
00883 return parse_phi_expr(expr_str, GAMMA_OP, symtab);
00884 else if (op == "mu")
00885 return parse_phi_expr(expr_str, MU_OP, symtab);
00886 else if (op == "min" || op == "max" || op == "mod" || op == "abs"
00887 || op == "ifix")
00888 return parse_intrinsic_call(expr_str, op, symtab);
00889 else
00890 return parse_function_call(expr_str, op, symtab);
00891 }
00892
00893 Expression *
00894 parse_wildcard_op(char *& expr_str, Symtab &symtab)
00895 {
00896 char buf[100];
00897 int i = 0;
00898
00899 if (*expr_str == '<')
00900 ++expr_str;
00901
00902 skip_whitespace(expr_str);
00903
00904 while (*expr_str && ! isspace(*expr_str)
00905 && *expr_str != '(' && *expr_str != ')' && *expr_str != '>')
00906 buf[i++] = *(expr_str++);
00907
00908 buf[i] = '\0';
00909
00910 String op(buf);
00911
00912 if (op == ".")
00913 return parse_no_arg_wildcard_expr(expr_str, ANY_WC, symtab);
00914 if (op == ".*")
00915 return parse_no_arg_wildcard_expr(expr_str,
00916 ANY_EXPR_SUBSET_WC,
00917 symtab);
00918 if (op == "AnyID")
00919 return parse_no_arg_wildcard_expr(expr_str, ANY_ID_WC, symtab);
00920 if (op == "AnyArrayRef")
00921 return parse_no_arg_wildcard_expr(expr_str, ANY_ARRAY_REF_WC, symtab);
00922 if (op == "AnyIntConst")
00923 return parse_no_arg_wildcard_expr(expr_str, ANY_INT_CONST_WC,
00924 symtab);
00925 if (op == "AnyLogicalConst")
00926 return parse_no_arg_wildcard_expr(expr_str, ANY_LOGICAL_CONST_WC,
00927 symtab);
00928 else if (op == "NOT")
00929 return parse_unary_wildcard_expr(expr_str, NOT_WC, symtab);
00930 else if (op == "Contains")
00931 return parse_unary_wildcard_expr(expr_str, CONTAINS_WC, symtab);
00932 else if (op == "AND")
00933 return parse_binary_wildcard_expr(expr_str, AND_WC, symtab);
00934 else if (op == "OR")
00935 return parse_binary_wildcard_expr(expr_str, OR_WC, symtab);
00936 else {
00937 cerr << "Unrecognized WildCard '" << op << "'\n";
00938 return 0;
00939 }
00940 }
00941
00942 Expression *
00943 parse_unary_expr(char *& expr_str, OP_TYPE op, EXPR_TYPE type, Symtab &symtab)
00944 {
00945 Expression *e = new UnaryExpr(op, make_type(type),
00946 parse_expr(expr_str, symtab));
00947 parse_close_paren(expr_str);
00948
00949 return e;
00950 }
00951
00952 Expression *
00953 parse_binary_expr(char *& expr_str, OP_TYPE op, EXPR_TYPE type, Symtab &symtab)
00954 {
00955 Expression *e = new BinaryExpr(op, make_type(type),
00956 parse_expr(expr_str, symtab),
00957 parse_expr(expr_str, symtab));
00958 parse_close_paren(expr_str);
00959
00960 return e;
00961 }
00962
00963 Expression *
00964 parse_nonbinary_expr(char *& expr_str, OP_TYPE op, EXPR_TYPE type,
00965 Symtab &symtab)
00966 {
00967 Expression *e = new NonBinaryExpr(op, make_type(type));
00968 parse_non_binary_args(expr_str, symtab, e);
00969 return e;
00970 }
00971
00972 Expression *
00973 parse_no_arg_wildcard_expr(char *& expr_str, OP_TYPE op, Symtab &symtab)
00974 {
00975 Expression *e = 0;
00976
00977 switch(op) {
00978 case ANY_WC:
00979 e = new AnyExpr;
00980 break;
00981 case ANY_EXPR_SUBSET_WC:
00982 e = new AnyExprSubset;
00983 break;
00984 case ANY_ID_WC:
00985 e = new AnyID;
00986 break;
00987 case ANY_INT_CONST_WC:
00988 e = new AnyIntConst;
00989 break;
00990 case ANY_LOGICAL_CONST_WC:
00991 e = new AnyLogicalConst;
00992 break;
00993 default:
00994 p_assert(0, "Unrecognized No-Arg WildCard Type");
00995 break;
00996 }
00997
00998 p_assert(e, "e is NULL");
00999
01000 parse_close_angle_bracket(expr_str);
01001 return e;
01002 }
01003
01004 Expression *
01005 parse_unary_wildcard_expr(char *& expr_str, OP_TYPE op, Symtab &symtab)
01006 {
01007 Expression *arg = parse_expr(expr_str, symtab);
01008
01009 Expression *e = 0;
01010
01011 switch(op) {
01012 case NOT_WC:
01013 e = new WildcardNot(arg);
01014 break;
01015 case CONTAINS_WC:
01016 e = new WildcardContains(arg);
01017 break;
01018 default:
01019 p_assert(0, "Unrecognized Unary WildCard Type");
01020 break;
01021 }
01022
01023 p_assert(e, "e is NULL");
01024
01025 parse_close_angle_bracket(expr_str);
01026 return e;
01027 }
01028
01029 Expression *
01030 parse_binary_wildcard_expr(char *& expr_str, OP_TYPE op, Symtab &symtab)
01031 {
01032 Expression *left = parse_expr(expr_str, symtab);
01033 Expression *right = parse_expr(expr_str, symtab);
01034
01035 Expression *e = 0;
01036
01037 switch(op) {
01038 case AND_WC:
01039 e = new WildcardAnd(left, right);
01040 break;
01041 case OR_WC:
01042 e = new WildcardOr(left, right);
01043 break;
01044 default:
01045 p_assert(0, "Unrecognized Binary WildCard Type");
01046 break;
01047 }
01048
01049 p_assert(e, "e is NULL");
01050 parse_close_angle_bracket(expr_str);
01051 return e;
01052 }
01053
01054 Expression *
01055 parse_array_ref(char *& expr_str, Symtab &symtab)
01056 {
01057 Expression *array = parse_expr(expr_str, symtab);
01058 Expression *subscript = new CommaExpr();
01059 parse_non_binary_args(expr_str, symtab, subscript);
01060
01061 return array_reference(array, subscript);
01062 }
01063
01064
01065 Expression *
01066 parse_intrinsic_call(char *& expr_str, const String &name, Symtab &symtab)
01067 {
01068 Symbol *nsym = parse_function_symbol(CASTAWAY(char *)(const char *)name, symtab);
01069 nsym->intrinsic(IS_INTRINSIC);
01070 Expression *args = new CommaExpr();
01071 parse_non_binary_args(expr_str, symtab, args);
01072
01073 return intrinsic_call(id(*nsym), args);
01074 }
01075
01076
01077 Expression *
01078 parse_function_call(char *& expr_str, const String &name, Symtab &symtab)
01079 {
01080 Symbol *nsym = parse_function_symbol(CASTAWAY(char *)(const char *)name, symtab);
01081 nsym->intrinsic(NOT_INTRINSIC);
01082 Expression *args = new CommaExpr();
01083 parse_non_binary_args(expr_str, symtab, args);
01084
01085 return function_call(id(*nsym), args);
01086 }
01087
01088 Expression *
01089 parse_phi_expr(char *& expr_str, OP_TYPE op, Symtab &symtab)
01090 {
01091 Expression *gate = 0;
01092
01093 if (op == GAMMA_OP)
01094 gate = parse_expr(expr_str, symtab);
01095
01096 Expression *args = new CommaExpr();
01097 parse_non_binary_args(expr_str, symtab, args);
01098
01099 switch (op) {
01100 case GAMMA_OP:
01101 return gamma(gate, args);
01102 case MU_OP:
01103 return mu(gate, args);
01104 default:
01105 return NULL;
01106 }
01107 return NULL;
01108 }
01109
01110
01111 void
01112 parse_non_binary_args(char *& expr_str, Symtab &symtab, Expression *nbe)
01113 {
01114 while (*expr_str && *expr_str != ')') {
01115 Expression *arg = parse_expr(expr_str, symtab);
01116
01117 if (arg)
01118 nbe->arg_list().ins_last(arg);
01119 }
01120
01121 parse_close_paren(expr_str);
01122 }
01123
01124 void
01125 parse_close_paren(char *& expr_str)
01126 {
01127 skip_whitespace(expr_str);
01128
01129 if (*expr_str != ')')
01130 cerr << "Missing closing ')' in expression string\n";
01131 else
01132 ++expr_str;
01133 }
01134 void
01135 parse_close_angle_bracket(char *& expr_str)
01136 {
01137 skip_whitespace(expr_str);
01138
01139 if (*expr_str != '>')
01140 cerr << "Missing closing '>' in wildcard expression string\n";
01141 else
01142 ++expr_str;
01143 }
01144
01145 Expression * do_fold(Expression * e,
01146 ExtraInfo &extra_data) {
01147 fold_info & info = ((Info<fold_info> &) extra_data).data();
01148 p_assert(info.hook1->matched_exists() && info.hook2->matched_exists(),
01149 "One of the hooks didn't match");
01150
01151 int folded_value = info.hook1->matched().value()
01152 + info.hook2->matched().value();
01153 delete e;
01154 return constant(folded_value);
01155 }
01156
01157
01158
01159
01160
01161 Boolean do_funny_check(const Expression &e, ExtraInfo &other) {
01162 return (e.op() == INTEGER_CONSTANT_OP && e.value() < 4);
01163 }
01164 Expression * do_funny(Expression * e,
01165 ExtraInfo &extra_data) {
01166 e->value(e->value() + 1);
01167 return add(constant("1.0"), e);
01168 }
01169
01170
01171
01172
01173
01174
01175
01176 Boolean do_funny2_check(const Expression &, ExtraInfo &other) {
01177 funny2_info & info = ((Info<funny2_info> &) other).data();
01178 p_assert(info.hook1->matched_exists(),
01179 "The hook didn't match");
01180
01181 return (info.hook1->matched().value() < 5);
01182 }
01183 Expression * do_funny2(Expression *e,
01184 ExtraInfo &extra_data) {
01185 funny2_info & info = ((Info<funny2_info> &) extra_data).data();
01186 p_assert(info.hook1->matched_exists(),
01187 "The hook didn't match");
01188
01189 info.hook1->matched().value(info.hook1->matched().value() + 1);
01190 return add(constant(-1), e);
01191 }
01192
01193
01194
01195 Expression * do_funny3(Expression * e,
01196 ExtraInfo &) {
01197 switch(e->op()) {
01198 case INTEGER_CONSTANT_OP:
01199 delete e;
01200 return constant(100);
01201 break;
01202 case ARRAY_REF_OP:
01203 {
01204 Expression *repl = constant(200);
01205 Expression *pattern = any_int_const();
01206 Expression *new_e = replace(e, *pattern, *repl);
01207 delete repl;
01208 delete pattern;
01209 return new_e;
01210 }
01211 break;
01212 default:
01213 p_assert(False, "Error");
01214 return 0;
01215 }
01216 }
01217
01218
01219
01220
01221
01222 class print_match {
01223 private:
01224 Wildcard &_w;
01225 public:
01226 print_match(Wildcard &w) : _w(w) { }
01227 friend ostream & operator << (ostream &o, const print_match &pm) {
01228 if (pm._w.matched_exists()) {
01229 o << "(matched [ " << pm._w.matched() << " ])";
01230 }
01231 else {
01232 o << "(No Match)";
01233 }
01234 return o;
01235 }
01236 };
01237
01238 void print_wildcard_matches(Expression &e) {
01239 if (e.is_wildcard()) {
01240 cout << " Wildcard '" << e << "': "
01241 << print_match((Wildcard&)e)
01242 << endl;
01243 }
01244 for (Iterator<Expression> iter = e.arg_list(); iter.valid(); ++iter) {
01245 print_wildcard_matches(iter.current());
01246 }
01247 }
01248
01249
01250
01251
01252 void
01253 traverse_action1(const Expression &subexpr, ExtraInfo &other_args) {
01254 cout << "** Traversal match: " << subexpr << endl;
01255 }