![]() ![]() | ![]() |
- 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: }