1 /* Id: cpy.y,v 1.18 2010/02/25 15:49:00 ragge Exp */ 2 /* $NetBSD: cpy.y,v 1.1.1.3 2010/06/03 18:57: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 67 #include "cpp.h" 68 69 void yyerror(const char *); 70 int yylex(void); 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 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