File:  [LON-CAPA] / capa / capa51 / pProj / capaFormulaLexer.c
Revision 1.2: download - view: text, annotated - select for diffs
Fri Jun 30 21:36:16 2000 UTC (23 years, 11 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- gave everyone the GPL header

    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 Library 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:    Library General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU Library 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: /* =========================================================== */
   20: /*      capaFormulaLexer.c  created by Isaac Tsai @ Feb 1999   */
   21: /* =========================================================== */
   22: 
   23: #include <ctype.h>    /* isspace() */
   24: #include <stdio.h>    /* sscanf()  */
   25: #include "capaParser.h"
   26: #define YYSTYPE  Symbol_p
   27: #include "capaFormula.h"
   28: #include "capaToken.h"
   29: 
   30: /* ---------------  Global variables ------------------------- */
   31: extern      int         Func_idx;
   32: extern      Symbol      FuncStack[MAX_FUNC_NEST];
   33: 
   34: 
   35: extern      char        Fbuf[ONE_K];          /* lexer input buffer */
   36: extern      int         Fidx;                 /* lexer input char index */
   37: 
   38: extern      Symbol_p    fml_lval;  /* lexical variable used in parser */
   39: 
   40: /* ---- Token value returned from this lexer ---------------- */
   41: 
   42: /* ---------------  Global variables ------------------------ */
   43: 
   44: 
   45: /* scan a F_NUMBER token */
   46: double
   47: f_get_float()
   48: {
   49:   double   num; 
   50:   int      ii=0, len;
   51:   char     num_str[QUARTER_K];
   52:   
   53:   num_str[ii]=0;
   54:   while( isspace(Fbuf[Fidx]) ) { Fidx++; }
   55:   if( Fbuf[Fidx] == '+' || Fbuf[Fidx] == '-' ) {
   56:     num_str[ii++] = Fbuf[Fidx++];
   57:   }
   58:   while( isdigit(Fbuf[Fidx]) || Fbuf[Fidx] == '.' ) {
   59:       num_str[ii++] = Fbuf[Fidx++];
   60:   }
   61:   if( Fbuf[Fidx] == 'E' || Fbuf[Fidx] == 'e' ) {  /* a number followed immediately by e or E */
   62:     if( Fbuf[Fidx+1] == '+' || Fbuf[Fidx+1] == '-' || isdigit(Fbuf[Fidx+1]) ) {  
   63:     /* e or E followed immediately by a digit */
   64:       num_str[ii++] = Fbuf[Fidx++];
   65:       num_str[ii++] = Fbuf[Fidx++];
   66:       while( isdigit(Fbuf[Fidx]) ) {
   67:         num_str[ii++] = Fbuf[Fidx++];
   68:       }
   69:     }
   70:   }
   71:   num_str[ii] = 0; /* terminate the str */
   72:   len = strlen(num_str);
   73:   if(len > 0 ) {
   74:     sscanf(num_str,"%lg", &num);
   75:   } else {
   76:     num = 1.0;
   77:   }
   78:   return (num);
   79: }
   80: 
   81: char *
   82: f_get_id()
   83: {
   84:   char    *var_p; 
   85:   int      ii=0, len;
   86:   char     id_str[QUARTER_K];
   87:   
   88:   id_str[ii]=0;
   89:   while( isspace(Fbuf[Fidx]) ) { Fidx++; }
   90:   if( isalpha( Fbuf[Fidx] ) ) {
   91:     id_str[ii++] = Fbuf[Fidx++];
   92:   }
   93:   while( isalnum(Fbuf[Fidx]) || Fbuf[Fidx] == '_' ) {
   94:       id_str[ii++] = Fbuf[Fidx++];
   95:   }
   96:   id_str[ii] = 0; /* terminate the str */
   97:   len = strlen(id_str);
   98:   var_p = (char *)capa_malloc( (len+1), sizeof(char));
   99:   strcpy(var_p,id_str);
  100:   return (var_p);
  101: }
  102: 
  103: int
  104: f_peek_next_token()
  105: {
  106:   int   idx;
  107:   
  108:   idx = Fidx;
  109:   while( isspace(Fbuf[idx]) ) { idx++; }
  110:   return (Fbuf[idx]); 
  111: }
  112: 
  113: 
  114: /* ======================================================= */
  115: 
  116: int
  117: fml_lex()
  118: {
  119:   char    *id_p;
  120:   int      c;
  121:   
  122:   if( Fbuf[Fidx] == 0 )  { /* printf("EoI\n"); */ return (EOF); }
  123:   while( isspace(Fbuf[Fidx]) ) { Fidx++; }
  124:   if( isalpha(Fbuf[Fidx]) ) {
  125:     id_p = f_get_id();
  126:     c = f_peek_next_token();
  127:     if( c == '(' ) {
  128:       (FuncStack[Func_idx]).s_type = FUNCTION_ID;
  129:       (FuncStack[Func_idx]).s_name = id_p;
  130:        Func_idx++;
  131:        
  132:        return (F_ID);
  133:     } else {
  134:       fml_lval = find_formula_id(id_p); capa_mfree((char *)id_p);
  135:       if( fml_lval == NULL) {
  136:         return (F_ERROR);
  137:       } else {
  138:         return (V_ID);
  139:       }
  140:     } 
  141:   }
  142:   if( isdigit(Fbuf[Fidx]) || Fbuf[Fidx] == '.' ) {
  143:     
  144:     fml_lval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
  145:     fml_lval->s_real = f_get_float();
  146:     fml_lval->s_type = R_CONSTANT;
  147:     
  148:     return (F_NUMBER);
  149:   }
  150:   if( Fbuf[Fidx] == '(' ) {
  151:     Fidx++;
  152:     return (F_LPAR);
  153:   }
  154:   if( Fbuf[Fidx] == ')' ) {
  155:     Fidx++;
  156:     return (F_RPAR);
  157:   }
  158:   if( Fbuf[Fidx] == '+' ) {
  159:     Fidx++;
  160:     return (F_PLUS);
  161:   }
  162:   if( Fbuf[Fidx] == '-' ) {
  163:     Fidx++;
  164:     return (F_MINUS);
  165:   }
  166:   if( Fbuf[Fidx] == '*' ) {
  167:     Fidx++;
  168:     return (F_MULT);
  169:   }
  170:   if( Fbuf[Fidx] == '/' ) {
  171:     Fidx++;
  172:     return (F_DIV);
  173:   }
  174:   if( Fbuf[Fidx] == '%' ) {
  175:     Fidx++;
  176:     return (F_MOD);
  177:   }
  178:   if( Fbuf[Fidx] == '^' ) {
  179:     Fidx++;
  180:     return (F_POW);
  181:   }
  182:   if( Fbuf[Fidx] == ',' ) {
  183:     Fidx++;
  184:     return (F_COMMA);
  185:   }
  186:   return (F_ERROR);
  187:   
  188: }

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