Annotation of OpenXM_contrib2/asir2000/parse/lex.c, Revision 1.9
1.4 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.5 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.4 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.9 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/parse/lex.c,v 1.8 2000/12/05 01:24:57 noro Exp $
1.4 noro 49: */
1.1 noro 50: #include <ctype.h>
51: #include "ca.h"
52: #include "al.h"
53: #include "base.h"
54: #include "parse.h"
55: #include <sys/types.h>
56: #include <sys/stat.h>
57: #include "y.tab.h"
58:
59: extern IN asir_infile;
60: extern struct oTKWD kwd[];
61:
62: int afternl();
63: int myatoi();
64: int aftercomment();
65:
66: extern int main_parser;
67: extern char *parse_strp;
68:
69: static int skipspace();
70: static int Getc();
71: static void Ungetc();
72: static void Gets();
73:
1.2 noro 74: #define NBUFSIZ (BUFSIZ*10)
75: #define TBUFSIZ (BUFSIZ)
76:
77: #define REALLOC_NBUF \
78: if ( i >= nbufsize ) {\
79: nbufsize += NBUFSIZ;\
80: if ( nbuf == nbuf0 ) {\
81: nbuf = (char *)MALLOC_ATOMIC(nbufsize);\
82: bcopy(nbuf0,nbuf,nbufsize-NBUFSIZ);\
83: } else\
84: nbuf = REALLOC(nbuf,nbufsize);\
85: }
86:
87: #define REALLOC_TBUF \
88: if ( i >= tbufsize ) {\
89: tbufsize += TBUFSIZ;\
90: if ( tbuf == tbuf0 ) {\
91: tbuf = (char *)MALLOC_ATOMIC(tbufsize);\
92: bcopy(tbuf0,tbuf,tbufsize-TBUFSIZ);\
93: } else\
94: tbuf = REALLOC(tbuf,tbufsize);\
95: }
96:
97: #define READ_ALNUM_NBUF \
98: while ( 1 ) {\
99: c = Getc();\
100: if ( isalnum(c) ) {\
101: REALLOC_NBUF nbuf[i++] = c;\
102: } else\
103: break;\
104: }
105:
106: #define READ_DIGIT_NBUF \
107: while ( 1 ) {\
108: c = Getc();\
109: if ( isdigit(c) ) {\
110: REALLOC_NBUF nbuf[i++] = c;\
111: } else\
112: break;\
113: }
114:
1.1 noro 115: yylex()
116: {
117: #define yylvalp (&yylval)
118: register int c,c1;
119: register int *ptr;
120: char *cptr;
121: int d,i,j;
1.2 noro 122: char nbuf0[NBUFSIZ],tbuf0[TBUFSIZ];
123: char *nbuf, *tbuf;
124: int nbufsize, tbufsize;
1.1 noro 125: N n,n1;
126: Q q;
127: Obj r;
128:
1.2 noro 129: /* initialize buffer pointers */
130: nbuf = nbuf0; tbuf = tbuf0;
131: nbufsize = NBUFSIZ; tbufsize = TBUFSIZ;
132:
1.1 noro 133: switch ( c = skipspace() ) {
134: case EOF :
135: asir_terminate(2); break;
136: case '0' :
137: while ( ( c = Getc() ) == '0' );
138: if ( c == '.' ) {
139: Ungetc(c); c = '0';
140: } else if ( c == 'x' ) {
141: for ( i = 0; i < 8; i++ )
142: nbuf[i] = '0';
1.2 noro 143: READ_ALNUM_NBUF
144: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
1.1 noro 145: hexton(nbuf,&n1);
146: NTOQ(n1,1,q); r = (Obj)q;
147: yylvalp->p = (pointer)r;
148: return ( FORMULA );
149: } else if ( c == 'b' ) {
150: for ( i = 0; i < 32; i++ )
151: nbuf[i] = '0';
1.2 noro 152: READ_ALNUM_NBUF
153: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
1.1 noro 154: binaryton(nbuf,&n1);
155: NTOQ(n1,1,q); r = (Obj)q;
156: yylvalp->p = (pointer)r;
157: return ( FORMULA );
158: } else if ( !isdigit(c) ) {
159: yylvalp->p = 0; Ungetc(c);
160: return ( FORMULA );
161: }
162: break;
163: case '\'' :
164: for ( i = 0; ; i++ ) {
165: c = Getc();
166: if ( c == '\'' )
167: break;
168: if ( c == '\\' )
169: c = Getc();
1.2 noro 170: REALLOC_TBUF tbuf[i] = c;
1.1 noro 171: }
1.2 noro 172: REALLOC_TBUF tbuf[i] = 0;
1.1 noro 173: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
174: yylvalp->p = (pointer)cptr;
175: return LCASE; break;
176: case '"' :
177: i = 0;
178: do {
179: c = Getc();
180: if ( c == '\\' ) {
181: c1 = Getc();
182: if ( c1 == 'n' )
183: c1 = '\n';
1.2 noro 184: REALLOC_NBUF nbuf[i++] = c1;
185: } else {
186: REALLOC_NBUF nbuf[i++] = c;
187: }
1.1 noro 188: } while ( c != '"' );
1.2 noro 189: nbuf[i-1] = 0; /* REALLOC_NBUF is not necessary */
1.1 noro 190: cptr = (char *)MALLOC(strlen(nbuf)+1);
191: strcpy(cptr,nbuf); yylvalp->p = (pointer) cptr;
192: return ( STR ); break;
193: case '>': case '<': case '=': case '!':
194: if ( (c1 = Getc()) == '=' )
195: switch ( c ) {
196: case '>': yylvalp->i = (int)C_GE; break;
197: case '<': yylvalp->i = (int)C_LE; break;
198: case '=': yylvalp->i = (int)C_EQ; break;
199: case '!': yylvalp->i = (int)C_NE; break;
200: default: break;
201: }
202: else if ( (c == '<' && c1 == '<') || (c == '>' && c1 == '>') )
203: return c;
204: else {
205: Ungetc(c1);
206: switch ( c ) {
207: case '>': yylvalp->i = (int)C_GT; break;
208: case '<': yylvalp->i = (int)C_LT; break;
209: default: return c; break;
210: }
211: }
212: return CMP; break;
213: case '+': case '-': case '*': case '/': case '%': case '^':
214: case '|': case '&':
215: switch ( c ) {
216: case '+': yylvalp->p = (pointer)addfs; break;
217: case '-': yylvalp->p = (pointer)subfs; break;
218: case '*': yylvalp->p = (pointer)mulfs; break;
219: case '/': yylvalp->p = (pointer)divfs; break;
220: case '%': yylvalp->p = (pointer)remfs; break;
221: case '^': yylvalp->p = (pointer)pwrfs; break;
222: default: break;
223: }
224: if ( (c1 = Getc()) == c )
225: switch ( c ) {
226: case '+': case '-': return SELF; break;
227: case '|': return OR; break;
228: case '&': return AND; break;
229: default: Ungetc(c1); return c; break;
230: }
231: else if ( c1 == '=' )
232: return BOPASS;
233: else if ( (c == '-') && (c1 == '>') )
234: return POINT;
235: else {
236: Ungetc(c1); return c;
237: }
238: break;
239: default :
240: break;
241: }
242: if ( isdigit(c) ) {
243: for ( i = 0; i < DLENGTH; i++ )
244: nbuf[i] = '0';
1.2 noro 245: REALLOC_NBUF nbuf[i++] = c;
246: READ_DIGIT_NBUF
1.1 noro 247: if ( c == '.' ) {
248: double dbl;
249: Real real;
250: double atof();
251: extern int bigfloat;
252:
1.2 noro 253: REALLOC_NBUF nbuf[i++] = c;
254: READ_DIGIT_NBUF
1.1 noro 255: if ( c == 'e' ) {
1.2 noro 256: REALLOC_NBUF nbuf[i++] = c;
257: c = Getc();
258: if ( (c == '+') || (c == '-') ) {
259: REALLOC_NBUF nbuf[i++] = c;
260: } else
261: Ungetc(c);
262: READ_DIGIT_NBUF
1.1 noro 263: }
1.2 noro 264: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
1.1 noro 265: #if PARI
266: if ( !bigfloat ) {
267: dbl = (double)atof(nbuf+DLENGTH);
268: MKReal(dbl,real); r = (Obj)real;
269: } else
270: strtobf(nbuf,(BF *)&r);
271: #else
272: dbl = (double)atof(nbuf+DLENGTH);
273: MKReal(dbl,real); r = (Obj)real;
274: #endif
275: } else {
276: Ungetc(c);
277: i -= DLENGTH; d = (i%DLENGTH?i/DLENGTH+1:i/DLENGTH);
278: n = NALLOC(d); PL(n) = d;
279: for ( j = 0, ptr = BD(n); j < d; j++ ,i -= DLENGTH )
280: ptr[j] = myatoi(nbuf+i);
281: bnton(DBASE,n,&n1);
282: NTOQ(n1,1,q); r = (Obj)q;
283: /* optobj(&r); */
284: }
285: yylvalp->p = (pointer)r;
286: return ( FORMULA );
287: } else if ( isalpha(c) ) {
1.2 noro 288: i = 0;
289: tbuf[i++] = c;
290: while ( 1 ) {
291: c = Getc();
292: if ( isalpha(c)||isdigit(c)||(c=='_') ) {
293: REALLOC_TBUF tbuf[i++] = c;
294: } else
295: break;
296: }
297: REALLOC_TBUF tbuf[i] = 0; Ungetc(c);
1.1 noro 298: if ( isupper(tbuf[0]) ) {
299: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
300: yylvalp->p = (pointer)cptr;
301: return UCASE;
302: } else {
303: for ( i = 0; kwd[i].name && strcmp(tbuf,kwd[i].name); i++ );
304: if ( kwd[i].name ) {
305: yylvalp->i = asir_infile->ln;
306: return kwd[i].token;
307: } else {
308: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
309: yylvalp->p = (pointer)cptr;
310: return LCASE;
311: }
312: }
313: } else if ( c == '@' ) {
314: if ( isdigit(c = Getc()) ) {
1.2 noro 315: i = 0;
316: nbuf[i++] = c;
317: READ_DIGIT_NBUF
318: Ungetc(c); REALLOC_NBUF nbuf[i] = 0;
319: yylvalp->i = atoi(nbuf);
1.1 noro 320: return ANS;
321: } else if ( c == '@' ) {
322: yylvalp->i = MAX(0,APVS->n-1);
323: return ANS;
324: } else if ( c == '>' || c == '<' || c == '=' || c == '!' ) {
325: if ( (c1 = Getc()) == '=' )
326: switch ( c ) {
327: case '>': yylvalp->i = (int)L_GE; break;
328: case '<': yylvalp->i = (int)L_LE; break;
329: case '=': yylvalp->i = (int)L_EQ; break;
330: case '!': yylvalp->i = (int)L_NE; break;
331: default: break;
332: }
333: else {
334: Ungetc(c1);
335: switch ( c ) {
336: case '>': yylvalp->i = (int)L_GT; break;
337: case '<': yylvalp->i = (int)L_LT; break;
338: case '=': yylvalp->i = (int)L_EQ; break;
339: case '!': yylvalp->i = (int)L_NOT; return FOP_NOT; break;
340: default: break;
341: }
342: }
343: return LOP;
344: } else if ( c == '|' || c == '&' ) {
345: if ( (c1 = Getc()) != c )
346: Ungetc(c1);
347: switch ( c ) {
348: case '|': yylvalp->i = (int)L_OR;
349: return FOP_OR; break;
350: case '&': yylvalp->i = (int)L_AND;
351: return FOP_AND; break;
352: }
353: } else if ( isalpha(c) ) {
1.2 noro 354: i = 0;
355: tbuf[i++] = '@';
356: tbuf[i++] = c;
357: while ( 1 ) {
358: c = Getc();
359: if ( isalpha(c) ) {
360: REALLOC_TBUF tbuf[i++] = c;
361: } else
362: break;
363: }
364: Ungetc(c); REALLOC_TBUF tbuf[i] = 0;
1.1 noro 365: if ( !strcmp(tbuf,"@p") )
366: return GFPNGEN;
367: else if ( !strcmp(tbuf,"@i") ) {
368: extern pointer IU;
369:
370: yylvalp->p = IU;
371: return FORMULA;
372: } else if ( !strcmp(tbuf,"@true") ) {
373: yylvalp->p = F_TRUE;
374: return FORMULA;
375: } else if ( !strcmp(tbuf,"@false") ) {
376: yylvalp->p = F_FALSE;
377: return FORMULA;
378: } else if ( !strcmp(tbuf,"@impl") ) {
379: yylvalp->i = (int)L_IMPL;
380: return FOP_IMPL;
381: } else if ( !strcmp(tbuf,"@repl") ) {
382: yylvalp->i = (int)L_REPL;
383: return FOP_REPL;
384: } else if ( !strcmp(tbuf,"@equiv") ) {
385: yylvalp->i = (int)L_EQUIV;
386: return FOP_EQUIV;
387: } else {
388: cptr = (char *)MALLOC(strlen(tbuf)+1); strcpy(cptr,tbuf);
389: yylvalp->p = (pointer)cptr;
390: return LCASE;
391: }
392: } else {
393: Ungetc(c);
394: return GF2NGEN;
395: }
396: } else
397: return ( c );
1.6 noro 398: }
399:
400: void purge_stdin()
401: {
1.7 noro 402: #if defined(__FreeBSD__)
1.6 noro 403: fpurge(stdin);
404: #elif defined(linux)
405: stdin->_IO_read_end = stdin->_IO_read_base;
406: stdin->_IO_read_ptr = stdin->_IO_read_base;
407: #elif defined(sparc) || defined(__alpha) || defined(__SVR4) || defined(mips)
408: stdin->_ptr = stdin->_base; stdin->_cnt = 0;
409: #elif defined(VISUAL)
410: w_purge_stdin();
411: #else
412: --->FIXIT
413: #endif
1.1 noro 414: }
415:
416: static int skipspace() {
417: int c,c1;
418:
419: for ( c = Getc(); ; )
420: switch ( c ) {
421: case ' ': case '\t':
422: c = Getc(); break;
423: case '\n':
424: c = afternl(); break;
425: case '/':
426: if ( (c1 = Getc()) == '*' )
427: c = aftercomment();
428: else {
429: Ungetc(c1); return c;
430: }
431: break;
432: default:
433: return c; break;
434: }
435: }
436:
437: int afternl() {
438: int c,ac,i,quote;
439: char *ptr;
440: char *av[BUFSIZ];
441: static int ilevel = 0;
442: char buf[BUFSIZ];
443:
444: if ( !ilevel )
445: asir_infile->ln++;
446: while ( (c = Getc()) == '#' ) {
447: Gets(buf);
448: for ( quote = 0, ptr = buf; *ptr; ptr++ )
449: if ( *ptr == '"' )
450: quote = quote ? 0 : 1;
451: else if ( quote && (*ptr == ' ') )
452: *ptr = '_';
453: stoarg(buf,&ac,av);
454: if ( ac == 3 )
455: if ( (i = atoi(av[2])) == 1 )
456: ilevel++;
457: else if ( i == 2 )
458: ilevel--;
459: if ( !ilevel )
460: asir_infile->ln = atoi(av[0]);
461: }
462: return c;
463: }
464:
465: int aftercomment() {
466: int c,c1;
467:
468: for ( c = Getc(); ; ) {
469: c1 = Getc();
470: if ( (c == '*') && (c1 == '/') )
471: return Getc();
472: else
473: c = c1;
474: }
475: }
476:
477: int myatoi(s)
478: char *s;
479: {
480: int i,r;
481: for ( i = 0, r = 0; i < DLENGTH; i++ ) r = r * 10 + ( s[i] - '0' );
482: return ( r );
483: }
484:
485: extern int ox_do_copy;
486:
487: void yyerror(s)
488: char *s;
489: {
490: if ( main_parser )
491: if ( ox_do_copy ) {
492: /* push errors to DebugStack */
493: } else {
494: if ( asir_infile->fp == stdin )
495: fprintf(stderr,"%s\n",s);
496: else
497: fprintf(stderr,"\"%s\", near line %d: %s\n",asir_infile->name,asir_infile->ln,s);
498: }
499: else
500: fprintf(stderr,"exprparse : %s\n",s);
501: }
502:
503: int echoback;
504:
505: extern int read_exec_file, do_fep, do_file;
506:
507: int readline_getc();
508: void readline_ungetc();
509: int Egetc();
510: void Eungetc();
511:
512: unsigned char encrypt_char(unsigned char);
513: unsigned char decrypt_char(unsigned char);
514:
515: int Egetc(fp)
516: FILE *fp;
517: {
518: int c;
519:
520: if ( fp ) {
521: c = getc(fp);
522: if ( c == EOF )
523: return c;
524: if ( asir_infile->encoded )
525: c = decrypt_char((unsigned char)c);
526: return c;
1.3 noro 527: } else if ( read_exec_file )
528: return EOF;
529: else {
1.1 noro 530: c = *parse_strp++;
531: if ( !c )
532: return EOF;
533: else
534: return c;
535: }
536: }
537:
538: void Eungetc(c,fp)
539: int c;
540: FILE *fp;
541: {
542: if ( fp ) {
543: if ( asir_infile->encoded )
544: c = (int)encrypt_char((unsigned char)c);
545: ungetc(c,fp);
546: } else
547: *--parse_strp = c;
548: }
549:
550: static int Getc() {
551: int c;
552:
553: if ( main_parser ) {
554: while ( 1 ) {
555: if ((c = Egetc(asir_infile->fp)) == EOF)
556: if ( NEXT(asir_infile) ) {
557: closecurrentinput();
1.9 ! noro 558: /* if the input is the top level, generate error */
! 559: if ( !NEXT(asir_infile) )
! 560: error("end-of-file detected during parsing");
! 561: else
! 562: c = Getc();
1.1 noro 563: break;
564: } else if ( read_exec_file || do_file )
565: asir_terminate(2);
566: else {
567: if ( asir_infile->fp )
568: clearerr(asir_infile->fp);
569: }
570: else
571: break;
572: }
573: if ( echoback )
574: fputc(c,asir_out);
575: } else
576: c = *parse_strp++;
577: return ( c );
578: }
579:
580: static void Ungetc(c) {
581: if ( main_parser ) {
582: Eungetc(c,asir_infile->fp);
583: if ( echoback )
584: fputc('',asir_out);
585: } else
586: *--parse_strp = c;
587: }
588:
589: static void Gets(s)
590: char *s;
591: {
592: int c;
593:
594: while ( (c = Getc()) != '\n' )
595: *s++ = c;
596: *s = 0;
597: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>