1 /* Id: cpy.y,v 1.21 2014/05/28 08:52:42 plunky Exp */
2 /* $NetBSD: cpy.y,v 1.1.1.4 2014/07/24 19:22:35 plunky Exp $ */
3
4 /*
5 * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /*
32 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
36 * are met:
37 *
38 * Redistributions of source code and documentation must retain the above
39 * copyright notice, this list of conditions and the following disclaimer.
40 * Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed or owned by Caldera
46 * International, Inc.
47 * Neither the name of Caldera International, Inc. nor the names of other
48 * contributors may be used to endorse or promote products derived from
49 * this software without specific prior written permission.
50 *
51 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
52 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
56 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
60 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
61 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
63 */
64
65 %{
66 #include "config.h"
67
68 #include "cpp.h"
69
70 void yyerror(const char *);
71 int setd(int l, int r);
72
73 #define EVALUNARY(tok, l, r) l.nd_val = tok r.nd_val; l.op = r.op
74 #define EVALBIN(tok, d, l, r) \
75 d.op = setd(l.op, r.op); d.nd_val = l.nd_val tok r.nd_val
76 #define EVALUBIN(tok, d, l, r, t) \
77 d.op = setd(l.op, r.op); \
78 if (d.op == NUMBER) d.nd_val = l.nd_val tok r.nd_val; \
79 else d.nd_uval = l.nd_uval tok r.nd_uval; \
80 if (t && d.op) d.op = NUMBER
81 #define XEVALUBIN(tok, d, l, r) \
82 if (r.nd_val) { EVALUBIN(tok, d, l, r, 0); } else d.op = 0
83 %}
84
85 %term stop
86 %term EQ NE LE GE LS RS
87 %term ANDAND OROR IDENT NUMBER UNUMBER DEFINED
88 /*
89 * The following terminals are not used in the yacc code.
90 */
91 %term STRING WSPACE CMNT
92
93 %left ','
94 %right '?' ':'
95 %left OROR
96 %left ANDAND
97 %left '|' '^'
98 %left '&'
99 %binary EQ NE
100 %binary '<' '>' LE GE
101 %left LS RS
102 %left '+' '-'
103 %left '*' '/' '%'
104 %right '!' '~' UMINUS
105 %left '('
106
107 %union {
108 struct nd node;
109 }
110
111 %type <node> term e NUMBER UNUMBER
112
113 %%
114 S: e '\n' {
115 if ($1.op == 0)
116 error("division by zero");
117 return $1.nd_val;
118 }
119
120 e: e '*' e
121 { EVALUBIN(*, $$, $1, $3, 0); }
122 | e '/' e
123 { XEVALUBIN(/, $$, $1, $3); }
124 | e '%' e
125 { XEVALUBIN(%, $$, $1, $3); }
126 | e '+' e
127 { EVALBIN(+, $$, $1, $3); }
128 | e '-' e
129 { EVALBIN(-, $$, $1, $3); }
130 | e LS e
131 { EVALBIN(<<, $$, $1, $3); }
132 | e RS e
133 { EVALUBIN(>>, $$, $1, $3, 0); }
134 | e '<' e
135 { EVALUBIN(<, $$, $1, $3, 1); }
136 | e '>' e
137 { EVALUBIN(>, $$, $1, $3, 1); }
138 | e LE e
139 { EVALUBIN(<=, $$, $1, $3, 1); }
140 | e GE e
141 { EVALUBIN(>=, $$, $1, $3, 1); }
142 | e EQ e
143 { EVALUBIN(==, $$, $1, $3, 1); }
144 | e NE e
145 { EVALUBIN(!=, $$, $1, $3, 1); }
146 | e '&' e
147 { EVALBIN(&, $$, $1, $3); }
148 | e '^' e
149 { EVALBIN(^, $$, $1, $3); }
150 | e '|' e
151 { EVALBIN(|, $$, $1, $3); }
152 | e ANDAND e {
153 $$ = $1;
154 if ($1.nd_val) {
155 $$.op = setd($1.op, $3.op);
156 $$.nd_val = ($3.nd_val != 0);
157 }
158 if ($$.op == UNUMBER) $$.op = NUMBER;
159 }
160 | e OROR e {
161 if ($1.nd_val != 0) {
162 $$.nd_val = ($1.nd_val != 0);
163 $$.op = $1.op;
164 } else {
165 $$.nd_val = ($3.nd_val != 0);
166 $$.op = setd($1.op, $3.op);
167 }
168 if ($$.op == UNUMBER) $$.op = NUMBER;
169 }
170 | e '?' e ':' e {
171 if ($1.op == 0)
172 $$ = $1;
173 else if ($1.nd_val)
174 $$ = $3;
175 else
176 $$ = $5;
177 }
178 | e ',' e {
179 $$.op = setd($1.op, $3.op);
180 $$.nd_val = $3.nd_val;
181 if ($$.op) $$.op = $3.op;
182 }
183 | term
184 {$$ = $1;}
185 term:
186 '-' term %prec UMINUS
187 { EVALUNARY(-, $$, $2); }
188 | '+' term %prec UMINUS
189 {$$ = $2;}
190 | '!' term
191 { $$.nd_val = ! $2.nd_val; $$.op = $2.op ? NUMBER : 0; }
192 | '~' term
193 { EVALUNARY(~, $$, $2); }
194 | '(' e ')'
195 {$$ = $2;}
196 | DEFINED '(' NUMBER ')'
197 {$$= $3;}
198 | DEFINED NUMBER
199 {$$ = $2;}
200 | NUMBER
201 {$$ = $1;}
202 %%
203
204 void
205 yyerror(const char *err)
206 {
207 error(err);
208 }
209
210 /*
211 * Set return type of an expression.
212 */
213 int
setd(int l,int r)214 setd(int l, int r)
215 {
216 if (!l || !r)
217 return 0; /* div by zero involved */
218 if (l == UNUMBER || r == UNUMBER)
219 return UNUMBER;
220 return NUMBER;
221 }
222
223