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 extern long evalval; 35 #define YYSTYPE long 36 %} 37 38 %term DIGITS 39 %left OROR 40 %left ANDAND 41 %left '|' 42 %left '^' 43 %left '&' 44 %nonassoc EQ NE 45 %nonassoc LE GE LT GT 46 %left LSHIFT RSHIFT 47 %left '+' '-' 48 %left '*' '/' '%' 49 %right POWER 50 %right '!' '~' UMINUS 51 %% 52 53 s : e = { evalval = $1; } 54 | = { evalval = 0; } 55 ; 56 57 e : e OROR e = { $$ = ($1 != 0 || $3 != 0) ? 1 : 0; } 58 | e ANDAND e = { $$ = ($1 != 0 && $3 != 0) ? 1 : 0; } 59 | '!' e = { $$ = $2 == 0; } 60 | '~' e = { $$ = ~$2; } 61 | e EQ e = { $$ = $1 == $3; } 62 | e NE e = { $$ = $1 != $3; } 63 | e GT e = { $$ = $1 > $3; } 64 | e GE e = { $$ = $1 >= $3; } 65 | e LT e = { $$ = $1 < $3; } 66 | e LE e = { $$ = $1 <= $3; } 67 | e LSHIFT e = { $$ = $1 << $3; } 68 | e RSHIFT e = { $$ = $1 >> $3; } 69 | e '|' 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 ')' = { $$ = ($2); } 78 | e POWER e = { for ($$ = 1; $3-- > 0; $$ *= $1); } 79 | '-' e %prec UMINUS = { $$ = $2-1; $$ = -$2; } 80 | '+' e %prec UMINUS = { $$ = $2-1; $$ = $2; } 81 | DIGITS = { $$ = evalval; } 82 ; 83 84 %% 85 86 #include "m4.h" 87 extern wchar_t *pe; 88 89 static int peek(char c, int r1, int r2); 90 static int peek3(char c1, int rc1, char c2, int rc2, int rc3); 91 92 int 93 yylex(void) 94 { 95 while (*pe == ' ' || *pe == '\t' || *pe == '\n') 96 pe++; 97 switch (*pe) { 98 case '\0': 99 case '+': 100 case '-': 101 case '/': 102 case '%': 103 case '^': 104 case '~': 105 case '(': 106 case ')': 107 return (*pe++); 108 case '*': 109 return (peek('*', POWER, '*')); 110 case '>': 111 return (peek3('=', GE, '>', RSHIFT, GT)); 112 case '<': 113 return (peek3('=', LE, '<', LSHIFT, LT)); 114 case '=': 115 return (peek('=', EQ, EQ)); 116 case '|': 117 return (peek('|', OROR, '|')); 118 case '&': 119 return (peek('&', ANDAND, '&')); 120 case '!': 121 return (peek('=', NE, '!')); 122 default: { 123 int base; 124 125 evalval = 0; 126 127 if (*pe == '0') { 128 if (*++pe == 'x' || *pe == 'X') { 129 base = 16; 130 ++pe; 131 } else 132 base = 8; 133 } else 134 base = 10; 135 136 for (;;) { 137 int c, dig; 138 139 c = *pe; 140 141 if (is_digit(c)) 142 dig = c - '0'; 143 else if (c >= 'a' && c <= 'f') 144 dig = c - 'a' + 10; 145 else if (c >= 'A' && c <= 'F') 146 dig = c - 'A' + 10; 147 else 148 break; 149 150 evalval = evalval*base + dig; 151 ++pe; 152 } 153 return (DIGITS); 154 } 155 } 156 } 157 158 static int 159 peek(char c, int r1, int r2) 160 { 161 if (*++pe != c) 162 return (r2); 163 ++pe; 164 return (r1); 165 } 166 167 static int 168 peek3(char c1, int rc1, char c2, int rc2, int rc3) 169 { 170 ++pe; 171 if (*pe == c1) { 172 ++pe; 173 return (rc1); 174 } 175 if (*pe == c2) { 176 ++pe; 177 return (rc2); 178 } 179 return (rc3); 180 } 181 182 /*ARGSUSED*/ 183 static void 184 yyerror(YYCONST char *msg) 185 { 186 } 187