xref: /freebsd/contrib/byacc/test/varsyntax_calc1.y (revision 6cec9cad762b6476313fb1f8e931a1647822db6b)
1*0c8de5b0SBaptiste Daroussin %IDENT "check variant syntax features"
2*0c8de5b0SBaptiste Daroussin %{
3*0c8de5b0SBaptiste Daroussin 
4*0c8de5b0SBaptiste Daroussin // http://dinosaur.compilertools.net/yacc/index.html */
5*0c8de5b0SBaptiste Daroussin 
6*0c8de5b0SBaptiste Daroussin #include <stdlib.h>
7*0c8de5b0SBaptiste Daroussin #include <stdio.h>
8*0c8de5b0SBaptiste Daroussin #include <ctype.h>
9*0c8de5b0SBaptiste Daroussin #include <math.h>
10*0c8de5b0SBaptiste Daroussin 
11*0c8de5b0SBaptiste Daroussin typedef struct interval
12*0c8de5b0SBaptiste Daroussin {
13*0c8de5b0SBaptiste Daroussin     double lo, hi;
14*0c8de5b0SBaptiste Daroussin }
15*0c8de5b0SBaptiste Daroussin INTERVAL;
16*0c8de5b0SBaptiste Daroussin 
17*0c8de5b0SBaptiste Daroussin INTERVAL vmul(double, double, INTERVAL);
18*0c8de5b0SBaptiste Daroussin INTERVAL vdiv(double, double, INTERVAL);
19*0c8de5b0SBaptiste Daroussin 
20*0c8de5b0SBaptiste Daroussin extern int yylex(void);
21*0c8de5b0SBaptiste Daroussin static void yyerror(const char *s);
22*0c8de5b0SBaptiste Daroussin 
23*0c8de5b0SBaptiste Daroussin int dcheck(INTERVAL);
24*0c8de5b0SBaptiste Daroussin 
25*0c8de5b0SBaptiste Daroussin double dreg[26];
26*0c8de5b0SBaptiste Daroussin INTERVAL vreg[26];
27*0c8de5b0SBaptiste Daroussin 
28*0c8de5b0SBaptiste Daroussin %}
29*0c8de5b0SBaptiste Daroussin %expect 18
30*0c8de5b0SBaptiste Daroussin 
31*0c8de5b0SBaptiste Daroussin %start line
32*0c8de5b0SBaptiste Daroussin %union
33*0c8de5b0SBaptiste Daroussin {
34*0c8de5b0SBaptiste Daroussin 	int ival;	// dreg & vreg array index values
35*0c8de5b0SBaptiste Daroussin 	double dval;	// floating point values
36*0c8de5b0SBaptiste Daroussin 	INTERVAL vval;	// interval values
37*0c8de5b0SBaptiste Daroussin }
38*0c8de5b0SBaptiste Daroussin 
39*0c8de5b0SBaptiste Daroussin %token <ival> DREG VREG		// indices into dreg, vreg arrays */
40*0c8de5b0SBaptiste Daroussin %token <dval> CONST		// floating point constant */
41*0c8de5b0SBaptiste Daroussin 
42*0c8de5b0SBaptiste Daroussin %type <dval> dexp		// expression */
43*0c8de5b0SBaptiste Daroussin %type <vval> vexp		// interval expression */
44*0c8de5b0SBaptiste Daroussin 
45*0c8de5b0SBaptiste Daroussin 	// precedence information about the operators */
46*0c8de5b0SBaptiste Daroussin 
47*0c8de5b0SBaptiste Daroussin %< '+' '-'			// %< is an obsolete synonym for %left
48*0c8de5b0SBaptiste Daroussin %< '*' '/'
49*0c8de5b0SBaptiste Daroussin %> UMINUS			// precedence for unary minus;
50*0c8de5b0SBaptiste Daroussin 				// %> is an obsolete synonym for %right
51*0c8de5b0SBaptiste Daroussin 
52*0c8de5b0SBaptiste Daroussin \\	// beginning of rules section; \\ is an obsolete synonym for %%
53*0c8de5b0SBaptiste Daroussin 
54*0c8de5b0SBaptiste Daroussin lines   : // empty */
55*0c8de5b0SBaptiste Daroussin 	| lines line
56*0c8de5b0SBaptiste Daroussin 	;
57*0c8de5b0SBaptiste Daroussin 
58*0c8de5b0SBaptiste Daroussin line	: dexp '\n'
59*0c8de5b0SBaptiste Daroussin 	{
60*0c8de5b0SBaptiste Daroussin 		(void) printf("%15.8f\n", $1);
61*0c8de5b0SBaptiste Daroussin 	}
62*0c8de5b0SBaptiste Daroussin 	| vexp '\n'
63*0c8de5b0SBaptiste Daroussin 	{
64*0c8de5b0SBaptiste Daroussin 		(void) printf("(%15.8f, %15.8f)\n", $1.lo, $1.hi);
65*0c8de5b0SBaptiste Daroussin 	}
66*0c8de5b0SBaptiste Daroussin 	| DREG '=' dexp '\n'
67*0c8de5b0SBaptiste Daroussin 	{
68*0c8de5b0SBaptiste Daroussin 		dreg[$1] = $3;
69*0c8de5b0SBaptiste Daroussin 	}
70*0c8de5b0SBaptiste Daroussin 	| VREG '=' vexp '\n'
71*0c8de5b0SBaptiste Daroussin 	{
72*0c8de5b0SBaptiste Daroussin 		vreg[$1] = $3;
73*0c8de5b0SBaptiste Daroussin 	}
74*0c8de5b0SBaptiste Daroussin 	| error '\n'
75*0c8de5b0SBaptiste Daroussin 	{
76*0c8de5b0SBaptiste Daroussin 		yyerrok;
77*0c8de5b0SBaptiste Daroussin 	}
78*0c8de5b0SBaptiste Daroussin 	;
79*0c8de5b0SBaptiste Daroussin 
80*0c8de5b0SBaptiste Daroussin dexp	: CONST
81*0c8de5b0SBaptiste Daroussin 	| DREG
82*0c8de5b0SBaptiste Daroussin 	{
83*0c8de5b0SBaptiste Daroussin 		$<dval>$ = dreg[$<ival>1]; // $$ & $1 are sufficient here
84*0c8de5b0SBaptiste Daroussin 	}
85*0c8de5b0SBaptiste Daroussin 	| dexp '+' dexp
86*0c8de5b0SBaptiste Daroussin 	{
87*0c8de5b0SBaptiste Daroussin 		$$ = $1 + $3;
88*0c8de5b0SBaptiste Daroussin 	}
89*0c8de5b0SBaptiste Daroussin 	| dexp '-' dexp
90*0c8de5b0SBaptiste Daroussin 	{
91*0c8de5b0SBaptiste Daroussin 		$$ = $1 - $3;
92*0c8de5b0SBaptiste Daroussin 	}
93*0c8de5b0SBaptiste Daroussin 	| dexp '*' dexp
94*0c8de5b0SBaptiste Daroussin 	{
95*0c8de5b0SBaptiste Daroussin 		$$ = $1 * $3;
96*0c8de5b0SBaptiste Daroussin 	}
97*0c8de5b0SBaptiste Daroussin 	| dexp '/' dexp
98*0c8de5b0SBaptiste Daroussin 	{
99*0c8de5b0SBaptiste Daroussin 		$$ = $1 / $3;
100*0c8de5b0SBaptiste Daroussin 	}
101*0c8de5b0SBaptiste Daroussin 	| '-' dexp %prec UMINUS
102*0c8de5b0SBaptiste Daroussin 	{
103*0c8de5b0SBaptiste Daroussin 		$$ = -$2;
104*0c8de5b0SBaptiste Daroussin 	}
105*0c8de5b0SBaptiste Daroussin 	| '(' dexp ')'
106*0c8de5b0SBaptiste Daroussin 	{
107*0c8de5b0SBaptiste Daroussin 		$$ = $2;
108*0c8de5b0SBaptiste Daroussin 	}
109*0c8de5b0SBaptiste Daroussin 	;
110*0c8de5b0SBaptiste Daroussin 
111*0c8de5b0SBaptiste Daroussin vexp	: dexp
112*0c8de5b0SBaptiste Daroussin 	{
113*0c8de5b0SBaptiste Daroussin 		$$.hi = $$.lo = $1;
114*0c8de5b0SBaptiste Daroussin 	}
115*0c8de5b0SBaptiste Daroussin 	| '(' dexp ',' dexp ')'
116*0c8de5b0SBaptiste Daroussin 	{
117*0c8de5b0SBaptiste Daroussin 		$$.lo = $2;
118*0c8de5b0SBaptiste Daroussin 		$$.hi = $4;
119*0c8de5b0SBaptiste Daroussin 		if ( $$.lo > $$.hi )
120*0c8de5b0SBaptiste Daroussin 		{
121*0c8de5b0SBaptiste Daroussin 			(void) printf("interval out of order\n");
122*0c8de5b0SBaptiste Daroussin 			YYERROR;
123*0c8de5b0SBaptiste Daroussin 		}
124*0c8de5b0SBaptiste Daroussin 	}
125*0c8de5b0SBaptiste Daroussin 	| VREG
126*0c8de5b0SBaptiste Daroussin 	{
127*0c8de5b0SBaptiste Daroussin 		$$ = vreg[$1];
128*0c8de5b0SBaptiste Daroussin 	}
129*0c8de5b0SBaptiste Daroussin 	| vexp '+' vexp
130*0c8de5b0SBaptiste Daroussin 	{
131*0c8de5b0SBaptiste Daroussin 		$$.hi = $1.hi + $3.hi;
132*0c8de5b0SBaptiste Daroussin 		$$.lo = $1.lo + $3.lo;
133*0c8de5b0SBaptiste Daroussin 	}
134*0c8de5b0SBaptiste Daroussin 	| dexp '+' vexp
135*0c8de5b0SBaptiste Daroussin 	{
136*0c8de5b0SBaptiste Daroussin 		$$.hi = $1 + $3.hi;
137*0c8de5b0SBaptiste Daroussin 		$$.lo = $1 + $3.lo;
138*0c8de5b0SBaptiste Daroussin 	}
139*0c8de5b0SBaptiste Daroussin 	| vexp '-' vexp
140*0c8de5b0SBaptiste Daroussin 	{
141*0c8de5b0SBaptiste Daroussin 		$$.hi = $1.hi - $3.lo;
142*0c8de5b0SBaptiste Daroussin 		$$.lo = $1.lo - $3.hi;
143*0c8de5b0SBaptiste Daroussin 	}
144*0c8de5b0SBaptiste Daroussin 	| dexp '-' vexp
145*0c8de5b0SBaptiste Daroussin 	{
146*0c8de5b0SBaptiste Daroussin 		$$.hi = $1 - $3.lo;
147*0c8de5b0SBaptiste Daroussin 		$$.lo = $1 - $3.hi;
148*0c8de5b0SBaptiste Daroussin 	}
149*0c8de5b0SBaptiste Daroussin 	| vexp '*' vexp
150*0c8de5b0SBaptiste Daroussin 	{
151*0c8de5b0SBaptiste Daroussin 		$$ = vmul( $1.lo, $1.hi, $3 );
152*0c8de5b0SBaptiste Daroussin 	}
153*0c8de5b0SBaptiste Daroussin 	| dexp '*' vexp
154*0c8de5b0SBaptiste Daroussin 	{
155*0c8de5b0SBaptiste Daroussin 		$$ = vmul ($1, $1, $3 );
156*0c8de5b0SBaptiste Daroussin 	}
157*0c8de5b0SBaptiste Daroussin 	| vexp '/' vexp
158*0c8de5b0SBaptiste Daroussin 	{
159*0c8de5b0SBaptiste Daroussin 		if (dcheck($3)) YYERROR;
160*0c8de5b0SBaptiste Daroussin 		$$ = vdiv ( $1.lo, $1.hi, $3 );
161*0c8de5b0SBaptiste Daroussin 	}
162*0c8de5b0SBaptiste Daroussin 	| dexp '/' vexp
163*0c8de5b0SBaptiste Daroussin 	{
164*0c8de5b0SBaptiste Daroussin 		if (dcheck ( $3 )) YYERROR;
165*0c8de5b0SBaptiste Daroussin 		$$ = vdiv ($1, $1, $3 );
166*0c8de5b0SBaptiste Daroussin 	}
167*0c8de5b0SBaptiste Daroussin 	| '-' vexp %prec UMINUS
168*0c8de5b0SBaptiste Daroussin 	{
169*0c8de5b0SBaptiste Daroussin 		$$.hi = -$2.lo;
170*0c8de5b0SBaptiste Daroussin 		$$.lo = -$2.hi;
171*0c8de5b0SBaptiste Daroussin 	}
172*0c8de5b0SBaptiste Daroussin 	| '(' vexp ')'
173*0c8de5b0SBaptiste Daroussin 	{
174*0c8de5b0SBaptiste Daroussin 		$$ = $2;
175*0c8de5b0SBaptiste Daroussin 	}
176*0c8de5b0SBaptiste Daroussin 	;
177*0c8de5b0SBaptiste Daroussin 
178*0c8de5b0SBaptiste Daroussin \\	/* beginning of subroutines section */
179*0c8de5b0SBaptiste Daroussin 
180*0c8de5b0SBaptiste Daroussin #define BSZ 50			/* buffer size for floating point numbers */
181*0c8de5b0SBaptiste Daroussin 
182*0c8de5b0SBaptiste Daroussin 	/* lexical analysis */
183*0c8de5b0SBaptiste Daroussin 
184*0c8de5b0SBaptiste Daroussin static void
185*0c8de5b0SBaptiste Daroussin yyerror(const char *s)
186*0c8de5b0SBaptiste Daroussin {
187*0c8de5b0SBaptiste Daroussin     fprintf(stderr, "%s\n", s);
188*0c8de5b0SBaptiste Daroussin }
189*0c8de5b0SBaptiste Daroussin 
190*0c8de5b0SBaptiste Daroussin int
191*0c8de5b0SBaptiste Daroussin yylex(void)
192*0c8de5b0SBaptiste Daroussin {
193*0c8de5b0SBaptiste Daroussin     int c;
194*0c8de5b0SBaptiste Daroussin 
195*0c8de5b0SBaptiste Daroussin     while ((c = getchar()) == ' ')
196*0c8de5b0SBaptiste Daroussin     {				/* skip over blanks */
197*0c8de5b0SBaptiste Daroussin     }
198*0c8de5b0SBaptiste Daroussin 
199*0c8de5b0SBaptiste Daroussin     if (isupper(c))
200*0c8de5b0SBaptiste Daroussin     {
201*0c8de5b0SBaptiste Daroussin 	yylval.ival = c - 'A';
202*0c8de5b0SBaptiste Daroussin 	return (VREG);
203*0c8de5b0SBaptiste Daroussin     }
204*0c8de5b0SBaptiste Daroussin     if (islower(c))
205*0c8de5b0SBaptiste Daroussin     {
206*0c8de5b0SBaptiste Daroussin 	yylval.ival = c - 'a';
207*0c8de5b0SBaptiste Daroussin 	return (DREG);
208*0c8de5b0SBaptiste Daroussin     }
209*0c8de5b0SBaptiste Daroussin 
210*0c8de5b0SBaptiste Daroussin     if (isdigit(c) || c == '.')
211*0c8de5b0SBaptiste Daroussin     {
212*0c8de5b0SBaptiste Daroussin 	/* gobble up digits, points, exponents */
213*0c8de5b0SBaptiste Daroussin 	char buf[BSZ + 1], *cp = buf;
214*0c8de5b0SBaptiste Daroussin 	int dot = 0, expr = 0;
215*0c8de5b0SBaptiste Daroussin 
216*0c8de5b0SBaptiste Daroussin 	for (; (cp - buf) < BSZ; ++cp, c = getchar())
217*0c8de5b0SBaptiste Daroussin 	{
218*0c8de5b0SBaptiste Daroussin 
219*0c8de5b0SBaptiste Daroussin 	    *cp = (char) c;
220*0c8de5b0SBaptiste Daroussin 	    if (isdigit(c))
221*0c8de5b0SBaptiste Daroussin 		continue;
222*0c8de5b0SBaptiste Daroussin 	    if (c == '.')
223*0c8de5b0SBaptiste Daroussin 	    {
224*0c8de5b0SBaptiste Daroussin 		if (dot++ || expr)
225*0c8de5b0SBaptiste Daroussin 		    return ('.');	/* will cause syntax error */
226*0c8de5b0SBaptiste Daroussin 		continue;
227*0c8de5b0SBaptiste Daroussin 	    }
228*0c8de5b0SBaptiste Daroussin 
229*0c8de5b0SBaptiste Daroussin 	    if (c == 'e')
230*0c8de5b0SBaptiste Daroussin 	    {
231*0c8de5b0SBaptiste Daroussin 		if (expr++)
232*0c8de5b0SBaptiste Daroussin 		    return ('e');	/*  will  cause  syntax  error  */
233*0c8de5b0SBaptiste Daroussin 		continue;
234*0c8de5b0SBaptiste Daroussin 	    }
235*0c8de5b0SBaptiste Daroussin 
236*0c8de5b0SBaptiste Daroussin 	    /*  end  of  number  */
237*0c8de5b0SBaptiste Daroussin 	    break;
238*0c8de5b0SBaptiste Daroussin 	}
239*0c8de5b0SBaptiste Daroussin 	*cp = '\0';
240*0c8de5b0SBaptiste Daroussin 
241*0c8de5b0SBaptiste Daroussin 	if ((cp - buf) >= BSZ)
242*0c8de5b0SBaptiste Daroussin 	    printf("constant  too  long:  truncated\n");
243*0c8de5b0SBaptiste Daroussin 	else
244*0c8de5b0SBaptiste Daroussin 	    ungetc(c, stdin);	/*  push  back  last  char  read  */
245*0c8de5b0SBaptiste Daroussin 	yylval.dval = atof(buf);
246*0c8de5b0SBaptiste Daroussin 	return (CONST);
247*0c8de5b0SBaptiste Daroussin     }
248*0c8de5b0SBaptiste Daroussin     return (c);
249*0c8de5b0SBaptiste Daroussin }
250*0c8de5b0SBaptiste Daroussin 
251*0c8de5b0SBaptiste Daroussin static INTERVAL
252*0c8de5b0SBaptiste Daroussin hilo(double a, double b, double c, double d)
253*0c8de5b0SBaptiste Daroussin {
254*0c8de5b0SBaptiste Daroussin     /*  returns  the  smallest  interval  containing  a,  b,  c,  and  d  */
255*0c8de5b0SBaptiste Daroussin     /*  used  by  *,  /  routines  */
256*0c8de5b0SBaptiste Daroussin     INTERVAL v;
257*0c8de5b0SBaptiste Daroussin 
258*0c8de5b0SBaptiste Daroussin     if (a > b)
259*0c8de5b0SBaptiste Daroussin     {
260*0c8de5b0SBaptiste Daroussin 	v.hi = a;
261*0c8de5b0SBaptiste Daroussin 	v.lo = b;
262*0c8de5b0SBaptiste Daroussin     }
263*0c8de5b0SBaptiste Daroussin     else
264*0c8de5b0SBaptiste Daroussin     {
265*0c8de5b0SBaptiste Daroussin 	v.hi = b;
266*0c8de5b0SBaptiste Daroussin 	v.lo = a;
267*0c8de5b0SBaptiste Daroussin     }
268*0c8de5b0SBaptiste Daroussin 
269*0c8de5b0SBaptiste Daroussin     if (c > d)
270*0c8de5b0SBaptiste Daroussin     {
271*0c8de5b0SBaptiste Daroussin 	if (c > v.hi)
272*0c8de5b0SBaptiste Daroussin 	    v.hi = c;
273*0c8de5b0SBaptiste Daroussin 	if (d < v.lo)
274*0c8de5b0SBaptiste Daroussin 	    v.lo = d;
275*0c8de5b0SBaptiste Daroussin     }
276*0c8de5b0SBaptiste Daroussin     else
277*0c8de5b0SBaptiste Daroussin     {
278*0c8de5b0SBaptiste Daroussin 	if (d > v.hi)
279*0c8de5b0SBaptiste Daroussin 	    v.hi = d;
280*0c8de5b0SBaptiste Daroussin 	if (c < v.lo)
281*0c8de5b0SBaptiste Daroussin 	    v.lo = c;
282*0c8de5b0SBaptiste Daroussin     }
283*0c8de5b0SBaptiste Daroussin     return (v);
284*0c8de5b0SBaptiste Daroussin }
285*0c8de5b0SBaptiste Daroussin 
286*0c8de5b0SBaptiste Daroussin INTERVAL
287*0c8de5b0SBaptiste Daroussin vmul(double a, double b, INTERVAL v)
288*0c8de5b0SBaptiste Daroussin {
289*0c8de5b0SBaptiste Daroussin     return (hilo(a * v.hi, a * v.lo, b * v.hi, b * v.lo));
290*0c8de5b0SBaptiste Daroussin }
291*0c8de5b0SBaptiste Daroussin 
292*0c8de5b0SBaptiste Daroussin int
293*0c8de5b0SBaptiste Daroussin dcheck(INTERVAL v)
294*0c8de5b0SBaptiste Daroussin {
295*0c8de5b0SBaptiste Daroussin     if (v.hi >= 0. && v.lo <= 0.)
296*0c8de5b0SBaptiste Daroussin     {
297*0c8de5b0SBaptiste Daroussin 	printf("divisor  interval  contains  0.\n");
298*0c8de5b0SBaptiste Daroussin 	return (1);
299*0c8de5b0SBaptiste Daroussin     }
300*0c8de5b0SBaptiste Daroussin     return (0);
301*0c8de5b0SBaptiste Daroussin }
302*0c8de5b0SBaptiste Daroussin 
303*0c8de5b0SBaptiste Daroussin INTERVAL
304*0c8de5b0SBaptiste Daroussin vdiv(double a, double b, INTERVAL v)
305*0c8de5b0SBaptiste Daroussin {
306*0c8de5b0SBaptiste Daroussin     return (hilo(a / v.hi, a / v.lo, b / v.hi, b / v.lo));
307*0c8de5b0SBaptiste Daroussin }
308