Annotation of OpenXM/src/ox_toolkit/parse.c, Revision 1.17
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.17 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/parse.c,v 1.16 2005/07/20 17:48:03 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 <setjmp.h>
1.5 ohara 14: #include <ctype.h>
1.17 ! ohara 15: #if !defined(_MSC_VER)
! 16: #include <sys/param.h>
! 17: #endif
1.4 ohara 18:
19: #include "ox_toolkit.h"
1.1 ohara 20: #include "parse.h"
21:
1.3 ohara 22: /* --- Parser --- */
23: /* Remarks for semantics.
1.1 ohara 24: CMO_LIST, CMO_STRING は、あらかじめ与えられた要素の個数を無視する.
25: CMO_MONOMIAL32 は無視しない. (つまりおかしいときは構文エラーになる)
26: */
27:
1.3 ohara 28: /*
29: parse.c では, Lisp 表現された CMO 文字列を読み込み,
1.1 ohara 30: バイト列を出力する. 中間表現として、cmo 構造体を利用する.
31: parse() はトークンの列から cmo 構造体を生成し、そのポインタを返す.
1.3 ohara 32: 重要なことはパーサ(の各サブルーチン)は
1.1 ohara 33: 常にトークンをひとつ先読みしていると言うことである.
34: */
35:
36: /* 現在読み込み中のトークンを表す. */
37: static int token = 0;
38:
39: /* トークンの属性値. yylval は lex() によってセットされる. */
40: static union{
41: int d;
42: char *sym;
43: } yylval;
44:
1.3 ohara 45: /*
46: If `pflag_cmo_addrev' sets, then we admit extended CMO expressions.
47: For example, (CMO_STRING, "hello") is not a real CMO expression
48: but it is admitted.
49: */
50: static int pflag_cmo_addrev = 1;
1.1 ohara 51:
1.3 ohara 52: /* definitions of local functions */
1.16 ohara 53: static void init_parser(char *s);
54: static cmo *parse();
1.5 ohara 55: static void parse_error(char *s);
56: static void parse_right_parenthesis();
57: static void parse_left_parenthesis();
58: static void parse_comma();
1.11 ohara 59: static mpz_ptr parse_mpz_integer();
60: static int parse_integer();
1.1 ohara 61: static char *parse_string();
62: static cmo *parse_cmo_null();
63: static cmo *parse_cmo_int32();
64: static cmo *parse_cmo_string();
65: static cmo *parse_cmo_mathcap();
66: static cmo *parse_cmo_list();
67: static cmo *parse_cmo_monomial32();
68: static cmo *parse_cmo_zz();
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.16 ohara 83: /* Parsing a Lisp-style expression of CMO. */
84: cmo *ox_parse_lisp(char *s)
85: {
86: return (s != NULL && strlen(s) > 0)? init_parser(s), parse(): NULL;
87: }
1.1 ohara 88:
89: static int is_token_cmo(int token)
90: {
91: return (token >= MIN_T_CMO && token < MAX_T_CMO) || token == TOKEN(CMO_ERROR2);
92: }
93:
94: static int is_token_sm(int token)
95: {
96: return token == TOKEN(SM);
97: }
98:
99: static int is_token_ox(int token)
100: {
101: return token >= MIN_T_OX && token < MAX_T_OX;
102: }
103:
104: static jmp_buf env_parse;
105:
1.3 ohara 106: /* This is a parsing fault. */
1.5 ohara 107: static void parse_error(char *s)
1.1 ohara 108: {
1.9 ohara 109: ox_printf("syntax error: %s\n", s);
1.1 ohara 110: longjmp(env_parse, 1);
111: }
112:
1.16 ohara 113: static void setflag_parse(int flag)
1.2 ohara 114: {
115: pflag_cmo_addrev = flag;
116: }
117:
1.16 ohara 118: static void init_parser(char *s)
1.2 ohara 119: {
1.5 ohara 120: setflag_parse(PFLAG_ADDREV);
121: init_lex(s);
1.2 ohara 122: }
123:
1.16 ohara 124: static cmo *parse()
1.1 ohara 125: {
1.16 ohara 126: cmo *m = NULL;
127: if (setjmp(env_parse) == 0) {
1.1 ohara 128: token = lex();
1.16 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: }
1.1 ohara 138: }
139: }
1.16 ohara 140: return m;
1.1 ohara 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;
225: case TOKEN(CMO_ZZ):
226: token = lex();
227: m = parse_cmo_zz();
228: break;
229: case TOKEN(CMO_ZERO):
230: token = lex();
231: m = parse_cmo_zero();
232: break;
233: case TOKEN(CMO_DMS_GENERIC):
234: token = lex();
235: m = parse_cmo_dms_generic();
236: break;
237: case TOKEN(CMO_RING_BY_NAME):
238: token = lex();
239: m = parse_cmo_ring_by_name();
240: break;
241: case TOKEN(CMO_DISTRIBUTED_POLYNOMIAL):
242: token = lex();
243: m = parse_cmo_distributed_polynomial();
244: break;
245: case TOKEN(CMO_INDETERMINATE):
246: token = lex();
247: m = parse_cmo_indeterminate();
248: break;
249: case TOKEN(CMO_ERROR2):
250: token = lex();
251: m = parse_cmo_error2();
252: break;
253: default:
254: parse_error("invalid cmo.");
255: }
256: return m;
257: }
258:
1.5 ohara 259: static void parse_left_parenthesis()
1.1 ohara 260: {
261: if (token != '(') {
262: parse_error("no left parenthesis.");
263: }
264: token = lex();
265: }
266:
1.5 ohara 267: static void parse_right_parenthesis()
1.1 ohara 268: {
269: if (token != ')') {
270: parse_error("no right parenthesis.");
271: }
272: token = lex();
273: }
274:
1.5 ohara 275: static void parse_comma()
1.1 ohara 276: {
277: if (token != ',') {
278: parse_error("no comma.");
279: }
280: token = lex();
281: }
282:
1.3 ohara 283: static mpz_ptr new_mpz_set_str(char *s)
284: {
1.14 ohara 285: mpz_ptr z = MALLOC(sizeof(mpz_t));
1.5 ohara 286: mpz_init_set_str(z, s, 10);
287: return z;
1.3 ohara 288: }
289:
290: static mpz_ptr my_mpz_neg(mpz_ptr src)
291: {
1.14 ohara 292: mpz_ptr z = MALLOC(sizeof(mpz_t));
1.5 ohara 293: mpz_init(z);
294: mpz_neg(z, src);
295: return z;
1.3 ohara 296: }
297:
1.11 ohara 298: static mpz_ptr parse_mpz_integer()
1.1 ohara 299: {
1.5 ohara 300: int sign = 1;
301: mpz_ptr val;
1.3 ohara 302:
1.5 ohara 303: if (token == '+') {
304: token = lex();
305: }else if (token == '-') {
306: sign = -1;
307: token = lex();
308: }
1.3 ohara 309:
310: if (token != T_DIGIT) {
1.1 ohara 311: parse_error("no integer.");
312: }
1.5 ohara 313: val = new_mpz_set_str(yylval.sym);
314: if (sign == -1) {
315: val = my_mpz_neg(val);
316: }
1.1 ohara 317: token = lex();
318: return val;
319: }
1.11 ohara 320:
321: static int parse_integer()
322: {
1.13 ohara 323: #if 0
1.11 ohara 324: return mpz_get_si(parse_mpz_integer());
325: #else
1.12 ohara 326: int sign = 1;
327: int val;
328:
329: if (token == '+') {
330: token = lex();
331: }else if (token == '-') {
332: sign = -1;
333: token = lex();
334: }
335:
336: if (token != T_DIGIT) {
337: parse_error("no integer.");
338: }
339: val = sign*atoi(yylval.sym);
340: token = lex();
341: return val;
1.11 ohara 342: #endif
343: }
1.1 ohara 344:
345: static char *parse_string()
346: {
347: char *s;
348: if (token != T_STRING) {
349: parse_error("no string.");
350: }
351: s = yylval.sym;
352: token = lex();
353: return s;
354: }
355:
356: static cmo *parse_cmo_null()
357: {
358: parse_right_parenthesis();
359: return (cmo *)new_cmo_null();
360: }
361:
362: static cmo *parse_cmo_int32()
363: {
1.11 ohara 364: int z;
1.1 ohara 365:
366: parse_comma();
1.3 ohara 367: z = parse_integer();
1.1 ohara 368: parse_right_parenthesis();
1.11 ohara 369: return (cmo *)new_cmo_int32(z);
1.1 ohara 370: }
371:
372: static cmo *parse_cmo_string()
373: {
374: cmo_string *m;
375: char *s;
376:
377: parse_comma();
1.3 ohara 378: if (token == T_DIGIT) {
1.1 ohara 379: parse_integer();
380: parse_comma();
381: }else if (!pflag_cmo_addrev) {
382: parse_error("invalid cmo string.");
383: }
384: s = parse_string();
385: m = new_cmo_string(s);
386: parse_right_parenthesis();
387: return (cmo *)m;
388: }
389:
390: static cmo *parse_cmo_mathcap()
391: {
392: cmo *ob;
393:
394: parse_comma();
395: parse_left_parenthesis();
396: ob = parse_cmo();
397: parse_right_parenthesis();
398: return (cmo *)new_cmo_mathcap(ob);
399: }
400:
401: static cmo *parse_cmo_list()
402: {
403: cmo_list *m = new_cmo_list();
404: cmo *newcmo;
405:
406: if (token == ',') {
407: parse_comma();
408:
1.3 ohara 409: if (token == T_DIGIT) {
1.1 ohara 410: parse_integer();
411: parse_comma();
412: }else if (!pflag_cmo_addrev) {
413: parse_error("invalid cmo_list.");
414: }
415:
416: while(token == '(') {
417: parse_left_parenthesis();
418: newcmo = parse_cmo();
1.5 ohara 419: list_append(m, newcmo);
1.1 ohara 420: if (token != ',') {
421: break;
422: }
423: parse_comma();
424: }
425: }else if (!pflag_cmo_addrev) {
426: parse_error("invalid cmo_list.");
427: }
428: parse_right_parenthesis();
429: return (cmo *)m;
430: }
431:
432: static cmo *parse_cmo_monomial32()
433: {
434: int size;
435: int i;
436: cmo_monomial32 *m;
437: int tag;
438:
439: parse_comma();
1.11 ohara 440: size = parse_integer();
1.1 ohara 441: if (size < 0) {
442: parse_error("invalid value.");
443: }
444: m = new_cmo_monomial32_size(size);
445:
446: for(i=0; i<size; i++) {
447: parse_comma();
1.11 ohara 448: m->exps[i] = parse_integer();
1.1 ohara 449: }
450: parse_comma();
451: parse_left_parenthesis();
452: m->coef = parse_cmo();
453: tag = m->coef->tag;
454:
1.3 ohara 455: /* semantics:
456: The tag of m->coef must be CMO_ZZ or CMO_INT32. */
1.1 ohara 457: if (tag != CMO_ZZ && tag != CMO_INT32) {
458: parse_error("invalid cmo.");
459: }
460: parse_right_parenthesis();
461: return (cmo *)m;
462: }
463:
1.3 ohara 464: /* the following function rewrite internal data of mpz/cmo_zz. */
1.1 ohara 465: static cmo *parse_cmo_zz()
466: {
467: int length;
468: int i=0;
469: cmo_zz *m= NULL;
1.5 ohara 470: mpz_ptr z;
1.1 ohara 471:
472: parse_comma();
1.11 ohara 473: z = parse_mpz_integer();
1.1 ohara 474: if (token == ',') {
1.5 ohara 475: length = mpz_get_si(z);
1.1 ohara 476: m = new_cmo_zz_size(length);
477:
478: length = abs(length);
479: for(i=0; i<length; i++) {
480: parse_comma();
1.11 ohara 481: m->mpz->_mp_d[i] = parse_integer();
1.1 ohara 482: }
483: }else if (pflag_cmo_addrev) {
1.3 ohara 484: m = new_cmo_zz_set_mpz(z);
1.1 ohara 485: }else {
486: parse_error("no comma.");
487: }
488:
489: parse_right_parenthesis();
490: return (cmo *)m;
491: }
492:
493: static cmo *parse_cmo_zero()
494: {
495: parse_right_parenthesis();
496: return (cmo *)new_cmo_zero();
497: }
498:
499: static cmo *parse_cmo_dms_generic()
500: {
501: parse_right_parenthesis();
502: return (cmo *)new_cmo_dms_generic();
503: }
504:
505: static cmo *parse_cmo_ring_by_name()
506: {
507: cmo *ob;
508:
509: parse_comma();
510: parse_left_parenthesis();
511: ob = parse_cmo();
512:
1.3 ohara 513: /* The ob has a type of CMO_STRING. */
1.1 ohara 514: if (ob->tag != CMO_STRING) {
515: parse_error("invalid cmo.");
516: }
517: parse_right_parenthesis();
518: return (cmo *)new_cmo_ring_by_name(ob);
519: }
520:
521: static cmo *parse_cmo_distributed_polynomial()
522: {
523: cmo_distributed_polynomial *m = new_cmo_distributed_polynomial();
524: cmo *ob;
525: int tag;
526:
527: if (token == ',') {
528: parse_comma();
529:
1.3 ohara 530: if (token == T_DIGIT) {
1.1 ohara 531: parse_integer();
532: parse_comma();
533: }else if (!pflag_cmo_addrev) {
534: parse_error("invalid d-polynomial.");
535: }
536:
537: parse_left_parenthesis();
538: m->ringdef = parse_cmo();
539: tag = m->ringdef->tag;
1.3 ohara 540: /* m->ringdef needs to be a DringDefinition. */
1.1 ohara 541: if (tag != CMO_RING_BY_NAME && tag != CMO_DMS_GENERIC
542: && tag != CMO_DMS_OF_N_VARIABLES) {
543: parse_error("invalid cmo.");
544: }
545:
546: parse_comma();
547:
548: while(token == '(') {
549: parse_left_parenthesis();
550: ob = parse_cmo();
551: if (ob->tag != CMO_MONOMIAL32 && ob->tag != CMO_ZERO) {
552: parse_error("invalid cmo.");
553: }
1.5 ohara 554: list_append((cmo_list *)m, ob);
1.1 ohara 555: if (token != ',') {
556: break;
557: }
558: parse_comma();
559: }
560: }else if (!pflag_cmo_addrev) {
561: parse_error("invalid d-polynomial.");
562: }
563: parse_right_parenthesis();
564: return (cmo *)m;
565: }
566:
567: static cmo *parse_cmo_indeterminate()
568: {
569: cmo *ob;
570:
571: parse_comma();
572: parse_left_parenthesis();
573: ob = parse_cmo();
574: parse_right_parenthesis();
575: return (cmo *)new_cmo_indeterminate(ob);
576: }
577:
578: static cmo *parse_cmo_error2()
579: {
580: cmo *ob;
581:
582: parse_comma();
583: parse_left_parenthesis();
584: ob = parse_cmo();
585: parse_right_parenthesis();
586: return (cmo *)new_cmo_error2(ob);
587: }
588:
1.3 ohara 589: /* --- lexical analyzer --- */
1.1 ohara 590:
1.3 ohara 591: /* A white space is ignored by lexical analyzer. */
1.1 ohara 592: static int c = ' ';
593:
1.3 ohara 594: /* getting a character from string. */
1.2 ohara 595: static char *mygetc_ptr;
596: static int mygetc()
597: {
1.5 ohara 598: return *mygetc_ptr++;
1.2 ohara 599: }
1.1 ohara 600:
1.5 ohara 601: static void init_lex(char *s)
1.1 ohara 602: {
1.7 ohara 603: c=' ';
1.2 ohara 604: mygetc_ptr=s;
1.1 ohara 605: }
606:
607: #define SIZE_BUFFER 8192
608: static char buffer[SIZE_BUFFER];
609:
1.14 ohara 610: static char *new_string(char *s)
1.1 ohara 611: {
1.14 ohara 612: char *t = MALLOC(strlen(s)+1);
613: strcpy(t, s);
614: return t;
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';
1.14 ohara 628: return new_string(buff);
1.5 ohara 629: }
1.3 ohara 630: c = mygetc();
1.5 ohara 631: }
632: buff[SIZE_BUFFER-1] = '\0';
1.14 ohara 633: return new_string(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.14 ohara 725: return new_string(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:
1.15 ohara 792: ;
1.1 ohara 793: }
794:
1.3 ohara 795: if (isalpha(c)) {
1.5 ohara 796: /* symbols */
1.1 ohara 797: return lex_symbol();
798: }
799:
1.5 ohara 800: /* digit */
1.1 ohara 801: if (isdigit(c)){
1.3 ohara 802: yylval.sym = lex_digit();
803: return T_DIGIT;
1.1 ohara 804: }
1.3 ohara 805: c = mygetc();
1.1 ohara 806: return 0;
807: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>