Annotation of capa/capa51/pProj/capaFormulaLexer.c, revision 1.5
1.2 albertel 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
1.4 albertel 5: modify it under the terms of the GNU General Public License as
1.2 albertel 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
1.4 albertel 12: General Public License for more details.
1.2 albertel 13:
1.4 albertel 14: You should have received a copy of the GNU General Public
1.2 albertel 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,
1.3 albertel 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: */
1.1 albertel 24:
25: /* =========================================================== */
26: /* capaFormulaLexer.c created by Isaac Tsai @ Feb 1999 */
27: /* =========================================================== */
28:
29: #include <ctype.h> /* isspace() */
30: #include <stdio.h> /* sscanf() */
1.5 ! raeburn 31: #include <string.h>
1.1 albertel 32: #include "capaParser.h"
1.2 albertel 33: #define YYSTYPE Symbol_p
1.1 albertel 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>