3 /* http://dinosaur.compilertools.net/yacc/index.html */
10 typedef struct interval
16 INTERVAL vmul(double, double, INTERVAL);
17 INTERVAL vdiv(double, double, INTERVAL);
19 extern int yylex(void);
20 static void yyerror(const char *s);
38 %token <ival> DREG VREG /* indices into dreg, vreg arrays */
39 %token <dval> CONST /* floating point constant */
41 %type <dval> dexp /* expression */
42 %type <vval> vexp /* interval expression */
44 /* precedence information about the operators */
48 %left UMINUS /* precedence for unary minus */
50 %% /* beginning of rules section */
58 (void) printf("%15.8f\n", $1);
62 (void) printf("(%15.8f, %15.8f)\n", $1.lo, $1.hi);
99 | '-' dexp %prec UMINUS
113 | '(' dexp ',' dexp ')'
119 (void) printf("interval out of order\n");
129 $$.hi = $1.hi + $3.hi;
130 $$.lo = $1.lo + $3.lo;
139 $$.hi = $1.hi - $3.lo;
140 $$.lo = $1.lo - $3.hi;
149 $$ = vmul( $1.lo, $1.hi, $3 );
153 $$ = vmul ($1, $1, $3 );
157 if (dcheck($3)) YYERROR;
158 $$ = vdiv ( $1.lo, $1.hi, $3 );
162 if (dcheck ( $3 )) YYERROR;
163 $$ = vdiv ($1, $1, $3 );
165 | '-' vexp %prec UMINUS
176 %% /* beginning of subroutines section */
178 #define BSZ 50 /* buffer size for floating point numbers */
180 /* lexical analysis */
183 yyerror(const char *s)
185 fprintf(stderr, "%s\n", s);
193 while ((c = getchar()) == ' ')
194 { /* skip over blanks */
199 yylval.ival = c - 'A';
204 yylval.ival = c - 'a';
208 if (isdigit(c) || c == '.')
210 /* gobble up digits, points, exponents */
211 char buf[BSZ + 1], *cp = buf;
212 int dot = 0, expr = 0;
214 for (; (cp - buf) < BSZ; ++cp, c = getchar())
223 return ('.'); /* will cause syntax error */
230 return ('e'); /* will cause syntax error */
239 if ((cp - buf) >= BSZ)
240 printf("constant too long: truncated\n");
242 ungetc(c, stdin); /* push back last char read */
243 yylval.dval = atof(buf);
250 hilo(double a, double b, double c, double d)
252 /* returns the smallest interval containing a, b, c, and d */
253 /* used by *, / routines */
285 vmul(double a, double b, INTERVAL v)
287 return (hilo(a * v.hi, a * v.lo, b * v.hi, b * v.lo));
293 if (v.hi >= 0. && v.lo <= 0.)
295 printf("divisor interval contains 0.\n");
302 vdiv(double a, double b, INTERVAL v)
304 return (hilo(a / v.hi, a / v.lo, b / v.hi, b / v.lo));