00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef lint
00012 static char vcid[] = "$Id: parser.c,v 1.2 1994/12/08 23:32:03 duchier Exp $";
00013 #endif
00014
00015 #include "extern.h"
00016 #include "memory.h"
00017 #include "trees.h"
00018 #include "token.h"
00019 #include "print.h"
00020 #include "copy.h"
00021 #include "modules.h"
00022 #include "login.h"
00023
00024
00025 #define NOP 2000
00026
00027 psi_term read_life_form();
00028
00029 psi_term psi_term_stack[PARSER_STACK_SIZE];
00030 long int_stack[PARSER_STACK_SIZE];
00031 operator op_stack[PARSER_STACK_SIZE];
00032
00033 long parse_ok;
00034 long parser_stack_index;
00035 ptr_node var_tree;
00036 long no_var_tree;
00037
00038
00039 psi_term parse_list();
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 bad_psi_term(t)
00052 ptr_psi_term t;
00053 {
00054 char *s,c;
00055 long r;
00056
00057
00058 if(t->type==final_dot || t->type==final_question)
00059 return TRUE;
00060
00061 s=t->type->keyword->symbol;
00062 c=s[0];
00063 r=(s[1]==0 &&
00064 (c=='(' ||
00065 c==')' ||
00066 c=='[' ||
00067 c==']' ||
00068 c=='{' ||
00069 c=='}'
00070
00071 )
00072 );
00073
00074 return r;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 void show(limit)
00084 long limit;
00085 {
00086 long i;
00087
00088 for (i=1;i<=parser_stack_index;i++) {
00089 if (i==limit)
00090 printf("-> ");
00091 else
00092 printf(" ");
00093 printf("%3d: ",i);
00094 switch (op_stack[i]) {
00095 case fx:
00096 printf("FX ");
00097 break;
00098 case xfx:
00099 printf("XFX ");
00100 break;
00101 case xf:
00102 printf("XF ");
00103 break;
00104 case nop:
00105 printf("NOP ");
00106 break;
00107 default:
00108 printf("??? ");
00109 }
00110 printf(" prec=%4d ",int_stack[i]);
00111 display_psi_stdout(&(psi_term_stack[i]));
00112 printf("\n");
00113 }
00114 printf("\n");
00115 }
00116
00117
00118
00119
00120
00121
00122 void push(tok,prec,op)
00123 psi_term tok;
00124 long prec;
00125 operator op;
00126 {
00127 if (parser_stack_index==PARSER_STACK_SIZE) {
00128 perr("*** Parser error ");
00129 psi_term_error();
00130 perr(": stack full.\n");
00131 }
00132 else {
00133 parser_stack_index++;
00134 psi_term_stack[parser_stack_index]=tok;
00135 int_stack[parser_stack_index]=prec;
00136 op_stack[parser_stack_index]=op;
00137 }
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 long pop(tok,op)
00147 ptr_psi_term tok;
00148 operator *op;
00149 {
00150 long r=0;
00151
00152 if (parser_stack_index==0) {
00153
00154
00155
00156
00157
00158
00159 (*tok)= *error_psi_term;
00160 parse_ok=FALSE;
00161 }
00162 else {
00163 (*tok)=psi_term_stack[parser_stack_index];
00164 (*op)=op_stack[parser_stack_index];
00165 r=int_stack[parser_stack_index];
00166 parser_stack_index--;
00167 }
00168
00169 return r;
00170 }
00171
00172
00173
00174
00175
00176
00177 long look()
00178 {
00179 return int_stack[parser_stack_index];
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 long precedence(tok,typ)
00191 psi_term tok;
00192 operator typ;
00193 {
00194 long r=NOP;
00195 ptr_operator_data o;
00196
00197 o=tok.type->op_data;
00198 while(o && r==NOP) {
00199 if(typ==o->type)
00200 r=o->precedence;
00201 else
00202 o=o->next;
00203 }
00204
00205 return r;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214 ptr_psi_term stack_copy_psi_term(t)
00215 psi_term t;
00216 {
00217 ptr_psi_term p;
00218
00219 p=STACK_ALLOC(psi_term);
00220 (*p)=t;
00221 #ifdef TS
00222 p->time_stamp=global_time_stamp;
00223 #endif
00224
00225 return p;
00226 }
00227
00228
00229
00230
00231
00232
00233 ptr_psi_term heap_copy_psi_term(t)
00234 psi_term t;
00235 {
00236 ptr_psi_term p;
00237
00238 p=HEAP_ALLOC(psi_term);
00239 (*p)=t;
00240 #ifdef TS
00241 p->time_stamp=global_time_stamp;
00242 #endif
00243
00244 return p;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 feature_insert(keystr,tree,psi)
00256 char *keystr;
00257 ptr_node *tree;
00258 ptr_psi_term psi;
00259 {
00260 ptr_node loc;
00261
00262
00263 if (loc=find(featcmp,keystr,*tree)) {
00264
00265 Syntaxerrorline("duplicate feature %s (%E)\n",keystr);
00266 }
00267 else {
00268
00269 ptr_psi_term stk_psi=stack_copy_psi_term(*psi);
00270 stack_insert_copystr(keystr,tree,(GENERIC)stk_psi);
00271 }
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 psi_term list_nil(type)
00285
00286 ptr_definition type;
00287 {
00288 psi_term nihil;
00289
00290 if(type==disjunction)
00291 nihil.type=disj_nil;
00292 else
00293 nihil.type=nil;
00294
00295 nihil.status=0;
00296 nihil.flags=FALSE;
00297 nihil.attr_list=NULL;
00298 nihil.resid=NULL;
00299 nihil.value=NULL;
00300 nihil.coref=NULL;
00301
00302 return nihil;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 psi_term parse_list(typ,e,s)
00334 ptr_definition typ;
00335 char e,s;
00336
00337 {
00338 ptr_psi_term car=NULL;
00339 ptr_psi_term cdr=NULL;
00340 psi_term result;
00341 psi_term t;
00342 char a;
00343
00344
00345
00346 result=list_nil(typ);
00347
00348 if (parse_ok) {
00349
00350
00351 a='|';
00352
00353
00354 read_token(&t);
00355
00356 if(!equ_tokc(t,e)) {
00357
00358
00359 put_back_token(t);
00360 car=stack_copy_psi_term(read_life_form(s,a));
00361
00362
00363 read_token(&t);
00364 if(equ_tokch(t,s))
00365 cdr=stack_copy_psi_term(parse_list(typ,e,s));
00366 else if(equ_tokch(t,e))
00367 cdr=stack_copy_psi_term(list_nil(typ));
00368 else if(equ_tokch(t,'|')) {
00369 cdr=stack_copy_psi_term(read_life_form(e,0));
00370 read_token(&t);
00371 if(!equ_tokch(t,e)) {
00372 if (stringparse) parse_ok=FALSE;
00373 else {
00374 perr("*** Syntax error ");psi_term_error();
00375 perr(": bad symbol for end of list '");
00376 display_psi_stderr(&t);
00377 perr("'.\n");
00378 put_back_token(t);
00379 }
00380 }
00381 }
00382 else
00383 if (stringparse) parse_ok=FALSE;
00384 else {
00385 perr("*** Syntax error ");psi_term_error();
00386 perr(": bad symbol in list '");
00387 display_psi_stderr(&t);
00388 perr("'.\n");
00389 put_back_token(t);
00390 }
00391
00392 result.type=typ;
00393 if(car)
00394 stack_insert(featcmp,one,&(result.attr_list),car);
00395 if(cdr)
00396 stack_insert(featcmp,two,&(result.attr_list),cdr);
00397 }
00398 }
00399
00400 return result;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 psi_term read_psi_term()
00430 {
00431 psi_term t,t2,t3;
00432 char s[10];
00433 long count=0,f=TRUE,f2,v;
00434 ptr_psi_term module;
00435
00436
00437 if(parse_ok) {
00438
00439 read_token(&t);
00440
00441 if(equ_tokch(t,'['))
00442 t=parse_list(alist,']',',');
00443 else
00444 if(equ_tokch(t,'{'))
00445 t=parse_list(disjunction,'}',';');
00446
00447
00448
00449
00450
00451
00452
00453 if(parse_ok
00454 && t.type!=eof
00455 && !bad_psi_term(&t)
00456
00457
00458 ) {
00459 read_token(&t2);
00460 if(equ_tokch(t2,'(')) {
00461
00462 do {
00463
00464 f2=TRUE;
00465 read_token(&t2);
00466
00467 if(wl_const(t2) && !bad_psi_term(&t2)) {
00468 read_token(&t3);
00469 if(equ_tok(t3,"=>")) {
00470 t3=read_life_form(',',')');
00471
00472 if(t2.type->keyword->private_feature)
00473 feature_insert(t2.type->keyword->combined_name,
00474
00475 &(t.attr_list),
00476 &t3);
00477 else
00478 feature_insert(t2.type->keyword->symbol,
00479
00480 &(t.attr_list),
00481 &t3);
00482
00483 f2=FALSE;
00484 }
00485 else
00486 put_back_token(t3);
00487 }
00488
00489 if(parse_ok && equal_types(t2.type,integer)) {
00490 read_token(&t3);
00491 if(equ_tok(t3,"=>")) {
00492 t3=read_life_form(',',')');
00493 v= *(REAL *)t2.value;
00494 sprintf(s,"%ld",v,0);
00495 feature_insert(s,&(t.attr_list),&t3);
00496 f2=FALSE;
00497 }
00498 else
00499 put_back_token(t3);
00500 }
00501
00502 if(f2) {
00503 put_back_token(t2);
00504 t2=read_life_form(',',')');
00505 ++count;
00506 sprintf(s,"%ld",count,0);
00507 feature_insert(s,&(t.attr_list),&t2);
00508 }
00509
00510 read_token(&t2);
00511
00512 if(equ_tokch(t2,')'))
00513 f=FALSE;
00514 else
00515 if(!equ_tokch(t2,',')) {
00516 if (stringparse) parse_ok=FALSE;
00517 else {
00518
00519
00520
00521
00522
00523
00524 Syntaxerrorline("',' expected in argument list (%E)\n");
00525
00526 f=FALSE;
00527 }
00528 }
00529
00530 } while(f && parse_ok);
00531 }
00532 else
00533 put_back_token(t2);
00534 }
00535 }
00536 else
00537 t= *error_psi_term;
00538
00539 if(t.type==variable && t.attr_list) {
00540 t2=t;
00541 t.type=apply;
00542 t.value=NULL;
00543 t.coref=NULL;
00544 t.resid=NULL;
00545 stack_insert(featcmp,functor->keyword->symbol,
00546 &(t.attr_list),
00547 stack_copy_psi_term(t2));
00548 }
00549
00550
00551
00552 if((t.type==add_module1 || t.type==add_module2 || t.type==add_module3) &&
00553 !find(featcmp,two,t.attr_list)) {
00554
00555 module=stack_psi_term(4);
00556 module->type=quoted_string;
00557 module->value=(GENERIC)heap_copy_string(current_module->module_name);
00558
00559 stack_insert(featcmp,two,&(t.attr_list),module);
00560 }
00561
00562 return t;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 psi_term make_life_form(tok,arg1,arg2)
00576 ptr_psi_term tok,arg1,arg2;
00577 {
00578 ptr_list l;
00579 ptr_psi_term a1,a2;
00580
00581 deref_ptr(tok);
00582 tok->attr_list=NULL;
00583 tok->resid=NULL;
00584
00585
00586
00587
00588
00589
00590
00591 a1=arg1;
00592 a2=arg2;
00593
00594 if(a1)
00595 deref_ptr(a1);
00596 if(a2)
00597 deref_ptr(a2);
00598
00599
00600
00601 if ( equ_tokch((*tok),':') && arg1 && arg2) {
00602
00603 if(a1!=a2) {
00604 if(a1->type==top &&
00605 !a1->attr_list &&
00606 !a1->resid) {
00607 if(a1!=arg1)
00608
00609 push_psi_ptr_value(a1,&(a1->coref));
00610 a1->coref=stack_copy_psi_term(*arg2);
00611 tok=arg1;
00612 }
00613 else
00614 if(a2->type==top &&
00615 !a2->attr_list &&
00616 !a2->resid) {
00617 if(a2!=arg2)
00618
00619 push_psi_ptr_value(a2,&(a2->coref));
00620 a2->coref=stack_copy_psi_term(*arg1);
00621 tok=arg2;
00622 }
00623 else {
00624 Syntaxerrorline("':' occurs where '&' required (%E)\n");
00625 *tok= *error_psi_term;
00626
00627 }
00628 }
00629 else
00630 tok=arg1;
00631 }
00632 else {
00633
00634
00635
00636 if(tok->type==minus_symbol &&
00637 a1 &&
00638 !a2 &&
00639 a1->value &&
00640 (a1->type==integer || a1->type==real)) {
00641
00642 tok->type=a1->type;
00643 tok->value=(GENERIC)heap_alloc(sizeof(REAL));
00644 *(REAL *)tok->value = - *(REAL *)a1->value;
00645
00646 return *tok;
00647 }
00648
00649
00650 stack_insert(featcmp,one,&(tok->attr_list),stack_copy_psi_term(*arg1));
00651 if (arg2)
00652 stack_insert(featcmp,two,&(tok->attr_list),stack_copy_psi_term(*arg2));
00653 }
00654
00655 return *tok;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665 void crunch(prec,limit)
00666 long prec;
00667 long limit;
00668 {
00669 psi_term t,t1,t2,t3;
00670 operator op1,op2,op3;
00671
00672 if(parse_ok && prec>=look() && parser_stack_index>limit) {
00673
00674 pop(&t1,&op1);
00675
00676 switch(op1) {
00677
00678 case nop:
00679 pop(&t2,&op2);
00680 if(op2==fx)
00681 t=make_life_form(&t2,&t1,NULL);
00682 else
00683 if(op2==xfx) {
00684 pop(&t3,&op3);
00685 if(op3==nop)
00686 t=make_life_form(&t2,&t3,&t1);
00687 else {
00688 printf("*** Parser: ooops, NOP expected.\n");
00689 parse_ok=FALSE;
00690 t= *error_psi_term;
00691 }
00692 }
00693 break;
00694
00695 case xf:
00696 pop(&t2,&op2);
00697 if(op2==nop)
00698 t=make_life_form(&t1,&t2,NULL);
00699 else {
00700 printf("*** Parser: ugh, NOP expected.\n");
00701 t= *error_psi_term;
00702 parse_ok=FALSE;
00703 }
00704 break;
00705
00706 default:
00707 printf("*** Parser: yuck, weirdo operator.\n");
00708 }
00709
00710 push(t,look(),nop);
00711
00712 crunch(prec,limit);
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 psi_term read_life_form(ch1,ch2)
00730 char ch1,ch2;
00731 {
00732 psi_term t,t2;
00733 long limit,pr_op,pr_1,pr_2,start=0;
00734 long fin=FALSE;
00735 long state=0;
00736 long prec=0;
00737
00738 operator op;
00739
00740 limit=parser_stack_index+1;
00741
00742 if(parse_ok)
00743 do {
00744 if(state)
00745 read_token(&t);
00746 else
00747 t=read_psi_term();
00748
00749 if(!start)
00750 start=line_count;
00751
00752 if(!fin)
00753 if(state) {
00754 if(equ_tokc(t,ch1) || equ_tokc(t,ch2)) {
00755 fin=TRUE;
00756 put_back_token(t);
00757 }
00758 else {
00759
00760 pr_op=precedence(t,xf);
00761 pr_1=pr_op-1;
00762
00763 if(pr_op==NOP) {
00764 pr_op=precedence(t,yf);
00765 pr_1=pr_op;
00766 }
00767
00768 if(pr_op==NOP) {
00769
00770 pr_op=precedence(t,xfx);
00771 pr_1=pr_op-1;
00772 pr_2=pr_op-1;
00773
00774 if(pr_op==NOP) {
00775 pr_op=precedence(t,xfy);
00776 pr_1=pr_op-1;
00777 pr_2=pr_op;
00778 }
00779
00780 if(pr_op==NOP) {
00781 pr_op=precedence(t,yfx);
00782 pr_1=pr_op;
00783 pr_2=pr_op-1;
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793 if(pr_op==NOP) {
00794 fin=TRUE;
00795 put_back_token(t);
00796 }
00797 else
00798 {
00799 crunch(pr_1,limit);
00800 push(t,pr_2,xfx);
00801 prec=pr_2;
00802 state=0;
00803 }
00804 }
00805 else {
00806 crunch(pr_1,limit);
00807 push(t,pr_1,xf);
00808 prec=pr_1;
00809 }
00810 }
00811 }
00812 else {
00813
00814 if(t.attr_list)
00815 pr_op=NOP;
00816 else {
00817 pr_op=precedence(t,fx);
00818 pr_2=pr_op-1;
00819
00820 if(pr_op==NOP) {
00821 pr_op=precedence(t,fy);
00822 pr_2=pr_op;
00823 }
00824 }
00825
00826 if(pr_op==NOP) {
00827 if(equ_tokch(t,'(')) {
00828 t2=read_life_form(')',0);
00829 if(parse_ok) {
00830 push(t2,prec,nop);
00831 read_token(&t2);
00832 if(!equ_tokch(t2,')')) {
00833 if (stringparse) parse_ok=FALSE;
00834 else {
00835
00836
00837
00838
00839
00840
00841 Syntaxerrorline("')' missing (%E)\n");
00842
00843 put_back_token(t2);
00844 }
00845 }
00846 state=1;
00847 }
00848 }
00849 else
00850 if(bad_psi_term(&t)) {
00851 put_back_token(t);
00852
00853 fin=TRUE;
00854 }
00855 else {
00856 push(t,prec,nop);
00857 state=1;
00858 }
00859 }
00860 else {
00861 push(t,pr_2,fx);
00862 prec=pr_2;
00863 }
00864
00865 }
00866
00867 } while (!fin && parse_ok);
00868
00869 if (state)
00870 crunch(MAX_PRECEDENCE,limit);
00871
00872 if (parse_ok && parser_stack_index!=limit) {
00873 if (stringparse) parse_ok=FALSE;
00874 else {
00875
00876
00877
00878
00879
00880
00881 Syntaxerrorline("bad expression (%E)\n");
00882 }
00883 }
00884 else
00885 pop(&t,&op);
00886
00887 if (!parse_ok)
00888 t= *error_psi_term;
00889
00890 parser_stack_index=limit-1;
00891
00892 return t;
00893 }
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 psi_term parse(q)
00908 long *q;
00909 {
00910 psi_term s,t,u;
00911 long c;
00912
00913 parser_stack_index=0;
00914 parse_ok=TRUE;
00915
00916
00917 s=read_life_form(0,0);
00918
00919 if (parse_ok) {
00920 if (s.type!=eof) {
00921 read_token(&t);
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 if (t.type==final_question)
00932 *q=QUERY;
00933 else if (t.type==final_dot)
00934 *q=FACT;
00935 else {
00936 if (stringparse) parse_ok=FALSE;
00937 else {
00938
00939
00940
00941
00942
00943
00944
00945 Syntaxerrorline("'%P' (%E)\n",&t);
00946
00947 }
00948 *q=ERROR;
00949 }
00950 }
00951 }
00952
00953
00954 if (!parse_ok) {
00955
00956 while (saved_psi_term!=NULL) read_token(&u);
00957
00958 prompt="error>";
00959 while((c=read_char()) && c!=EOF && c!='.' && c!='?' && c!=EOLN) {}
00960
00961 *q=ERROR;
00962 }
00963 else if (saved_char)
00964 do {
00965 c=read_char();
00966 if (c==EOLN)
00967 c=0;
00968 else if (c<0 || c>32) {
00969 put_back_char(c);
00970 c=0;
00971 }
00972 } while(c && c!=EOF);
00973
00974
00975 if (parse_ok) mark_nonstrict(&s);
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 return s;
00986 }