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

Diff for /OpenXM/src/ox_toolkit/parse.c between version 1.2 and 1.16

version 1.2, 1999/12/22 11:26:37 version 1.16, 2005/07/20 17:48:03
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM: OpenXM/src/ox_toolkit/parse.c,v 1.1 1999/12/09 22:44:56 ohara Exp $ */  /* $OpenXM: OpenXM/src/ox_toolkit/parse.c,v 1.15 2004/12/01 17:32:26 ohara Exp $ */
   
 /* OX expression, CMO expression パーサ */  /*
      This module is a parser for OX/CMO expressions.
      Some commnets are written in Japanese by using the EUC-JP coded
      character set.
   */
   
 #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 <setjmp.h>
 #include "oxtag.h"  #include <ctype.h>
 #include "ox.h"  
   #include "ox_toolkit.h"
 #include "parse.h"  #include "parse.h"
   
 /* --- 構文解析部 --- */  /* --- Parser --- */
 /* (重要)セマンティックスについての注意.  /* Remarks for semantics.
    CMO_LIST, CMO_STRING は、あらかじめ与えられた要素の個数を無視する.     CMO_LIST, CMO_STRING は、あらかじめ与えられた要素の個数を無視する.
    CMO_MONOMIAL32 は無視しない. (つまりおかしいときは構文エラーになる)     CMO_MONOMIAL32 は無視しない. (つまりおかしいときは構文エラーになる)
 */  */
   
 /* parse.c, lex.c では, Lisp 表現された CMO 文字列を読み込み,  /*
      parse.c では, Lisp 表現された CMO 文字列を読み込み,
    バイト列を出力する.  中間表現として、cmo 構造体を利用する.     バイト列を出力する.  中間表現として、cmo 構造体を利用する.
    parse() はトークンの列から cmo 構造体を生成し、そのポインタを返す.     parse() はトークンの列から cmo 構造体を生成し、そのポインタを返す.
 */     重要なことはパーサ(の各サブルーチン)は
   
 /* 重要なことはパーサ(の各サブルーチン)は  
    常にトークンをひとつ先読みしていると言うことである.     常にトークンをひとつ先読みしていると言うことである.
 */  */
   
Line 36  static union{
Line 40  static union{
     char *sym;      char *sym;
 } yylval;  } yylval;
   
 /* pflag_cmo_addrev がセットされていれば、厳密には CMO expression では  /*
    ないもの, 例えば (CMO_STRING, "hello") も CMO に変換される. */     If `pflag_cmo_addrev' sets, then we admit extended CMO expressions.
      For example, (CMO_STRING, "hello") is not a real CMO expression
      but it is admitted.
   */
   static int pflag_cmo_addrev = 1;
   
 static int pflag_cmo_addrev = 1;  /* CMO の省略記法を許すか否かのフラグ */  /* definitions of local functions */
   static void  init_parser(char *s);
 /* 関数の宣言 */  static cmo  *parse();
 static int  parse_error(char *s);  static void parse_error(char *s);
 static int  parse_lf();  static void parse_right_parenthesis();
 static int  parse_right_parenthesis();  static void parse_left_parenthesis();
 static int  parse_left_parenthesis();  static void parse_comma();
 static int  parse_comma();  static mpz_ptr parse_mpz_integer();
 static int  parse_integer();  static int   parse_integer();
 static char *parse_string();  static char *parse_string();
 static cmo  *parse_cmo_null();  static cmo  *parse_cmo_null();
 static cmo  *parse_cmo_int32();  static cmo  *parse_cmo_int32();
Line 67  static int  parse_sm();
Line 75  static int  parse_sm();
 static ox   *parse_ox();  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 void init_lex(char *s);
   static int  lex();
   
   /* Parsing a Lisp-style expression of CMO. */
   cmo *ox_parse_lisp(char *s)
   {
       return (s != NULL && strlen(s) > 0)? init_parser(s), parse(): NULL;
   }
   
 static int is_token_cmo(int token)  static int is_token_cmo(int token)
 {  {
     return (token >= MIN_T_CMO && token < MAX_T_CMO) || token == TOKEN(CMO_ERROR2);      return (token >= MIN_T_CMO && token < MAX_T_CMO) || token == TOKEN(CMO_ERROR2);
Line 85  static int is_token_ox(int token)
Line 101  static int is_token_ox(int token)
   
 static jmp_buf env_parse;  static jmp_buf env_parse;
   
 /* 構文解析に失敗したことを意味する. */  /* This is a parsing fault. */
 static int parse_error(char *s)  static void parse_error(char *s)
 {  {
     fprintf(stderr, "syntax error: %s\n", s);      ox_printf("syntax error: %s\n", s);
     longjmp(env_parse, 1);      longjmp(env_parse, 1);
 }  }
   
 int setflag_parse(int flag)  static void setflag_parse(int flag)
 {  {
     pflag_cmo_addrev = flag;      pflag_cmo_addrev = flag;
 }  }
   
 int init_parser(char *s)  static void init_parser(char *s)
 {  {
         setflag_parse(PFLAG_ADDREV);      setflag_parse(PFLAG_ADDREV);
         setmode_mygetc(s);      init_lex(s);
 }  }
   
 /* この部分は書き換え予定. */  static cmo *parse()
 cmo *parse()  
 {  {
     cmo *m;      cmo *m = NULL;
       if (setjmp(env_parse) == 0) {
     if (setjmp(env_parse) != 0) {  
         return NULL; /* 構文解析に失敗したら NULL を返す. */  
     }  
   
     do{  
         token = lex();          token = lex();
     }while (token == '\n');          if (token == '(') {
               token = lex();
     if (token == '(') {              if (is_token_cmo(token)) {
         token = lex();                  m = parse_cmo();
         if (is_token_cmo(token)) {              }else if(is_token_ox(token)) {
             m = parse_cmo();                  m = parse_ox();
         }else if(is_token_ox(token)) {              }else {
             m = parse_ox();                  parse_error("invalid symbol.");
         }else {              }
             parse_error("invalid symbol.");  
         }          }
 /*      parse_lf(); */  
         return m;  
     }      }
     return NULL;      return m;
 }  }
   
 /* トークンを先読みしない(重要). */  
 static int parse_lf()  
 {  
     if (token != '\n') {  
         parse_error("no new line.");  
     }  
     return 0;  
 }  
   
   
 static ox *parse_ox()  static ox *parse_ox()
 {  {
     ox *m = NULL;      ox *m = NULL;
Line 194  static int parse_sm()
Line 191  static int parse_sm()
     return sm_code;      return sm_code;
 }  }
   
   
 /* 正しい入力ならば, parse_cmo を呼ぶ時点で, token には  
    TOKEN(CMO_xxx), TOKEN(OX_xxx) のいずれかがセットされている. */  
 static cmo *parse_cmo()  static cmo *parse_cmo()
 {  {
     cmo *m = NULL;      cmo *m = NULL;
Line 260  static cmo *parse_cmo()
Line 254  static cmo *parse_cmo()
     return m;      return m;
 }  }
   
 static int parse_left_parenthesis()  static void parse_left_parenthesis()
 {  {
     if (token != '(') {      if (token != '(') {
         parse_error("no left parenthesis.");          parse_error("no left parenthesis.");
Line 268  static int parse_left_parenthesis()
Line 262  static int parse_left_parenthesis()
     token = lex();      token = lex();
 }  }
   
 static int parse_right_parenthesis()  static void parse_right_parenthesis()
 {  {
     if (token != ')') {      if (token != ')') {
         parse_error("no right parenthesis.");          parse_error("no right parenthesis.");
Line 276  static int parse_right_parenthesis()
Line 270  static int parse_right_parenthesis()
     token = lex();      token = lex();
 }  }
   
 static int parse_comma()  static void parse_comma()
 {  {
     if (token != ',') {      if (token != ',') {
         parse_error("no comma.");          parse_error("no comma.");
Line 284  static int parse_comma()
Line 278  static int parse_comma()
     token = lex();      token = lex();
 }  }
   
   static mpz_ptr new_mpz_set_str(char *s)
   {
       mpz_ptr z = MALLOC(sizeof(mpz_t));
       mpz_init_set_str(z, s, 10);
       return z;
   }
   
   static mpz_ptr my_mpz_neg(mpz_ptr src)
   {
       mpz_ptr z = MALLOC(sizeof(mpz_t));
       mpz_init(z);
       mpz_neg(z, src);
       return z;
   }
   
   static mpz_ptr parse_mpz_integer()
   {
       int sign = 1;
       mpz_ptr val;
   
       if (token == '+') {
           token = lex();
       }else if (token == '-') {
           sign = -1;
           token = lex();
       }
   
       if (token != T_DIGIT) {
           parse_error("no integer.");
       }
       val = new_mpz_set_str(yylval.sym);
       if (sign == -1) {
           val = my_mpz_neg(val);
       }
       token = lex();
       return val;
   }
   
 static int parse_integer()  static int parse_integer()
 {  {
   #if 0
       return mpz_get_si(parse_mpz_integer());
   #else
       int sign = 1;
     int val;      int val;
     if (token != T_INTEGER) {  
       if (token == '+') {
           token = lex();
       }else if (token == '-') {
           sign = -1;
           token = lex();
       }
   
       if (token != T_DIGIT) {
         parse_error("no integer.");          parse_error("no integer.");
     }      }
     val = yylval.d;      val = sign*atoi(yylval.sym);
     token = lex();      token = lex();
     return val;      return val;
   #endif
 }  }
   
 static char *parse_string()  static char *parse_string()
Line 314  static cmo *parse_cmo_null()
Line 359  static cmo *parse_cmo_null()
   
 static cmo *parse_cmo_int32()  static cmo *parse_cmo_int32()
 {  {
     int i;      int z;
   
     parse_comma();      parse_comma();
     i = parse_integer();      z = parse_integer();
     parse_right_parenthesis();      parse_right_parenthesis();
     return (cmo *)new_cmo_int32(i);      return (cmo *)new_cmo_int32(z);
 }  }
   
 static cmo *parse_cmo_string()  static cmo *parse_cmo_string()
Line 328  static cmo *parse_cmo_string()
Line 373  static cmo *parse_cmo_string()
     char *s;      char *s;
   
     parse_comma();      parse_comma();
     if (token == T_INTEGER) {      if (token == T_DIGIT) {
         parse_integer();          parse_integer();
         parse_comma();          parse_comma();
     }else if (!pflag_cmo_addrev) {      }else if (!pflag_cmo_addrev) {
Line 353  static cmo *parse_cmo_mathcap()
Line 398  static cmo *parse_cmo_mathcap()
   
 static cmo *parse_cmo_list()  static cmo *parse_cmo_list()
 {  {
     int length=0;  
     int i=0;  
     cmo_list *m = new_cmo_list();      cmo_list *m = new_cmo_list();
     cmo *newcmo;      cmo *newcmo;
   
     if (token == ',') {      if (token == ',') {
         parse_comma();          parse_comma();
   
         if (token == T_INTEGER) {          if (token == T_DIGIT) {
             parse_integer();              parse_integer();
             parse_comma();              parse_comma();
         }else if (!pflag_cmo_addrev) {          }else if (!pflag_cmo_addrev) {
Line 371  static cmo *parse_cmo_list()
Line 414  static cmo *parse_cmo_list()
         while(token == '(') {          while(token == '(') {
             parse_left_parenthesis();              parse_left_parenthesis();
             newcmo = parse_cmo();              newcmo = parse_cmo();
             append_cmo_list(m, newcmo);              list_append(m, newcmo);
             if (token != ',') {              if (token != ',') {
                 break;                  break;
             }              }
Line 387  static cmo *parse_cmo_list()
Line 430  static cmo *parse_cmo_list()
 static cmo *parse_cmo_monomial32()  static cmo *parse_cmo_monomial32()
 {  {
     int size;      int size;
     int *exps;  
     int i;      int i;
     cmo_monomial32 *m;      cmo_monomial32 *m;
     int tag;      int tag;
Line 408  static cmo *parse_cmo_monomial32()
Line 450  static cmo *parse_cmo_monomial32()
     m->coef = parse_cmo();      m->coef = parse_cmo();
     tag = m->coef->tag;      tag = m->coef->tag;
   
     /* m->coef は CMO_ZZ 型か CMO_INT32 型でなければならない */      /* semantics:
          The tag of m->coef must be CMO_ZZ or CMO_INT32. */
     if (tag != CMO_ZZ && tag != CMO_INT32) {      if (tag != CMO_ZZ && tag != CMO_INT32) {
         parse_error("invalid cmo.");          parse_error("invalid cmo.");
     }      }
Line 416  static cmo *parse_cmo_monomial32()
Line 459  static cmo *parse_cmo_monomial32()
     return (cmo *)m;      return (cmo *)m;
 }  }
   
 /* cmo_zz の内部を直接いじる. */  /* the following function rewrite internal data of mpz/cmo_zz. */
 static cmo *parse_cmo_zz()  static cmo *parse_cmo_zz()
 {  {
     int length;      int length;
     int i=0;      int i=0;
     cmo_zz *m= NULL;      cmo_zz *m= NULL;
       mpz_ptr z;
   
     parse_comma();      parse_comma();
     length = parse_integer();      z = parse_mpz_integer();
     if (token == ',') {      if (token == ',') {
           length = mpz_get_si(z);
         m = new_cmo_zz_size(length);          m = new_cmo_zz_size(length);
   
         length = abs(length);          length = abs(length);
Line 434  static cmo *parse_cmo_zz()
Line 479  static cmo *parse_cmo_zz()
             m->mpz->_mp_d[i] = parse_integer();              m->mpz->_mp_d[i] = parse_integer();
         }          }
     }else if (pflag_cmo_addrev) {      }else if (pflag_cmo_addrev) {
         m = new_cmo_zz_set_si(length);          m = new_cmo_zz_set_mpz(z);
     }else {      }else {
         parse_error("no comma.");          parse_error("no comma.");
     }      }
Line 463  static cmo *parse_cmo_ring_by_name()
Line 508  static cmo *parse_cmo_ring_by_name()
     parse_left_parenthesis();      parse_left_parenthesis();
     ob = parse_cmo();      ob = parse_cmo();
   
     /* ob は CMO_STRING 型でなければならない */      /* The ob has a type of CMO_STRING. */
     if (ob->tag != CMO_STRING) {      if (ob->tag != CMO_STRING) {
         parse_error("invalid cmo.");          parse_error("invalid cmo.");
     }      }
Line 473  static cmo *parse_cmo_ring_by_name()
Line 518  static cmo *parse_cmo_ring_by_name()
   
 static cmo *parse_cmo_distributed_polynomial()  static cmo *parse_cmo_distributed_polynomial()
 {  {
     int length=0;  
     int i=0;  
     cmo_distributed_polynomial *m = new_cmo_distributed_polynomial();      cmo_distributed_polynomial *m = new_cmo_distributed_polynomial();
     cmo *ob;      cmo *ob;
     int tag;      int tag;
Line 482  static cmo *parse_cmo_distributed_polynomial()
Line 525  static cmo *parse_cmo_distributed_polynomial()
     if (token == ',') {      if (token == ',') {
         parse_comma();          parse_comma();
   
         if (token == T_INTEGER) {          if (token == T_DIGIT) {
             parse_integer();              parse_integer();
             parse_comma();              parse_comma();
         }else if (!pflag_cmo_addrev) {          }else if (!pflag_cmo_addrev) {
Line 492  static cmo *parse_cmo_distributed_polynomial()
Line 535  static cmo *parse_cmo_distributed_polynomial()
         parse_left_parenthesis();          parse_left_parenthesis();
         m->ringdef = parse_cmo();          m->ringdef = parse_cmo();
         tag = m->ringdef->tag;          tag = m->ringdef->tag;
         /* m->ringdef は DringDefinition でなければならない */          /* m->ringdef needs to be a DringDefinition. */
         if (tag != CMO_RING_BY_NAME && tag != CMO_DMS_GENERIC          if (tag != CMO_RING_BY_NAME && tag != CMO_DMS_GENERIC
             && tag != CMO_DMS_OF_N_VARIABLES) {              && tag != CMO_DMS_OF_N_VARIABLES) {
             parse_error("invalid cmo.");              parse_error("invalid cmo.");
Line 506  static cmo *parse_cmo_distributed_polynomial()
Line 549  static cmo *parse_cmo_distributed_polynomial()
             if (ob->tag != CMO_MONOMIAL32 && ob->tag != CMO_ZERO) {              if (ob->tag != CMO_MONOMIAL32 && ob->tag != CMO_ZERO) {
                 parse_error("invalid cmo.");                  parse_error("invalid cmo.");
             }              }
             append_cmo_list((cmo_list *)m, ob);              list_append((cmo_list *)m, ob);
             if (token != ',') {              if (token != ',') {
                 break;                  break;
             }              }
Line 541  static cmo *parse_cmo_error2()
Line 584  static cmo *parse_cmo_error2()
     return (cmo *)new_cmo_error2(ob);      return (cmo *)new_cmo_error2(ob);
 }  }
   
 /* --- 字句解析部 --- */  /* --- lexical analyzer --- */
   
 /* lexical analyzer で読み飛ばされる文字なら何を初期値にしてもよい */  /* A white space is ignored by lexical analyzer. */
 static int c = ' ';  static int c = ' ';
   
 /* 一文字読み込む関数 */  /* getting a character from string. */
 static char *mygetc_ptr;  static char *mygetc_ptr;
 static int mygetc()  static int mygetc()
 {  {
         return *mygetc_ptr++;      return *mygetc_ptr++;
 }  }
   
 int setmode_mygetc(char *s)  static void init_lex(char *s)
 {  {
       c=' ';
     mygetc_ptr=s;      mygetc_ptr=s;
 }  }
   
 static int (*GETC)() = mygetc;  #define SIZE_BUFFER  8192
   static char buffer[SIZE_BUFFER];
   
 /* 一文字読み込む関数の選択 (ex. setgetc(getchar); ) */  static char *new_string(char *s)
 int setgetc(int (*foo)())  
 {  {
         if (foo == NULL) {      char *t = MALLOC(strlen(s)+1);
                 GETC = mygetc;      strcpy(t, s);
         }else {      return t;
                 GETC = foo;  
         }  
 }  }
   
 #define SIZE_BUFFER  8192  /* no measure for buffer overflow */
 static char buffer[SIZE_BUFFER];  static char *lex_digit()
   
 /* 桁溢れの場合の対策はない */  
 static int lex_digit()  
 {  {
     int d = 0;      static char buff[SIZE_BUFFER];
     do {      int i;
         d = 10*d + (c - '0');  
         c = GETC();      for(i=0; i<SIZE_BUFFER-1; i++) {
     } while(isdigit(c));          if(isdigit(c)) {
     return d;              buff[i] = c;
           }else {
               buff[i] = '\0';
               return new_string(buff);
           }
           c = mygetc();
       }
       buff[SIZE_BUFFER-1] = '\0';
       return new_string(buff);
 }  }
   
 #define MK_KEY_CMO(x)  { #x , x  , TOKEN(x)  , IS_CMO }  #define MK_KEY_CMO(x)  { #x , x  , TOKEN(x)  , IS_CMO }
 #define MK_KEY_SM(x)   { #x , x  , TOKEN(SM) , IS_SM  }  #define MK_KEY_SM(x)   { #x , x  , TOKEN(SM) , IS_SM  }
 #define MK_KEY_OX(x)   { #x , x  , TOKEN(x)  , IS_OX  }  #define MK_KEY_OX(x)   { #x , x  , TOKEN(x)  , IS_OX  }
   
 static symbol symbol_list[] = {  static struct symbol symbol_list[] = {
     MK_KEY_CMO(CMO_NULL),      MK_KEY_CMO(CMO_NULL),
     MK_KEY_CMO(CMO_INT32),      MK_KEY_CMO(CMO_INT32),
     MK_KEY_CMO(CMO_DATUM),      MK_KEY_CMO(CMO_DATUM),
Line 618  static symbol symbol_list[] = {
Line 665  static symbol symbol_list[] = {
     {NULL, 0, 0, 0}        /* a gate keeper */      {NULL, 0, 0, 0}        /* a gate keeper */
 };  };
   
 symbol* lookup_by_symbol(char *key)  symbol_t lookup_by_symbol(char *key)
 {  {
     symbol *symp;      symbol_t symp;
     for(symp = symbol_list; symp->key != NULL; symp++) {      for(symp = symbol_list; symp->key != NULL; symp++) {
         if (strcmp(key, symp->key)==0) {          if (strcmp(key, symp->key)==0) {
             return symp;              return symp;
Line 629  symbol* lookup_by_symbol(char *key)
Line 676  symbol* lookup_by_symbol(char *key)
     return NULL;      return NULL;
 }  }
   
 symbol* lookup_by_token(int tok)  symbol_t lookup_by_token(int tok)
 {  {
     symbol *symp;      symbol_t symp;
     for(symp = symbol_list; symp->key != NULL; symp++) {      for(symp = symbol_list; symp->key != NULL; symp++) {
         if (tok == symp->token) {          if (tok == symp->token) {
             return symp;              return symp;
Line 640  symbol* lookup_by_token(int tok)
Line 687  symbol* lookup_by_token(int tok)
     return NULL;      return NULL;
 }  }
   
 symbol* lookup_by_tag(int tag)  symbol_t lookup_by_tag(int tag)
 {  {
     symbol *symp;      symbol_t symp;
     for(symp = symbol_list; symp->key != NULL; symp++) {      for(symp = symbol_list; symp->key != NULL; symp++) {
         if (tag == symp->tag) {          if (tag == symp->tag) {
             return symp;              return symp;
Line 651  symbol* lookup_by_tag(int tag)
Line 698  symbol* lookup_by_tag(int tag)
     return NULL;      return NULL;
 }  }
   
 symbol* lookup(int i)  symbol_t lookup(int i)
 {  {
     return &symbol_list[i];      return &symbol_list[i];
 }  }
   
 /* バッファあふれした場合の対策をちゃんと考えるべき */  char *get_symbol_by_tag(int tag)
   {
       symbol_t symp = lookup_by_tag(tag);
       return (symp != NULL)? symp->key: NULL;
   }
   
   /* no measure for buffer overflow */
 static char *lex_quoted_string()  static char *lex_quoted_string()
 {  {
     int i;      int i;
     char c0 = ' ';      char c0 = ' ';
     char *s = NULL;  
     for (i=0; i<SIZE_BUFFER; i++) {      for (i=0; i<SIZE_BUFFER; i++) {
         c = GETC();          c = mygetc();
         if(c == '"') {          if(c == '"') {
             s = malloc(i+1);              c = mygetc();
             buffer[i]='\0';              buffer[i]='\0';
             strcpy(s, buffer);              return new_string(buffer);
   
             c = GETC();  
             return s;  
         }else if (c == '\\') {          }else if (c == '\\') {
             c0 = c;              c0 = c;
             c = GETC();              c = mygetc();
             if (c != '"') {              if (c != '"') {
                 buffer[i++] = c0;                  buffer[i++] = c0;
             }              }
         }          }
         buffer[i]=c;          buffer[i]=c;
     }      }
     fprintf(stderr, "buffer overflow!\n");      ox_printf("buffer overflow!\n");
     exit(1);      exit(1);
     /* return NULL; */      /* return NULL; */
 }  }
   
 static int token_of_symbol(char *key)  static int token_of_symbol(char *key)
 {  {
     symbol *symp = lookup_by_symbol(key);      symbol_t symp = lookup_by_symbol(key);
     if (symp != NULL) {      if (symp != NULL) {
         yylval.d = symp->tag;          yylval.d = symp->tag;
         return symp->token;          return symp->token;
     }      }
 #if DEBUG      ox_printf("lex error:: \"%s\" is unknown symbol.\n", key);
     fprintf(stderr, "lex error:: \"%s\" is unknown symbol.\n", key);  
 #endif  
     return 0;      return 0;
 }  }
   
Line 707  static int lex_symbol()
Line 755  static int lex_symbol()
             return token_of_symbol(buffer);              return token_of_symbol(buffer);
         }          }
         buffer[i]=c;          buffer[i]=c;
         c = GETC();          c = mygetc();
     }      }
     fprintf(stderr, "buffer overflow!\n");      ox_printf("buffer overflow!\n");
     return 0;      return 0;
 }  }
   
 /* return する前に一文字先読みしておく. */  /* Remark: prefetching a character before return. */
 int lex()  static int lex()
 {  {
     int c_dash = 0;      int c_dash = 0;
   
     /* 空白をスキップする. */      /* white spaces are ignored. */
     while (isspace(c) && c != '\n') {      while (isspace(c)) {
         c = GETC();          c = mygetc();
     }      }
   
     switch(c) {      switch(c) {
     case '(':      case '(':
     case ')':      case ')':
     case ',':      case ',':
     case '\n':      case '+':
       case '-':
         c_dash = c;          c_dash = c;
         c = ' ';          c = ' ';
         return c_dash;          return c_dash;
     case EOF:      case EOF:
         c = GETC();          c = mygetc();
         return c_dash;          return c_dash;
     case '"':      /* a quoted string! */      case '"':      /* a quoted string! */
         yylval.sym = lex_quoted_string();          yylval.sym = lex_quoted_string();
         return T_STRING;          return T_STRING;
     default:      default:
                   ;
     }      }
   
     if (isalpha(c)) {    /* 識別子 */      if (isalpha(c)) {
           /* symbols */
         return lex_symbol();          return lex_symbol();
     }      }
   
     /* 32bit 整数値 */      /* digit */
     if (isdigit(c)){      if (isdigit(c)){
         yylval.d = lex_digit();          yylval.sym = lex_digit();
         return T_INTEGER;          return T_DIGIT;
     }      }
     if (c == '-') {      c = mygetc();
         c = GETC();  
         while (isspace(c) && c != '\n') {  
             c = GETC();  
         }  
         if (isdigit(c)){  
             yylval.d = - lex_digit();  
             return T_INTEGER;  
         }  
         return 0;  
     }  
   
     c = GETC();  
     return 0;      return 0;
 }  }

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

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