00001
00002
00003
00004
00005
00006 #ifndef lint
00007 static char vcid[] = "$Id: token.c,v 1.4 1995/07/27 19:22:17 duchier Exp $";
00008 #endif
00009 #ifndef OS2_PORT
00010 #include <pwd.h>
00011
00012 #else
00013 #include <stdlib.h>
00014 #endif
00015 #include "extern.h"
00016 #include "trees.h"
00017 #include "types.h"
00018 #include "token.h"
00019 #include "memory.h"
00020 #include "error.h"
00021 #include "parser.h"
00022 #include "modules.h"
00023
00024
00025 long var_occurred;
00026 ptr_node symbol_table;
00027 ptr_psi_term error_psi_term;
00028 long psi_term_line_number;
00029 long trace_input=FALSE;
00030
00031 FILE *output_stream;
00032 char *prompt;
00033
00034 long stdin_terminal;
00035
00036
00037 long stringparse;
00038 char *stringinput;
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 FILE *input_stream;
00050 string input_file_name;
00051 long line_count;
00052 long start_of_line;
00053 long saved_char;
00054 long old_saved_char;
00055 ptr_psi_term saved_psi_term;
00056 ptr_psi_term old_saved_psi_term;
00057 long eof_flag;
00058
00059
00060 ptr_psi_term input_state;
00061
00062
00063 ptr_psi_term stdin_state;
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 void TOKEN_ERROR(p)
00075
00076 ptr_psi_term p;
00077 {
00078 if(p->type==error_psi_term->type) {
00079 Syntaxerrorline("Module violation (%E).\n");
00080 }
00081 }
00082
00083
00084
00085
00086 void stdin_cleareof()
00087 {
00088 if (eof_flag && stdin_terminal) {
00089 clearerr(stdin);
00090 start_of_line=TRUE;
00091 saved_psi_term=NULL;
00092 old_saved_psi_term=NULL;
00093 saved_char=0;
00094 old_saved_char=0;
00095 eof_flag=FALSE;
00096 }
00097 }
00098
00099
00100
00101
00102 void heap_add_int_attr(t, attrname, value)
00103 ptr_psi_term t;
00104 char *attrname;
00105 long value;
00106 {
00107 ptr_psi_term t1;
00108
00109 t1=heap_psi_term(4);
00110 t1->type=integer;
00111 t1->value=heap_alloc(sizeof(REAL));
00112 *(REAL *)t1->value = (REAL) value;
00113
00114 heap_insert(featcmp,heap_copy_string(attrname),&(t->attr_list), t1);
00115 }
00116
00117 void stack_add_int_attr(t, attrname, value)
00118 ptr_psi_term t;
00119 char *attrname;
00120 long value;
00121 {
00122 ptr_psi_term t1;
00123
00124 t1=stack_psi_term(4);
00125 t1->type=integer;
00126 t1->value=heap_alloc(sizeof(REAL));
00127 *(REAL *)t1->value = (REAL) value;
00128
00129 stack_insert(featcmp,heap_copy_string(attrname),&(t->attr_list), t1);
00130 }
00131
00132
00133
00134
00135 void heap_mod_int_attr(t, attrname, value)
00136 ptr_psi_term t;
00137 char *attrname;
00138 long value;
00139 {
00140 ptr_node n;
00141 ptr_psi_term t1;
00142
00143 n=find(featcmp,attrname,t->attr_list);
00144 t1=(ptr_psi_term)n->data;
00145 *(REAL *)t1->value = (REAL) value;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 void heap_add_str_attr(t, attrname, str)
00167 ptr_psi_term t;
00168 char *attrname;
00169 char *str;
00170 {
00171 ptr_psi_term t1;
00172
00173 t1=heap_psi_term(4);
00174 t1->type=quoted_string;
00175 t1->value=(GENERIC)heap_copy_string(str);
00176
00177 heap_insert(featcmp,heap_copy_string(attrname),&(t->attr_list), t1);
00178 }
00179
00180 void stack_add_str_attr(t, attrname, str)
00181 ptr_psi_term t;
00182 char *attrname;
00183 char *str;
00184 {
00185 ptr_psi_term t1;
00186
00187 t1=stack_psi_term(4);
00188 t1->type=quoted_string;
00189 t1->value=(GENERIC)stack_copy_string(str);
00190
00191 stack_insert(featcmp,heap_copy_string(attrname),&(t->attr_list), t1);
00192 }
00193
00194
00195
00196
00197 void heap_mod_str_attr(t, attrname, str)
00198 ptr_psi_term t;
00199 char *attrname;
00200 char *str;
00201 {
00202 ptr_node n;
00203 ptr_psi_term t1;
00204
00205 n=find(featcmp,attrname,t->attr_list);
00206 t1=(ptr_psi_term)n->data;
00207 t1->value=(GENERIC)heap_copy_string(str);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 void heap_add_psi_attr(t, attrname, g)
00229 ptr_psi_term t;
00230 char *attrname;
00231 ptr_psi_term g;
00232 {
00233 heap_insert(featcmp,heap_copy_string(attrname),&(t->attr_list), g);
00234 }
00235
00236 void stack_add_psi_attr(t, attrname, g)
00237 ptr_psi_term t;
00238 char *attrname;
00239 ptr_psi_term g;
00240 {
00241 stack_insert(featcmp,heap_copy_string(attrname),&(t->attr_list), g);
00242 }
00243
00244 void bk_stack_add_psi_attr(t, attrname, g)
00245 ptr_psi_term t;
00246 char *attrname;
00247 ptr_psi_term g;
00248 {
00249 bk_stack_insert(featcmp,heap_copy_string(attrname),&(t->attr_list), g);
00250 }
00251
00252
00253
00254 GENERIC get_attr(t, attrname)
00255 ptr_psi_term t;
00256 char *attrname;
00257 {
00258 ptr_node n=find(featcmp,attrname,t->attr_list);
00259 return (GENERIC) n->data;
00260 }
00261
00262
00263 FILE *get_stream(t)
00264 ptr_psi_term t;
00265 {
00266 return (FILE *) ((ptr_psi_term)get_attr(t,STREAM))->value;
00267 }
00268
00269
00270
00271
00272
00273
00274 void save_state(t)
00275 ptr_psi_term t;
00276 {
00277 ptr_node n;
00278 ptr_psi_term t1;
00279
00280 n=find(featcmp,STREAM,t->attr_list);
00281 t1=(ptr_psi_term)n->data;
00282 t1->value=(GENERIC)input_stream;
00283
00284
00285
00286
00287
00288 heap_mod_str_attr(t,INPUT_FILE_NAME,input_file_name);
00289 heap_mod_int_attr(t,LINE_COUNT,line_count);
00290 heap_mod_int_attr(t,SAVED_CHAR,saved_char);
00291 heap_mod_int_attr(t,OLD_SAVED_CHAR,old_saved_char);
00292
00293 t1=saved_psi_term?saved_psi_term:null_psi_term;
00294 heap_add_psi_attr(t,SAVED_PSI_TERM,t1);
00295
00296 t1=old_saved_psi_term?old_saved_psi_term:null_psi_term;
00297 heap_add_psi_attr(t,OLD_SAVED_PSI_TERM,t1);
00298
00299 t1=heap_psi_term(4);
00300 t1->type=(eof_flag?true:false);
00301 heap_add_psi_attr(t,EOF_FLAG,t1);
00302
00303 t1=heap_psi_term(4);
00304 t1->type=(start_of_line?true:false);
00305 heap_add_psi_attr(t,START_OF_LINE,t1);
00306 }
00307
00308
00309
00310
00311 void restore_state(t)
00312 ptr_psi_term t;
00313 {
00314 long i;
00315 char *str;
00316
00317
00318 input_stream = (FILE *) ((ptr_psi_term)get_attr(t,STREAM))->value;
00319 str = (char*) ((ptr_psi_term)get_attr(t,INPUT_FILE_NAME))->value;
00320 strcpy(input_file_name,str);
00321
00322 line_count = *(REAL *) ((ptr_psi_term)get_attr(t,LINE_COUNT))->value;
00323 saved_char = *(REAL *) ((ptr_psi_term)get_attr(t,SAVED_CHAR))->value;
00324 old_saved_char= *(REAL *)((ptr_psi_term)get_attr(t,OLD_SAVED_CHAR))->value;
00325
00326 saved_psi_term=(ptr_psi_term)get_attr(t,SAVED_PSI_TERM);
00327 if (saved_psi_term==null_psi_term) saved_psi_term=NULL;
00328
00329 old_saved_psi_term=(ptr_psi_term)get_attr(t,OLD_SAVED_PSI_TERM);
00330 if (old_saved_psi_term==null_psi_term) old_saved_psi_term=NULL;
00331
00332 eof_flag = ((ptr_psi_term)get_attr(t,EOF_FLAG))->type==true;
00333 start_of_line = ((ptr_psi_term)get_attr(t,START_OF_LINE))->type==true;
00334
00335
00336
00337
00338
00339
00340
00341 }
00342
00343
00344
00345 void new_state(t)
00346 ptr_psi_term *t;
00347 {
00348 ptr_psi_term t1;
00349
00350 *t=heap_psi_term(4);
00351 (*t)->type=inputfilesym;
00352
00353 t1=heap_psi_term(4);
00354 t1->type=stream;
00355 t1->value=(GENERIC)input_stream;
00356 heap_add_psi_attr(*t,STREAM,t1);
00357
00358
00359 heap_add_str_attr(*t,CURRENT_MODULE,current_module->module_name);
00360
00361
00362
00363
00364
00365
00366
00367 heap_add_str_attr(*t,INPUT_FILE_NAME,input_file_name);
00368 heap_add_int_attr(*t,LINE_COUNT,line_count);
00369 heap_add_int_attr(*t,SAVED_CHAR,saved_char);
00370 heap_add_int_attr(*t,OLD_SAVED_CHAR,old_saved_char);
00371
00372 t1=saved_psi_term?saved_psi_term:null_psi_term;
00373 heap_add_psi_attr(*t,SAVED_PSI_TERM,t1);
00374
00375 t1=old_saved_psi_term?old_saved_psi_term:null_psi_term;
00376 heap_add_psi_attr(*t,OLD_SAVED_PSI_TERM,t1);
00377
00378 t1=heap_psi_term(4);
00379 t1->type=(eof_flag?true:false);
00380 heap_add_psi_attr(*t,EOF_FLAG,t1);
00381
00382 t1=heap_psi_term(4);
00383 t1->type=(start_of_line?true:false);
00384 heap_add_psi_attr(*t,START_OF_LINE,t1);
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394 void save_parse_state(pb)
00395 ptr_parse_block pb;
00396 {
00397 if (pb) {
00398 pb->lc = line_count;
00399 pb->sol = start_of_line;
00400 pb->sc = saved_char;
00401 pb->osc = old_saved_char;
00402 pb->spt = saved_psi_term;
00403 pb->ospt = old_saved_psi_term;
00404 pb->ef = eof_flag;
00405 }
00406 }
00407
00408
00409 void restore_parse_state(pb)
00410 ptr_parse_block pb;
00411 {
00412 if (pb) {
00413 line_count = pb->lc;
00414 start_of_line = pb->sol;
00415 saved_char = pb->sc;
00416 old_saved_char = pb->osc;
00417 saved_psi_term = pb->spt;
00418 old_saved_psi_term = pb->ospt;
00419 eof_flag = pb->ef;
00420 }
00421 }
00422
00423
00424
00425 void init_parse_state()
00426 {
00427 line_count=0;
00428 start_of_line=TRUE;
00429 saved_char=0;
00430 old_saved_char=0;
00431 saved_psi_term=NULL;
00432 old_saved_psi_term=NULL;
00433 eof_flag=FALSE;
00434 stringparse=FALSE;
00435 }
00436
00437
00438
00439
00440
00441 static long inchange, outchange;
00442 static FILE *out;
00443 ptr_psi_term old_state=NULL;
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 void begin_terminal_io()
00455 {
00456 inchange = (input_stream!=stdin);
00457 outchange = (output_stream!=stdout);
00458
00459 if (outchange) {
00460 out=output_stream;
00461 output_stream=stdout;
00462 }
00463
00464 if (inchange) {
00465 old_state=input_state;
00466 open_input_file("stdin");
00467 }
00468 }
00469
00470
00471
00472
00473
00474
00475 void end_terminal_io()
00476 {
00477 if (inchange) {
00478 input_state=old_state;
00479 restore_state(old_state);
00480 old_state=NULL;
00481 }
00482 if (outchange)
00483 output_stream=out;
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493 #ifndef OS2_PORT
00494 char *expand_file_name(s)
00495 char *s;
00496 {
00497 char *r;
00498 char *home, *getenv();
00499 struct passwd *pw;
00500 char *user="eight character name";
00501 char userbuf[STRLEN];
00502
00503
00504 char *t1,*t2;
00505
00506 r=s;
00507 if (s[0]=='~') {
00508 t1=s+1;
00509 t2=user;
00510 while (*t1!=0 && *t1!='/') {
00511 *t2= *t1;
00512 *t2++;
00513 *t1++;
00514 }
00515 *t2=0;
00516 if ((int)strlen(user)>0) {
00517 pw = getpwnam(user);
00518 if (pw) {
00519 user=pw->pw_dir;
00520 r=(char *)malloc(strlen(user)+strlen(t1)+1);
00521 sprintf(r,"%s%s",user,t1);
00522 }
00523 else
00524 ;
00525 }
00526 else {
00527 home=getenv("HOME");
00528 if (home) {
00529 r=(char *)malloc(strlen(home)+strlen(s)+1);
00530 sprintf(r,"%s%s",home,s+1);
00531 }
00532 else
00533 ;
00534 }
00535 }
00536
00537
00538
00539 return r;
00540 }
00541 #else
00542 char *expand_file_name(s)
00543 char *s;
00544 {
00545 char *r;
00546 char *home;
00547 char *pw;
00548 char userbuf[STRLEN];
00549 char *user;
00550 char *t1,*t2;
00551 r = s;
00552 if (s[0]=='~') {
00553 t1=s+1;
00554 if (user=getenv("LIFEHOME") ) {
00555 r=(char *)malloc(strlen(user)+strlen(t1)+2);
00556 sprintf(r,"%s\\%s",user,t1);
00557 }
00558 else
00559 {
00560 user = OS2_HOME;
00561 r=(char *)malloc(strlen(user)+strlen(t1)+1);
00562 sprintf(r,"%s%s",user,t1);
00563 }
00564 }
00565 return r;
00566 }
00567 #endif
00568 #if 0
00569
00570 char *expand_file_name(s)
00571 char *s;
00572 {
00573 char *r;
00574 char *home, *getenv();
00575
00576 char userbuf[STRLEN];
00577 char *user=userbuf;
00578 char *t1,*t2;
00579 r=s;
00580 if (s[0]=='~') {
00581 t1=s+1;
00582 t2=user;
00583 while (*t1!=0 && *t1!='/') {
00584 *t2= *t1;
00585 *t2++;
00586 *t1++;
00587 }
00588 *t2=0;
00589 if ((int)strlen(user)>0) {
00590 if (TRUE) {
00591 user=OS2_HOME;
00592 r=(char *)malloc(strlen(user)+strlen(t1)+1);
00593 sprintf(r,"%s%s",user,t1);
00594 }
00595 else
00596 ;
00597 }
00598 else {
00599 home=getenv("HOME");
00600 if (home) {
00601 r=(char *)malloc(strlen(home)+strlen(s)+1);
00602 sprintf(r,"%s%s",home,s+1);
00603 }
00604 else
00605 ;
00606 }
00607 }
00608
00609
00610
00611 return r;
00612 }
00613 #endif
00614
00615
00616
00617
00618
00619
00620
00621 long open_input_file(file)
00622 char *file;
00623 {
00624 long ok=TRUE;
00625 long stdin_flag;
00626 #ifdef OS2_PORT
00627 char *file2;
00628 #endif
00629
00630
00631 if (input_state!=NULL) save_state(input_state);
00632
00633 #ifndef OS2_PORT2
00634 file=expand_file_name(file);
00635
00636 if (stdin_flag=(!strcmp(file,"stdin"))) {
00637 input_stream=stdin;
00638 noisy=TRUE;
00639 }
00640 else {
00641 input_stream=fopen(file,"r");
00642 noisy=FALSE;
00643 }
00644
00645 if (input_stream==NULL) {
00646 Errorline("file '%s' does not exist.\n",file);
00647 file="stdin";
00648 input_stream=stdin;
00649 noisy=TRUE;
00650 ok=FALSE;
00651 }
00652
00653 if (!stdin_flag || stdin_state==NULL) {
00654
00655 strcpy(input_file_name,file);
00656 init_parse_state();
00657
00658 new_state(&input_state);
00659 if (stdin_flag) stdin_state=input_state;
00660 }
00661 else {
00662 input_state=stdin_state;
00663 restore_state(input_state);
00664 }
00665
00666 return ok;
00667 #else
00668 file2=expand_file_name(file);
00669
00670 if (stdin_flag=(!strcmp(file2,"stdin"))) {
00671 input_stream=stdin;
00672 noisy=TRUE;
00673 }
00674 else {
00675 input_stream=fopen(file2,"r");
00676 noisy=FALSE;
00677 }
00678
00679 if (input_stream==NULL) {
00680 #ifdef DJD_DEBUG
00681 printf("missing file == %s\n",file2);
00682 #endif
00683
00684
00685 Errorline("file '%s' does not exist.\n",file2);
00686 file="stdin";
00687 input_stream=stdin;
00688 noisy=TRUE;
00689 ok=FALSE;
00690 }
00691
00692 if (!stdin_flag || stdin_state==NULL) {
00693
00694 strcpy(input_file_name,file2);
00695 init_parse_state();
00696
00697 new_state(&input_state);
00698 if (stdin_flag) stdin_state=input_state;
00699 }
00700 else {
00701 input_state=stdin_state;
00702 restore_state(input_state);
00703 }
00704
00705 return ok;
00706 #endif
00707 }
00708
00709
00710
00711
00712
00713
00714
00715 long open_output_file(file)
00716 string file;
00717 {
00718 long ok=TRUE;
00719
00720
00721 file=expand_file_name(file);
00722
00723 if (!strcmp(file,"stdout"))
00724 output_stream=stdout;
00725 else
00726 if (!strcmp(file,"stderr"))
00727 output_stream=stderr;
00728 else
00729 output_stream=fopen(file,"w");
00730
00731 if (output_stream==NULL) {
00732 Errorline("file '%s' could not be opened for output.\n",file);
00733 ok=FALSE;
00734 output_stream=stdout;
00735 }
00736
00737 return ok;
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 long read_char()
00749 {
00750 long c=0;
00751
00752 if (c=saved_char) {
00753 saved_char=old_saved_char;
00754 old_saved_char=0;
00755 }
00756 else if (stringparse) {
00757 if (c=(*stringinput))
00758 stringinput++;
00759 else
00760 c=EOF;
00761 }
00762 else if (feof(input_stream))
00763 c=EOF;
00764 else {
00765 if (start_of_line) {
00766 start_of_line=FALSE;
00767 line_count++;
00768 if (input_stream==stdin) Infoline("%s",prompt);
00769 }
00770
00771 c=fgetc(input_stream);
00772
00773 if(trace_input)
00774 if(c!=EOF)
00775 printf("%c",c);
00776 else
00777 printf(" <EOF>\n");
00778 #ifdef OS2_PORT
00779 fflush(stdout);
00780 #endif
00781 if (c==EOLN)
00782 start_of_line=TRUE;
00783 }
00784
00785
00786
00787 return c;
00788 }
00789
00790
00791
00792
00793
00794
00795
00796 void put_back_char(c)
00797 long c;
00798 {
00799 if (old_saved_char)
00800 Errorline("in tokenizer, put_back_char three times (last=%d).\n",c);
00801 old_saved_char=saved_char;
00802 saved_char=c;
00803 }
00804
00805
00806
00807
00808
00809
00810 void put_back_token(t)
00811 psi_term t;
00812 {
00813 if (old_saved_psi_term!=NULL)
00814 Errorline("in parser, put_back_token three times (last=%P).\n",t);
00815 old_saved_psi_term=saved_psi_term;
00816 saved_psi_term=stack_copy_psi_term(t);
00817 }
00818
00819
00820
00821
00822
00823
00824 void psi_term_error()
00825 {
00826 perr_i("near line %d",psi_term_line_number);
00827 if (strcmp(input_file_name,"stdin")) {
00828 perr_s(" in file \042%s\042",input_file_name);
00829 }
00830
00831 parse_ok=FALSE;
00832 }
00833
00834
00835
00836
00837
00838
00839 void read_comment(tok)
00840 ptr_psi_term tok;
00841 {
00842 long c;
00843
00844 do {
00845 c=read_char();
00846 } while (c!=EOF && c!=EOLN);
00847
00848 tok->type=comment;
00849 }
00850
00851 void
00852 read_string_error(n)
00853 int n;
00854 {
00855 if (stringparse) parse_ok=FALSE;
00856 else
00857 switch (n) {
00858 case 0:
00859 Syntaxerrorline("end of file reached before end of string (%E).\n");
00860 break;
00861 case 1:
00862 Syntaxerrorline("Hexadecimal digit expected (%E).\n");
00863 break;
00864 }
00865 }
00866
00867 int
00868 base2int(n)
00869 int n;
00870 {
00871 switch (n) {
00872 case '0': return 0;
00873 case '1': return 1;
00874 case '2': return 2;
00875 case '3': return 3;
00876 case '4': return 4;
00877 case '5': return 5;
00878 case '6': return 6;
00879 case '7': return 7;
00880 case '8': return 8;
00881 case '9': return 9;
00882 case 'a':
00883 case 'A': return 10;
00884 case 'b':
00885 case 'B': return 11;
00886 case 'c':
00887 case 'C': return 12;
00888 case 'd':
00889 case 'D': return 13;
00890 case 'e':
00891 case 'E': return 14;
00892 case 'f':
00893 case 'F': return 15;
00894 default:
00895 fprintf(stderr,"base2int('%c'): illegal argument\n",n);
00896 exit(-1);
00897 }
00898 }
00899
00900 #define isoctal(c) (c=='0'||c=='1'||c=='2'||c=='3'||c=='4'||c=='5'||c=='6'||c=='7')
00901
00902
00903
00904
00905
00906 void read_string(tok,e)
00907 ptr_psi_term tok;
00908 long e;
00909 {
00910 long c;
00911 string str;
00912 long len=0;
00913 long store=TRUE;
00914 long flag=TRUE;
00915
00916 str[len]=0;
00917
00918 do {
00919 c=read_char();
00920 if (c==EOF) {
00921 store=FALSE;
00922 flag=FALSE;
00923 read_string_error(0);
00924 }
00925 else if (e=='"' && c=='\\') {
00926 c=read_char();
00927 if (c==EOF) {
00928 store=FALSE;
00929 flag=FALSE;
00930 put_back_char('\\');
00931 read_string_error(0);
00932 }
00933 else {
00934 switch (c) {
00935 case 'a': c='\a'; break;
00936 case 'b': c='\b'; break;
00937 case 'f': c='\f'; break;
00938 case 'n': c='\n'; break;
00939 case 'r': c='\r'; break;
00940 case 't': c='\t'; break;
00941 case 'v': c='\v'; break;
00942
00943 case 'x':
00944 {
00945 int n;
00946 c=read_char();
00947 if (c==EOF) {
00948 store=flag=FALSE;
00949 read_string_error(0);
00950 break;
00951 }
00952 else if (!isxdigit(c)) {
00953 store=flag=FALSE;
00954 read_string_error(1);
00955 break;
00956 }
00957 else {
00958 n = base2int(c);
00959 }
00960 c=read_char();
00961 if (isxdigit(c)) n = 16*n+base2int(c);
00962 else put_back_char(c);
00963 c=n;
00964 break;
00965 }
00966 default:
00967 if (isoctal(c)) {
00968 int n,i;
00969 for(i=n=0;i<3&&isoctal(c);i++,c=read_char())
00970 n = n*8 + base2int(c);
00971 if (c!=EOF) put_back_char(c);
00972 c=n;
00973 break;
00974 }
00975 else break;
00976 }
00977 }
00978 }
00979 else
00980 if (c==e) {
00981 c=read_char();
00982 if (c!=e) {
00983 store=FALSE;
00984 flag=FALSE;
00985 put_back_char(c);
00986 }
00987 }
00988 if (store)
00989 if (len==STRLEN) {
00990 Warningline("string too long, extra ignored (%E).\n");
00991 store=FALSE;
00992 }
00993 else {
00994 str[len++]=c;
00995 str[len]=0;
00996 }
00997 } while(flag);
00998
00999 if (e=='"')
01000 tok->value=(GENERIC)heap_copy_string(str);
01001 else {
01002 tok->type=update_symbol(NULL,str);
01003 tok->value=NULL;
01004 TOKEN_ERROR(tok);
01005 }
01006 }
01007
01008
01009
01010
01011
01012
01013 long symbolic(c)
01014 long c;
01015 {
01016 return SYMBOL(c);
01017 }
01018
01019
01020
01021
01022
01023
01024 long legal_in_name(c)
01025 long c;
01026 {
01027 return
01028 UPPER(c) ||
01029 LOWER(c) ||
01030 DIGIT(c);
01031
01032 ;
01033 }
01034
01035
01036
01037
01038
01039
01040
01041 void read_name(tok,ch,f,typ)
01042 ptr_psi_term tok;
01043 long ch;
01044 long (*f)();
01045 ptr_definition typ;
01046 {
01047 long c;
01048 string str;
01049 long len=1;
01050 long store=TRUE;
01051 long flag=TRUE;
01052 ptr_module module=NULL;
01053 ptr_node n;
01054
01055 tok->coref=NULL;
01056 tok->resid=NULL;
01057 tok->attr_list=NULL;
01058
01059 str[0]=ch;
01060
01061 do {
01062 c=read_char();
01063 flag=(*f)(c);
01064
01065 if(c=='#' &&
01066 f==legal_in_name &&
01067 len>0 &&
01068 len<STRLEN &&
01069 !module) {
01070 str[len]=0;
01071 module=create_module(str);
01072 len=0;
01073 flag=TRUE;
01074
01075
01076
01077 c=read_char();
01078 if SYMBOL(c)
01079 f=symbolic;
01080 put_back_char(c);
01081 }
01082 else
01083 if (flag) {
01084 if (store)
01085 if (len==STRLEN) {
01086 Warningline("name too long, extra ignored (%E).\n");
01087 store=FALSE;
01088 }
01089 else
01090 str[len++]=c;
01091 }
01092 else
01093 put_back_char(c);
01094 } while(flag);
01095
01096 if(module && len==0) {
01097 strcpy(str,module->module_name);
01098 len=strlen(str);
01099 put_back_char('#');
01100 module=NULL;
01101 }
01102
01103 str[len]=0;
01104
01105 tok->type=typ;
01106
01107 if(typ==constant) {
01108
01109 tok->type=update_symbol(module,str);
01110 tok->value=NULL;
01111
01112 TOKEN_ERROR(tok);
01113
01114
01115 if (tok->type->type==global) {
01116 var_occurred=TRUE;
01117 }
01118 if (FALSE ) {
01119
01120
01121
01122
01123
01124
01125
01126 var_occurred=TRUE;
01127 n=find(strcmp,tok->type->keyword->symbol,var_tree);
01128 if (n==NULL) {
01129
01130 bk2_stack_insert(strcmp,
01131 tok->type->keyword->symbol,
01132 &var_tree,
01133 tok->type->global_value);
01134 }
01135 }
01136
01137 }
01138 else
01139 tok->value=(GENERIC)heap_copy_string(str);
01140 }
01141
01142
01143
01144
01145
01146
01147
01148
01149 void read_number(tok,c)
01150 ptr_psi_term tok;
01151 long c;
01152 {
01153 long c2;
01154 REAL f,p;
01155 long sgn,pwr,posflag;
01156
01157
01158
01159
01160
01161 f=0.0;
01162 do { f=f*10.0+(c-'0'); c=read_char(); } while (DIGIT(c));
01163
01164 if (c=='.') {
01165 c2=read_char();
01166 if DIGIT(c2) {
01167
01168 p=10.0;
01169 while (DIGIT(c2)) { f=f+(c2-'0')/p; p=p*10.0; c2=read_char(); }
01170 put_back_char(c2);
01171 }
01172 else {
01173 put_back_char(c2);
01174 put_back_char(c);
01175 }
01176 }
01177 else
01178 put_back_char(c);
01179
01180 c=read_char();
01181 if (c=='e' || c=='E') {
01182 c2=read_char();
01183 if (c2=='+' || c2=='-' || DIGIT(c2)) {
01184 tok->type=real;
01185 posflag = (c2=='+' || DIGIT(c2));
01186 if (!DIGIT(c2)) c2=read_char();
01187 pwr=0;
01188 while (DIGIT(c2)) { pwr=pwr*10+(c2-'0'); c2=read_char(); }
01189 put_back_char(c2);
01190 p=1.0;
01191 while (pwr>=100) { pwr-=100; if (posflag) p*=1e100; else p/=1e100; }
01192 while (pwr>=10 ) { pwr-=10; if (posflag) p*=1e10; else p/=1e10; }
01193 while (pwr>0 ) { pwr-=1; if (posflag) p*=1e1; else p/=1e1; }
01194 f*=p;
01195 }
01196 else {
01197 put_back_char(c2);
01198 put_back_char(c);
01199 }
01200 }
01201 else
01202 put_back_char(c);
01203
01204
01205 tok->value=heap_alloc(sizeof(REAL));
01206 *(REAL *)tok->value=f;
01207
01208
01209 if(f==floor(f))
01210 tok->type=integer;
01211 else
01212 tok->type=real;
01213 }
01214
01215
01216
01217
01218
01219
01220
01221
01222 void read_token_main();
01223
01224
01225
01226 void read_token(tok)
01227 ptr_psi_term tok;
01228 { read_token_main(tok, TRUE); }
01229
01230
01231
01232 void read_token_b(tok)
01233 ptr_psi_term tok;
01234 { read_token_main(tok, FALSE); }
01235
01236 void read_token_main(tok, for_parser)
01237 ptr_psi_term tok;
01238 long for_parser;
01239 {
01240 long c, c2;
01241 ptr_node n;
01242 char p[2];
01243
01244 if (for_parser && (saved_psi_term!=NULL)) {
01245 *tok= *saved_psi_term;
01246 saved_psi_term=old_saved_psi_term;
01247 old_saved_psi_term=NULL;
01248 }
01249 else {
01250 tok->type=nothing;
01251
01252 do {
01253 c=read_char();
01254 } while(c!=EOF && (c<=32));
01255
01256 if (for_parser) psi_term_line_number=line_count;
01257
01258 switch(c) {
01259 case EOF:
01260 tok->type=eof;
01261 tok->value=NULL;
01262 break;
01263 case '%':
01264 read_comment(tok);
01265 break;
01266 case '"':
01267 read_string(tok,c);
01268 tok->type=quoted_string;
01269 break;
01270 case 39:
01271 read_string(tok,c);
01272 break;
01273
01274 default:
01275
01276
01277
01278
01279
01280
01281
01282
01283 if(c=='.' || c=='?') {
01284 c2=read_char();
01285 put_back_char(c2);
01286
01287 if(c2<=' ' || c2==EOF) {
01288 if(c=='.')
01289 tok->type=final_dot;
01290 else
01291 tok->type=final_question;
01292
01293 tok->value=NULL;
01294 }
01295 else
01296 read_name(tok,c,symbolic,constant);
01297 }
01298 else
01299 if DIGIT(c)
01300 read_number(tok,c);
01301 else
01302 if UPPER(c) {
01303 read_name(tok,c,legal_in_name,variable);
01304 }
01305 else
01306 if LOWER(c) {
01307 read_name(tok,c,legal_in_name,constant);
01308 }
01309 else
01310 if SYMBOL(c) {
01311 read_name(tok,c,symbolic,constant);
01312 }
01313 else
01314 if SINGLE(c) {
01315 p[0]=c; p[1]=0;
01316 tok->type=update_symbol(current_module,p);
01317 tok->value=NULL;
01318 TOKEN_ERROR(tok);
01319 }
01320 else {
01321 Errorline("illegal character %d in input (%E).\n",c);
01322 }
01323 }
01324
01325 if (tok->type==variable) {
01326 if (tok->value) {
01327
01328
01329
01330 if (!strcmp((char *)tok->value,"_")) {
01331 p[0]='@'; p[1]=0;
01332 tok->type=update_symbol(current_module,p);
01333 tok->value=NULL;
01334 TOKEN_ERROR(tok);
01335 }
01336 else {
01337
01338 var_occurred=TRUE;
01339 n=find(strcmp,tok->value,var_tree);
01340 if (n==NULL) {
01341 ptr_psi_term t=stack_psi_term(0);
01342
01343 bk2_stack_insert(strcmp,tok->value,&var_tree,t);
01344 tok->coref=t;
01345 }
01346 else
01347 tok->coref=(ptr_psi_term)n->data;
01348 }
01349 }
01350
01351 }
01352 }
01353
01354 if (tok->type==comment)
01355 read_token(tok);
01356
01357 if (tok->type!=variable)
01358 tok->coref=NULL;
01359
01360 tok->attr_list=NULL;
01361 tok->status=0;
01362 tok->flags=FALSE;
01363 tok->resid=NULL;
01364
01365 if (tok->type==cut)
01366 tok->value=(GENERIC)choice_stack;
01367
01368 do {
01369 c=read_char();
01370 if (c==EOLN) {
01371 if (for_parser) put_back_char(c);
01372 c=0;
01373 }
01374 else if (c<0 || c>32) {
01375 put_back_char(c);
01376 c=0;
01377 }
01378 } while(c && c!=EOF);
01379
01380 if (for_parser) prompt="| ";
01381 }
01382
01383