[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.2

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

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