Annotation of OpenXM/src/ox_toolkit/parse.c, Revision 1.12
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.12 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/parse.c,v 1.11 2003/03/23 20:17:35 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
1.12 ! ohara 336: int sign = 1;
! 337: int val;
! 338:
! 339: if (token == '+') {
! 340: token = lex();
! 341: }else if (token == '-') {
! 342: sign = -1;
! 343: token = lex();
! 344: }
! 345:
! 346: if (token != T_DIGIT) {
! 347: parse_error("no integer.");
! 348: }
! 349: val = sign*atoi(yylval.sym);
! 350: #ifdef DEBUG
! 351: free(yylval.sym);
! 352: #endif
! 353: token = lex();
! 354: return val;
1.11 ohara 355: #endif
356: }
1.1 ohara 357:
358: static char *parse_string()
359: {
360: char *s;
361: if (token != T_STRING) {
362: parse_error("no string.");
363: }
364: s = yylval.sym;
365: token = lex();
366: return s;
367: }
368:
369: static cmo *parse_cmo_null()
370: {
371: parse_right_parenthesis();
372: return (cmo *)new_cmo_null();
373: }
374:
375: static cmo *parse_cmo_int32()
376: {
1.11 ohara 377: int z;
1.1 ohara 378:
379: parse_comma();
1.3 ohara 380: z = parse_integer();
1.1 ohara 381: parse_right_parenthesis();
1.11 ohara 382: return (cmo *)new_cmo_int32(z);
1.1 ohara 383: }
384:
385: static cmo *parse_cmo_string()
386: {
387: cmo_string *m;
388: char *s;
389:
390: parse_comma();
1.3 ohara 391: if (token == T_DIGIT) {
1.1 ohara 392: parse_integer();
393: parse_comma();
394: }else if (!pflag_cmo_addrev) {
395: parse_error("invalid cmo string.");
396: }
397: s = parse_string();
398: m = new_cmo_string(s);
399: parse_right_parenthesis();
400: return (cmo *)m;
401: }
402:
403: static cmo *parse_cmo_mathcap()
404: {
405: cmo *ob;
406:
407: parse_comma();
408: parse_left_parenthesis();
409: ob = parse_cmo();
410: parse_right_parenthesis();
411: return (cmo *)new_cmo_mathcap(ob);
412: }
413:
414: static cmo *parse_cmo_list()
415: {
416: cmo_list *m = new_cmo_list();
417: cmo *newcmo;
418:
419: if (token == ',') {
420: parse_comma();
421:
1.3 ohara 422: if (token == T_DIGIT) {
1.1 ohara 423: parse_integer();
424: parse_comma();
425: }else if (!pflag_cmo_addrev) {
426: parse_error("invalid cmo_list.");
427: }
428:
429: while(token == '(') {
430: parse_left_parenthesis();
431: newcmo = parse_cmo();
1.5 ohara 432: list_append(m, newcmo);
1.1 ohara 433: if (token != ',') {
434: break;
435: }
436: parse_comma();
437: }
438: }else if (!pflag_cmo_addrev) {
439: parse_error("invalid cmo_list.");
440: }
441: parse_right_parenthesis();
442: return (cmo *)m;
443: }
444:
445: static cmo *parse_cmo_monomial32()
446: {
447: int size;
448: int i;
449: cmo_monomial32 *m;
450: int tag;
451:
452: parse_comma();
1.11 ohara 453: size = parse_integer();
1.1 ohara 454: if (size < 0) {
455: parse_error("invalid value.");
456: }
457: m = new_cmo_monomial32_size(size);
458:
459: for(i=0; i<size; i++) {
460: parse_comma();
1.11 ohara 461: m->exps[i] = parse_integer();
1.1 ohara 462: }
463: parse_comma();
464: parse_left_parenthesis();
465: m->coef = parse_cmo();
466: tag = m->coef->tag;
467:
1.3 ohara 468: /* semantics:
469: The tag of m->coef must be CMO_ZZ or CMO_INT32. */
1.1 ohara 470: if (tag != CMO_ZZ && tag != CMO_INT32) {
471: parse_error("invalid cmo.");
472: }
473: parse_right_parenthesis();
474: return (cmo *)m;
475: }
476:
1.11 ohara 477: #if defined(WITH_GMP)
1.3 ohara 478: /* the following function rewrite internal data of mpz/cmo_zz. */
1.1 ohara 479: static cmo *parse_cmo_zz()
480: {
481: int length;
482: int i=0;
483: cmo_zz *m= NULL;
1.5 ohara 484: mpz_ptr z;
1.1 ohara 485:
486: parse_comma();
1.11 ohara 487: z = parse_mpz_integer();
1.1 ohara 488: if (token == ',') {
1.5 ohara 489: length = mpz_get_si(z);
1.1 ohara 490: m = new_cmo_zz_size(length);
491:
492: length = abs(length);
493: for(i=0; i<length; i++) {
494: parse_comma();
1.11 ohara 495: m->mpz->_mp_d[i] = parse_integer();
1.1 ohara 496: }
497: }else if (pflag_cmo_addrev) {
1.3 ohara 498: m = new_cmo_zz_set_mpz(z);
1.1 ohara 499: }else {
500: parse_error("no comma.");
501: }
502:
503: parse_right_parenthesis();
504: return (cmo *)m;
505: }
1.11 ohara 506: #endif /* WITH_GMP */
1.1 ohara 507:
508: static cmo *parse_cmo_zero()
509: {
510: parse_right_parenthesis();
511: return (cmo *)new_cmo_zero();
512: }
513:
514: static cmo *parse_cmo_dms_generic()
515: {
516: parse_right_parenthesis();
517: return (cmo *)new_cmo_dms_generic();
518: }
519:
520: static cmo *parse_cmo_ring_by_name()
521: {
522: cmo *ob;
523:
524: parse_comma();
525: parse_left_parenthesis();
526: ob = parse_cmo();
527:
1.3 ohara 528: /* The ob has a type of CMO_STRING. */
1.1 ohara 529: if (ob->tag != CMO_STRING) {
530: parse_error("invalid cmo.");
531: }
532: parse_right_parenthesis();
533: return (cmo *)new_cmo_ring_by_name(ob);
534: }
535:
536: static cmo *parse_cmo_distributed_polynomial()
537: {
538: cmo_distributed_polynomial *m = new_cmo_distributed_polynomial();
539: cmo *ob;
540: int tag;
541:
542: if (token == ',') {
543: parse_comma();
544:
1.3 ohara 545: if (token == T_DIGIT) {
1.1 ohara 546: parse_integer();
547: parse_comma();
548: }else if (!pflag_cmo_addrev) {
549: parse_error("invalid d-polynomial.");
550: }
551:
552: parse_left_parenthesis();
553: m->ringdef = parse_cmo();
554: tag = m->ringdef->tag;
1.3 ohara 555: /* m->ringdef needs to be a DringDefinition. */
1.1 ohara 556: if (tag != CMO_RING_BY_NAME && tag != CMO_DMS_GENERIC
557: && tag != CMO_DMS_OF_N_VARIABLES) {
558: parse_error("invalid cmo.");
559: }
560:
561: parse_comma();
562:
563: while(token == '(') {
564: parse_left_parenthesis();
565: ob = parse_cmo();
566: if (ob->tag != CMO_MONOMIAL32 && ob->tag != CMO_ZERO) {
567: parse_error("invalid cmo.");
568: }
1.5 ohara 569: list_append((cmo_list *)m, ob);
1.1 ohara 570: if (token != ',') {
571: break;
572: }
573: parse_comma();
574: }
575: }else if (!pflag_cmo_addrev) {
576: parse_error("invalid d-polynomial.");
577: }
578: parse_right_parenthesis();
579: return (cmo *)m;
580: }
581:
582: static cmo *parse_cmo_indeterminate()
583: {
584: cmo *ob;
585:
586: parse_comma();
587: parse_left_parenthesis();
588: ob = parse_cmo();
589: parse_right_parenthesis();
590: return (cmo *)new_cmo_indeterminate(ob);
591: }
592:
593: static cmo *parse_cmo_error2()
594: {
595: cmo *ob;
596:
597: parse_comma();
598: parse_left_parenthesis();
599: ob = parse_cmo();
600: parse_right_parenthesis();
601: return (cmo *)new_cmo_error2(ob);
602: }
603:
1.3 ohara 604: /* --- lexical analyzer --- */
1.1 ohara 605:
1.3 ohara 606: /* A white space is ignored by lexical analyzer. */
1.1 ohara 607: static int c = ' ';
608:
1.3 ohara 609: /* getting a character from string. */
1.2 ohara 610: static char *mygetc_ptr;
611: static int mygetc()
612: {
1.5 ohara 613: return *mygetc_ptr++;
1.2 ohara 614: }
1.1 ohara 615:
1.5 ohara 616: static void init_lex(char *s)
1.1 ohara 617: {
1.7 ohara 618: c=' ';
1.2 ohara 619: mygetc_ptr=s;
1.1 ohara 620: }
621:
622: #define SIZE_BUFFER 8192
623: static char buffer[SIZE_BUFFER];
624:
1.3 ohara 625: static char *mkstr(char *src)
1.1 ohara 626: {
1.5 ohara 627: int len;
628: char *s;
629: len = strlen(src);
630: s = malloc(len+1);
631: strcpy(s, src);
632: return s;
1.3 ohara 633: }
634:
635: /* no measure for buffer overflow */
636: static char *lex_digit()
637: {
1.5 ohara 638: static char buff[SIZE_BUFFER];
639: int i;
640:
641: for(i=0; i<SIZE_BUFFER-1; i++) {
642: if(isdigit(c)) {
643: buff[i] = c;
644: }else {
645: buff[i] = '\0';
646: return mkstr(buff);
647: }
1.3 ohara 648: c = mygetc();
1.5 ohara 649: }
650: buff[SIZE_BUFFER-1] = '\0';
651: return mkstr(buff);
1.1 ohara 652: }
653:
654: #define MK_KEY_CMO(x) { #x , x , TOKEN(x) , IS_CMO }
655: #define MK_KEY_SM(x) { #x , x , TOKEN(SM) , IS_SM }
656: #define MK_KEY_OX(x) { #x , x , TOKEN(x) , IS_OX }
657:
1.4 ohara 658: static struct symbol symbol_list[] = {
1.1 ohara 659: MK_KEY_CMO(CMO_NULL),
660: MK_KEY_CMO(CMO_INT32),
661: MK_KEY_CMO(CMO_DATUM),
662: MK_KEY_CMO(CMO_STRING),
663: MK_KEY_CMO(CMO_MATHCAP),
664: MK_KEY_CMO(CMO_LIST),
665: MK_KEY_CMO(CMO_MONOMIAL32),
666: MK_KEY_CMO(CMO_ZZ),
667: MK_KEY_CMO(CMO_ZERO),
668: MK_KEY_CMO(CMO_DMS_GENERIC),
669: MK_KEY_CMO(CMO_RING_BY_NAME),
670: MK_KEY_CMO(CMO_INDETERMINATE),
671: MK_KEY_CMO(CMO_DISTRIBUTED_POLYNOMIAL),
672: MK_KEY_CMO(CMO_ERROR2),
673: MK_KEY_SM(SM_popCMO),
674: MK_KEY_SM(SM_popString),
675: MK_KEY_SM(SM_mathcap),
676: MK_KEY_SM(SM_pops),
677: MK_KEY_SM(SM_executeStringByLocalParser),
678: MK_KEY_SM(SM_executeFunction),
679: MK_KEY_SM(SM_setMathCap),
680: MK_KEY_SM(SM_shutdown),
681: MK_KEY_SM(SM_control_kill),
682: MK_KEY_SM(SM_control_reset_connection),
683: MK_KEY_OX(OX_COMMAND),
684: MK_KEY_OX(OX_DATA),
685: {NULL, 0, 0, 0} /* a gate keeper */
686: };
687:
1.4 ohara 688: symbol_t lookup_by_symbol(char *key)
1.1 ohara 689: {
1.4 ohara 690: symbol_t symp;
1.1 ohara 691: for(symp = symbol_list; symp->key != NULL; symp++) {
692: if (strcmp(key, symp->key)==0) {
693: return symp;
694: }
695: }
696: return NULL;
697: }
698:
1.4 ohara 699: symbol_t lookup_by_token(int tok)
1.1 ohara 700: {
1.4 ohara 701: symbol_t symp;
1.1 ohara 702: for(symp = symbol_list; symp->key != NULL; symp++) {
703: if (tok == symp->token) {
704: return symp;
705: }
706: }
707: return NULL;
708: }
709:
1.4 ohara 710: symbol_t lookup_by_tag(int tag)
1.1 ohara 711: {
1.4 ohara 712: symbol_t symp;
1.1 ohara 713: for(symp = symbol_list; symp->key != NULL; symp++) {
714: if (tag == symp->tag) {
715: return symp;
716: }
717: }
718: return NULL;
719: }
720:
1.4 ohara 721: symbol_t lookup(int i)
1.1 ohara 722: {
723: return &symbol_list[i];
724: }
725:
1.10 ohara 726: char *get_symbol_by_tag(int tag)
1.4 ohara 727: {
1.10 ohara 728: symbol_t symp = lookup_by_tag(tag);
729: return (symp != NULL)? symp->key: NULL;
1.4 ohara 730: }
731:
1.3 ohara 732: /* no measure for buffer overflow */
1.1 ohara 733: static char *lex_quoted_string()
734: {
735: int i;
736: char c0 = ' ';
1.3 ohara 737:
1.1 ohara 738: for (i=0; i<SIZE_BUFFER; i++) {
1.3 ohara 739: c = mygetc();
1.1 ohara 740: if(c == '"') {
1.3 ohara 741: c = mygetc();
1.1 ohara 742: buffer[i]='\0';
1.5 ohara 743: return mkstr(buffer);
1.1 ohara 744: }else if (c == '\\') {
745: c0 = c;
1.3 ohara 746: c = mygetc();
1.1 ohara 747: if (c != '"') {
748: buffer[i++] = c0;
749: }
750: }
751: buffer[i]=c;
752: }
1.9 ohara 753: ox_printf("buffer overflow!\n");
1.1 ohara 754: exit(1);
755: /* return NULL; */
756: }
757:
758: static int token_of_symbol(char *key)
759: {
1.4 ohara 760: symbol_t symp = lookup_by_symbol(key);
1.1 ohara 761: if (symp != NULL) {
762: yylval.d = symp->tag;
763: return symp->token;
764: }
1.9 ohara 765: ox_printf("lex error:: \"%s\" is unknown symbol.\n", key);
1.1 ohara 766: return 0;
767: }
768:
769: static int lex_symbol()
770: {
771: int i;
772: for (i=0; i<SIZE_BUFFER; i++) {
773: if (!isalnum(c) && c != '_') {
774: buffer[i]='\0';
775: return token_of_symbol(buffer);
776: }
777: buffer[i]=c;
1.3 ohara 778: c = mygetc();
1.1 ohara 779: }
1.9 ohara 780: ox_printf("buffer overflow!\n");
1.1 ohara 781: return 0;
782: }
783:
1.6 ohara 784: /* Remark: prefetching a character before return. */
1.5 ohara 785: static int lex()
1.1 ohara 786: {
787: int c_dash = 0;
788:
1.3 ohara 789: /* white spaces are ignored. */
790: while (isspace(c)) {
791: c = mygetc();
1.1 ohara 792: }
793:
794: switch(c) {
795: case '(':
796: case ')':
797: case ',':
1.5 ohara 798: case '+':
799: case '-':
1.1 ohara 800: c_dash = c;
801: c = ' ';
802: return c_dash;
803: case EOF:
1.3 ohara 804: c = mygetc();
1.1 ohara 805: return c_dash;
806: case '"': /* a quoted string! */
807: yylval.sym = lex_quoted_string();
808: return T_STRING;
809: default:
810: }
811:
1.3 ohara 812: if (isalpha(c)) {
1.5 ohara 813: /* symbols */
1.1 ohara 814: return lex_symbol();
815: }
816:
1.5 ohara 817: /* digit */
1.1 ohara 818: if (isdigit(c)){
1.3 ohara 819: yylval.sym = lex_digit();
820: return T_DIGIT;
1.1 ohara 821: }
1.3 ohara 822: c = mygetc();
1.1 ohara 823: return 0;
824: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>