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

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

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