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