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

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

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