1:
2: /* ====================================================== */
3: /* capaFormula.y created by Isaac Tsai @ Feb 1999 */
4: /* copyrighted by Isaac Tsai 1999 */
5: /* TODO: checking user inputs 2/27/99 IT */
6: /* ====================================================== */
7: %{
8: #include <stdio.h>
9: #include <ctype.h>
10: #include <string.h>
11: #include <math.h>
12: #include "capaParser.h" /* _symbol structure def */
13: #include "capaCommon.h"
14: #include "capaFunction.h"
15: #include "capaToken.h"
16:
17: #ifdef __hpux
18: #include <stdlib.h>
19: #include <alloca.h>
20: #endif
21:
22: #ifdef FML_DBUG
23: #define FMLDBUG_PR1(xx) { printf(xx); fflush(stdout); }
24: #define FMLDBUG_PR2(xx,yy) { printf(xx,yy); fflush(stdout); }
25: #define FMLDBUG_PR3(xx,yy,zz) { printf(xx,yy,zz); fflush(stdout); }
26: #else
27: #define FMLDBUG_PR1(xx) { }
28: #define FMLDBUG_PR2(xx,yy) { }
29: #define FMLDBUG_PR3(xx,yy,zz) { }
30: #endif
31:
32: #define ADD_op 1
33: #define SUB_op 2
34: #define MUL_op 3
35: #define DIV_op 4
36: #define IDIV_op 5
37: #define NOT_DEFINED_op 9
38:
39: #ifdef YYSTYPE
40: #undef YYSTYPE
41: #endif
42: #define YYSTYPE Symbol_p
43:
44: /* =============================================================== */
45:
46: extern int Func_idx;
47: extern Symbol FuncStack[MAX_FUNC_NEST];
48:
49: double FormulaVal;
50: int FormulaParseOK=1;
51:
52: %}
53:
54:
55: %token F_NUMBER V_ID F_ID EoI F_ERROR
56: %left F_PLUS F_MINUS
57: %left F_MULT F_DIV F_MOD
58: %token F_POW F_LPAR F_RPAR F_COMMA
59:
60:
61: %start f_expr
62:
63:
64: %%
65:
66: f_expr : block { switch($1->s_type) {
67: case I_VAR:
68: case I_CONSTANT: FormulaVal = (double)($1->s_int);
69: break;
70: case R_VAR:
71: case R_CONSTANT: FormulaVal = $1->s_real;
72: break;
73: case S_VAR:
74: case S_CONSTANT: FormulaParseOK = 0;
75: break;
76: default: FormulaParseOK = 0;
77: break;
78: }
79: capa_mfree((char *)$1);
80: FMLDBUG_PR1("[f_expr <= block ]\n");
81: }
82: ;
83:
84: block : block F_PLUS term { $$ = symbols_op($1, $3, ADD_op); }
85: | block F_MINUS term { $$ = symbols_op($1, $3, SUB_op); }
86: | term { $$ = $1; }
87: | F_ERROR { FormulaParseOK = 0; FMLDBUG_PR1("[F_ERROR]\n"); return 0;}
88: | error { FormulaParseOK = 0; FMLDBUG_PR1("[ERROR]\n"); return 0; }
89: ;
90:
91: term : term F_MULT basic_constr { $$ = symbols_op($1, $3, MUL_op); }
92: | term F_DIV basic_constr { $$ = symbols_op($1, $3, DIV_op); }
93: | term F_MOD basic_constr { $$ = symbols_op($1, $3, IDIV_op); }
94: | basic_constr { $$ = $1; }
95: ;
96:
97: basic_constr : basic_constr F_POW basic_item { $$ = f_symbol_pow($1,$3);
98: FMLDBUG_PR3("[%.16g ^ %.16g] ",$1->s_real,$3->s_real); }
99: | basic_item { $$ = $1; }
100: ;
101:
102: arg_list : arg_list F_COMMA block { $$ = $1;
103: $$->s_argc++;
104: $$->s_argp = addto_arglist($1->s_argp, $3);
105: }
106: | block { $$ = $1;
107: $$->s_argc = 1;
108: $$->s_argp = new_arglist($1);
109: }
110: ;
111:
112: basic_item : F_ID F_LPAR F_RPAR { int tmp;
113:
114: Func_idx--;
115: if(Func_idx >= 0 ) {
116: tmp = match_function(FuncStack[Func_idx].s_name,0);
117: $$ = do_function(tmp, 0, NULL );
118: capa_mfree(FuncStack[Func_idx].s_name);
119: }
120: }
121: | F_ID F_LPAR arg_list F_RPAR { int tmp;
122:
123: Func_idx--;
124: if(Func_idx >= 0 ) {
125: tmp = match_function(FuncStack[Func_idx].s_name,$3->s_argc);
126: $$ = do_function(tmp, $3->s_argc, $3->s_argp);
127: capa_mfree(FuncStack[Func_idx].s_name);
128: free_arglist($3->s_argp);
129: }
130: }
131: | V_ID { FMLDBUG_PR3("[V %s = %.16g] ",$1->s_name, $1->s_real);
132: $$ = $1;
133: }
134: | F_MINUS basic_item { $$ = $2;
135: switch($2->s_type) {
136: case I_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
137: $$->s_type = I_CONSTANT;
138: case I_CONSTANT: $$->s_int = - $2->s_int; break;
139: case R_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
140: $$->s_type = R_CONSTANT;
141: case R_CONSTANT: $$->s_real = (-1.0)*($2->s_real);
142: break;
143: case S_VAR:
144: case S_CONSTANT: break;
145: default: break;
146: }
147: }
148: | F_PLUS basic_item { $$ = $2; }
149: | F_NUMBER { FMLDBUG_PR2("[F %.16g] ",$1->s_real);
150: $$ = $1;
151: }
152: | F_LPAR block F_RPAR { $$ = $2; }
153: ;
154: %%
155: void
156: fml_error(char *msg)
157: {
158: FormulaParseOK=0;
159: printf("Error Parsing: %s\n",msg);
160:
161: }
162: /* ---------------------------------------------------- */
163: Symbol *
164: f_symbol_pow(ap,bp) Symbol *ap; Symbol *bp;
165: {
166: Symbol *cp;
167: double a, b;
168: int error = 0;
169:
170: cp = NULL;
171: switch(ap->s_type) {
172: case I_VAR: a = (double)(ap->s_int);
173: break;
174: case I_CONSTANT: a = (double)(ap->s_int); capa_mfree((char *)ap);
175: break;
176: case R_VAR: a = ap->s_real;
177: break;
178: case R_CONSTANT: a = ap->s_real; capa_mfree((char *)ap);
179: break;
180: case S_VAR:
181: case S_CONSTANT:
182: default: error = 1; break;
183: }
184: switch(bp->s_type) {
185: case I_VAR: b = (double)(bp->s_int);
186: break;
187: case I_CONSTANT: b = (double)(bp->s_int); capa_mfree((char *)bp);
188: break;
189: case R_VAR: b = bp->s_real;
190: break;
191: case R_CONSTANT: b = bp->s_real; capa_mfree((char *)bp);
192: break;
193: case S_VAR:
194: case S_CONSTANT:
195: default: error = 1; break;
196: }
197: if (!error) {
198: cp = (Symbol *)capa_malloc(sizeof(Symbol),1);
199: cp->s_type = R_CONSTANT;
200: cp->s_real = pow(a,b);
201:
202: }
203: return (cp);
204: }
205:
206: /* ============================================================================= */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>