Annotation of capa/capa51/pProj/capaFormula.y, revision 1.8
1.3 albertel 1: /* formula parser
2: Copyright (C) 1992-2000 Michigan State University
3:
4: The CAPA system is free software; you can redistribute it and/or
1.6 albertel 5: modify it under the terms of the GNU General Public License as
1.3 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.6 albertel 12: General Public License for more details.
1.3 albertel 13:
1.6 albertel 14: You should have received a copy of the GNU General Public
1.3 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.5 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: /* capaFormula.y created by Isaac Tsai @ Feb 1999 */
27: /* TODO: checking user inputs 2/27/99 IT */
28: /* ====================================================== */
29: %{
30: #include <stdio.h>
31: #include <ctype.h>
32: #include <string.h>
33: #include <math.h>
34: #include "capaParser.h" /* _symbol structure def */
35: #include "capaCommon.h"
36: #include "capaFunction.h"
1.2 albertel 37: #ifdef YYSTYPE
38: #undef YYSTYPE
39: #endif
40: #define YYSTYPE Symbol_p
1.1 albertel 41: #include "capaToken.h"
42:
43: #ifdef __hpux
44: #include <stdlib.h>
45: #include <alloca.h>
46: #endif
47:
48: #ifdef FML_DBUG
49: #define FMLDBUG_PR1(xx) { printf(xx); fflush(stdout); }
50: #define FMLDBUG_PR2(xx,yy) { printf(xx,yy); fflush(stdout); }
51: #define FMLDBUG_PR3(xx,yy,zz) { printf(xx,yy,zz); fflush(stdout); }
52: #else
53: #define FMLDBUG_PR1(xx) { }
54: #define FMLDBUG_PR2(xx,yy) { }
55: #define FMLDBUG_PR3(xx,yy,zz) { }
56: #endif
57:
58: #define ADD_op 1
59: #define SUB_op 2
60: #define MUL_op 3
61: #define DIV_op 4
62: #define IDIV_op 5
63: #define NOT_DEFINED_op 9
64:
65:
66: /* =============================================================== */
67:
68: extern int Func_idx;
69: extern Symbol FuncStack[MAX_FUNC_NEST];
1.2 albertel 70: void fml_error(char *msg);
1.1 albertel 71: double FormulaVal;
72: int FormulaParseOK=1;
73:
74: %}
75:
76:
77: %token F_NUMBER V_ID F_ID EoI F_ERROR
78: %left F_PLUS F_MINUS
79: %left F_MULT F_DIV F_MOD
80: %token F_POW F_LPAR F_RPAR F_COMMA
81:
82:
83: %start f_expr
84:
85:
86: %%
87:
88: f_expr : block { switch($1->s_type) {
89: case I_VAR:
90: case I_CONSTANT: FormulaVal = (double)($1->s_int);
91: break;
92: case R_VAR:
93: case R_CONSTANT: FormulaVal = $1->s_real;
94: break;
95: case S_VAR:
96: case S_CONSTANT: FormulaParseOK = 0;
97: break;
98: default: FormulaParseOK = 0;
99: break;
100: }
101: capa_mfree((char *)$1);
102: FMLDBUG_PR1("[f_expr <= block ]\n");
103: }
104: ;
105:
106: block : block F_PLUS term { $$ = symbols_op($1, $3, ADD_op); }
107: | block F_MINUS term { $$ = symbols_op($1, $3, SUB_op); }
1.8 ! albertel 108: | F_MINUS term { $$ = $2;
! 109: switch($2->s_type) {
! 110: case I_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
! 111: $$->s_type = I_CONSTANT;
! 112: case I_CONSTANT: $$->s_int = - $2->s_int; break;
! 113: case R_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
! 114: $$->s_type = R_CONSTANT;
! 115: case R_CONSTANT: $$->s_real = (-1.0)*($2->s_real);
! 116: break;
! 117: case S_VAR:
! 118: case S_CONSTANT: break;
! 119: default: break;
! 120: }
! 121: }
1.1 albertel 122: | term { $$ = $1; }
123: | F_ERROR { FormulaParseOK = 0; FMLDBUG_PR1("[F_ERROR]\n"); return 0;}
124: | error { FormulaParseOK = 0; FMLDBUG_PR1("[ERROR]\n"); return 0; }
125: ;
126:
127: term : term F_MULT basic_constr { $$ = symbols_op($1, $3, MUL_op); }
128: | term F_DIV basic_constr { $$ = symbols_op($1, $3, DIV_op); }
129: | term F_MOD basic_constr { $$ = symbols_op($1, $3, IDIV_op); }
130: | basic_constr { $$ = $1; }
131: ;
132:
133: basic_constr : basic_constr F_POW basic_item { $$ = f_symbol_pow($1,$3);
134: FMLDBUG_PR3("[%.16g ^ %.16g] ",$1->s_real,$3->s_real); }
135: | basic_item { $$ = $1; }
136: ;
137:
138: arg_list : arg_list F_COMMA block { $$ = $1;
139: $$->s_argc++;
140: $$->s_argp = addto_arglist($1->s_argp, $3);
141: }
142: | block { $$ = $1;
143: $$->s_argc = 1;
144: $$->s_argp = new_arglist($1);
145: }
146: ;
147:
148: basic_item : F_ID F_LPAR F_RPAR { int tmp;
149:
150: Func_idx--;
151: if(Func_idx >= 0 ) {
152: tmp = match_function(FuncStack[Func_idx].s_name,0);
153: $$ = do_function(tmp, 0, NULL );
154: capa_mfree(FuncStack[Func_idx].s_name);
155: }
156: }
157: | F_ID F_LPAR arg_list F_RPAR { int tmp;
158:
159: Func_idx--;
160: if(Func_idx >= 0 ) {
161: tmp = match_function(FuncStack[Func_idx].s_name,$3->s_argc);
162: $$ = do_function(tmp, $3->s_argc, $3->s_argp);
163: capa_mfree(FuncStack[Func_idx].s_name);
164: free_arglist($3->s_argp);
1.7 albertel 165: $3->s_argp=NULL;
1.1 albertel 166: }
167: }
168: | V_ID { FMLDBUG_PR3("[V %s = %.16g] ",$1->s_name, $1->s_real);
169: $$ = $1;
170: }
171: | F_PLUS basic_item { $$ = $2; }
172: | F_NUMBER { FMLDBUG_PR2("[F %.16g] ",$1->s_real);
173: $$ = $1;
174: }
175: | F_LPAR block F_RPAR { $$ = $2; }
176: ;
177: %%
178: void
179: fml_error(char *msg)
180: {
181: FormulaParseOK=0;
182: printf("Error Parsing: %s\n",msg);
183:
184: }
185: /* ---------------------------------------------------- */
186: Symbol *
187: f_symbol_pow(ap,bp) Symbol *ap; Symbol *bp;
188: {
189: Symbol *cp;
190: double a, b;
191: int error = 0;
192:
193: cp = NULL;
194: switch(ap->s_type) {
195: case I_VAR: a = (double)(ap->s_int);
196: break;
197: case I_CONSTANT: a = (double)(ap->s_int); capa_mfree((char *)ap);
198: break;
199: case R_VAR: a = ap->s_real;
200: break;
201: case R_CONSTANT: a = ap->s_real; capa_mfree((char *)ap);
202: break;
203: case S_VAR:
204: case S_CONSTANT:
205: default: error = 1; break;
206: }
207: switch(bp->s_type) {
208: case I_VAR: b = (double)(bp->s_int);
209: break;
210: case I_CONSTANT: b = (double)(bp->s_int); capa_mfree((char *)bp);
211: break;
212: case R_VAR: b = bp->s_real;
213: break;
214: case R_CONSTANT: b = bp->s_real; capa_mfree((char *)bp);
215: break;
216: case S_VAR:
217: case S_CONSTANT:
218: default: error = 1; break;
219: }
1.4 albertel 220: if ((!(((double)((int)b)) == b)) && (a < 0.0)) {
221: error = 1;
222: }
1.1 albertel 223: if (!error) {
224: cp = (Symbol *)capa_malloc(sizeof(Symbol),1);
225: cp->s_type = R_CONSTANT;
226: cp->s_real = pow(a,b);
227:
228: }
229: return (cp);
230: }
231:
232: /* ============================================================================= */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>