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