1 %{ 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License, Version 1.0 only 7 * (the "License"). You may not use this file except in compliance 8 * with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 */ 23 %} 24 25 /* 26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 /* Copyright (c) 1988 AT&T */ 31 /* All Rights Reserved */ 32 33 %{ 34 #pragma ident "%Z%%M% %I% %E% SMI" 35 extern long evalval; 36 #define YYSTYPE long 37 %} 38 39 %term DIGITS 40 %left OROR 41 %left ANDAND 42 %left '|' 43 %left '^' 44 %left '&' 45 %nonassoc EQ NE 46 %nonassoc LE GE LT GT 47 %left LSHIFT RSHIFT 48 %left '+' '-' 49 %left '*' '/' '%' 50 %right POWER 51 %right '!' '~' UMINUS 52 %% 53 54 s : e = { evalval = $1; } 55 | = { evalval = 0; } 56 ; 57 58 e : e OROR e = { $$ = ($1 != 0 || $3 != 0) ? 1 : 0; } 59 | e ANDAND e = { $$ = ($1 != 0 && $3 != 0) ? 1 : 0; } 60 | '!' e = { $$ = $2 == 0; } 61 | '~' e = { $$ = ~$2; } 62 | e EQ e = { $$ = $1 == $3; } 63 | e NE e = { $$ = $1 != $3; } 64 | e GT e = { $$ = $1 > $3; } 65 | e GE e = { $$ = $1 >= $3; } 66 | e LT e = { $$ = $1 < $3; } 67 | e LE e = { $$ = $1 <= $3; } 68 | e LSHIFT e = { $$ = $1 << $3; } 69 | e RSHIFT e = { $$ = $1 >> $3; } 70 | e '|' e = { $$ = ($1 | $3); } 71 | e '&' e = { $$ = ($1 & $3); } 72 | e '^' e = { $$ = ($1 ^ $3); } 73 | e '+' e = { $$ = ($1 + $3); } 74 | e '-' e = { $$ = ($1 - $3); } 75 | e '*' e = { $$ = ($1 * $3); } 76 | e '/' e = { $$ = ($1 / $3); } 77 | e '%' e = { $$ = ($1 % $3); } 78 | '(' e ')' = { $$ = ($2); } 79 | e POWER e = { for ($$ = 1; $3-- > 0; $$ *= $1); } 80 | '-' e %prec UMINUS = { $$ = $2-1; $$ = -$2; } 81 | '+' e %prec UMINUS = { $$ = $2-1; $$ = $2; } 82 | DIGITS = { $$ = evalval; } 83 ; 84 85 %% 86 87 #include "m4.h" 88 extern wchar_t *pe; 89 90 static int peek(char c, int r1, int r2); 91 static int peek3(char c1, int rc1, char c2, int rc2, int rc3); 92 93 int 94 yylex(void) 95 { 96 while (*pe == ' ' || *pe == '\t' || *pe == '\n') 97 pe++; 98 switch (*pe) { 99 case '\0': 100 case '+': 101 case '-': 102 case '/': 103 case '%': 104 case '^': 105 case '~': 106 case '(': 107 case ')': 108 return (*pe++); 109 case '*': 110 return (peek('*', POWER, '*')); 111 case '>': 112 return (peek3('=', GE, '>', RSHIFT, GT)); 113 case '<': 114 return (peek3('=', LE, '<', LSHIFT, LT)); 115 case '=': 116 return (peek('=', EQ, EQ)); 117 case '|': 118 return (peek('|', OROR, '|')); 119 case '&': 120 return (peek('&', ANDAND, '&')); 121 case '!': 122 return (peek('=', NE, '!')); 123 default: { 124 int base; 125 126 evalval = 0; 127 128 if (*pe == '0') { 129 if (*++pe == 'x' || *pe == 'X') { 130 base = 16; 131 ++pe; 132 } else 133 base = 8; 134 } else 135 base = 10; 136 137 for (;;) { 138 int c, dig; 139 140 c = *pe; 141 142 if (is_digit(c)) 143 dig = c - '0'; 144 else if (c >= 'a' && c <= 'f') 145 dig = c - 'a' + 10; 146 else if (c >= 'A' && c <= 'F') 147 dig = c - 'A' + 10; 148 else 149 break; 150 151 evalval = evalval*base + dig; 152 ++pe; 153 } 154 return (DIGITS); 155 } 156 } 157 } 158 159 static int 160 peek(char c, int r1, int r2) 161 { 162 if (*++pe != c) 163 return (r2); 164 ++pe; 165 return (r1); 166 } 167 168 static int 169 peek3(char c1, int rc1, char c2, int rc2, int rc3) 170 { 171 ++pe; 172 if (*pe == c1) { 173 ++pe; 174 return (rc1); 175 } 176 if (*pe == c2) { 177 ++pe; 178 return (rc2); 179 } 180 return (rc3); 181 } 182 183 /*ARGSUSED*/ 184 static void 185 yyerror(YYCONST char *msg) 186 { 187 } 188