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

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

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