Annotation of OpenXM/src/kan96xx/Kan/scanner.c, Revision 1.4
1.4 ! takayama 1: /*$OpenXM: OpenXM/src/kan96xx/Kan/scanner.c,v 1.3 2000/03/20 01:53:46 takayama Exp $*/
1.1 maekawa 2: /* scanner.c (SM StackMachine) */
3: /* export: struct tokens getokenSM(actionType kind,char *str);
4: scanner.c is used to get tokens from streams.
5: files: none
6: */
7: #include <stdio.h>
8: #include "datatype.h"
9: #include "stackm.h"
10: struct tokens lookupTokens(struct tokens t);
11: int isLiteral(char *s);
12: struct object lookupLiteralString(char *s);
13: char *getLOAD_SM1_PATH();
14: /**************** defined in stackm.h ****************************
15: typedef enum {INIT,GET,PUT,OPEN} actionType;
16:
17: struct tokens{
18: char *token;
19: int kind;
20: };
21:
22:
23: #define ID 2
24: #define DOLLAR 3 strings enclosed by dollar sign
25: #define EXECUTABLE_STRING 4 strings enclosed by {}
26: #define EXECUTABLE_ARRAY 8 Don't set it in this file.
27: ******************************************************************/
28:
29:
30: /******* declaration-part of lexical analizer ********************/
31: /* #define mygetchar() getSM() */
32: /* to use getSM() ( input from StringSM ),
33: setup StringSM;
34: getokenSM(INIT);
35: */
36: /* to use getchar(),
37: getokenSM(INIT);
38: */
39:
40:
41:
1.3 takayama 42: FILE *BaseFp = NULL; /* Initialized to stdin in stackmachine_init().
43: file pointer of the first file. */
1.1 maekawa 44:
45: int EchoInScanner = 0; /* echo in scanner */
46:
47: #define BUF0LIMIT 20000
48: static char *StringSM;
49: static int StrpSM = 0;
50: static char BufSMorg[BUF0LIMIT];
51: static char *BufSM = BufSMorg;
52: static int Buf0limit = BUF0LIMIT;
53: static int ExistSM = 0;
54: static int TypeSM = ID;
55:
56: #define FILESTACK_LIMIT 10
57: static FILE * Cfp; /* current input file pointer */
58: static FILE * FileStack[FILESTACK_LIMIT];
59: static int FileStackP = 0;
60: /**************** end of declaration part of lexical analizer ******/
61:
62: static int getSM();
63: static putSM();
64: static struct tokens flushSM();
65: static isSpaceSM();
66: static isDollarSM();
67: static isBraceSM();
68: static isKakkoSM();
69: static isSymbolSM();
70: static mygetchar();
71: static myungetchar();
72:
73:
74: /*
75: static mygetchar()
76: {
77: return( getc(Cfp) );
78: }
79: */
80:
81: static mygetchar()
82: { int c;
1.4 ! takayama 83: if (EchoInScanner) {
! 84: c = getc(Cfp);
! 85: if (c==EOF) {
! 86: printf("\n%% EOF of file %x\n",(int) Cfp);
! 87: }else{
! 88: printf("%c",c);
! 89: }
! 90: return( c );
! 91: }else{
! 92: return( getc(Cfp) );
! 93: }
1.1 maekawa 94: }
95:
96:
97: static myungetchar(c)
1.4 ! takayama 98: int c;
1.1 maekawa 99: {
100: return( ungetc(c,Cfp) );
101: }
102:
103: /**************** code part of lexical analizer ********************/
104: static int getSM()
1.4 ! takayama 105: /* get a letter from StringSM */
1.1 maekawa 106: {
107: int c;
108: c = StringSM[StrpSM++];
109: if (c == '\0') {
110: StrpSM--;return(EOF);
111: } else return(c);
112: }
113:
114: static putSM(c)
1.4 ! takayama 115: int c;
! 116: /* put a letter on BufSM */
1.1 maekawa 117: {
118: char *new; int i;
119: BufSM[ExistSM++] = ((c=='\n')? ' ' : c);
120: if (ExistSM >= Buf0limit-1) {
121: new = (char *) sGC_malloc(sizeof(char *)*Buf0limit*2) ;
122: if (new == (char *)NULL) {
123: fprintf(stderr,"No more memory in parserpass0.c\n");
124: exit(18);
125: }
126: fprintf(stderr,"\nSystem Message: Increasing BufSM to %d in scanner.c\n",Buf0limit*2);
127: for (i=0; i<Buf0limit; i++) {
128: new[i] = BufSM[i];
129: }
130: BufSM = new; Buf0limit *= 2;
131: }
132: }
133:
134: static struct tokens flushSM()
135: {
136: char *token;
137: struct tokens r;
138: if (ExistSM<=0) {
139: fprintf(stderr,"\n flushSM() is called without data. Don't use the empty string $$. \n");
140: r.token = (char *)NULL; r.kind = -10; /* -1 ==> -10 */
141: return(r);
142: }
143: BufSM[ExistSM] = '\0';
144: ExistSM = 0;
145: token = (char *)sGC_malloc((strlen(BufSM)+1)*sizeof(char));
146: strcpy(token,BufSM);
147: r.token = token;
148: r.kind = TypeSM;
149: if (r.kind == ID) {
150: if (isLiteral(r.token)) {
151: r.object = lookupLiteralString(r.token);
152: }else{
153: r = lookupTokens(r); /* Compute hashing values */
154: }
155: }
156: return(r);
157: }
158:
159: static isSpaceSM(c)
1.4 ! takayama 160: int c;
1.1 maekawa 161: {
162: if ((c <= ' ') && (c!= EOF)) return(1);
163: else return(0);
164: }
165:
166: static isDollarSM(c)
1.4 ! takayama 167: int c;
1.1 maekawa 168: {
169: if (c == '$') return(1);
170: else return(0);
171: }
172:
173: static isBraceSM(c)
1.4 ! takayama 174: int c;
1.1 maekawa 175: {
176: if (c == '{') return(1);
177: else return(0);
178: }
179:
180: static isKakkoSM(c)
1.4 ! takayama 181: int c;
1.1 maekawa 182: {
183: if (c == '(') return(1);
184: else return(0);
185: }
186:
187: static isSymbolSM(c)
1.4 ! takayama 188: int c;
1.1 maekawa 189: {
190: if ((c == '{') ||
191: (c == '}') ||
192: (c == '[') ||
193: (c == ']') ||
194: (c == '(') ||
195: (c == ')'))
196: return(1);
197: else return(0);
198: }
199:
200: struct tokens getokenSM(kind,str)
1.4 ! takayama 201: actionType kind;
! 202: char *str;
1.1 maekawa 203: {
204: static int c;
205: static struct tokens rnull;
206: int level;
207: char fname[1024];
208:
209: if (kind == INIT) {
210: StrpSM = 0;
211: ExistSM = 0;
212:
213: Cfp = BaseFp; /* set the file name to BaseFp */
214: FileStackP = 0; /* Clear the file stack */
215:
216: myungetchar('\n'); /* dummy */
217: c = mygetchar(); /* Notice that you need at least on input to return
1.4 ! takayama 218: from the getokenSM(INIT); ^^^^^^^^*/
1.1 maekawa 219: rnull.token = (char *)NULL; rnull.kind = -1;
220: return(rnull);
221: }
222:
223: if (kind == OPEN) {
224: rnull.token = (char *)NULL; rnull.kind = -2;
225: /* -2: suceeded, -3: fail */
226: myungetchar(c);
227: FileStack[FileStackP++] = Cfp; /* push the current file */
228: if (FileStackP >= FILESTACK_LIMIT) {
229: fprintf(stderr,"\nError: I cannot open more than %d files.\n",FILESTACK_LIMIT);
230: FileStackP--;
231: c = mygetchar();
232: rnull.kind = -3;
233: return(rnull); /* error */
234: }else {
235: Cfp = fopen(str,"r");
236: if (EchoInScanner)
1.4 ! takayama 237: printf("\n%% I open the file %s.\n",str);
1.1 maekawa 238: if (Cfp == (FILE *)NULL) {
239:
1.4 ! takayama 240: strcpy(fname,getLOAD_SM1_PATH());
! 241: strcat(fname,str);
! 242: Cfp = fopen(fname,"r");
! 243: if (Cfp == (FILE *)NULL) {
! 244: strcpy(fname,LOAD_SM1_PATH);
! 245: strcat(fname,str);
! 246: Cfp = fopen(fname,"r");
! 247: if (Cfp == (FILE *)NULL) {
! 248: fprintf(stderr,"Warning: Cannot open the file <<%s>> for loading in the current directory nor the library directories %s and %s.\n",str,getLOAD_SM1_PATH(),LOAD_SM1_PATH);
! 249:
! 250: Cfp = FileStack[--FileStackP];
! 251: fprintf(stderr,"\nWarning: I could not open the file %s\n",str);
! 252: c = mygetchar();
! 253: rnull.kind = -3;
! 254: return(rnull); /* error */
! 255: }else{
! 256: c = mygetchar(); /* input from the new file */
! 257: return(rnull);
! 258: }
! 259: }else{
! 260: c = mygetchar(); /* input from the new file */
! 261: return(rnull);
! 262: }
1.1 maekawa 263: }else{
1.4 ! takayama 264: c = mygetchar(); /* input from the new file */
! 265: return(rnull);
1.1 maekawa 266: }
267: }
268: }
269:
270: for (;;) {
271: TypeSM = ID;
272: if (c == EOF) {
273: if (FileStackP <= 0) {
1.4 ! takayama 274: if (ExistSM) return(flushSM());
! 275: else return(rnull);
1.1 maekawa 276: }else { /* return to the previous file */
1.4 ! takayama 277: fclose(Cfp); /* close the file */
! 278: Cfp = FileStack[--FileStackP];
! 279: c = mygetchar(Cfp);
1.1 maekawa 280: }
281: } else if (isSpaceSM(c)) {
282: if (ExistSM) {
1.4 ! takayama 283: c = mygetchar(); return(flushSM());
1.1 maekawa 284: }else {
1.4 ! takayama 285: while (isSpaceSM(c=mygetchar())) ;
1.1 maekawa 286: }
287: } else if (isDollarSM(c)) { /* output contents in dollar signs. */
288: if (ExistSM) return(flushSM());
289: else {
1.4 ! takayama 290: c = mygetchar();
! 291: while ((c != EOF) && (c != '$')) {
! 292: putSM(c);
! 293: c = mygetchar();
! 294: }
! 295: if (c=='$') c=mygetchar();
! 296: TypeSM = DOLLAR;
! 297: return(flushSM());
1.1 maekawa 298: }
299: } else if (isBraceSM(c)) { /* output contents in { } */
300: /* { { } } */
301: level = 0;
302: if (ExistSM) return(flushSM());
303: else {
1.4 ! takayama 304: c = mygetchar();
! 305: while (1) {
! 306: if (c == '%') { /* skip the comment in the brace. */
! 307: while (((c=mygetchar()) != '\n') && (c != EOF)) ;
! 308: }
! 309: if (c == EOF) break;
! 310: if ((c == '}') && (level <= 0)) break;
! 311: if ( c == '{') ++level;
! 312: if ( c == '}') --level;
! 313: putSM(c);
! 314: c = mygetchar();
! 315: }
! 316: if (c=='}') c=mygetchar();
! 317: TypeSM = EXECUTABLE_STRING;
! 318: return(flushSM());
1.1 maekawa 319: }
320: } else if (isKakkoSM(c)) { /* output contents in ( ) */
321: level = 0;
322: if (ExistSM) return(flushSM());
323: else {
1.4 ! takayama 324: c = mygetchar();
! 325: while (1) {
! 326: if (c == EOF) break;
! 327: if (c == '\\') { /* e.g. \( */
! 328: putSM(c);
! 329: c = mygetchar();
! 330: if (c == EOF) break;
! 331: }else{
! 332: if ((c == ')') && (level <= 0)) break;
! 333: if ( c == '(') ++level;
! 334: if ( c == ')') --level;
! 335: }
! 336: putSM(c);
! 337: c = mygetchar();
! 338: }
! 339: if (c==')') c=mygetchar();
! 340: TypeSM = DOLLAR;
! 341: return(flushSM());
1.1 maekawa 342: }
343: } else if (c=='%') { /* comment */
344: while (((c=mygetchar()) != '\n') && (c != EOF)) ;
345: if(ExistSM) return(flushSM());
346: } else if (isSymbolSM(c)) { /* symbols. {,} etc */
347: if(ExistSM) return(flushSM());
348: else {
1.4 ! takayama 349: putSM(c);
! 350: c = mygetchar();
! 351: return(flushSM());
1.1 maekawa 352: }
353: } else { /* identifier */
354: putSM(c);
355: c =mygetchar();
356: while ((!isDollarSM(c)) &&
1.4 ! takayama 357: (!isSpaceSM(c)) &&
! 358: (!isSymbolSM(c)) &&
! 359: (c != EOF)) {
! 360: putSM(c);
! 361: c = mygetchar();
1.1 maekawa 362: }
363: return(flushSM());
364: }
365: }
366: }
367:
368: /*********** end of code part of lexical analizer ********************/
369:
370: /*
371: main() {
372: char input[1000];
373: struct tokens r;
374:
375: getokenSM(INIT);
376: r = getokenSM(GET);
377: while (r.token != (char *)NULL) {
378: printf("%s %d\n",r.token,r.kind);
379: r =getokenSM(GET);
380: }
381:
382: }
383: */
384:
385: /*
386: gets(input);
387: StringSM = (char *)sGC_malloc((strlen(input)+2)*sizeof(char));
388: strcpy(StringSM,input);
389: getokenSM(INIT);
390: */
391:
392: char *getLOAD_SM1_PATH() {
393: char *p;
394: char *p2;
395: char *getenv(char *s);
396: p = getenv("LOAD_SM1_PATH");
397: if (p == NULL) {
1.2 takayama 398: p = getenv("OpenXM_HOME");
399: if (p == NULL) {
400: return("/usr/local/lib/sm1/");
401: }else{
402: if (strlen(p) == 0) return(p);
403: p2 = (char *) sGC_malloc(sizeof(char)*(strlen(p)+strlen("/lib/sm1/")+3));
404: if (p2 == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
405: if (p[strlen(p)-1] != '/') {
1.4 ! takayama 406: strcpy(p2,p); strcat(p2,"/lib/sm1/");
1.2 takayama 407: }else{
1.4 ! takayama 408: strcpy(p2,p); strcat(p2,"lib/sm1/");
1.2 takayama 409: }
410: return(p2);
411: }
1.1 maekawa 412: }else{
413: if (strlen(p) == 0) return(p);
414: if (p[strlen(p)-1] == '/') return(p);
415: /* Add / */
416: p2 = (char *) sGC_malloc(sizeof(char)*(strlen(p)+3));
417: if (p2 == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
418: strcpy(p2,p); strcat(p2,"/");
419: return(p2);
420: }
421: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>