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