File:  [LON-CAPA] / capa / capa51 / pProj / capaFormulaLexer.c
Revision 1.6: download - view: text, annotated - select for diffs
Wed May 1 20:31:19 2024 UTC (2 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_X, version_2_11_5, HEAD
- Add explanation for <string.h> (rev. 1.5)

    1: /* Lexer for formula answers
    2:    Copyright (C) 1992-2000 Michigan State University
    3: 
    4:    The CAPA system is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU General Public License as
    6:    published by the Free Software Foundation; either version 2 of the
    7:    License, or (at your option) any later version.
    8: 
    9:    The CAPA system is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU General Public
   15:    License along with the CAPA system; see the file COPYING.  If not,
   16:    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17:    Boston, MA 02111-1307, USA.
   18: 
   19:    As a special exception, you have permission to link this program
   20:    with the TtH/TtM library and distribute executables, as long as you
   21:    follow the requirements of the GNU GPL in regard to all of the
   22:    software in the executable aside from TtH/TtM.
   23: */
   24: 
   25: /* =========================================================== */
   26: /*      capaFormulaLexer.c  created by Isaac Tsai @ Feb 1999   */
   27: /* =========================================================== */
   28: 
   29: #include <ctype.h>    /* isspace() */
   30: #include <stdio.h>    /* sscanf()  */
   31: #include <string.h>   /* strlen() strcpy() */
   32: #include "capaParser.h"
   33: #define YYSTYPE  Symbol_p
   34: #include "capaFormula.h"
   35: #include "capaToken.h"
   36: 
   37: /* ---------------  Global variables ------------------------- */
   38: extern      int         Func_idx;
   39: extern      Symbol      FuncStack[MAX_FUNC_NEST];
   40: 
   41: 
   42: extern      char        Fbuf[ONE_K];          /* lexer input buffer */
   43: extern      int         Fidx;                 /* lexer input char index */
   44: 
   45: extern      Symbol_p    fml_lval;  /* lexical variable used in parser */
   46: 
   47: /* ---- Token value returned from this lexer ---------------- */
   48: 
   49: /* ---------------  Global variables ------------------------ */
   50: 
   51: 
   52: /* scan a F_NUMBER token */
   53: double
   54: f_get_float()
   55: {
   56:   double   num; 
   57:   int      ii=0, len;
   58:   char     num_str[QUARTER_K];
   59:   
   60:   num_str[ii]=0;
   61:   while( isspace(Fbuf[Fidx]) ) { Fidx++; }
   62:   if( Fbuf[Fidx] == '+' || Fbuf[Fidx] == '-' ) {
   63:     num_str[ii++] = Fbuf[Fidx++];
   64:   }
   65:   while( isdigit(Fbuf[Fidx]) || Fbuf[Fidx] == '.' ) {
   66:       num_str[ii++] = Fbuf[Fidx++];
   67:   }
   68:   if( Fbuf[Fidx] == 'E' || Fbuf[Fidx] == 'e' ) {  /* a number followed immediately by e or E */
   69:     if( Fbuf[Fidx+1] == '+' || Fbuf[Fidx+1] == '-' || isdigit(Fbuf[Fidx+1]) ) {  
   70:     /* e or E followed immediately by a digit */
   71:       num_str[ii++] = Fbuf[Fidx++];
   72:       num_str[ii++] = Fbuf[Fidx++];
   73:       while( isdigit(Fbuf[Fidx]) ) {
   74:         num_str[ii++] = Fbuf[Fidx++];
   75:       }
   76:     }
   77:   }
   78:   num_str[ii] = 0; /* terminate the str */
   79:   len = strlen(num_str);
   80:   if(len > 0 ) {
   81:     sscanf(num_str,"%lg", &num);
   82:   } else {
   83:     num = 1.0;
   84:   }
   85:   return (num);
   86: }
   87: 
   88: char *
   89: f_get_id()
   90: {
   91:   char    *var_p; 
   92:   int      ii=0, len;
   93:   char     id_str[QUARTER_K];
   94:   
   95:   id_str[ii]=0;
   96:   while( isspace(Fbuf[Fidx]) ) { Fidx++; }
   97:   if( isalpha( Fbuf[Fidx] ) ) {
   98:     id_str[ii++] = Fbuf[Fidx++];
   99:   }
  100:   while( isalnum(Fbuf[Fidx]) || Fbuf[Fidx] == '_' ) {
  101:       id_str[ii++] = Fbuf[Fidx++];
  102:   }
  103:   id_str[ii] = 0; /* terminate the str */
  104:   len = strlen(id_str);
  105:   var_p = (char *)capa_malloc( (len+1), sizeof(char));
  106:   strcpy(var_p,id_str);
  107:   return (var_p);
  108: }
  109: 
  110: int
  111: f_peek_next_token()
  112: {
  113:   int   idx;
  114:   
  115:   idx = Fidx;
  116:   while( isspace(Fbuf[idx]) ) { idx++; }
  117:   return (Fbuf[idx]); 
  118: }
  119: 
  120: 
  121: /* ======================================================= */
  122: 
  123: int
  124: fml_lex()
  125: {
  126:   char    *id_p;
  127:   int      c;
  128:   
  129:   if( Fbuf[Fidx] == 0 )  { /* printf("EoI\n"); */ return (EOF); }
  130:   while( isspace(Fbuf[Fidx]) ) { Fidx++; }
  131:   if( isalpha(Fbuf[Fidx]) ) {
  132:     id_p = f_get_id();
  133:     c = f_peek_next_token();
  134:     if( c == '(' ) {
  135:       (FuncStack[Func_idx]).s_type = FUNCTION_ID;
  136:       (FuncStack[Func_idx]).s_name = id_p;
  137:        Func_idx++;
  138:        
  139:        return (F_ID);
  140:     } else {
  141:       fml_lval = find_formula_id(id_p); capa_mfree((char *)id_p);
  142:       if( fml_lval == NULL) {
  143:         return (F_ERROR);
  144:       } else {
  145:         return (V_ID);
  146:       }
  147:     } 
  148:   }
  149:   if( isdigit(Fbuf[Fidx]) || Fbuf[Fidx] == '.' ) {
  150:     
  151:     fml_lval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
  152:     fml_lval->s_real = f_get_float();
  153:     fml_lval->s_type = R_CONSTANT;
  154:     
  155:     return (F_NUMBER);
  156:   }
  157:   if( Fbuf[Fidx] == '(' ) {
  158:     Fidx++;
  159:     return (F_LPAR);
  160:   }
  161:   if( Fbuf[Fidx] == ')' ) {
  162:     Fidx++;
  163:     return (F_RPAR);
  164:   }
  165:   if( Fbuf[Fidx] == '+' ) {
  166:     Fidx++;
  167:     return (F_PLUS);
  168:   }
  169:   if( Fbuf[Fidx] == '-' ) {
  170:     Fidx++;
  171:     return (F_MINUS);
  172:   }
  173:   if( Fbuf[Fidx] == '*' ) {
  174:     Fidx++;
  175:     return (F_MULT);
  176:   }
  177:   if( Fbuf[Fidx] == '/' ) {
  178:     Fidx++;
  179:     return (F_DIV);
  180:   }
  181:   if( Fbuf[Fidx] == '%' ) {
  182:     Fidx++;
  183:     return (F_MOD);
  184:   }
  185:   if( Fbuf[Fidx] == '^' ) {
  186:     Fidx++;
  187:     return (F_POW);
  188:   }
  189:   if( Fbuf[Fidx] == ',' ) {
  190:     Fidx++;
  191:     return (F_COMMA);
  192:   }
  193:   return (F_ERROR);
  194:   
  195: }

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