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