00001
00002
00003
00004
00005
00006
00007 #include "def.h"
00008 int label_count;
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 static int
00036 more_specific(A, B)
00037 NODE *A, *B;
00038 {
00039 extern OP *untyped_prim;
00040 extern OP *undeclared_prim;
00041 extern OP *positive_type, *nonzero_type;
00042 register OP *opa = A->op;
00043 register OP *opb = B->op;
00044 register OP *sop;
00045
00046 if (opa != opb) {
00047 if (opb == untyped_prim) return 1;
00048 if (opa == untyped_prim) return -1;
00049 for (sop = opa->super; sop; sop = sop->super) if (sop == opb) return 1;
00050 for (sop = opb->super; sop; sop = sop->super) if (sop == opa) return -1;
00051 if (opb->arity == OP_NAME && opa->arity != OP_NAME) return 1;
00052 if (opa->arity == OP_NAME && opb->arity != OP_NAME) return -1;
00053 if (opa->precedence > opb->precedence) return 1;
00054 if (opa->precedence < opb->precedence) return -1;
00055 if (opa > opb) return 1;
00056 if (opa < opb) return -1;
00057 }
00058
00059 if (opa->arity == NULLARY) return 0;
00060 if ((opa->arity & BINARY) || (opa->arity & UNARY)) {
00061 if ((opa->arity & BINARY) || (opa->arity == POSTFIX))
00062 return more_specific(((TERM_NODE *)A)->left, ((TERM_NODE *)B)->left);
00063 if (opa->arity != POSTFIX)
00064 return more_specific(((TERM_NODE *)A)->right, ((TERM_NODE *)B)->right);
00065 }
00066 return 0;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 RULE *
00080 rule_build(head, body, tag, names)
00081 NODE *head, *body;
00082 OP *tag;
00083 NAME_NODE *names;
00084 {
00085 char *malloc();
00086 void rule_print();
00087 register RULE *rr;
00088 RULE *cr, *pr = NULL;
00089 int cmp;
00090 static int rule_verbose = -1;
00091
00092 if (!(head->op->arity & OP_TERM)) {
00093 error("head of rule must be an expression");
00094 }
00095 rr = (RULE *) malloc(sizeof(RULE));
00096 rr->head = head;
00097 rr->body = body;
00098 rr->tag = tag;
00099 rr->space = names;
00100 rr->size = label_count;
00101
00102 if (rule_verbose == -1) rule_verbose = verbose;
00103 if (rule_verbose) {
00104 rr->verbose = 1;
00105 rule_print(rr);
00106 }
00107 else rr->verbose = 0;
00108 rule_verbose = verbose;
00109
00110 cr = head->op->hash;
00111 if (cr == NULL) {
00112 rr->next = NULL;
00113 head->op->hash = rr;
00114 return rr;
00115 }
00116 while (cr) {
00117 if (1 == more_specific(rr->head, cr->head)) {
00118 rr->next = cr;
00119 if (pr) pr->next = rr;
00120 else head->op->hash = rr;
00121 return rr;
00122 }
00123 pr = cr;
00124 cr = cr->next;
00125 }
00126 pr->next = rr;
00127 rr->next = NULL;
00128 return rr;
00129 }
00130
00131
00132
00133
00134
00135
00136 void rule_free(rr)
00137 RULE *rr;
00138 {
00139 void expr_free();
00140
00141 expr_free(rr->head);
00142 expr_free(rr->body);
00143 name_free(rr->space);
00144 free((char *)rr);
00145 }
00146
00147
00148
00149
00150
00151
00152 void rule_print(rp)
00153 RULE *rp;
00154 {
00155 void expr_print();
00156 void name_space_print();
00157
00158 expr_print(rp->head);
00159 fprintf(stderr, " { ");
00160 expr_print(rp->body);
00161 fprintf(stderr, " }");
00162 if (rp->tag) fprintf(stderr, " '%s", rp->tag->pname);
00163 fprintf(stderr, "\t");
00164 name_space_print(rp->space);
00165 fprintf(stderr, "\n");
00166 }