[BACK]Return to parse.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_toolkit

Annotation of OpenXM/src/ox_toolkit/parse.c, Revision 1.5

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>