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