4 /* http://dinosaur.compilertools.net/yacc/index.html */
11 typedef struct interval
17 INTERVAL vmul(double, double, INTERVAL);
18 INTERVAL vdiv(double, double, INTERVAL);
36 %token <ival> DREG VREG /* indices into dreg, vreg arrays */
37 %token <dval> CONST /* floating point constant */
39 %type <dval> dexp /* expression */
40 %type <vval> vexp /* interval expression */
42 /* precedence information about the operators */
46 %right UMINUS /* precedence for unary minus */
48 %% /* beginning of rules section */
51 | lines line '\n' [YYVALID;]
52 | lines error '\n' [YYVALID;]
60 (void) printf("%15.8f\n", $1);
64 (void) printf("(%15.8f, %15.8f)\n", $1.lo, $1.hi);
97 | '-' dexp %prec UMINUS
111 | '(' dexp ',' dexp ')'
117 (void) printf("interval out of order\n");
127 $$.hi = $1.hi + $3.hi;
128 $$.lo = $1.lo + $3.lo;
137 $$.hi = $1.hi - $3.lo;
138 $$.lo = $1.lo - $3.hi;
147 $$ = vmul( $1.lo, $1.hi, $3 );
151 $$ = vmul ($1, $1, $3 );
155 if (dcheck($3)) YYERROR;
156 $$ = vdiv ( $1.lo, $1.hi, $3 );
160 if (dcheck ( $3 )) YYERROR;
161 $$ = vdiv ($1, $1, $3 );
163 | '-' vexp %prec UMINUS
174 %% /* beginning of subroutines section */
179 while(!feof(stdin)) {
185 #define BSZ 50 /* buffer size for floating point numbers */
190 fprintf(stderr, "%s\n", s);
193 /* lexical analysis */
200 while ((c = getchar()) == ' ')
201 { /* skip over blanks */
207 (*yylval).ival = c - 'A';
209 yylval.ival = c - 'A';
216 (*yylval).ival = c - 'a';
218 yylval.ival = c - 'a';
223 if (isdigit(c) || c == '.')
225 /* gobble up digits, points, exponents */
226 char buf[BSZ + 1], *cp = buf;
227 int dot = 0, expr = 0;
229 for (; (cp - buf) < BSZ; ++cp, c = getchar())
238 return ('.'); /* will cause syntax error */
245 return ('e'); /* will cause syntax error */
254 if ((cp - buf) >= BSZ)
255 printf("constant too long: truncated\n");
257 ungetc(c, stdin); /* push back last char read */
259 (*yylval).dval = atof(buf);
261 yylval.dval = atof(buf);
269 hilo(double a, double b, double c, double d)
271 /* returns the smallest interval containing a, b, c, and d */
272 /* used by *, / routines */
304 vmul(double a, double b, INTERVAL v)
306 return (hilo(a * v.hi, a * v.lo, b * v.hi, b * v.lo));
312 if (v.hi >= 0. && v.lo <= 0.)
314 printf("divisor interval contains 0.\n");
321 vdiv(double a, double b, INTERVAL v)
323 return (hilo(a / v.hi, a / v.lo, b / v.hi, b / v.lo));