Annotation of OpenXM/src/ox_toolkit/parse.c, Revision 1.11
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.11 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/parse.c,v 1.10 2003/02/03 23:13:23 ohara Exp $ */
1.1 ohara 3:
1.3 ohara 4: /*
5: This module is a parser for OX/CMO expressions.
1.6 ohara 6: Some commnets are written in Japanese by using the EUC-JP coded
1.3 ohara 7: character set.
8: */
1.1 ohara 9:
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <sys/param.h>
14: #include <setjmp.h>
1.5 ohara 15: #include <ctype.h>
1.4 ohara 16:
17: #include "ox_toolkit.h"
1.1 ohara 18: #include "parse.h"
19:
1.3 ohara 20: /* --- Parser --- */
21: /* Remarks for semantics.
1.1 ohara 22: CMO_LIST, CMO_STRING は、あらかじめ与えられた要素の個数を無視する.
23: CMO_MONOMIAL32 は無視しない. (つまりおかしいときは構文エラーになる)
24: */
25:
1.3 ohara 26: /*
27: parse.c では, Lisp 表現された CMO 文字列を読み込み,
1.1 ohara 28: バイト列を出力する. 中間表現として、cmo 構造体を利用する.
29: parse() はトークンの列から cmo 構造体を生成し、そのポインタを返す.
1.3 ohara 30: 重要なことはパーサ(の各サブルーチン)は
1.1 ohara 31: 常にトークンをひとつ先読みしていると言うことである.
32: */
33:
34: /* 現在読み込み中のトークンを表す. */
35: static int token = 0;
36:
37: /* トークンの属性値. yylval は lex() によってセットされる. */
38: static union{
39: int d;
40: char *sym;
41: } yylval;
42:
1.3 ohara 43: /*
44: If `pflag_cmo_addrev' sets, then we admit extended CMO expressions.
45: For example, (CMO_STRING, "hello") is not a real CMO expression
46: but it is admitted.
47: */
48: static int pflag_cmo_addrev = 1;
1.1 ohara 49:
1.3 ohara 50: /* definitions of local functions */
1.5 ohara 51: static void parse_error(char *s);
52: static void parse_right_parenthesis();
53: static void parse_left_parenthesis();
54: static void parse_comma();
1.11 ! ohara 55: #if defined(WITH_GMP)
! 56: static mpz_ptr parse_mpz_integer();
! 57: #endif /* WITH_GMP */
! 58: static int parse_integer();
1.1 ohara 59: static char *parse_string();
60: static cmo *parse_cmo_null();
61: static cmo *parse_cmo_int32();
62: static cmo *parse_cmo_string();
63: static cmo *parse_cmo_mathcap();
64: static cmo *parse_cmo_list();
65: static cmo *parse_cmo_monomial32();
1.11 ! ohara 66: #if defined(WITH_GMP)
1.1 ohara 67: static cmo *parse_cmo_zz();
1.11 ! ohara 68: #endif /* WITH_GMP */
1.1 ohara 69: static cmo *parse_cmo_zero();
70: static cmo *parse_cmo_dms_generic();
71: static cmo *parse_cmo_ring_by_name();
72: static cmo *parse_cmo_distributed_polynomial();
73: static cmo *parse_cmo_indeterminate();
74: static cmo *parse_cmo_error2();
75: static cmo *parse_cmo();
76: static int parse_sm();
77: static ox *parse_ox();
78: static ox *parse_ox_command();
79: static ox *parse_ox_data();
1.5 ohara 80: static void init_lex(char *s);
81: static int lex();
82:
1.1 ohara 83:
84: static int is_token_cmo(int token)
85: {
86: return (token >= MIN_T_CMO && token < MAX_T_CMO) || token == TOKEN(CMO_ERROR2);
87: }
88:
89: static int is_token_sm(int token)
90: {
91: return token == TOKEN(SM);
92: }
93:
94: static int is_token_ox(int token)
95: {
96: return token >= MIN_T_OX && token < MAX_T_OX;
97: }
98:
99: static jmp_buf env_parse;
100:
1.3 ohara 101: /* This is a parsing fault. */
1.5 ohara 102: static void parse_error(char *s)
1.1 ohara 103: {
1.9 ohara 104: ox_printf("syntax error: %s\n", s);
1.1 ohara 105: longjmp(env_parse, 1);
106: }
107:
1.5 ohara 108: void setflag_parse(int flag)
1.2 ohara 109: {
110: pflag_cmo_addrev = flag;
111: }
112:
1.5 ohara 113: void init_parser(char *s)
1.2 ohara 114: {
1.5 ohara 115: setflag_parse(PFLAG_ADDREV);
116: init_lex(s);
1.2 ohara 117: }
118:
1.1 ohara 119: cmo *parse()
120: {
121: cmo *m;
122:
123: if (setjmp(env_parse) != 0) {
1.3 ohara 124: return NULL;
1.5 ohara 125: /* This is an error. */
1.1 ohara 126: }
127:
1.5 ohara 128: token = lex();
1.1 ohara 129: if (token == '(') {
130: token = lex();
131: if (is_token_cmo(token)) {
132: m = parse_cmo();
133: }else if(is_token_ox(token)) {
134: m = parse_ox();
135: }else {
136: parse_error("invalid symbol.");
137: }
138: return m;
139: }
140: return NULL;
141: }
142:
143: static ox *parse_ox()
144: {
145: ox *m = NULL;
146:
147: switch(token) {
148: case TOKEN(OX_COMMAND):
149: token = lex();
150: m = parse_ox_command();
151: break;
152: case TOKEN(OX_DATA):
153: token = lex();
154: m = parse_ox_data();
155: break;
156: default:
157: parse_error("invalid ox.");
158: }
159: return m;
160: }
161:
162: static ox *parse_ox_data()
163: {
164: ox *m;
165:
166: parse_comma();
167: parse_left_parenthesis();
168: m = (ox *)new_ox_data(parse_cmo());
169: parse_right_parenthesis();
170: return m;
171: }
172:
173: static ox *parse_ox_command()
174: {
175: ox *m;
176:
177: parse_comma();
178: parse_left_parenthesis();
179: m = (ox *)new_ox_command(parse_sm());
180: parse_right_parenthesis();
181: return m;
182: }
183:
184: static int parse_sm()
185: {
186: int sm_code;
187: if (token != TOKEN(SM)) {
188: parse_error("no opecode.");
189: }
190: sm_code = yylval.d;
191: token = lex();
192: parse_right_parenthesis();
193: return sm_code;
194: }
195:
196: static cmo *parse_cmo()
197: {
198: cmo *m = NULL;
199:
200: switch(token) {
201: case TOKEN(CMO_NULL):
202: token = lex();
203: m = parse_cmo_null();
204: break;
205: case TOKEN(CMO_INT32):
206: token = lex();
207: m = parse_cmo_int32();
208: break;
209: case TOKEN(CMO_STRING):
210: token = lex();
211: m = parse_cmo_string();
212: break;
213: case TOKEN(CMO_MATHCAP):
214: token = lex();
215: m = parse_cmo_mathcap();
216: break;
217: case TOKEN(CMO_LIST):
218: token = lex();
219: m = parse_cmo_list();
220: break;
221: case TOKEN(CMO_MONOMIAL32):
222: token = lex();
223: m = parse_cmo_monomial32();
224: break;
1.11 ! ohara 225: #if defined(WITH_GMP)
1.1 ohara 226: case TOKEN(CMO_ZZ):
227: token = lex();
228: m = parse_cmo_zz();
229: break;
1.11 ! ohara 230: #endif /* WITH_GMP */
1.1 ohara 231: case TOKEN(CMO_ZERO):
232: token = lex();
233: m = parse_cmo_zero();
234: break;
235: case TOKEN(CMO_DMS_GENERIC):
236: token = lex();
237: m = parse_cmo_dms_generic();
238: break;
239: case TOKEN(CMO_RING_BY_NAME):
240: token = lex();
241: m = parse_cmo_ring_by_name();
242: break;
243: case TOKEN(CMO_DISTRIBUTED_POLYNOMIAL):
244: token = lex();
245: m = parse_cmo_distributed_polynomial();
246: break;
247: case TOKEN(CMO_INDETERMINATE):
248: token = lex();
249: m = parse_cmo_indeterminate();
250: break;
251: case TOKEN(CMO_ERROR2):
252: token = lex();
253: m = parse_cmo_error2();
254: break;
255: default:
256: parse_error("invalid cmo.");
257: }
258: return m;
259: }
260:
1.5 ohara 261: static void parse_left_parenthesis()
1.1 ohara 262: {
263: if (token != '(') {
264: parse_error("no left parenthesis.");
265: }
266: token = lex();
267: }
268:
1.5 ohara 269: static void parse_right_parenthesis()
1.1 ohara 270: {
271: if (token != ')') {
272: parse_error("no right parenthesis.");
273: }
274: token = lex();
275: }
276:
1.5 ohara 277: static void parse_comma()
1.1 ohara 278: {
279: if (token != ',') {
280: parse_error("no comma.");
281: }
282: token = lex();
283: }
284:
1.11 ! ohara 285: #if defined(WITH_GMP)
1.3 ohara 286: static mpz_ptr new_mpz_set_str(char *s)
287: {
1.5 ohara 288: mpz_ptr z = malloc(sizeof(mpz_t));
289: mpz_init_set_str(z, s, 10);
290: return z;
1.3 ohara 291: }
292:
293: static mpz_ptr my_mpz_neg(mpz_ptr src)
294: {
1.5 ohara 295: mpz_ptr z = malloc(sizeof(mpz_t));
296: mpz_init(z);
297: mpz_neg(z, src);
1.11 ! ohara 298: #ifdef DEBUG
1.5 ohara 299: free(src);
1.3 ohara 300: #endif
1.5 ohara 301: return z;
1.3 ohara 302: }
303:
1.11 ! ohara 304: static mpz_ptr parse_mpz_integer()
1.1 ohara 305: {
1.5 ohara 306: int sign = 1;
307: mpz_ptr val;
1.3 ohara 308:
1.5 ohara 309: if (token == '+') {
310: token = lex();
311: }else if (token == '-') {
312: sign = -1;
313: token = lex();
314: }
1.3 ohara 315:
316: if (token != T_DIGIT) {
1.1 ohara 317: parse_error("no integer.");
318: }
1.5 ohara 319: val = new_mpz_set_str(yylval.sym);
320: if (sign == -1) {
321: val = my_mpz_neg(val);
322: }
1.11 ! ohara 323: #ifdef DEBUG
1.5 ohara 324: free(yylval.sym);
1.3 ohara 325: #endif
1.1 ohara 326: token = lex();
327: return val;
328: }
1.11 ! ohara 329: #endif /* WITH_GMP */
! 330:
! 331: static int parse_integer()
! 332: {
! 333: #if defined(WITH_GMP)
! 334: return mpz_get_si(parse_mpz_integer());
! 335: #else
! 336: abort(); /* not implemented */
! 337: #endif
! 338: }
1.1 ohara 339:
340: static char *parse_string()
341: {
342: char *s;
343: if (token != T_STRING) {
344: parse_error("no string.");
345: }
346: s = yylval.sym;
347: token = lex();
348: return s;
349: }
350:
351: static cmo *parse_cmo_null()
352: {
353: parse_right_parenthesis();
354: return (cmo *)new_cmo_null();
355: }
356:
357: static cmo *parse_cmo_int32()
358: {
1.11 ! ohara 359: int z;
1.1 ohara 360:
361: parse_comma();
1.3 ohara 362: z = parse_integer();
1.1 ohara 363: parse_right_parenthesis();
1.11 ! ohara 364: return (cmo *)new_cmo_int32(z);
1.1 ohara 365: }
366:
367: static cmo *parse_cmo_string()
368: {
369: cmo_string *m;
370: char *s;
371:
372: parse_comma();
1.3 ohara 373: if (token == T_DIGIT) {
1.1 ohara 374: parse_integer();
375: parse_comma();
376: }else if (!pflag_cmo_addrev) {
377: parse_error("invalid cmo string.");
378: }
379: s = parse_string();
380: m = new_cmo_string(s);
381: parse_right_parenthesis();
382: return (cmo *)m;
383: }
384:
385: static cmo *parse_cmo_mathcap()
386: {
387: cmo *ob;
388:
389: parse_comma();
390: parse_left_parenthesis();
391: ob = parse_cmo();
392: parse_right_parenthesis();
393: return (cmo *)new_cmo_mathcap(ob);
394: }
395:
396: static cmo *parse_cmo_list()
397: {
398: cmo_list *m = new_cmo_list();
399: cmo *newcmo;
400:
401: if (token == ',') {
402: parse_comma();
403:
1.3 ohara 404: if (token == T_DIGIT) {
1.1 ohara 405: parse_integer();
406: parse_comma();
407: }else if (!pflag_cmo_addrev) {
408: parse_error("invalid cmo_list.");
409: }
410:
411: while(token == '(') {
412: parse_left_parenthesis();
413: newcmo = parse_cmo();
1.5 ohara 414: list_append(m, newcmo);
1.1 ohara 415: if (token != ',') {
416: break;
417: }
418: parse_comma();
419: }
420: }else if (!pflag_cmo_addrev) {
421: parse_error("invalid cmo_list.");
422: }
423: parse_right_parenthesis();
424: return (cmo *)m;
425: }
426:
427: static cmo *parse_cmo_monomial32()
428: {
429: int size;
430: int i;
431: cmo_monomial32 *m;
432: int tag;
433:
434: parse_comma();
1.11 ! ohara 435: size = parse_integer();
1.1 ohara 436: if (size < 0) {
437: parse_error("invalid value.");
438: }
439: m = new_cmo_monomial32_size(size);
440:
441: for(i=0; i<size; i++) {
442: parse_comma();
1.11 ! ohara 443: m->exps[i] = parse_integer();
1.1 ohara 444: }
445: parse_comma();
446: parse_left_parenthesis();
447: m->coef = parse_cmo();
448: tag = m->coef->tag;
449:
1.3 ohara 450: /* semantics:
451: The tag of m->coef must be CMO_ZZ or CMO_INT32. */
1.1 ohara 452: if (tag != CMO_ZZ && tag != CMO_INT32) {
453: parse_error("invalid cmo.");
454: }
455: parse_right_parenthesis();
456: return (cmo *)m;
457: }
458:
1.11 ! ohara 459: #if defined(WITH_GMP)
1.3 ohara 460: /* the following function rewrite internal data of mpz/cmo_zz. */
1.1 ohara 461: static cmo *parse_cmo_zz()
462: {
463: int length;
464: int i=0;
465: cmo_zz *m= NULL;
1.5 ohara 466: mpz_ptr z;
1.1 ohara 467:
468: parse_comma();
1.11 ! ohara 469: z = parse_mpz_integer();
1.1 ohara 470: if (token == ',') {
1.5 ohara 471: length = mpz_get_si(z);
1.1 ohara 472: m = new_cmo_zz_size(length);
473:
474: length = abs(length);
475: for(i=0; i<length; i++) {
476: parse_comma();
1.11 ! ohara 477: m->mpz->_mp_d[i] = parse_integer();
1.1 ohara 478: }
479: }else if (pflag_cmo_addrev) {
1.3 ohara 480: m = new_cmo_zz_set_mpz(z);
1.1 ohara 481: }else {
482: parse_error("no comma.");
483: }
484:
485: parse_right_parenthesis();
486: return (cmo *)m;
487: }
1.11 ! ohara 488: #endif /* WITH_GMP */
1.1 ohara 489:
490: static cmo *parse_cmo_zero()
491: {
492: parse_right_parenthesis();
493: return (cmo *)new_cmo_zero();
494: }
495:
496: static cmo *parse_cmo_dms_generic()
497: {
498: parse_right_parenthesis();
499: return (cmo *)new_cmo_dms_generic();
500: }
501:
502: static cmo *parse_cmo_ring_by_name()
503: {
504: cmo *ob;
505:
506: parse_comma();
507: parse_left_parenthesis();
508: ob = parse_cmo();
509:
1.3 ohara 510: /* The ob has a type of CMO_STRING. */
1.1 ohara 511: if (ob->tag != CMO_STRING) {
512: parse_error("invalid cmo.");
513: }
514: parse_right_parenthesis();
515: return (cmo *)new_cmo_ring_by_name(ob);
516: }
517:
518: static cmo *parse_cmo_distributed_polynomial()
519: {
520: cmo_distributed_polynomial *m = new_cmo_distributed_polynomial();
521: cmo *ob;
522: int tag;
523:
524: if (token == ',') {
525: parse_comma();
526:
1.3 ohara 527: if (token == T_DIGIT) {
1.1 ohara 528: parse_integer();
529: parse_comma();
530: }else if (!pflag_cmo_addrev) {
531: parse_error("invalid d-polynomial.");
532: }
533:
534: parse_left_parenthesis();
535: m->ringdef = parse_cmo();
536: tag = m->ringdef->tag;
1.3 ohara 537: /* m->ringdef needs to be a DringDefinition. */
1.1 ohara 538: if (tag != CMO_RING_BY_NAME && tag != CMO_DMS_GENERIC
539: && tag != CMO_DMS_OF_N_VARIABLES) {
540: parse_error("invalid cmo.");
541: }
542:
543: parse_comma();
544:
545: while(token == '(') {
546: parse_left_parenthesis();
547: ob = parse_cmo();
548: if (ob->tag != CMO_MONOMIAL32 && ob->tag != CMO_ZERO) {
549: parse_error("invalid cmo.");
550: }
1.5 ohara 551: list_append((cmo_list *)m, ob);
1.1 ohara 552: if (token != ',') {
553: break;
554: }
555: parse_comma();
556: }
557: }else if (!pflag_cmo_addrev) {
558: parse_error("invalid d-polynomial.");
559: }
560: parse_right_parenthesis();
561: return (cmo *)m;
562: }
563:
564: static cmo *parse_cmo_indeterminate()
565: {
566: cmo *ob;
567:
568: parse_comma();
569: parse_left_parenthesis();
570: ob = parse_cmo();
571: parse_right_parenthesis();
572: return (cmo *)new_cmo_indeterminate(ob);
573: }
574:
575: static cmo *parse_cmo_error2()
576: {
577: cmo *ob;
578:
579: parse_comma();
580: parse_left_parenthesis();
581: ob = parse_cmo();
582: parse_right_parenthesis();
583: return (cmo *)new_cmo_error2(ob);
584: }
585:
1.3 ohara 586: /* --- lexical analyzer --- */
1.1 ohara 587:
1.3 ohara 588: /* A white space is ignored by lexical analyzer. */
1.1 ohara 589: static int c = ' ';
590:
1.3 ohara 591: /* getting a character from string. */
1.2 ohara 592: static char *mygetc_ptr;
593: static int mygetc()
594: {
1.5 ohara 595: return *mygetc_ptr++;
1.2 ohara 596: }
1.1 ohara 597:
1.5 ohara 598: static void init_lex(char *s)
1.1 ohara 599: {
1.7 ohara 600: c=' ';
1.2 ohara 601: mygetc_ptr=s;
1.1 ohara 602: }
603:
604: #define SIZE_BUFFER 8192
605: static char buffer[SIZE_BUFFER];
606:
1.3 ohara 607: static char *mkstr(char *src)
1.1 ohara 608: {
1.5 ohara 609: int len;
610: char *s;
611: len = strlen(src);
612: s = malloc(len+1);
613: strcpy(s, src);
614: return s;
1.3 ohara 615: }
616:
617: /* no measure for buffer overflow */
618: static char *lex_digit()
619: {
1.5 ohara 620: static char buff[SIZE_BUFFER];
621: int i;
622:
623: for(i=0; i<SIZE_BUFFER-1; i++) {
624: if(isdigit(c)) {
625: buff[i] = c;
626: }else {
627: buff[i] = '\0';
628: return mkstr(buff);
629: }
1.3 ohara 630: c = mygetc();
1.5 ohara 631: }
632: buff[SIZE_BUFFER-1] = '\0';
633: return mkstr(buff);
1.1 ohara 634: }
635:
636: #define MK_KEY_CMO(x) { #x , x , TOKEN(x) , IS_CMO }
637: #define MK_KEY_SM(x) { #x , x , TOKEN(SM) , IS_SM }
638: #define MK_KEY_OX(x) { #x , x , TOKEN(x) , IS_OX }
639:
1.4 ohara 640: static struct symbol symbol_list[] = {
1.1 ohara 641: MK_KEY_CMO(CMO_NULL),
642: MK_KEY_CMO(CMO_INT32),
643: MK_KEY_CMO(CMO_DATUM),
644: MK_KEY_CMO(CMO_STRING),
645: MK_KEY_CMO(CMO_MATHCAP),
646: MK_KEY_CMO(CMO_LIST),
647: MK_KEY_CMO(CMO_MONOMIAL32),
648: MK_KEY_CMO(CMO_ZZ),
649: MK_KEY_CMO(CMO_ZERO),
650: MK_KEY_CMO(CMO_DMS_GENERIC),
651: MK_KEY_CMO(CMO_RING_BY_NAME),
652: MK_KEY_CMO(CMO_INDETERMINATE),
653: MK_KEY_CMO(CMO_DISTRIBUTED_POLYNOMIAL),
654: MK_KEY_CMO(CMO_ERROR2),
655: MK_KEY_SM(SM_popCMO),
656: MK_KEY_SM(SM_popString),
657: MK_KEY_SM(SM_mathcap),
658: MK_KEY_SM(SM_pops),
659: MK_KEY_SM(SM_executeStringByLocalParser),
660: MK_KEY_SM(SM_executeFunction),
661: MK_KEY_SM(SM_setMathCap),
662: MK_KEY_SM(SM_shutdown),
663: MK_KEY_SM(SM_control_kill),
664: MK_KEY_SM(SM_control_reset_connection),
665: MK_KEY_OX(OX_COMMAND),
666: MK_KEY_OX(OX_DATA),
667: {NULL, 0, 0, 0} /* a gate keeper */
668: };
669:
1.4 ohara 670: symbol_t lookup_by_symbol(char *key)
1.1 ohara 671: {
1.4 ohara 672: symbol_t symp;
1.1 ohara 673: for(symp = symbol_list; symp->key != NULL; symp++) {
674: if (strcmp(key, symp->key)==0) {
675: return symp;
676: }
677: }
678: return NULL;
679: }
680:
1.4 ohara 681: symbol_t lookup_by_token(int tok)
1.1 ohara 682: {
1.4 ohara 683: symbol_t symp;
1.1 ohara 684: for(symp = symbol_list; symp->key != NULL; symp++) {
685: if (tok == symp->token) {
686: return symp;
687: }
688: }
689: return NULL;
690: }
691:
1.4 ohara 692: symbol_t lookup_by_tag(int tag)
1.1 ohara 693: {
1.4 ohara 694: symbol_t symp;
1.1 ohara 695: for(symp = symbol_list; symp->key != NULL; symp++) {
696: if (tag == symp->tag) {
697: return symp;
698: }
699: }
700: return NULL;
701: }
702:
1.4 ohara 703: symbol_t lookup(int i)
1.1 ohara 704: {
705: return &symbol_list[i];
706: }
707:
1.10 ohara 708: char *get_symbol_by_tag(int tag)
1.4 ohara 709: {
1.10 ohara 710: symbol_t symp = lookup_by_tag(tag);
711: return (symp != NULL)? symp->key: NULL;
1.4 ohara 712: }
713:
1.3 ohara 714: /* no measure for buffer overflow */
1.1 ohara 715: static char *lex_quoted_string()
716: {
717: int i;
718: char c0 = ' ';
1.3 ohara 719:
1.1 ohara 720: for (i=0; i<SIZE_BUFFER; i++) {
1.3 ohara 721: c = mygetc();
1.1 ohara 722: if(c == '"') {
1.3 ohara 723: c = mygetc();
1.1 ohara 724: buffer[i]='\0';
1.5 ohara 725: return mkstr(buffer);
1.1 ohara 726: }else if (c == '\\') {
727: c0 = c;
1.3 ohara 728: c = mygetc();
1.1 ohara 729: if (c != '"') {
730: buffer[i++] = c0;
731: }
732: }
733: buffer[i]=c;
734: }
1.9 ohara 735: ox_printf("buffer overflow!\n");
1.1 ohara 736: exit(1);
737: /* return NULL; */
738: }
739:
740: static int token_of_symbol(char *key)
741: {
1.4 ohara 742: symbol_t symp = lookup_by_symbol(key);
1.1 ohara 743: if (symp != NULL) {
744: yylval.d = symp->tag;
745: return symp->token;
746: }
1.9 ohara 747: ox_printf("lex error:: \"%s\" is unknown symbol.\n", key);
1.1 ohara 748: return 0;
749: }
750:
751: static int lex_symbol()
752: {
753: int i;
754: for (i=0; i<SIZE_BUFFER; i++) {
755: if (!isalnum(c) && c != '_') {
756: buffer[i]='\0';
757: return token_of_symbol(buffer);
758: }
759: buffer[i]=c;
1.3 ohara 760: c = mygetc();
1.1 ohara 761: }
1.9 ohara 762: ox_printf("buffer overflow!\n");
1.1 ohara 763: return 0;
764: }
765:
1.6 ohara 766: /* Remark: prefetching a character before return. */
1.5 ohara 767: static int lex()
1.1 ohara 768: {
769: int c_dash = 0;
770:
1.3 ohara 771: /* white spaces are ignored. */
772: while (isspace(c)) {
773: c = mygetc();
1.1 ohara 774: }
775:
776: switch(c) {
777: case '(':
778: case ')':
779: case ',':
1.5 ohara 780: case '+':
781: case '-':
1.1 ohara 782: c_dash = c;
783: c = ' ';
784: return c_dash;
785: case EOF:
1.3 ohara 786: c = mygetc();
1.1 ohara 787: return c_dash;
788: case '"': /* a quoted string! */
789: yylval.sym = lex_quoted_string();
790: return T_STRING;
791: default:
792: }
793:
1.3 ohara 794: if (isalpha(c)) {
1.5 ohara 795: /* symbols */
1.1 ohara 796: return lex_symbol();
797: }
798:
1.5 ohara 799: /* digit */
1.1 ohara 800: if (isdigit(c)){
1.3 ohara 801: yylval.sym = lex_digit();
802: return T_DIGIT;
1.1 ohara 803: }
1.3 ohara 804: c = mygetc();
1.1 ohara 805: return 0;
806: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>