Annotation of OpenXM/src/kan96xx/Kan/scanner.c, Revision 1.6
1.6 ! takayama 1: /*$OpenXM: OpenXM/src/kan96xx/Kan/scanner.c,v 1.5 2004/09/10 13:20:23 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;
1.6 ! takayama 108:
! 109: if ((StrpSM > 0) && (StringSM[StrpSM] == ',') && (StringSM[StrpSM-1] == ',')) { int i;
! 110: fprintf(stderr,"Warning: ,, is found.");
! 111: for (i=(StrpSM-30>0?StrpSM-30:0); i<=StrpSM; i++) {
! 112: fprintf(stderr,"%c",StringSM[i]);
! 113: }
! 114: fprintf(stderr,"\n");
! 115: }
! 116:
1.1 maekawa 117: c = StringSM[StrpSM++];
118: if (c == '\0') {
119: StrpSM--;return(EOF);
120: } else return(c);
121: }
122:
123: static putSM(c)
1.4 takayama 124: int c;
125: /* put a letter on BufSM */
1.1 maekawa 126: {
127: char *new; int i;
128: BufSM[ExistSM++] = ((c=='\n')? ' ' : c);
129: if (ExistSM >= Buf0limit-1) {
130: new = (char *) sGC_malloc(sizeof(char *)*Buf0limit*2) ;
131: if (new == (char *)NULL) {
132: fprintf(stderr,"No more memory in parserpass0.c\n");
133: exit(18);
134: }
135: fprintf(stderr,"\nSystem Message: Increasing BufSM to %d in scanner.c\n",Buf0limit*2);
136: for (i=0; i<Buf0limit; i++) {
137: new[i] = BufSM[i];
138: }
139: BufSM = new; Buf0limit *= 2;
140: }
141: }
142:
143: static struct tokens flushSM()
144: {
145: char *token;
146: struct tokens r;
147: if (ExistSM<=0) {
148: fprintf(stderr,"\n flushSM() is called without data. Don't use the empty string $$. \n");
149: r.token = (char *)NULL; r.kind = -10; /* -1 ==> -10 */
150: return(r);
151: }
152: BufSM[ExistSM] = '\0';
153: ExistSM = 0;
154: token = (char *)sGC_malloc((strlen(BufSM)+1)*sizeof(char));
155: strcpy(token,BufSM);
156: r.token = token;
157: r.kind = TypeSM;
158: if (r.kind == ID) {
159: if (isLiteral(r.token)) {
160: r.object = lookupLiteralString(r.token);
161: }else{
162: r = lookupTokens(r); /* Compute hashing values */
163: }
164: }
165: return(r);
166: }
167:
168: static isSpaceSM(c)
1.4 takayama 169: int c;
1.1 maekawa 170: {
1.5 takayama 171: if (((c <= ' ') || c == ',') && (c!= EOF)) return(1);
1.1 maekawa 172: else return(0);
173: }
174:
175: static isDollarSM(c)
1.4 takayama 176: int c;
1.1 maekawa 177: {
178: if (c == '$') return(1);
179: else return(0);
180: }
181:
182: static isBraceSM(c)
1.4 takayama 183: int c;
1.1 maekawa 184: {
185: if (c == '{') return(1);
186: else return(0);
187: }
188:
189: static isKakkoSM(c)
1.4 takayama 190: int c;
1.1 maekawa 191: {
192: if (c == '(') return(1);
193: else return(0);
194: }
195:
196: static isSymbolSM(c)
1.4 takayama 197: int c;
1.1 maekawa 198: {
199: if ((c == '{') ||
200: (c == '}') ||
201: (c == '[') ||
202: (c == ']') ||
203: (c == '(') ||
204: (c == ')'))
205: return(1);
206: else return(0);
207: }
208:
209: struct tokens getokenSM(kind,str)
1.4 takayama 210: actionType kind;
211: char *str;
1.1 maekawa 212: {
213: static int c;
214: static struct tokens rnull;
215: int level;
216: char fname[1024];
217:
218: if (kind == INIT) {
219: StrpSM = 0;
220: ExistSM = 0;
221:
222: Cfp = BaseFp; /* set the file name to BaseFp */
223: FileStackP = 0; /* Clear the file stack */
224:
225: myungetchar('\n'); /* dummy */
226: c = mygetchar(); /* Notice that you need at least on input to return
1.4 takayama 227: from the getokenSM(INIT); ^^^^^^^^*/
1.1 maekawa 228: rnull.token = (char *)NULL; rnull.kind = -1;
229: return(rnull);
230: }
231:
232: if (kind == OPEN) {
233: rnull.token = (char *)NULL; rnull.kind = -2;
234: /* -2: suceeded, -3: fail */
235: myungetchar(c);
236: FileStack[FileStackP++] = Cfp; /* push the current file */
237: if (FileStackP >= FILESTACK_LIMIT) {
238: fprintf(stderr,"\nError: I cannot open more than %d files.\n",FILESTACK_LIMIT);
239: FileStackP--;
240: c = mygetchar();
241: rnull.kind = -3;
242: return(rnull); /* error */
243: }else {
244: Cfp = fopen(str,"r");
245: if (EchoInScanner)
1.4 takayama 246: printf("\n%% I open the file %s.\n",str);
1.1 maekawa 247: if (Cfp == (FILE *)NULL) {
248:
1.4 takayama 249: strcpy(fname,getLOAD_SM1_PATH());
250: strcat(fname,str);
251: Cfp = fopen(fname,"r");
252: if (Cfp == (FILE *)NULL) {
253: strcpy(fname,LOAD_SM1_PATH);
254: strcat(fname,str);
255: Cfp = fopen(fname,"r");
256: if (Cfp == (FILE *)NULL) {
257: 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);
258:
259: Cfp = FileStack[--FileStackP];
260: fprintf(stderr,"\nWarning: I could not open the file %s\n",str);
261: c = mygetchar();
262: rnull.kind = -3;
263: return(rnull); /* error */
264: }else{
265: c = mygetchar(); /* input from the new file */
266: return(rnull);
267: }
268: }else{
269: c = mygetchar(); /* input from the new file */
270: return(rnull);
271: }
1.1 maekawa 272: }else{
1.4 takayama 273: c = mygetchar(); /* input from the new file */
274: return(rnull);
1.1 maekawa 275: }
276: }
277: }
278:
279: for (;;) {
280: TypeSM = ID;
281: if (c == EOF) {
282: if (FileStackP <= 0) {
1.4 takayama 283: if (ExistSM) return(flushSM());
284: else return(rnull);
1.1 maekawa 285: }else { /* return to the previous file */
1.4 takayama 286: fclose(Cfp); /* close the file */
287: Cfp = FileStack[--FileStackP];
288: c = mygetchar(Cfp);
1.1 maekawa 289: }
290: } else if (isSpaceSM(c)) {
291: if (ExistSM) {
1.4 takayama 292: c = mygetchar(); return(flushSM());
1.1 maekawa 293: }else {
1.4 takayama 294: while (isSpaceSM(c=mygetchar())) ;
1.1 maekawa 295: }
296: } else if (isDollarSM(c)) { /* output contents in dollar signs. */
297: if (ExistSM) return(flushSM());
298: else {
1.4 takayama 299: c = mygetchar();
300: while ((c != EOF) && (c != '$')) {
301: putSM(c);
302: c = mygetchar();
303: }
304: if (c=='$') c=mygetchar();
305: TypeSM = DOLLAR;
306: return(flushSM());
1.1 maekawa 307: }
308: } else if (isBraceSM(c)) { /* output contents in { } */
309: /* { { } } */
310: level = 0;
311: if (ExistSM) return(flushSM());
312: else {
1.4 takayama 313: c = mygetchar();
314: while (1) {
315: if (c == '%') { /* skip the comment in the brace. */
316: while (((c=mygetchar()) != '\n') && (c != EOF)) ;
317: }
318: if (c == EOF) break;
319: if ((c == '}') && (level <= 0)) break;
320: if ( c == '{') ++level;
321: if ( c == '}') --level;
322: putSM(c);
323: c = mygetchar();
324: }
325: if (c=='}') c=mygetchar();
326: TypeSM = EXECUTABLE_STRING;
327: return(flushSM());
1.1 maekawa 328: }
329: } else if (isKakkoSM(c)) { /* output contents in ( ) */
330: level = 0;
331: if (ExistSM) return(flushSM());
332: else {
1.4 takayama 333: c = mygetchar();
334: while (1) {
335: if (c == EOF) break;
336: if (c == '\\') { /* e.g. \( */
337: putSM(c);
338: c = mygetchar();
339: if (c == EOF) break;
340: }else{
341: if ((c == ')') && (level <= 0)) break;
342: if ( c == '(') ++level;
343: if ( c == ')') --level;
344: }
345: putSM(c);
346: c = mygetchar();
347: }
348: if (c==')') c=mygetchar();
349: TypeSM = DOLLAR;
350: return(flushSM());
1.1 maekawa 351: }
352: } else if (c=='%') { /* comment */
353: while (((c=mygetchar()) != '\n') && (c != EOF)) ;
354: if(ExistSM) return(flushSM());
355: } else if (isSymbolSM(c)) { /* symbols. {,} etc */
356: if(ExistSM) return(flushSM());
357: else {
1.4 takayama 358: putSM(c);
359: c = mygetchar();
360: return(flushSM());
1.1 maekawa 361: }
362: } else { /* identifier */
363: putSM(c);
364: c =mygetchar();
365: while ((!isDollarSM(c)) &&
1.4 takayama 366: (!isSpaceSM(c)) &&
367: (!isSymbolSM(c)) &&
368: (c != EOF)) {
369: putSM(c);
370: c = mygetchar();
1.1 maekawa 371: }
372: return(flushSM());
373: }
374: }
375: }
376:
377: /*********** end of code part of lexical analizer ********************/
378:
379: /*
380: main() {
381: char input[1000];
382: struct tokens r;
383:
384: getokenSM(INIT);
385: r = getokenSM(GET);
386: while (r.token != (char *)NULL) {
387: printf("%s %d\n",r.token,r.kind);
388: r =getokenSM(GET);
389: }
390:
391: }
392: */
393:
394: /*
395: gets(input);
396: StringSM = (char *)sGC_malloc((strlen(input)+2)*sizeof(char));
397: strcpy(StringSM,input);
398: getokenSM(INIT);
399: */
400:
401: char *getLOAD_SM1_PATH() {
402: char *p;
403: char *p2;
404: char *getenv(char *s);
405: p = getenv("LOAD_SM1_PATH");
406: if (p == NULL) {
1.2 takayama 407: p = getenv("OpenXM_HOME");
408: if (p == NULL) {
409: return("/usr/local/lib/sm1/");
410: }else{
411: if (strlen(p) == 0) return(p);
412: p2 = (char *) sGC_malloc(sizeof(char)*(strlen(p)+strlen("/lib/sm1/")+3));
413: if (p2 == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
414: if (p[strlen(p)-1] != '/') {
1.4 takayama 415: strcpy(p2,p); strcat(p2,"/lib/sm1/");
1.2 takayama 416: }else{
1.4 takayama 417: strcpy(p2,p); strcat(p2,"lib/sm1/");
1.2 takayama 418: }
419: return(p2);
420: }
1.1 maekawa 421: }else{
422: if (strlen(p) == 0) return(p);
423: if (p[strlen(p)-1] == '/') return(p);
424: /* Add / */
425: p2 = (char *) sGC_malloc(sizeof(char)*(strlen(p)+3));
426: if (p2 == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
427: strcpy(p2,p); strcat(p2,"/");
428: return(p2);
429: }
430: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>