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