Remove building with NOCRYPTO option
[minix3.git] / external / bsd / byacc / dist / test / btyacc_calc1.y
blobf36c6fae1a691a967e7d8256f2c697e43f3e949d
1 /* $NetBSD: btyacc_calc1.y,v 1.1.1.1 2015/01/03 22:58:23 christos Exp $ */
3 %PURE_PARSER
4 %{
6 /* http://dinosaur.compilertools.net/yacc/index.html */
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <ctype.h>
11 #include <math.h>
13 typedef struct interval
15 double lo, hi;
17 INTERVAL;
19 INTERVAL vmul(double, double, INTERVAL);
20 INTERVAL vdiv(double, double, INTERVAL);
22 int dcheck(INTERVAL);
24 double dreg[26];
25 INTERVAL vreg[26];
28 %expect 17
30 %start lines
31 %union
33 int ival;
34 double dval;
35 INTERVAL vval;
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 */
46 %left '+' '-'
47 %left '*' '/'
48 %right UMINUS /* precedence for unary minus */
50 %% /* beginning of rules section */
52 lines : /* empty */
53 | lines line '\n' [YYVALID;]
54 | lines error '\n' [YYVALID;]
56 yyerrok;
60 line : dexp
62 (void) printf("%15.8f\n", $1);
64 | vexp
66 (void) printf("(%15.8f, %15.8f)\n", $1.lo, $1.hi);
68 | DREG '=' dexp
70 dreg[$1] = $3;
72 | VREG '=' vexp
74 vreg[$1] = $3;
78 dexp : CONST
79 | DREG
81 $$ = dreg[$1];
83 | dexp '+' dexp
85 $$ = $1 + $3;
87 | dexp '-' dexp
89 $$ = $1 - $3;
91 | dexp '*' dexp
93 $$ = $1 * $3;
95 | dexp '/' dexp
97 $$ = $1 / $3;
99 | '-' dexp %prec UMINUS
101 $$ = -$2;
103 | '(' dexp ')'
105 $$ = $2;
109 vexp : dexp
111 $$.hi = $$.lo = $1;
113 | '(' dexp ',' dexp ')'
115 $$.lo = $2;
116 $$.hi = $4;
117 if ( $$.lo > $$.hi )
119 (void) printf("interval out of order\n");
120 YYERROR;
123 | VREG
125 $$ = vreg[$1];
127 | vexp '+' vexp
129 $$.hi = $1.hi + $3.hi;
130 $$.lo = $1.lo + $3.lo;
132 | dexp '+' vexp
134 $$.hi = $1 + $3.hi;
135 $$.lo = $1 + $3.lo;
137 | vexp '-' vexp
139 $$.hi = $1.hi - $3.lo;
140 $$.lo = $1.lo - $3.hi;
142 | dexp '-' vexp
144 $$.hi = $1 - $3.lo;
145 $$.lo = $1 - $3.hi;
147 | vexp '*' vexp
149 $$ = vmul( $1.lo, $1.hi, $3 );
151 | dexp '*' vexp
153 $$ = vmul ($1, $1, $3 );
155 | vexp '/' vexp
157 if (dcheck($3)) YYERROR;
158 $$ = vdiv ( $1.lo, $1.hi, $3 );
160 | dexp '/' vexp
162 if (dcheck ( $3 )) YYERROR;
163 $$ = vdiv ($1, $1, $3 );
165 | '-' vexp %prec UMINUS
167 $$.hi = -$2.lo;
168 $$.lo = -$2.hi;
170 | '(' vexp ')'
172 $$ = $2;
176 %% /* beginning of subroutines section */
179 main (void)
181 while(!feof(stdin)) {
182 yyparse();
184 return 0;
187 #define BSZ 50 /* buffer size for floating point numbers */
189 static void
190 YYERROR_DECL()
192 fprintf(stderr, "%s\n", s);
195 /* lexical analysis */
197 static int
198 YYLEX_DECL()
200 int c;
202 while ((c = getchar()) == ' ')
203 { /* skip over blanks */
206 if (isupper(c))
208 #if YYPURE
209 (*yylval).ival = c - 'A';
210 #else
211 yylval.ival = c - 'A';
212 #endif
213 return (VREG);
215 if (islower(c))
217 #if YYPURE
218 (*yylval).ival = c - 'a';
219 #else
220 yylval.ival = c - 'a';
221 #endif
222 return (DREG);
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())
234 *cp = (char) c;
235 if (isdigit(c))
236 continue;
237 if (c == '.')
239 if (dot++ || expr)
240 return ('.'); /* will cause syntax error */
241 continue;
244 if (c == 'e')
246 if (expr++)
247 return ('e'); /* will cause syntax error */
248 continue;
251 /* end of number */
252 break;
254 *cp = '\0';
256 if ((cp - buf) >= BSZ)
257 printf("constant too long: truncated\n");
258 else
259 ungetc(c, stdin); /* push back last char read */
260 #if YYPURE
261 (*yylval).dval = atof(buf);
262 #else
263 yylval.dval = atof(buf);
264 #endif
265 return (CONST);
267 return (c);
270 static INTERVAL
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 */
275 INTERVAL v;
277 if (a > b)
279 v.hi = a;
280 v.lo = b;
282 else
284 v.hi = b;
285 v.lo = a;
288 if (c > d)
290 if (c > v.hi)
291 v.hi = c;
292 if (d < v.lo)
293 v.lo = d;
295 else
297 if (d > v.hi)
298 v.hi = d;
299 if (c < v.lo)
300 v.lo = c;
302 return (v);
305 INTERVAL
306 vmul(double a, double b, INTERVAL v)
308 return (hilo(a * v.hi, a * v.lo, b * v.hi, b * v.lo));
312 dcheck(INTERVAL v)
314 if (v.hi >= 0. && v.lo <= 0.)
316 printf("divisor interval contains 0.\n");
317 return (1);
319 return (0);
322 INTERVAL
323 vdiv(double a, double b, INTERVAL v)
325 return (hilo(a / v.hi, a / v.lo, b / v.hi, b / v.lo));