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