00001
00002
00003
00004
00005
00006
00007 #include "def.h"
00008
00009
00010 #define OPER_TYPE 401
00011 #define EXPR_TYPE 402
00012
00013
00014 #define HEAD 501
00015 #define BODY 502
00016
00017 static SNODE *pstack = NULL;
00018
00019 static NODE *boe;
00020
00021 static int next_token;
00022 static int token;
00023 extern double token_val;
00024 extern char token_prval[];
00025 extern OP *token_op;
00026 static NAME_NODE *rule_names = NULL;
00027
00028
00029
00030
00031
00032
00033 void
00034 ps_print(st)
00035 SNODE *st;
00036 {
00037 void expr_print();
00038
00039 while(st) {
00040 if (st->info == OPER_TYPE) fprintf(stderr, "\tOP: %s\n", st->node->op->pname);
00041 else {
00042 fprintf(stderr, "\t");
00043 expr_print(st->node);
00044 fprintf(stderr, "\n");
00045 }
00046 st = st->next;
00047 }
00048 }
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 void
00064 reduce(rop)
00065 register SNODE *rop;
00066 {
00067 extern OP *undeclared_prim;
00068 char *arity_name();
00069 void st_free();
00070 extern int label_count;
00071
00072 SNODE *q;
00073
00074 #ifdef DEBUG
00075 fprintf(stderr, "reducing operator: %s, parse stack:\n", rop->node->op->pname);
00076 ps_print(pstack);
00077 #endif
00078
00079
00080 if (rop->node->op->eval < 0) {
00081 # ifdef DEBUG
00082 fprintf(stderr, "special reduce function: %d\n", rop->node->op->eval);
00083 # endif
00084 switch(- rop->node->op->eval) {
00085 case 1:
00086 if (!(rop->node->op->arity & UNARY)) {
00087 fprintf(stderr, "operator: %s, arity: %s\n",
00088 rop->node->op->pname, arity_name(rop->node->op->arity));
00089 error("special reduce function 1 requires unary operator");
00090 }
00091 if (rop == pstack || pstack->info != EXPR_TYPE) {
00092 fprintf(stderr, "unary operator: %s\n", rop->node->op->pname);
00093 error("unary operator has no argument");
00094 }
00095 pstack->next = pstack->next->next;
00096 st_free(rop);
00097 break;
00098 case 2:
00099 if (!(rop->node->op->arity & BINARY)) {
00100 fprintf(stderr, "operator: %s, arity: %s\n",
00101 rop->node->op->pname, arity_name(rop->node->op->arity));
00102 error("special label operator must be binary operator");
00103 }
00104 if (rop == pstack || pstack->info != EXPR_TYPE) {
00105 fprintf(stderr, "binary operator: %s\n", rop->node->op->pname);
00106 error("binary operator has no right argument");
00107 }
00108 if (!rop->next || rop->next->info != EXPR_TYPE) {
00109 fprintf(stderr, "binary operator: %s\n", rop->node->op->pname);
00110 error("binary operator has no left argument");
00111 }
00112 if (!(rop->next->node->op->arity == OP_NAME)) {
00113 fprintf(stderr, "operator: %s, arity: %s\n",
00114 rop->next->node->op->pname,
00115 arity_name(rop->next->node->op->arity));
00116 error("special label operator requires name for left argument");
00117 }
00118 if (rop->next->node->op != undeclared_prim) {
00119 fprintf(stderr, "parameter: %s\n",
00120 ((NAME_NODE *)rop->next->node)->pval);
00121 error("parameter may not be used as a label name");
00122 }
00123 if (!(pstack->node->op->arity & OP_TERM)) {
00124 fprintf(stderr, "right argument is: %s, of type: %s\n",
00125 arity_name(pstack->node->op->arity), pstack->node->op->pname);
00126 error("special label operator requires term for right argument");
00127 }
00128 if (((TERM_NODE *)(pstack->node))->label) {
00129
00130 fprintf(stderr, "new label: %s, old label: %s, operator: %s\n",
00131 ((NAME_NODE *)(rop->next->node))->pval,
00132 ((TERM_NODE *)(pstack->node))->label->pval,
00133 pstack->node->op->pname);
00134 error("multiple labels on single expression");
00135 }
00136 label_count++;
00137 ((TERM_NODE *)(pstack->node))->label = (NAME_NODE *) rop->next->node;
00138 pstack->next = pstack->next->next->next;
00139 st_free(rop->next);
00140 st_free(rop);
00141 break;
00142 case 3:
00143 if (!(rop->node->op->arity & UNARY)) {
00144 fprintf(stderr, "operator: %s, arity: %s\n",
00145 rop->node->op->pname, arity_name(rop->node->op->arity));
00146 error("special negation operator must be unary operator");
00147 }
00148 if (rop == pstack || pstack->info != EXPR_TYPE) {
00149 fprintf(stderr, "unary operator: %s\n", rop->node->op->pname);
00150 error("unary operator has no argument");
00151 }
00152 if (!(pstack->node->op->arity & OP_NUM)) {
00153 fprintf(stderr, "right argument is: %s, of type: %s\n",
00154 arity_name(pstack->node->op->arity), pstack->node->op->pname);
00155 error("special negation operator requires constant for argument");
00156 }
00157 ((NUM_NODE *)(pstack->node))->value *= -1;
00158 pstack->next = pstack->next->next;
00159 st_free(rop);
00160 break;
00161 case 4:
00162 break;
00163 case 5:
00164 break;
00165 default:
00166 fprintf(stderr,"operator: %s, function: %d\n",
00167 rop->node->op->pname, rop->node->op->eval);
00168 error("unknown parser reduce function");
00169 break;
00170 }
00171 # ifdef DEBUG
00172 fprintf(stderr, "result expr is: ");
00173 expr_print(pstack->node);
00174 fprintf(stderr, "\n");
00175 # endif
00176 }
00177
00178
00179
00180
00181
00182 else if (rop->node->op->arity & BINARY) {
00183 if (rop == pstack || pstack->info != EXPR_TYPE) {
00184 fprintf(stderr, "binary operator: %s\n", rop->node->op->pname);
00185 error("binary operator has no right argument");
00186 }
00187 if (!rop->next || rop->next->info != EXPR_TYPE) {
00188 fprintf(stderr, "binary operator: %s\n", rop->node->op->pname);
00189 error("binary operator has no left argument");
00190 }
00191 ((TERM_NODE *)(rop->node))->right = pstack->node;
00192 ((TERM_NODE *)(rop->node))->left = rop->next->node;
00193 # ifdef DEBUG
00194 fprintf(stderr, "reduce BINARY\n");
00195 fprintf(stderr, "right child is: %s\n",
00196 ((TERM_NODE *)(rop->node))->right->op->pname);
00197 fprintf(stderr, "left child is: %s\n",
00198 ((TERM_NODE *)(rop->node))->left->op->pname);
00199 # endif
00200 rop->info = EXPR_TYPE;
00201 st_free(pstack);
00202 pstack = rop;
00203 q = rop->next;
00204 rop->next = rop->next->next;
00205 st_free(q);
00206 }
00207
00208
00209 else if (rop->node->op->arity == PREFIX) {
00210 if (rop == pstack || pstack->info != EXPR_TYPE) {
00211 fprintf(stderr, "prefix operator: %s\n", rop->node->op->pname);
00212 error("prefix operator has no argument");
00213 }
00214 ((TERM_NODE *)(rop->node))->left = NULL;
00215 ((TERM_NODE *)(rop->node))->right = pstack->node;
00216 # ifdef DEBUG
00217 fprintf(stderr, "reduce PREFIX\n");
00218 fprintf(stderr, "right child is: %s\n",
00219 ((TERM_NODE *)(rop->node))->right->op->pname);
00220 # endif
00221 st_free(pstack);
00222 pstack = rop;
00223 rop->info = EXPR_TYPE;
00224 }
00225
00226
00227 else if (rop->node->op->arity == POSTFIX) {
00228 if (!rop->next || rop->next->info != EXPR_TYPE) {
00229 fprintf(stderr, "postfix operator: %s\n", rop->node->op->pname);
00230 error("postfix operator has no left argument");
00231 }
00232 ((TERM_NODE *)(rop->node))->left = rop->next->node;
00233 ((TERM_NODE *)(rop->node))->right = NULL;
00234 # ifdef DEBUG
00235 fprintf(stderr, "reduce POSTFIX\n");
00236 fprintf(stderr, "left child is: %s\n",
00237 ((TERM_NODE *)(rop->node))->left->op->pname);
00238 # endif
00239 rop->info = EXPR_TYPE;
00240 q = rop->next;
00241 rop->next = rop->next->next;
00242 st_free(q);
00243 }
00244
00245
00246
00247
00248
00249 else if (rop->node->op->arity == OUTFIX1) {
00250 if (rop == pstack || pstack->info != EXPR_TYPE) {
00251 fprintf(stderr, "outfix operator: %s\n", rop->node->op->pname);
00252 error("outfix operator has no argument");
00253 }
00254 ((TERM_NODE *)(rop->node))->left = NULL;
00255 ((TERM_NODE *)(rop->node))->right = pstack->node;
00256 # ifdef DEBUG
00257 fprintf(stderr, "OUTFIX1\n");
00258 fprintf(stderr, "right child is: %s\n",
00259 ((TERM_NODE *)(rop->node))->right->op->pname);
00260 # endif
00261 rop->info = EXPR_TYPE;
00262 st_free(pstack);
00263 pstack = rop;
00264 }
00265 else {
00266 fprintf(stderr, "can't reduce %s, arity: %s\n", rop->node->op,
00267 arity_name(rop->node->op->arity));
00268 error("Don't know how to reduce");
00269 }
00270
00271 #ifdef DEBUG
00272 fprintf(stderr, "leaving reduce with parse stack:\n");
00273 ps_print(pstack);
00274 #endif
00275
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 void
00287 shift(p, type)
00288 NODE *p;
00289 int type;
00290 {
00291 void expr_print();
00292 register SNODE *temp;
00293 SNODE *st_get();
00294
00295 #ifdef DEBUG
00296 if (type==OPER_TYPE) fprintf(stderr, "shifting operator %s onto pstack\n",
00297 p->op->pname);
00298 else if (type==EXPR_TYPE) {
00299 fprintf(stderr, "shifting expression onto pstack: ");
00300 expr_print(p);
00301 fprintf(stderr, "\n");
00302 }
00303 else fprintf(stderr, "shifting unknown %s onto pstack\n",
00304 p->op->pname);
00305 #endif
00306
00307 temp = st_get();
00308 temp->next = pstack;
00309 pstack = temp;
00310 pstack->node = p;
00311 pstack->info = type;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 NODE *
00327 exp_parse(part)
00328 int part;
00329 {
00330 register NODE *cnode;
00331 register SNODE *lop;
00332 int done = FALSE;
00333 char prev_prval[MAXTOKEN];
00334 int holdtoken = TRUE;
00335 NAME_NODE *cspace;
00336
00337 void st_free();
00338 char *char_copy();
00339 NODE *node_new();
00340 NODE *name_put();
00341 extern OP *pnum_prim;
00342 extern OP *znum_prim;
00343 extern OP *nnum_prim;
00344 extern OP *str_prim;
00345 extern OP *undeclared_prim;
00346 extern OP *untyped_prim;
00347 extern NAME_NODE *global_names;
00348
00349 #ifdef DEBUG
00350 if (part==HEAD) fprintf(stderr, "parsing HEAD\n");
00351 else if (part==BODY) fprintf(stderr, "parsing BODY\n");
00352 else fprintf(stderr, "parsing unknown = %d\n", part);
00353
00354 if (pstack) fprintf(stderr, "nodes left on parse stack!\n");
00355 #endif
00356
00357 pstack = NULL;
00358
00359
00360 shift(boe, OPER_TYPE);
00361
00362 while (!done) {
00363 if (holdtoken) {
00364 # ifdef DEBUG
00365 fprintf(stderr, "holdtoken is true, using next_token = %s\n", token_prval);
00366 # endif
00367 token = next_token;
00368 holdtoken = FALSE;
00369 }
00370 else {
00371 token = scan();
00372 # ifdef DEBUG
00373 fprintf(stderr, "called scanner, token = %s\n", token_prval);
00374 if (token == OPER) fprintf(stderr, "OPER precedence = %ld\n",
00375 token_op->precedence);
00376 # endif
00377 }
00378
00379 switch(token) {
00380 case EOF: error("EOF encountered before end of expression");
00381 break;
00382 case '{':
00383 if (part == HEAD) done = TRUE;
00384 else error("Opening brace found in body of rule");
00385 break;
00386 case '}':
00387 if (part == BODY) done = TRUE;
00388 else error("Closing brace found, but not in body of rule");
00389 break;
00390 case IDENT:
00391
00392 if (pstack->info != OPER_TYPE) {
00393 fprintf(stderr, "for tokens: ");
00394 expr_print(pstack->node);
00395 fprintf(stderr, " and %s\n", token_prval);
00396 error("missing operator");
00397 }
00398 strcpy(prev_prval, token_prval);
00399 next_token = scan();
00400 # ifdef DEBUG
00401 fprintf(stderr, "lookahead next_token = %s\n", token_prval);
00402 # endif
00403 if (part == HEAD) {
00404 if (next_token == '.') {
00405 fprintf(stderr, "name beginning with: %s\n", prev_prval);
00406 error("qualified names illegal in head of rule");
00407 }
00408 if (next_token == TYPE) {
00409 cnode = name_put(prev_prval, rule_names, token_op);
00410 }
00411 else {
00412 cnode = name_put(prev_prval, rule_names, untyped_prim);
00413 holdtoken = TRUE;
00414 }
00415 if (((NAME_NODE *) cnode)->refs != 2) {
00416 fprintf(stderr, "parameter: %s\n", prev_prval);
00417 error("reuse of parameter name in head of rule");
00418 }
00419 shift(cnode, EXPR_TYPE);
00420 break;
00421 }
00422
00423
00424 if (next_token == TYPE) {
00425 fprintf(stderr, "ident: %s, type: %s\n", prev_prval, token_prval);
00426 error("types not allowed in body of rule");
00427 }
00428
00429
00430 cspace = rule_names;
00431 while (next_token == '.') {
00432 cspace = (NAME_NODE *) name_put(prev_prval, cspace, undeclared_prim);
00433 next_token = scan();
00434 if (next_token != IDENT) {
00435 if (next_token == OPER)
00436 fprintf(stderr, "token: %s is an operator\n", token_prval);
00437 else fprintf(stderr, "token: %s\n", token_prval);
00438 error("expected identifier following '.'");
00439 }
00440 strcpy(prev_prval, token_prval);
00441 next_token = scan();
00442 }
00443 holdtoken = TRUE;
00444 cnode = name_put(prev_prval, cspace, undeclared_prim);
00445 shift(cnode, EXPR_TYPE);
00446 break;
00447
00448 case '.':
00449 if (part == HEAD) {
00450 fprintf(stderr, "token: %s\n", token_prval);
00451 error("global names illegal in head of rule");
00452 }
00453
00454 if (pstack->info != OPER_TYPE) {
00455 fprintf(stderr, "for tokens: ");
00456 expr_print(pstack->node);
00457 fprintf(stderr, " and %s\n", token_prval);
00458 error("missing operator");
00459 }
00460 cspace = global_names;
00461 while (next_token == '.') {
00462 cspace = (NAME_NODE *) name_put(prev_prval, cspace, undeclared_prim);
00463 next_token = scan();
00464 if (next_token != IDENT) {
00465 if (next_token == OPER)
00466 fprintf(stderr, "token: %s is an operator\n", token_prval);
00467 else fprintf(stderr, "token: %s\n", token_prval);
00468 error("expected identifier following '.'");
00469 }
00470 strcpy(prev_prval, token_prval);
00471 next_token = scan();
00472 }
00473 holdtoken = TRUE;
00474 cnode = name_put(prev_prval, cspace, undeclared_prim);
00475 shift(cnode, EXPR_TYPE);
00476 break;
00477
00478 case NUMBER:
00479 # ifdef DEBUG
00480 fprintf(stderr, "type is number\n");
00481 # endif
00482 cnode = node_new();
00483 cnode->op = (token_val > 0.0) ? pnum_prim :
00484 ((token_val < 0.0) ? nnum_prim : znum_prim );
00485 ((NUM_NODE *) cnode)->value = token_val;
00486 if (pstack->info != OPER_TYPE) {
00487 fprintf(stderr, "for tokens: ");
00488 expr_print(pstack->node);
00489 fprintf(stderr, " and %s\n", token_prval);
00490 error("missing operator");
00491 }
00492 shift(cnode, EXPR_TYPE);
00493 break;
00494
00495 case STRING:
00496 # ifdef DEBUG
00497 fprintf(stderr, "type is string\n");
00498 # endif
00499 cnode = node_new();
00500 cnode->op = str_prim;
00501 ((STR_NODE *) cnode)->value = char_copy(token_prval);
00502 if (pstack->info != OPER_TYPE) {
00503 fprintf(stderr, "for tokens: ");
00504 expr_print(pstack->node);
00505 fprintf(stderr, " and %s\n", token_prval);
00506 error("missing operator");
00507 }
00508 shift(cnode, EXPR_TYPE);
00509 break;
00510
00511 case OPER:
00512 # ifdef DEBUG
00513 fprintf(stderr, "type of %s is oper\n", token_prval);
00514 # endif
00515
00516 cnode = node_new();
00517 cnode->op = token_op;
00518 ((TERM_NODE *) cnode)->label = (NAME_NODE *) NULL;
00519 ((TERM_NODE *) cnode)->left = (NODE *) NULL;
00520 ((TERM_NODE *) cnode)->right = (NODE *) NULL;
00521
00522 if (cnode->op->arity == NULLARY) {
00523 shift(cnode, EXPR_TYPE);
00524 break;
00525 }
00526
00527 if (cnode->op->arity == OUTFIX1 || cnode->op->arity == PREFIX) {
00528 shift(cnode, OPER_TYPE);
00529 break;
00530 }
00531
00532
00533
00534
00535
00536 for (;;) {
00537
00538
00539 lop = pstack;
00540 if (lop && lop->info != OPER_TYPE) lop = lop->next;
00541 if (!lop || lop->info != OPER_TYPE)
00542 error("syntax error: missing operator!");
00543
00544
00545
00546
00547
00548
00549
00550
00551 if (lop == pstack && (lop->node->op->arity & BINARY) &&
00552 cnode->op->arity & BINARY) {
00553
00554
00555 if (cnode->op->other && cnode->op->other->arity == PREFIX) {
00556
00557 if (lop->node->op->other &&
00558 lop->node->op->other->arity == POSTFIX) {
00559
00560
00561
00562
00563 if (lop->node->op->precedence > cnode->op->precedence) {
00564 lop->node->op = lop->node->op->other;
00565 # ifdef DEBUG
00566 fprintf(stderr, "switching last binary node to unary\n");
00567 fprintf(stderr, "calling reduce\n");
00568 # endif
00569 reduce(lop);
00570 }
00571 else {
00572 cnode->op = cnode->op->other;
00573 # ifdef DEBUG
00574 fprintf(stderr, "switching current binary node to unary\n");
00575 fprintf(stderr, "breaking out and shifting\n");
00576 # endif
00577 break;
00578 }
00579 }
00580 else {
00581 cnode->op = cnode->op->other;
00582 # ifdef DEBUG
00583 fprintf(stderr, "switching current binary node to unary\n");
00584 fprintf(stderr, "breaking out and shifting\n");
00585 # endif
00586 break;
00587 }
00588 }
00589
00590 else if (lop->node->op->other &&
00591 lop->node->op->other->arity == POSTFIX) {
00592 # ifdef DEBUG
00593 fprintf(stderr, "switching last binary node to unary\n");
00594 fprintf(stderr, "calling reduce\n");
00595 # endif
00596 reduce(lop);
00597 }
00598 else {
00599 fprintf(stderr, "operator: %s and operator: %s\n",
00600 lop->node->op->pname, cnode->op->pname);
00601 error("syntax error: missing operand");
00602 }
00603 }
00604
00605
00606
00607
00608
00609 if (cnode->op->arity & BINARY && lop == pstack && (lop->node->op->arity
00610 == PREFIX || lop->node->op->arity == OUTFIX1)) {
00611 if (cnode->op->other && cnode->op->other->arity == PREFIX) {
00612 cnode->op = cnode->op->other;
00613 # ifdef DEBUG
00614 fprintf(stderr, "switching current binary node to unary\n");
00615 fprintf(stderr, "breaking out and shifting\n");
00616 # endif
00617 break;
00618 }
00619 else {
00620 fprintf(stderr, "infix operator: %s\n", cnode->op->pname);
00621 error("syntax error: missing left operand");
00622 }
00623 }
00624
00625
00626
00627
00628 if (cnode->op->arity == OUTFIX2) {
00629 if (lop->node->op->arity == OUTFIX1) {
00630 if (cnode->op->other == lop->node->op) {
00631 reduce(lop);
00632 break;
00633 }
00634 else {
00635 fprintf(stderr, "outfix operators: %s and %s\n",
00636 lop->node->op->pname, cnode->op->pname);
00637 error("outfix operators do not match");
00638 }
00639 }
00640 else reduce(lop);
00641 }
00642
00643
00644
00645 else if (cnode->op->precedence < lop->node->op->precedence ||
00646 (cnode->op->precedence == lop->node->op->precedence &&
00647 cnode->op->arity == LEFT)) {
00648 # ifdef DEBUG
00649 fprintf(stderr, "calling reduce from <= prec\n");
00650 # endif
00651 reduce(lop);
00652 }
00653
00654 else if (lop->node->op->arity != OUTFIX1 &&
00655 (cnode->op->precedence==lop->node->op->precedence) &&
00656 (cnode->op->arity == NONASSOC)) {
00657 fprintf(stderr, "input = %s\n", cnode->op->pname);
00658 fprintf(stderr, "pstack node = %s\n", lop->node->op->pname);
00659 error("2 opers to be reduced are nonassociative");
00660 }
00661
00662 else {
00663 # ifdef DEBUG
00664 fprintf(stderr, "breaking out because none of the if's apply\n");
00665 # endif
00666 break;
00667 }
00668
00669 }
00670
00671
00672 if (cnode->op->arity != OUTFIX2) shift(cnode, OPER_TYPE);
00673
00674 break;
00675
00676 case TYPE:
00677 fprintf(stderr,"type: %s\n", token_prval);
00678 if (part == BODY) error("types not allowed in body of rule");
00679 else error("type with no parameter");
00680
00681 default:
00682 fprintf(stderr,"token: %s\n", token_prval);
00683 error("illegal token in rule");
00684
00685 }
00686
00687 # ifdef DEBUG
00688 fprintf(stderr, "\n");
00689 # endif
00690 }
00691
00692 #ifdef DEBUG
00693 ps_print(pstack);
00694 #endif
00695
00696
00697 for (lop = pstack; lop; lop = lop->next) {
00698 if (lop->info == OPER_TYPE) {
00699 if (lop->node == boe) break;
00700 else {
00701 reduce(lop);
00702 lop = pstack;
00703 }
00704 }
00705 }
00706 if (!lop) error("empty parse stack!");
00707 if (lop->next) error("nodes left on parse stack!");
00708 st_free(lop);
00709 cnode = pstack->node;
00710 st_free(pstack);
00711 pstack = (SNODE *) NULL;
00712 return(cnode);
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 void parse()
00725 {
00726 RULE *rule_build();
00727 NODE *node_new();
00728 OP *op_new();
00729 void st_mem_free();
00730 extern int label_count;
00731 extern OP *undeclared_prim;
00732
00733 NODE *head;
00734 NODE *body;
00735 OP *rule_tag;
00736
00737 pstack = NULL;
00738
00739
00740 boe = node_new();
00741 boe->op = op_new(3);
00742 strcpy(boe->op->pname,"BOE");
00743 boe->op->arity = OUTFIX1;
00744 boe->op->other = (OP *) NULL;
00745 ((TERM_NODE *) boe)->label = (NAME_NODE *) NULL;
00746 ((TERM_NODE *) boe)->left = (NODE *) NULL;
00747 ((TERM_NODE *) boe)->right = (NODE *) NULL;
00748
00749 for (next_token = scan(); EOF != next_token; ) {
00750
00751 rule_names = (NAME_NODE *) node_new();
00752 rule_names->op = undeclared_prim;
00753 rule_names->next = (NAME_NODE *) NULL;
00754 rule_names->parent = (NAME_NODE *) NULL;
00755 rule_names->child = (NAME_NODE *) NULL;
00756 rule_names->pval = NULL;
00757 rule_names->refs = 1;
00758 rule_names->interest = 0;
00759 label_count = 0;
00760
00761 head = exp_parse(HEAD);
00762 next_token = scan();
00763 if (next_token == EOF) error("EOF encountered before end of rule");
00764 body = exp_parse(BODY);
00765
00766 next_token = scan();
00767 if (next_token == TYPE) {
00768 rule_tag = token_op;
00769 next_token = scan();
00770 }
00771 else {
00772 rule_tag = (OP *) NULL;
00773 }
00774 rule_build(head, body, rule_tag, rule_names);
00775 }
00776 st_mem_free();
00777 }