[BACK]Return to parse.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_math

Diff for /OpenXM/src/ox_math/Attic/parse.c between version 1.1 and 1.2

version 1.1, 1999/10/29 08:06:41 version 1.2, 1999/11/02 06:11:58
Line 3 
Line 3 
 /* $Id$ */  /* $Id$ */
 /* OX expression, CMO expression パーサ */  /* OX expression, CMO expression パーサ */
   
 /* cmo_addrev がセットされていれば、  
    厳密には CMO expression でないもの, 例えば  
    (CMO_STRING, "abcdef") も CMO に変換される. */  
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <sys/param.h>  #include <sys/param.h>
   #include <setjmp.h>
 #include "oxtag.h"  #include "oxtag.h"
 #include "ox.h"  #include "ox.h"
 #include "parse.h"  #include "parse.h"
   
 /* --- 構文解析部 --- */  /* --- 構文解析部 --- */
   /* (重要)セマンティックスについての注意.
      CMO_LIST, CMO_STRING は、あらかじめ与えられた要素の個数を無視する.
      CMO_MONOMIAL32 は無視しない. (つまりおかしいときは構文エラーになる)
   */
   
   
 /* parse.c, lex.c では, Lisp 表現された CMO 文字列を読み込み,  /* parse.c, lex.c では, Lisp 表現された CMO 文字列を読み込み,
    バイト列を出力する.  中間表現として、cmo *を利用する.     バイト列を出力する.  中間表現として、cmo *を利用する.
    parse() はトークンの列から cmo *(の指す構造体)を生成する.     parse() はトークンの列から cmo *(の指す構造体)を生成する.
Line 28 
Line 31 
 /* 現在読み込み中のトークンを表す. */  /* 現在読み込み中のトークンを表す. */
 static int token = 0;  static int token = 0;
   
 /* yylval は lex() によってセットされる. */  /* トークンの属性値. yylval は lex() によってセットされる. */
 extern lex_value_t yylval;  static union{
       int   d;
       char* sym;
   } yylval;
   
 int cmo_addrev = 1;  /* CMO の省略記法を許すか否かのフラグ */  /* pflag_cmo_addrev がセットされていれば、厳密には CMO expression では
      ないもの, 例えば (CMO_STRING, "hello") も CMO に変換される. */
   
   static int pflag_cmo_addrev = 1;  /* CMO の省略記法を許すか否かのフラグ */
   
 /* 関数の宣言 */  /* 関数の宣言 */
 static int parse_error(char *s);  static int parse_error(char *s);
 static int parse_lf();  static int parse_lf();
Line 41  static int parse_left_parenthesis();
Line 50  static int parse_left_parenthesis();
 static int parse_comma();  static int parse_comma();
 static int parse_integer();  static int parse_integer();
 static cmo *parse_cmo_null();  static cmo *parse_cmo_null();
 static cmo *parse_cmo_zz();  
 static cmo *parse_cmo_list();  
 static cmo *parse_cmo_int32();  static cmo *parse_cmo_int32();
 static cmo *parse_cmo_string();  static cmo *parse_cmo_string();
   static cmo *parse_cmo_mathcap();
   static cmo *parse_cmo_dms_generic();
   static cmo *parse_cmo_ring_by_name();
   static cmo *parse_cmo_error2();
   static cmo *parse_cmo_zero();
   static cmo *parse_cmo_zz();
   static cmo *parse_cmo_list();
 static cmo *parse_cmo();  static cmo *parse_cmo();
 static char *parse_string();  static char *parse_string();
 static int parse_sm();  static int parse_sm();
Line 52  static ox* parse_ox();
Line 66  static ox* parse_ox();
 static ox* parse_ox_command();  static ox* parse_ox_command();
 static ox* parse_ox_data();  static ox* parse_ox_data();
   
 static int parse_error(char *s)  
 {  
     if (s != NULL) {  
         fprintf(stderr, "%s\n", s);  
     }else {  
         fprintf(stderr, "syntax error.\n");  
     }  
     exit(1);  /* 例外処理.  本当は longjmp すべきであろう. */  
 }  
   
 #define MIN_T_CMO      (T_MAGIC + 0)  
 #define MAX_T_CMO      (T_MAGIC + 256)  
   
 static int is_t_cmo(int token)  static int is_t_cmo(int token)
 {  {
     return (token >= MIN_T_CMO && token < MAX_T_CMO) || token == T_CMO_ERROR2;      return (token >= MIN_T_CMO && token < MAX_T_CMO) || token == TOKEN(CMO_ERROR2);
 }  }
   
 #define MIN_T_SM      (T_MAGIC + 256)  
 #define MAX_T_SM      (T_MAGIC + 1100)  
   
 static int is_t_sm(int token)  static int is_t_sm(int token)
 {  {
     return token >= MIN_T_SM && token < MAX_T_SM;      return token >= MIN_T_SM && token < MAX_T_SM;
 }  }
   
 #define MIN_T_OX      (T_MAGIC + 512)  
 #define MAX_T_OX      (T_MAGIC + 600)  
   
 static int is_t_ox(int token)  static int is_t_ox(int token)
 {  {
     return token >= MIN_T_OX && token < MAX_T_OX;      return token >= MIN_T_OX && token < MAX_T_OX;
 }  }
   
   static jmp_buf env_parse;
   
   /* 構文解析に失敗したことを意味する. */
   static int parse_error(char *s)
   {
           fprintf(stderr, "%s\n", s);
           longjmp(env_parse, 1);
   }
   
 /* この部分は書き換え予定. */  /* この部分は書き換え予定. */
 cmo *parse()  cmo *parse()
 {  {
     cmo *m;      cmo *m;
   
           if (setjmp(env_parse) != 0) {
                   return NULL; /* 構文解析に失敗したら NULL を返す. */
           }
   
     do{      do{
         token = lex();          token = lex();
     }while (token == '\n');      }while (token == '\n');
Line 102  cmo *parse()
Line 110  cmo *parse()
         }else if(is_t_ox(token)) {          }else if(is_t_ox(token)) {
             m = parse_ox();              m = parse_ox();
         }else {          }else {
             parse_error("syntax error: unknown keyword.");              parse_error("syntax error: unknown symbol.");
             return NULL;  
         }          }
         parse_lf();          parse_lf();
         return m;          return m;
Line 126  static ox* parse_ox()
Line 133  static ox* parse_ox()
     ox *m = NULL;      ox *m = NULL;
   
     switch(token) {      switch(token) {
     case T_OX_COMMAND:      case TOKEN(OX_COMMAND):
         token = lex();          token = lex();
         m = parse_ox_command();          m = parse_ox_command();
         break;          break;
     case T_OX_DATA:      case TOKEN(OX_DATA):
         token = lex();          token = lex();
         m = parse_ox_data();          m = parse_ox_data();
         break;          break;
Line 174  static ox* parse_ox_command()
Line 181  static ox* parse_ox_command()
 }  }
   
 /* 正しい入力ならば, parse_cmo を呼ぶ時点で, token には  /* 正しい入力ならば, parse_cmo を呼ぶ時点で, token には
    T_CMO_xxx, T_OX_xxx のいずれかがセットされている. */     TOKEN(CMO_xxx), TOKEN(OX_xxx) のいずれかがセットされている. */
 static cmo *parse_cmo()  static cmo *parse_cmo()
 {  {
     cmo *m = NULL;      cmo *m = NULL;
   
     switch(token) {      switch(token) {
     case T_CMO_NULL:      case TOKEN(CMO_NULL):
         token = lex();          token = lex();
         m = parse_cmo_null();          m = parse_cmo_null();
         break;          break;
     case T_CMO_INT32:      case TOKEN(CMO_INT32):
         token = lex();          token = lex();
         m = parse_cmo_int32();          m = parse_cmo_int32();
         break;          break;
     case T_CMO_STRING:      case TOKEN(CMO_STRING):
         token = lex();          token = lex();
         m = parse_cmo_string();          m = parse_cmo_string();
         break;          break;
     case T_CMO_ZZ:      case TOKEN(CMO_MATHCAP):
         token = lex();          token = lex();
         m = parse_cmo_zz();          m = parse_cmo_mathcap();
         break;          break;
     case T_CMO_LIST:      case TOKEN(CMO_LIST):
         token = lex();          token = lex();
         m = parse_cmo_list();          m = parse_cmo_list();
         break;          break;
       case TOKEN(CMO_MONOMIAL32):
           token = lex();
           m = parse_cmo_monomial32();
           break;
       case TOKEN(CMO_ZZ):
           token = lex();
           m = parse_cmo_zz();
           break;
       case TOKEN(CMO_ZERO):
           token = lex();
           m = parse_cmo_zero();
           break;
       case TOKEN(CMO_DMS_GENERIC):
           token = lex();
           m = parse_cmo_dms_generic();
           break;
       case TOKEN(CMO_RING_BY_NAME):
           token = lex();
           m = parse_cmo_ring_by_name();
           break;
       case TOKEN(CMO_ERROR2):
           token = lex();
           m = parse_cmo_error2();
           break;
     default:      default:
         parse_error("syntax error: invalid cmo_tag.");          parse_error("syntax error: invalid cmo_tag.");
     }      }
     return m;      return m;
 }  }
   
 static int parse_right_parenthesis()  static int parse_left_parenthesis()
 {  {
     if (token != ')') {      if (token != '(') {
         parse_error("syntax error: no right parenthesis exists.");          parse_error("syntax error: no left parenthesis.");
         return 0;  
     }      }
     token = lex();      token = lex();
 }  }
   
 static int parse_left_parenthesis()  static int parse_right_parenthesis()
 {  {
     if (token != '(') {      if (token != ')') {
         parse_error("syntax error: no left parenthesis exists.");          parse_error("syntax error: no right parenthesis.");
         return 0;  
     }      }
     token = lex();      token = lex();
 }  }
Line 227  static int parse_left_parenthesis()
Line 256  static int parse_left_parenthesis()
 static int parse_comma()  static int parse_comma()
 {  {
     if (token != ',') {      if (token != ',') {
         parse_error("syntax error: no comma exists.");          parse_error("syntax error: no comma.");
         return 0;  
     }      }
     token = lex();      token = lex();
     return 1;  
 }  }
   
 /* cmo_zz の内部を直接いじる. */  
 static cmo *parse_cmo_zz()  
 {  
     int length;  
     int i=0;  
     cmo_zz *m= NULL;  
   
     parse_comma();  
     length = parse_integer();  
     if (token == ',') {  
         m = new_cmo_zz_size(length);  
   
         length = abs(length);  
         for(i=0; i<length; i++) {  
             parse_comma();  
             m->mpz->_mp_d[i] = parse_integer();  
         }  
     }else if (cmo_addrev) {  
         m = new_cmo_zz_set_si(length);  
     }else {  
         parse_error("syntax error: invalid keyword.");  
     }  
   
     parse_right_parenthesis();  
     return (cmo *)m;  
 }  
   
 static cmo *parse_cmo_list()  
 {  
     int length=0;  
     int i=0;  
     cmo_list *m;  
     cmo *newcmo;  
   
     parse_comma();  
   
     length = parse_integer();  
     m = new_cmo_list();  
     if (length<0) {  
         parse_error("semantics error: a list has negative length.");  
     }  
   
     for(i=0; i<length; i++) {  
         parse_comma();  
         parse_left_parenthesis();  
         newcmo = parse_cmo();  
         append_cmo_list(m, newcmo);  
     }  
     parse_right_parenthesis();  
     return (cmo *)m;  
 }  
   
 static int parse_integer()  static int parse_integer()
 {  {
     int val;      int val;
     if (token != T_INTEGER) {      if (token != T_INTEGER) {
         parse_error("syntax error: in parse_integer().");          parse_error("syntax error: no integer.");
     }      }
     val = yylval.d;      val = yylval.d;
     token = lex();      token = lex();
Line 301  static char *parse_string()
Line 276  static char *parse_string()
 {  {
     char *s;      char *s;
     if (token != T_STRING) {      if (token != T_STRING) {
         parse_error("syntax error: in parse_string().");          parse_error("syntax error: no string.");
     }      }
     s = yylval.sym;      s = yylval.sym;
     token = lex();      token = lex();
Line 310  static char *parse_string()
Line 285  static char *parse_string()
   
 static cmo *parse_cmo_null()  static cmo *parse_cmo_null()
 {  {
     cmo_null *m = new_cmo_null();  
     parse_right_parenthesis();      parse_right_parenthesis();
     return (cmo *)m;      return (cmo *)new_cmo_null();
 }  }
   
 static cmo *parse_cmo_int32()  static cmo *parse_cmo_int32()
 {  {
     cmo_int32 *m;  
     int i;      int i;
   
     parse_comma();      parse_comma();
     i = parse_integer();      i = parse_integer();
     m = new_cmo_int32(i);  
     parse_right_parenthesis();      parse_right_parenthesis();
     return (cmo *)m;      return (cmo *)new_cmo_int32(i);
 }  }
   
 static cmo *parse_cmo_string()  static cmo *parse_cmo_string()
 {  {
     cmo_string *m;      cmo_string *m;
     int length;  
     char *s;      char *s;
   
     parse_comma();      parse_comma();
     if (token == T_INTEGER) {      if (token == T_INTEGER) {
         length = parse_integer();          parse_integer();
         parse_comma();          parse_comma();
         s = parse_string();      }else if (!pflag_cmo_addrev) {
         if (length != strlen(s)) {          parse_error("syntax error: not a cmo string.");
           fprintf(stderr, "warning: strlen unmatched.\n");      }
           s = parse_string();
       m = new_cmo_string(s);
       parse_right_parenthesis();
       return (cmo *)m;
   }
   
   static cmo *parse_cmo_mathcap()
   {
           cmo *ob;
   
       parse_comma();
           parse_left_parenthesis();
           ob = parse_cmo();
       parse_right_parenthesis();
       return (cmo *)new_cmo_mathcap(ob);
   }
   
   static cmo *parse_cmo_list()
   {
       int length=0;
       int i=0;
       cmo_list *m = new_cmo_list();
       cmo *newcmo;
   
           if (token == ',') {
                   parse_comma();
   
                   if (token == T_INTEGER) {
                           parse_integer();
                           parse_comma();
                   }else if (!pflag_cmo_addrev) {
                           parse_error("syntax error: not a list.");
                   }
   
                   while(token == '(') {
                           parse_left_parenthesis();
                           newcmo = parse_cmo();
                           append_cmo_list(m, newcmo);
                           if (token != ',') {
                                   break;
                           }
                           parse_comma();
                   }
           }else if (!pflag_cmo_addrev) {
                   parse_error("syntax error: not a list.");
           }
       parse_right_parenthesis();
       return (cmo *)m;
   }
   
   static cmo *parse_cmo_monomial32()
   {
           int size;
           int *exps;
           int i;
           cmo_monomial32 *m;
   
           parse_comma();
           size = parse_integer();
           if (size <= 0) {
                   parse_error("syntax error: invalid value.");
           }
           m = new_cmo_monomial32_size(size);
   
           for(i=0; i<size; i++) {
                   parse_comma();
                   m->exps[i] = parse_integer();
           }
           parse_comma();
           parse_left_parenthesis();
           m->coef = parse_cmo();
       /* 意味的チェックの必要あり */
       parse_right_parenthesis();
       return (cmo *)m;
   }
   
   /* cmo_zz の内部を直接いじる. */
   static cmo *parse_cmo_zz()
   {
       int length;
       int i=0;
       cmo_zz *m= NULL;
   
       parse_comma();
       length = parse_integer();
       if (token == ',') {
           m = new_cmo_zz_size(length);
   
           length = abs(length);
           for(i=0; i<length; i++) {
               parse_comma();
               m->mpz->_mp_d[i] = parse_integer();
         }          }
     }else if (cmo_addrev) {      }else if (pflag_cmo_addrev) {
         s = parse_string();          m = new_cmo_zz_set_si(length);
     }else {      }else {
         parse_error("syntax error: invalid keyword.");          parse_error("syntax error: invalid symbol.");
     }      }
     m = new_cmo_string(s);  
     parse_right_parenthesis();      parse_right_parenthesis();
     return (cmo *)m;      return (cmo *)m;
 }  }
   
 /* --- 字句解析部 --- */  static cmo *parse_cmo_zero()
   {
       parse_right_parenthesis();
       return (cmo *)new_cmo_zero();
   }
   
 lex_value_t yylval;  static cmo *parse_cmo_dms_generic()
   {
       parse_right_parenthesis();
       return (cmo *)new_cmo_dms_generic();
   }
   
   static cmo *parse_cmo_ring_by_name()
   {
           cmo *ob;
   
       parse_comma();
           parse_left_parenthesis();
           ob = parse_cmo();
       /* 意味的チェックが必要(ob->tag == CMO_STRINGでなければいけない) */
       parse_right_parenthesis();
       return (cmo *)new_cmo_ring_by_name(ob);
   }
   
   static cmo *parse_cmo_error2()
   {
           cmo *ob;
   
       parse_comma();
           parse_left_parenthesis();
           ob = parse_cmo();
       parse_right_parenthesis();
       return (cmo *)new_cmo_error2(ob);
   }
   
   /* --- 字句解析部 --- */
   
 /* lexical analyzer で読み飛ばされる文字なら何を初期値にしてもよい */  /* lexical analyzer で読み飛ばされる文字なら何を初期値にしてもよい */
 static int c = ' ';  static int c = ' ';
   
Line 371  int resetgetc()
Line 467  int resetgetc()
     GETC = getchar;      GETC = getchar;
 }  }
   
 #define SIZE_BUFFER  1024  #define SIZE_BUFFER  8192
 static char buffer[SIZE_BUFFER];  static char buffer[SIZE_BUFFER];
 static char* PARS = "(),\n";  
   
 /* 桁溢れの場合の対策はない */  /* 桁溢れの場合の対策はない */
 static int lex_digit()  static int lex_digit()
Line 415  static char *lex_quoted_string()
Line 510  static char *lex_quoted_string()
     /* return NULL; */      /* return NULL; */
 }  }
   
 /* キーワードを増やしたあと修正するのを忘れてはいけない */  typedef struct {
 #undef NUM_OF_KEYWORDS  18          char *key;
           int  token;
   } symbol;
   
 static char *keywords[] = {  #define MK_KEY(x)  { #x  , TOKEN(x) }
     "CMO_INT32", "CMO_STRING", "CMO_LIST", "CMO_ZZ", "CMO_NULL",  
     "CMO_ZERO", "CMO_DATUM",  
     "SM_popCMO", "SM_popString", "SM_mathcap", "SM_pops",  
     "SM_executeStringByLocalParser", "SM_executeFunction",  
     "SM_setMathcap",  
     "SM_control_kill", "SM_control_reset_connection",  
     "OX_COMMAND", "OX_DATA",  
     NULL  /* a gate keeper */  
 };  
   
 static int token_of_keyword[] = {  static symbol symbol_list[] = {
     T_CMO_INT32, T_CMO_STRING, T_CMO_LIST, T_CMO_ZZ, T_CMO_NULL,          MK_KEY(CMO_NULL),
     T_CMO_ZERO, T_CMO_DATUM,      MK_KEY(CMO_INT32),
     T_SM_popCMO, T_SM_popString, T_SM_mathcap, T_SM_pops,          MK_KEY(CMO_DATUM),
     T_SM_executeStringByLocalParser, T_SM_executeFunction,          MK_KEY(CMO_STRING),
     T_SM_setMathcap,          MK_KEY(CMO_MATHCAP),
     T_SM_control_kill, T_SM_control_reset_connection,          MK_KEY(CMO_LIST),
     T_OX_COMMAND, T_OX_DATA,          MK_KEY(CMO_MONOMIAL32),
     0     /* dummy */          MK_KEY(CMO_ZZ),
 };          MK_KEY(CMO_ZERO),
           MK_KEY(CMO_DMS_GENERIC),
           MK_KEY(CMO_RING_BY_NAME),
           MK_KEY(CMO_INDETERMINATE),
           MK_KEY(CMO_ERROR2),
       MK_KEY(SM_popCMO),
           MK_KEY(SM_popString),
           MK_KEY(SM_mathcap),
           MK_KEY(SM_pops),
           MK_KEY(SM_executeStringByLocalParser),
           MK_KEY(SM_executeFunction),
           MK_KEY(SM_setMathCap),
       MK_KEY(SM_control_kill),
           MK_KEY(SM_control_reset_connection),
       MK_KEY(OX_COMMAND),  MK_KEY(OX_DATA),
           {NULL, 0}        /* a gate keeper */
   };
   
 static int token_of_matched_keyword(char *key)  static int token_of_symbol(char *key)
 {  {
     int i;          symbol *kp;
           for(kp = symbol_list; kp->key != NULL; kp++) {
     for(i=0; keywords[i] != NULL; i++) {                  if (strcmp(key, kp->key)==0) {
         if(strcmp(key, keywords[i])==0) {                          return kp->token;
             return token_of_keyword[i];                  }
         }          }
     }  #if DEBUG
     fprintf(stderr, "lex error\n");      fprintf(stderr, "lex error\n");
   #endif
     return 0;      return 0;
 }  }
   
 static int lex_keyword()  static int lex_symbol()
 {  {
     int i;      int i;
     for (i=0; i<SIZE_BUFFER; i++) {      for (i=0; i<SIZE_BUFFER; i++) {
         if (!isalnum(c) && c != '_') {          if (!isalnum(c) && c != '_') {
             buffer[i]='\0';              buffer[i]='\0';
             return token_of_matched_keyword(buffer);              return token_of_symbol(buffer);
         }          }
         buffer[i]=c;          buffer[i]=c;
         c = GETC();          c = GETC();
     }      }
     fprintf(stderr, "buffer overflow!\n");      fprintf(stderr, "buffer overflow!\n");
     exit(1);          return 0;
 }  }
   
 /* return する前に一文字先読みしておく。 */  /* return する前に一文字先読みしておく。 */
Line 496  int lex()
Line 601  int lex()
     }      }
   
     if (isalpha(c)) {    /* 識別子 */      if (isalpha(c)) {    /* 識別子 */
         return lex_keyword();          return lex_symbol();
     }      }
   
     /* 32bit 整数値 */      /* 32bit 整数値 */
Line 537  int setmode_mygetc(char *s, int len)
Line 642  int setmode_mygetc(char *s, int len)
     mygetc_counter=0;      mygetc_counter=0;
     mygetc_counter_max=len;      mygetc_counter_max=len;
     mygetc_line=s;      mygetc_line=s;
   }
   
   int setflag_parse(int flag)
   {
           pflag_cmo_addrev = flag;
 }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

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