home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / trc / part6 < prev    next >
Encoding:
Text File  |  1986-11-30  |  26.6 KB  |  1,138 lines

  1. Newsgroups: mod.sources
  2. Subject: TRC - expert system building tool (part 6 of 8)
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 3, Issue 114
  6. Submitted by: ihnp4!dicomed!ndsuvax!nckary (Daniel D. Kary)
  7.  
  8. : This is a shar archive.  Extract with sh, not csh.
  9. : The rest of this file will extract:
  10. : Makefile main.c main.h optimize.c
  11. echo extracting - Makefile
  12. sed 's/^X//' > Makefile << '!EOR!'
  13. Xtrc : y.tab.o main.o output.o optimize.o p_out.o
  14. X    cc y.tab.o main.o output.o optimize.o p_out.o -o trc
  15. X
  16. Xy.tab.o : y.tab.c   scanner.c main.h
  17. X    cc -c y.tab.c
  18. X
  19. Xy.tab.c : parser
  20. X    yacc parser
  21. X
  22. Xmain.o : main.c    main.h
  23. X    cc -c main.c
  24. X
  25. Xoutput.o : output.c main.h
  26. X    cc -c output.c
  27. X
  28. Xp_out.o : p_out.c main.h
  29. X    cc -c p_out.c
  30. X
  31. Xoptimize.o : optimize.c main.h
  32. X    cc -c optimize.c
  33. !EOR!
  34. echo extracting - main.c
  35. sed 's/^X//' > main.c << '!EOR!'
  36. X#include    <stdio.h>
  37. X#include    <signal.h>
  38. X#include     "main.h"
  39. X#define        total_files    12
  40. X
  41. XFILE *fp[total_files];
  42. Xchar *file_name[total_files] = {
  43. X        "loop.h",
  44. X        "loop.c",
  45. X        "free.c",
  46. X        "misc.c",
  47. X        "search.c",
  48. X        "add.c",
  49. X        "dump.c",
  50. X        "relink.c",
  51. X        "backtrack.c",
  52. X        "profile.c",
  53. X        "zero.c",
  54. X        "save.c"
  55. X};
  56. X
  57. Xbus_error()
  58. X{
  59. X    fprintf(stderr,"%d: unable to recover from earlier errors\n", lineno);
  60. X    exit(0);
  61. X}
  62. X
  63. X
  64. Xint next_label;
  65. X
  66. Xmain(argc, argv)
  67. Xint argc;
  68. Xchar *argv[];
  69. X{
  70. X    int i, j;
  71. X    char s[512];
  72. X
  73. X    setbuf(stdout, NULL);
  74. X    errors = pnum = total_tokens = 0;
  75. X    tracing = profiling = backtracking = 0;
  76. X    dumping = optimizing = recursing = 0;
  77. X    pascal = saving = zeroing = 0;
  78. X    next_label = lineno = 1;  
  79. X    prefix = "";
  80. X    if(argc < 2){
  81. X        fprintf(stderr,"usage: %s [options] file\n", argv[0]);
  82. X        exit();
  83. X    }
  84. X    for(i = 1; i < (argc-1); i++){
  85. X        j = 0;
  86. X        while(argv[i][j]){
  87. X            switch(argv[i][j]){
  88. X            case '-': break;
  89. X                case 'b': backtracking++;
  90. X                      break;
  91. X                case 'd': dumping++;
  92. X                      break;
  93. X                case 'p': profiling++;
  94. X                      break;
  95. X                case 'r': recursing++;
  96. X                      break;
  97. X                case 's': saving++;
  98. X                      break;
  99. X                case 't': tracing++;
  100. X                      break;
  101. X                case 'z': zeroing++;
  102. X                      break;
  103. X                case 'O': optimizing++;
  104. X                      break;
  105. X                case 'P': pascal++;
  106. X                      break;
  107. X                default: fprintf(stderr,"undefined flag (%c)\n",argv[i][1]);
  108. X                     break;
  109. X            }
  110. X            j++;
  111. X        }
  112. X    }
  113. X    if((freopen(argv[argc-1], "r", stdin)) == NULL){
  114. X        fprintf(stderr,"unable to attach %s to the standard input\n", argv[argc-1]);
  115. X        exit(0);
  116. X    }
  117. X    insert_init();                /* initialize this list */
  118. X    signal(SIGBUS, bus_error);
  119. X    yyparse();                /* parse the input */
  120. X    rule_list = rule_list->next;        /* the first entry is just a place holder */
  121. X    rule_list->prev = NULL;
  122. X    nice_token_stuff();
  123. X    if(errors){
  124. X        fprintf(stderr,"no code produced due to errors in source\n");
  125. X        exit();
  126. X    }
  127. X    if(pascal){
  128. X        if(optimizing)
  129. X        optimize();
  130. X        p_translate();
  131. X        exit();
  132. X    }
  133. X    for(i = 0; i < total_files; i++){
  134. X        strcpy(s, prefix);
  135. X        strcat(s, file_name[i]);
  136. X        if((fp[i] = fopen(s,"w")) == NULL){
  137. X            fprintf(stderr,"unable to open %s\n",s);
  138. X            exit(0);
  139. X        }
  140. X        if(i){
  141. X        fprintf(fp[i],"#include\t\"%sloop.h\"\n\n",prefix);
  142. X        if(i > 1){
  143. X            fprintf(fp[i],"extern int %stotal_tokens, %stoken[];\n", prefix, prefix);
  144. X             fprintf(fp[i],"extern char *%stoken_name[];\n", prefix);
  145. X             fprintf(fp[i],"extern int %srestoring;\n", prefix);
  146. X            }
  147. X        else{
  148. X             fprintf(fp[i],"int %srestoring = 0;\n", prefix);
  149. X        }
  150. X        }
  151. X    }
  152. X    header = fp[0];
  153. X    loop = fp[1];
  154. X    fre = fp[2];
  155. X    misc = fp[3];
  156. X    search = fp[4];
  157. X    add = fp[5];
  158. X    dump = fp[6];
  159. X    relink = fp[7];
  160. X    backtrack = fp[8];
  161. X    profile = fp[9];
  162. X    zero = fp[10];
  163. X    save = fp[11];
  164. X    if(optimizing)
  165. X        optimize();
  166. X    translate();
  167. X}
  168. X
  169. Xyyerror(s) char *s;{
  170. X    return;
  171. X}
  172. X
  173. Xyywrap(){
  174. X    return(1);
  175. X}
  176. X
  177. X
  178. Xchar *gen_next_label()
  179. X/* generate a unique rule label */
  180. X{
  181. X    int i, j;
  182. X    char *r, *s, t[8];
  183. X
  184. X    /* an unlikely prefix */
  185. X    s = "ZqWr_";
  186. X    i = 0;
  187. X    j = next_label++;
  188. X    while(j){
  189. X        t[i++] = '0' + (j % 10);
  190. X        j = j/10;
  191. X    }
  192. X    t[i] = '\0';
  193. X    r = (char *) malloc (i + 6);
  194. X    strcpy(r, s);
  195. X    strcat(r, t);
  196. X    return(r);
  197. X
  198. X}
  199. X
  200. X
  201. Xnice_token_stuff()
  202. X/* remove superfluous stuff from the case list */
  203. X{
  204. X    struct def_list *d_temp;
  205. X    struct data_type *dt_temp;
  206. X    struct case_list *c_temp;
  207. X
  208. X    d_temp = token_list;
  209. X    while(d_temp){
  210. X        dt_temp = d_temp->data_types;
  211. X        while(dt_temp){
  212. X        if(dt_temp->elts){
  213. X            while((dt_temp->elts) && (dt_temp->elts->used == 0))
  214. X            dt_temp->elts= dt_temp->elts->next;
  215. X            c_temp = dt_temp->elts;
  216. X            while(c_temp){
  217. X                if((c_temp->next) && (c_temp->next->used == 0))
  218. X                c_temp->next = c_temp->next->next;
  219. X                c_temp = c_temp->next;
  220. X            }
  221. X        }
  222. X        dt_temp = dt_temp->next;
  223. X        }
  224. X        d_temp = d_temp->next;
  225. X    }
  226. X}
  227. X
  228. X
  229. Xbuild_case_list()
  230. X/* search the token_list for possible cross compare items */
  231. X{
  232. X    int i;
  233. X    struct def_list *d_temp, *d_temp2;
  234. X    struct data_type *dt_temp, *dt_temp2;
  235. X    struct case_list *c_temp, *c_temp2;
  236. X
  237. X    d_temp = token_list;
  238. X    while(d_temp){
  239. X        dt_temp = d_temp->data_types;
  240. X        while(dt_temp){
  241. X            i = 1;
  242. X            dt_temp2 = d_temp->data_types;
  243. X        while(dt_temp2){
  244. X            if((dt_temp != dt_temp2) && (dt_temp->type == dt_temp2->type)){
  245. X                if(dt_temp->elts){
  246. X                c_temp->next = (struct case_list *) malloc(sizeof(struct case_list));
  247. X                c_temp = c_temp->next;
  248. X                }
  249. X                else{
  250. X                dt_temp->elts = (struct case_list *) malloc(sizeof(struct case_list));
  251. X                c_temp = dt_temp->elts;
  252. X                }
  253. X                c_temp->next = NULL;
  254. X                c_temp->name = dt_temp2->name;
  255. X                c_temp->id   = i++;
  256. X                c_temp->used = 0;
  257. X            }
  258. X            dt_temp2 = dt_temp2->next;
  259. X        }
  260. X        dt_temp = dt_temp->next;
  261. X        }
  262. X        d_temp = d_temp->next;
  263. X    }
  264. X}
  265. X
  266. Xcmp_type(object, elt1, elt2)
  267. X/* compare the types of elt1 and elt2 to see if they match */
  268. Xchar *object, *elt1, *elt2;
  269. X{
  270. X    struct def_list *d_temp;
  271. X    struct data_type *dt_temp;
  272. X    struct case_list *c_temp;
  273. X
  274. X    d_temp = token_list;
  275. X    while(d_temp){
  276. X        if(strcmp(object, d_temp->name) == 0){
  277. X        dt_temp = d_temp->data_types;
  278. X        while(dt_temp){
  279. X            if(strcmp(elt1, dt_temp->name) == 0){
  280. X            c_temp = dt_temp->elts;
  281. X            while(c_temp){
  282. X                if(strcmp(elt2, c_temp->name) == 0)
  283. X                return(1);    /* the types are equal */
  284. X                else
  285. X                c_temp = c_temp->next;
  286. X            }
  287. X            return(-1);        /* the types are different */
  288. X            }
  289. X            dt_temp = dt_temp->next;
  290. X        }
  291. X        return(-1);            /* the types were not found */
  292. X        }
  293. X        d_temp = d_temp->next;
  294. X    }
  295. X}
  296. X
  297. X
  298. Xinsert_label(s)
  299. X/* insert the label of a rule into the name_list */
  300. Xchar *s;
  301. X{
  302. X    struct list *temp;
  303. X
  304. X    if(! first_label)
  305. X        first_label = s;
  306. X    temp = (struct list *) malloc(sizeof(struct list));
  307. X    temp->name = s;
  308. X    if(name_list)
  309. X        temp->next = name_list;
  310. X    else
  311. X        temp->next = NULL;
  312. X    name_list = temp;
  313. X    rule_list->label = s;
  314. X}
  315. X
  316. X
  317. Xinsert_token(s) 
  318. X/* insert the name of an object into the token_list */
  319. Xchar *s;
  320. X{
  321. X    struct def_list *temp, *temp2;
  322. X
  323. X    if(token_list){            /* if the list is not nil */
  324. X        temp = token_list;
  325. X        while(temp){        /* search for duplicates */
  326. X        if(strcmp(s, temp->name) == 0){
  327. X            fprintf(stderr,"%d: duplicate declaration  -> %s\n",lineno, s);
  328. X            errors++;
  329. X            return(0);
  330. X        }
  331. X        temp = temp->next;
  332. X        }
  333. X    }
  334. X    temp = (struct def_list *) malloc(sizeof(struct def_list));
  335. X    temp->name = s;
  336. X    temp->data_types = data_list;
  337. X    temp->next = NULL;
  338. X    total_tokens++;
  339. X    data_list = NULL;
  340. X    temp2 = token_list;
  341. X    if(temp2){
  342. X        while(temp2->next)
  343. X        temp2 = temp2->next;
  344. X        temp2->next = temp;
  345. X    }
  346. X    else
  347. X        token_list = temp;
  348. X}
  349. X
  350. X
  351. Xinsert_fields(element, value, free_name, type, index)
  352. X/* insert a fields structure into the current object in the init list */
  353. Xchar *element, *value, *free_name;
  354. Xint  type, index;
  355. X{
  356. X    struct fields *temp;
  357. X    struct match *temp2;
  358. X
  359. X    temp2 = rule_list->complex;
  360. X    temp = (struct fields *) malloc(sizeof(struct fields));
  361. X    temp->empty = 0;
  362. X    temp->object = NULL;
  363. X    if(free_name)
  364. X        while(temp2){
  365. X            if(strcmp(temp2->free_name, free_name) == 0){
  366. X            temp->empty  = temp2->empty;
  367. X            temp->object = temp2->object;
  368. X            temp2 = NULL;
  369. X            }
  370. X            else temp2 = temp2->next;
  371. X        }
  372. X    temp->index     = index;
  373. X    temp->element   = element;
  374. X    temp->value     = value;
  375. X    temp->type      = type;
  376. X    temp->next      = init_list->items;
  377. X    init_list->items = temp;
  378. X}
  379. X
  380. X
  381. Xinsert_init()
  382. X/* insert an empty structure in the stm initialization list */
  383. X{
  384. X    struct init *temp;
  385. X
  386. X    temp = (struct init *) malloc(sizeof(struct init));
  387. X    temp->count  = 0;
  388. X    temp->object = NULL;
  389. X    temp->next   = NULL;
  390. X    temp->items  = NULL;
  391. X    if(init_list){
  392. X        temp->next = init_list;
  393. X        init_list = temp;
  394. X    }
  395. X    else init_list = temp;
  396. X}
  397. X
  398. X
  399. Xinsert_count(n)
  400. X/* initialize count in init_list */
  401. Xint n;
  402. X{
  403. X    init_list->count = n;
  404. X}
  405. X
  406. X
  407. Xinsert_rule()
  408. X/* insert an empty structure in the list of rules */
  409. X{
  410. X    struct rule *temp;
  411. X
  412. X    temp = (struct rule *) malloc(sizeof(struct rule));
  413. X    temp->recurs = 0;
  414. X    temp->prev   = NULL;
  415. X    temp->opt    = NULL;
  416. X    temp->label  = NULL;
  417. X    temp->search = (int *) calloc(total_tokens , sizeof(int));
  418. X    temp->mark   = (int *) calloc(total_tokens , sizeof(int));
  419. X    if(rule_list){
  420. X        temp->next = rule_list;
  421. X        rule_list->prev = temp;
  422. X        rule_list = temp;
  423. X    }
  424. X    else{
  425. X        temp->next = NULL;
  426. X        rule_list = temp;
  427. X    }
  428. X}
  429. X
  430. X
  431. Xfind_name(s)
  432. X/* test to see if a rule label has already been used */
  433. Xchar *s;
  434. X{
  435. X    struct list *temp;
  436. X
  437. X
  438. X    temp = name_list;
  439. X    while(temp){
  440. X        if(strcmp(s, temp->name) == 0){
  441. X        return(-1);
  442. X        }
  443. X        temp = temp->next;
  444. X    }
  445. X    return(0);
  446. X}
  447. X
  448. Xfind_token(s)
  449. X/* test to see if an object name has already been used */
  450. Xchar *s;
  451. X{
  452. X    int i;
  453. X    struct def_list *temp;
  454. X
  455. X    i = 0;
  456. X    temp = token_list;
  457. X    while(temp){
  458. X        if(strcmp(s, temp->name) == 0){
  459. X        return(i);
  460. X        }
  461. X        temp = temp->next;
  462. X        i++;
  463. X    }
  464. X    return(-1);
  465. X}
  466. X
  467. X
  468. Xadd_struct(s,i)
  469. X/* add a structure to define an object to the data_list */
  470. Xchar *s;
  471. Xint i;
  472. X{
  473. X    struct data_type *a, *b;
  474. X
  475. X    /* first check for duplicate definitions */
  476. X    a = data_list;
  477. X    while(a){
  478. X        if(strcmp(s, a->name) == 0)
  479. X        return(-1);
  480. X        a = a->next;
  481. X    }
  482. X    /* add the new element to the list */
  483. X    a = (struct data_type *) malloc(sizeof(struct data_type));
  484. X    a->name = s;
  485. X    a->type = i;
  486. X    a->elts = NULL;
  487. X    a->next = NULL;
  488. X    if(data_list){
  489. X        b = data_list;
  490. X        while(b->next != NULL)
  491. X        b = b->next;
  492. X        b->next = a;
  493. X    }
  494. X    else
  495. X        data_list = a;
  496. X    return(2);
  497. X}
  498. X
  499. X
  500. Xappend_code(s)
  501. X/* append a line of C code to a temporary buffer */
  502. Xchar *s;
  503. X{
  504. X    struct list *a, *b;
  505. X
  506. X    a = (struct list *) malloc(sizeof(struct list));
  507. X    a->name = s;
  508. X    a->next = NULL;
  509. X    if(temp_c_code){
  510. X        b = temp_c_code;
  511. X        while(b->next != NULL)
  512. X        b = b->next;
  513. X        b->next = a;
  514. X    }
  515. X    else
  516. X        temp_c_code = a;
  517. X}
  518. X
  519. X
  520. Xopt(s)
  521. Xchar *s;
  522. X{
  523. X    rule_list->opt = s;
  524. X}
  525. X
  526. X
  527. Xdo_header()
  528. X/* copy the temporary C code to the header */
  529. X{
  530. X    header_code = temp_c_code;
  531. X    temp_c_code = NULL;
  532. X}
  533. X
  534. X
  535. Xdo_trailer()
  536. X/* copy the temporary C code to the trailer */
  537. X{
  538. X    trailer_code = temp_c_code;
  539. X    temp_c_code = NULL;
  540. X}
  541. X
  542. X
  543. Xdo_init_list(s)
  544. X/* add an object to the list of objects to be initialized */
  545. Xchar *s;
  546. X{
  547. X    int found;
  548. X    struct fields *temp;
  549. X    struct def_list *d_temp;
  550. X    struct data_type *dt_temp, *dt_temp2;
  551. X
  552. X    if(init_list->items){
  553. X        d_temp = token_list;
  554. X        while(strcmp(d_temp->name, s) != 0)
  555. X        d_temp = d_temp->next;
  556. X        temp = init_list->items;
  557. X        while(temp){
  558. X        found = 0;
  559. X        dt_temp = d_temp->data_types;
  560. X        while(dt_temp){
  561. X            if(strcmp(dt_temp->name, temp->element) == 0){
  562. X            dt_temp2 = dt_temp;
  563. X            dt_temp = NULL; found = 1;
  564. X            }
  565. X            if(dt_temp) dt_temp = dt_temp->next;
  566. X        }
  567. X        if(found == 0){
  568. X            fprintf(stderr,"%d: %s is not an element of %s\n",lineno,
  569. X                  temp->element, s);
  570. X            errors++;
  571. X        }
  572. X        else if((temp->type >= 0) && (temp->type <= 2)){
  573. X            if(temp->type != dt_temp2->type){
  574. X            fprintf(stderr,"%d: types of element (%s) and value (%s) do not match\n", lineno, temp->element, temp->value);
  575. X            errors++;
  576. X            }
  577. X        }
  578. X        temp = temp->next;
  579. X        }
  580. X    }
  581. X    init_list->object = s;
  582. X}
  583. X
  584. X
  585. Xdo_code()
  586. X/* copy the temporary C code to the current rule's action part */
  587. X{
  588. X    rule_list->c_code = temp_c_code;
  589. X    temp_c_code = NULL;
  590. X}
  591. X
  592. X
  593. Xdo_mark(s)
  594. X/* MARK an object */
  595. Xchar *s;
  596. X{
  597. X    int i;
  598. X
  599. X    i = find_token(s);
  600. X    if(i < 0) {
  601. X        return(0);
  602. X    }
  603. X    rule_list->mark[i]++;
  604. X    return(1);
  605. X}
  606. X
  607. X
  608. Xmark_free(free_name)
  609. X/* mark an object by name */
  610. Xchar *free_name;
  611. X{
  612. X    struct match *temp;
  613. X
  614. X    temp = rule_list->complex;
  615. X    while(temp){
  616. X        if(strcmp(free_name, temp->free_name) == 0){
  617. X        if(temp->empty){
  618. X            fprintf(stderr,"%d: can't MARK an EMPTY object\n", lineno);
  619. X            errors++;
  620. X        }
  621. X        else{
  622. X            temp->mark = 1;
  623. X        }
  624. X        return(1);
  625. X        }
  626. X        temp = temp->next;
  627. X    }
  628. X    return(0);
  629. X}
  630. X
  631. Xfind_free(free_name)
  632. X/* determine if free_name is a declared free variable */
  633. Xchar *free_name;
  634. X{
  635. X    struct match *temp;
  636. X
  637. X    temp = rule_list->complex;
  638. X    while(temp){
  639. X        if(strcmp(free_name, temp->free_name) == 0)
  640. X        return(temp->index);
  641. X        temp = temp->next;
  642. X    }
  643. X    return(-1);
  644. X}
  645. X
  646. X
  647. Xmatch_type(object, o_elt, free_name, f_elt)
  648. X/* check to see if the types match */
  649. Xchar *object, *o_elt, *free_name, *f_elt;
  650. X{
  651. X    int type;
  652. X    struct match *temp;
  653. X    struct def_list *temp2, *temp4;
  654. X    struct data_type *temp3, *temp5;
  655. X
  656. X    temp = rule_list->complex;
  657. X    while(temp){
  658. X        if(strcmp(free_name, temp->free_name) == 0){
  659. X        temp2 = token_list;
  660. X        while(temp2){
  661. X            if(strcmp(temp->object, temp2->name) == 0){
  662. X            temp3 = temp2->data_types;
  663. X            while(temp3){
  664. X                if(strcmp(temp3->name, f_elt) == 0){
  665. X                type = temp3->type;
  666. X                temp4 = token_list;
  667. X                while(temp4){
  668. X                    if(strcmp(temp4->name, object) == 0){
  669. X                    temp5 = temp4->data_types;
  670. X                    while(temp5){
  671. X                        if(strcmp(temp5->name, o_elt) == 0){
  672. X                        if(type == temp5->type){
  673. X                            if(strcmp(temp->object, object))
  674. X                                return(1);
  675. X                            else
  676. X                            return(2);
  677. X                            }
  678. X                        else
  679. X                            return(0);
  680. X                        }
  681. X                        temp5 = temp5->next;
  682. X                    }
  683. X                    return(0);
  684. X                    }
  685. X                    temp4 = temp4->next;
  686. X                }
  687. X                return(0);
  688. X                }
  689. X                temp3 = temp3->next;
  690. X            }
  691. X            return(0);
  692. X            }
  693. X            temp2 = temp2->next;
  694. X        }
  695. X        return(0);
  696. X        }
  697. X        temp = temp->next;
  698. X    }
  699. X    return(0);
  700. X}
  701. X
  702. X
  703. Xadd_count(n)
  704. X/* add the count of how many objects to search 
  705. X   to the rule's situation part */
  706. Xint n;
  707. X{
  708. X    struct match *temp;
  709. X
  710. X    if((rule_list->complex) && (n > 1)){
  711. X        temp = rule_list->complex;
  712. X        while(temp->next)
  713. X        temp = temp->next;
  714. X        temp->count = n;
  715. X    }
  716. X}
  717. X
  718. X
  719. Xadd_test_code()
  720. X/* insert C language code in the situation part */
  721. X{
  722. X    struct match *temp;
  723. X
  724. X        if(rule_list->complex){        /* not the first match in a rule */
  725. X            temp = rule_list->complex;
  726. X            while(temp->next)
  727. X            temp = temp->next;
  728. X            temp->next = (struct match *) malloc(sizeof(struct match));
  729. X            temp = temp->next;
  730. X        }
  731. X        else{                /* first match in a rule */
  732. X            rule_list->complex = (struct match *) malloc(sizeof(struct match));
  733. X            temp = rule_list->complex;
  734. X        }
  735. X        temp->tests = NULL;
  736. X        temp->next = NULL;
  737. X        temp->object = NULL;
  738. X        temp->free_name = NULL;
  739. X        temp->empty = 0;
  740. X        temp->mark  = 0;
  741. X        temp->index = 0;
  742. X        temp->count = 1;
  743. X        temp->c_code = temp_c_code;
  744. X        temp_c_code = NULL;
  745. X}
  746. X
  747. X
  748. Xadd_test(object, element, relop, value, type, free_name, index, empty)
  749. X/*
  750. Xadd data needed for complex matching to rule structure
  751. Xobject is the name of the object class this test applies to
  752. Xelement is the name of the element of the object this test applies to
  753. Xrelop is the relational operator used in the test
  754. Xvalue is the value to test against
  755. Xtype is the data type of the element
  756. Xfree_name is the name of the free variable associated with this object (if any)
  757. Xindex is the array index of the free variable this test will assign to
  758. Xempty - boolean: is this an empty test?
  759. X*/
  760. Xchar *object, *element, *value, *free_name;
  761. Xint relop, type, index;
  762. X{
  763. X    struct match *temp;
  764. X    struct test *temp2;
  765. X    struct def_list *d_temp;
  766. X    struct data_type *dt_temp;
  767. X    struct case_list *c_temp;
  768. X
  769. X    if(current_match == NULL){        /* the first test in a match */
  770. X        if(rule_list->complex){        /* not the first match in a rule */
  771. X            temp = rule_list->complex;
  772. X            while(temp->next)
  773. X            temp = temp->next;
  774. X            temp->next = (struct match *) malloc(sizeof(struct match));
  775. X            temp = temp->next;
  776. X        }
  777. X        else{                /* first match in a rule */
  778. X            rule_list->complex = (struct match *) malloc(sizeof(struct match));
  779. X            temp = rule_list->complex;
  780. X        }
  781. X        temp->tests = NULL;
  782. X        temp->next = NULL;
  783. X        temp->object = object;
  784. X        temp->free_name = free_name;
  785. X        temp->index = index;
  786. X        temp->c_code = NULL;
  787. X        temp->count = 1;
  788. X        temp->mark  = 0;
  789. X        temp->empty = empty;
  790. X        current_match = temp;
  791. X    }
  792. X    temp = current_match;
  793. X    if(strcmp(temp->object, object) != 0){
  794. X        fprintf(stderr,"%d: objects in a complex test must match\n",lineno);
  795. X        errors++;
  796. X        return(0);
  797. X    }
  798. X    if(temp->tests){
  799. X        temp2 = temp->tests;
  800. X        while(temp2->next)
  801. X        temp2 = temp2->next;
  802. X        temp2->next = (struct test *) malloc(sizeof(struct test));
  803. X        temp2 = temp2->next;
  804. X    }
  805. X    else{
  806. X        temp->tests = (struct test *) malloc(sizeof(struct test));
  807. X        temp2 = temp->tests;
  808. X    }
  809. X    temp2->element = element;
  810. X    temp2->relop = relop;
  811. X    temp2->free_name = free_name;
  812. X    temp2->value = value;
  813. X    temp2->type = type;
  814. X    temp2->next = NULL;
  815. X    temp2->id = 0;
  816. X    if(strcmp(object, free_name) == 0){
  817. X        d_temp = token_list;
  818. X        while(d_temp){
  819. X        if(strcmp(object, d_temp->name) == 0){
  820. X            dt_temp = d_temp->data_types;
  821. X            while(dt_temp){
  822. X            if(strcmp(element, dt_temp->name) == 0){
  823. X                c_temp = dt_temp->elts;
  824. X                while(c_temp){
  825. X                if(strcmp(value, c_temp->name) == 0){
  826. X                    c_temp->used = 1;
  827. X                    temp2->id = c_temp->id;
  828. X                    return;
  829. X                }
  830. X                c_temp = c_temp->next;
  831. X                }
  832. X            }
  833. X            dt_temp = dt_temp->next;
  834. X            }
  835. X        }
  836. X        d_temp = d_temp->next;
  837. X        }
  838. X    }
  839. X}
  840. X
  841. X
  842. Xsearch_structs(object, element)
  843. X/*
  844. Xsearch the list of structures for 'object', see if it has a field 'element'
  845. Xreturn -1 if 'object' is not found, data type of 'element' if it is found.
  846. X*/
  847. Xchar *object, *element;
  848. X{
  849. X    struct def_list *temp;
  850. X    struct data_type *temp2;
  851. X
  852. X    temp = token_list;
  853. X    while(temp){
  854. X        if((strcmp(temp->name, object)) == 0){
  855. X        temp2 = temp->data_types;
  856. X        while(temp2){
  857. X            if((strcmp(temp2->name,element)) == 0){
  858. X                return(temp2->type);
  859. X            }
  860. X            temp2 = temp2->next;
  861. X        }
  862. X        return(-1);
  863. X        }
  864. X        temp = temp->next;
  865. X    }
  866. X    return(-1);
  867. X}
  868. !EOR!
  869. echo extracting - main.h
  870. sed 's/^X//' > main.h << '!EOR!'
  871. X#include    <stdio.h>
  872. X
  873. Xstruct list{
  874. X        char *name;
  875. X        struct list *next;
  876. X} *name_list, *temp_c_code, *header_code, *trailer_code, *label_list;
  877. X
  878. Xstruct case_list{
  879. X        char *name;    /* name of the element */
  880. X        int id;        /* case identifier */
  881. X        int used;    /* is this case ever used? */
  882. X        struct case_list *next;
  883. X};
  884. X
  885. Xstruct data_type{
  886. X        int type;    /* -1 = free variable */    
  887. X                /*  0 = integer */
  888. X                /*  1 = floating */
  889. X                /*  2 = string */
  890. X                /*  3 = pointer */
  891. X        char *name;    /*  name of the element */
  892. X        struct case_list *elts;    /* elements that may be compared */
  893. X        struct data_type *next;
  894. X} *data_list;
  895. X
  896. Xstruct def_list{                /* list of defined objects */
  897. X        char *name;            /* the name of the object */
  898. X        struct data_type *data_types;    /* pointer to the element list */
  899. X        struct def_list *next;        /* next object in the list */
  900. X} *token_list;
  901. X
  902. X
  903. Xstruct test{                /* one test in a complex match */
  904. X        char *element;        /* the element of the object to test */
  905. X        int  relop;        /* relational operators are bit encoded
  906. X                       < = >
  907. X                       0 0 0    0   No Match
  908. X                       0 0 1    1   >
  909. X                       0 1 0    2   =
  910. X                       0 1 1    3   >=
  911. X                       1 0 0    4   <
  912. X                       1 0 1    5   !=
  913. X                       1 1 0    6   <=
  914. X                       1 1 1    7   Match Any
  915. X                    */
  916. X        char *free_name;    /* name of free var */
  917. X        char *value;        /* the value to test for */
  918. X        int  type;        /* the data type of the element */
  919. X        int  id;        /* case id for self tests */
  920. X        struct test *next;    /* pointer to the next one in the list */
  921. X} *current_test;
  922. X
  923. X
  924. Xstruct match{                /* description of a complex matching */
  925. X        char *object;        /* the object to test */
  926. X        char *free_name;    /* name of free var attached to the object */
  927. X        int index;        /* initial array index of this free variable */
  928. X        int count;        /* number of times to repeat this test */
  929. X        int mark;        /* boolean: mark this object? */
  930. X        int empty;        /* boolean: is this an empty test? */
  931. X        struct list *c_code;    /* C code included in the situation */
  932. X        struct test *tests;    /* the list of tests for this match */
  933. X        struct match *next;    /* pointer to the next one in the list */
  934. X} *current_match;
  935. X
  936. X
  937. Xstruct rule {                /* facts needed to generate code */
  938. X                    /* one per rule */
  939. X        char *label;        /* label of this rule */
  940. X        char *opt;        /* optimization - goto this label */
  941. X        int  recurs;        /* boolean indicates recursive search */
  942. X        int *search;        /* items to search for in stm */
  943. X        int *mark;        /* items to remove from stm */
  944. X        struct init *add;    /* items to add to stm */
  945. X        struct list *c_code;    /* code to execute if this rule fires */
  946. X        struct match *complex;    /* complex matching list */
  947. X        struct rule *next;
  948. X        struct rule *prev;
  949. X} *rule_list;
  950. X
  951. Xstruct fields {
  952. X        char *object;        /* the name of the object to be init */
  953. X        char *element;        /* the name of the element to be init */
  954. X        char *value;        /* the value to be assigned to the element */
  955. X        int index;        /* the array index of this free variable */
  956. X        int type;        /* the type of the element */
  957. X        int empty;        /* boolean: is this an empty test? */
  958. X        struct fields *next;    /* the next element of this object to be initialized */
  959. X};
  960. X
  961. Xstruct init {                /* stm initialization */
  962. X        char *object;        /* the name of the object to be initialized */
  963. X        int count;        /* number of reps of this item */
  964. X        struct fields *items;    /* list of fields to initialize */
  965. X        struct init *next;    /* next object in list */
  966. X} *init_list, *init_list2;
  967. X
  968. X
  969. Xint total_tokens,            /* total number of objects declared */
  970. X    pnum,                 /* current production */
  971. X    *stm,                 /* array of number of each object type
  972. X                       to MARK or ADD */
  973. X    *current_free,             /* index of the current free variable
  974. X                       for each object type */
  975. X    *max_free,                 /* maximum number of free variables
  976. X                       needed for each object type */
  977. X    *current_empty,             /* index of the current empty variable
  978. X                       for each object type */
  979. X    *max_empty,                /* maximum number of empty variables
  980. X                       needed for each object type */
  981. X    errors,                 /* count of errors detected */
  982. X    backtracking,            /* boolean to indicate if the user wants
  983. X                       to generate backtracking code */
  984. X    profiling,                /* boolean to indicate if the user wants
  985. X                       to generate profiling code */
  986. X    tracing,                /* boolean to indicate if the user wants
  987. X                       to generate tracing code */
  988. X    dumping,                /* boolean to indicate if the user wants
  989. X                       to generate code to dump stm*/
  990. X    optimizing,                /* boolean to indicate if the user wants
  991. X                       to invoke the loop optimizer */
  992. X    recursing,                /* boolean to indicate if the user wants
  993. X                       recursive searches to be the default */
  994. X    saving,                /* boolean to indicate if the user wants
  995. X                       to generate code to save STM*/
  996. X    zeroing,                /* boolean to indicate if the user wants
  997. X                       to generate code to zero STM*/
  998. X    pascal,                /* boolean to indicate if the user wants
  999. X                       to generate pascal instead of C*/
  1000. X    lineno;                /* line number of input file */
  1001. X
  1002. Xchar *first_label,            /* label of the first rule in LTM */
  1003. X     *prefix;                    /* prefix for all objects */
  1004. X
  1005. XFILE  *header, *fre, *misc, *search,    /* output files */
  1006. X    *add, *dump, *loop, *relink,    /* purposes are obvious */
  1007. X    *backtrack, *profile, *zero, *save;
  1008. X    
  1009. !EOR!
  1010. echo extracting - optimize.c
  1011. sed 's/^X//' > optimize.c << '!EOR!'
  1012. X#include    "main.h"
  1013. X
  1014. Xoptimize()
  1015. X/* optimize the goto statements that will be generated for loop.c */
  1016. X{
  1017. X    struct rule *r_const, *r_temp, *r_temp2;
  1018. X    struct match *m_temp;
  1019. X    struct test *t_temp;
  1020. X    struct init *i_temp;
  1021. X    int i;
  1022. X
  1023. X    /* find the end of the rule list */
  1024. X    /* since rules are inserted, the first rule is at the end of the list */
  1025. X    r_const = rule_list;
  1026. X    while(r_const->next != NULL)
  1027. X        r_const = r_const->next;
  1028. X
  1029. X    /* scan the rule list from the end */
  1030. X    /* mark all rules with tests that do not check elements as recursive */
  1031. X    r_temp = r_const;
  1032. X    while(r_temp){
  1033. X        if(r_temp->recurs == 0){
  1034. X        i = 1;
  1035. X        m_temp = r_temp->complex;
  1036. X        if(m_temp == NULL){
  1037. X            r_temp->recurs = 111;
  1038. X        }
  1039. X        while(m_temp && i){
  1040. X            if(m_temp->tests){
  1041. X            t_temp = m_temp->tests;
  1042. X            while(t_temp)
  1043. X                if(t_temp->element){
  1044. X                i = 0;
  1045. X                t_temp = NULL;
  1046. X                }    
  1047. X                else
  1048. X                t_temp = t_temp->next;
  1049. X            }
  1050. X            if(i){
  1051. X            if(m_temp->next == NULL){
  1052. X                r_temp->recurs = 111;
  1053. X            }
  1054. X            }
  1055. X            m_temp = m_temp->next;
  1056. X        }
  1057. X        }
  1058. X        r_temp = r_temp->prev;
  1059. X    }
  1060. X
  1061. X    /* scan the rule list for rules that have not been hand optimized */
  1062. X    /* optimize these rules by scanning for the first rule that could */
  1063. X    /* possibly fire after the given rule */
  1064. X    r_temp = r_const;
  1065. X    while(r_temp){
  1066. X        if(r_temp->opt == NULL){
  1067. X        r_temp2 = r_const;
  1068. X        while(r_temp2){
  1069. X            r_temp->opt = r_temp2->label;
  1070. X            if(r_temp2->complex == NULL){
  1071. X            r_temp2 = NULL;
  1072. X            }
  1073. X            else if(strcmp(r_temp->label, r_temp2->label) == 0){
  1074. X            r_temp2 = NULL;
  1075. X            }
  1076. X            else{
  1077. X                /* NOT tests first */
  1078. X                for(i = 0; i < total_tokens; i++){
  1079. X                if(r_temp2->search[i] < 0){
  1080. X                    if(r_temp->mark[i] > 0){
  1081. X                    r_temp2 = NULL;
  1082. X                    goto next_rule;
  1083. X                    }
  1084. X                    i_temp = r_temp->add;
  1085. X                    while(i_temp){
  1086. X                    if(find_token(i_temp->object) == i)
  1087. X                        goto next_rule;
  1088. X                    i_temp = i_temp->next;
  1089. X                    }
  1090. X                }
  1091. X                }
  1092. X                m_temp = r_temp2->complex;
  1093. X                while(m_temp){
  1094. X                i = find_token(m_temp->object);
  1095. X                    /* ADD test for all rules */
  1096. X                i_temp = r_temp->add;
  1097. X                while(i_temp){
  1098. X                    if(strcmp(i_temp->object, m_temp->object) == 0){
  1099. X                    r_temp2 = NULL;
  1100. X                    m_temp  = NULL;
  1101. X                    i_temp  = NULL;
  1102. X                    }
  1103. X                    else
  1104. X                    i_temp = i_temp->next;
  1105. X                }
  1106. X                /* MARK test for non recursive rules */
  1107. X                if((r_temp2)
  1108. X                && (r_temp->recurs == 0)
  1109. X                && (r_temp->mark[i])){
  1110. X                    r_temp2 = NULL;
  1111. X                    m_temp  = NULL;
  1112. X                }
  1113. X                else{
  1114. X                    if(m_temp) {
  1115. X                    m_temp = m_temp->next;
  1116. X                    }
  1117. X                }
  1118. X                }    
  1119. X            }
  1120. X            next_rule:
  1121. X            if(r_temp2 != NULL){
  1122. X            r_temp2 = r_temp2->prev;
  1123. X            }
  1124. X        }
  1125. X        }
  1126. X        r_temp = r_temp->prev;
  1127. X    }
  1128. X
  1129. X    /* unmark rules temporarily marked as recursive */
  1130. X    r_temp = r_const;
  1131. X    while(r_temp){
  1132. X        if(r_temp->recurs == 111)
  1133. X        r_temp->recurs = 0;
  1134. X        r_temp = r_temp->prev;
  1135. X    }    
  1136. X}
  1137. !EOR!
  1138.