1 /* $NetBSD: btyacc_calc1.y,v 1.1.1.1 2015/01/03 22:58:23 christos Exp $ */
6 /* http://dinosaur.compilertools.net/yacc/index.html */
13 typedef
struct interval
19 INTERVAL vmul
(double, double, INTERVAL
);
20 INTERVAL vdiv
(double, double, INTERVAL
);
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 %right UMINUS
/* precedence for unary minus */
50 %%
/* beginning of rules section */
53 | lines line
'\n' [YYVALID
;]
54 | lines
error '\n' [YYVALID
;]
62 (void) printf
("%15.8f\n", $1);
66 (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 */
181 while
(!feof
(stdin
)) {
187 #define BSZ 50 /* buffer size for floating point numbers */
192 fprintf
(stderr
, "%s\n", s
);
195 /* lexical analysis */
202 while
((c
= getchar
()) == ' ')
203 { /* skip over blanks */
209 (*yylval).ival
= c
- 'A';
211 yylval.ival
= c
- 'A';
218 (*yylval).ival
= c
- 'a';
220 yylval.ival
= c
- 'a';
225 if
(isdigit
(c
) || c
== '.')
227 /* gobble up digits, points, exponents */
228 char buf
[BSZ
+ 1], *cp
= buf
;
229 int dot
= 0, expr
= 0;
231 for
(; (cp
- buf
) < BSZ
; ++cp
, c
= getchar
())
240 return
('.'); /* will cause syntax error */
247 return
('e'); /* will cause syntax error */
256 if
((cp
- buf
) >= BSZ
)
257 printf
("constant too long: truncated\n");
259 ungetc
(c
, stdin
); /* push back last char read */
261 (*yylval).dval
= atof
(buf
);
263 yylval.dval
= atof
(buf
);
271 hilo
(double a
, double b
, double c
, double d
)
273 /* returns the smallest interval containing a, b, c, and d */
274 /* used by *, / routines */
306 vmul
(double a
, double b
, INTERVAL v
)
308 return
(hilo
(a
* v.hi
, a
* v.lo
, b
* v.hi
, b
* v.lo
));
314 if
(v.hi
>= 0.
&& v.lo
<= 0.
)
316 printf
("divisor interval contains 0.\n");
323 vdiv
(double a
, double b
, INTERVAL v
)
325 return
(hilo
(a
/ v.hi
, a
/ v.lo
, b
/ v.hi
, b
/ v.lo
));