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