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