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
yylex(void)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
peek(char c,int r1,int r2)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
peek3(char c1,int rc1,char c2,int rc2,int rc3)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
yyerror(YYCONST char * msg)184 yyerror(YYCONST char *msg)
185 {
186 }
187