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
yylex(void)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
peek(int c,int r1,int r2)153 peek(int c, int r1, int r2)
154 {
155 if (*++pe != c)
156 return (r2);
157 ++pe;
158 return (r1);
159 }
160
161 /*ARGSUSED*/
162 static void
yyerror(YYCONST char * msg)163 yyerror(YYCONST char *msg)
164 {
165 }
166