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

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

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