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

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

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