Reactos
1/*
2 * Copyright 2014 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19%{
20
21#include "jscript.h"
22#include "engine.h"
23#include "parser.h"
24
25#include "wine/debug.h"
26
27WINE_DEFAULT_DEBUG_CHANNEL(jscript);
28
29%}
30
31%lex-param { parser_ctx_t *ctx }
32%parse-param { parser_ctx_t *ctx }
33%define api.pure
34%start CCExpr
35
36%union {
37 ccval_t ccval;
38}
39
40%token tEQ tEQEQ tNEQ tNEQEQ tLSHIFT tRSHIFT tRRSHIFT tOR tAND tLEQ tGEQ
41%token <ccval> tCCValue
42
43%type <ccval> CCUnaryExpression CCLogicalORExpression CCLogicalANDExpression
44%type <ccval> CCBitwiseORExpression CCBitwiseXORExpression CCBitwiseANDExpression
45%type <ccval> CCEqualityExpression CCRelationalExpression CCShiftExpression CCAdditiveExpression CCMultiplicativeExpression
46
47%{
48
49static int cc_parser_error(parser_ctx_t *ctx, const char *str)
50{
51 if(SUCCEEDED(ctx->hres)) {
52 WARN("%s\n", str);
53 ctx->hres = JS_E_SYNTAX;
54 }
55
56 return 0;
57}
58
59static int cc_parser_lex(void *lval, parser_ctx_t *ctx)
60{
61 int r;
62
63 r = try_parse_ccval(ctx, lval);
64 if(r)
65 return r > 0 ? tCCValue : -1;
66
67 switch(*ctx->ptr) {
68 case '(':
69 case ')':
70 case '+':
71 case '-':
72 case '*':
73 case '/':
74 case '~':
75 case '%':
76 case '^':
77 return *ctx->ptr++;
78 case '=':
79 if(*++ctx->ptr == '=') {
80 if(*++ctx->ptr == '=') {
81 ctx->ptr++;
82 return tEQEQ;
83 }
84 return tEQ;
85 }
86 break;
87 case '!':
88 if(*++ctx->ptr == '=') {
89 if(*++ctx->ptr == '=') {
90 ctx->ptr++;
91 return tNEQEQ;
92 }
93 return tNEQ;
94 }
95 return '!';
96 case '<':
97 switch(*++ctx->ptr) {
98 case '<':
99 ctx->ptr++;
100 return tLSHIFT;
101 case '=':
102 ctx->ptr++;
103 return tLEQ;
104 default:
105 return '<';
106 }
107 case '>':
108 switch(*++ctx->ptr) {
109 case '>':
110 if(*++ctx->ptr == '>') {
111 ctx->ptr++;
112 return tRRSHIFT;
113 }
114 return tRSHIFT;
115 case '=':
116 ctx->ptr++;
117 return tGEQ;
118 default:
119 return '>';
120 }
121 case '|':
122 if(*++ctx->ptr == '|') {
123 ctx->ptr++;
124 return tOR;
125 }
126 return '|';
127 case '&':
128 if(*++ctx->ptr == '&') {
129 ctx->ptr++;
130 return tAND;
131 }
132 return '&';
133 }
134
135 WARN("Failed to interpret %s\n", debugstr_w(ctx->ptr));
136 return -1;
137}
138
139%}
140
141%%
142
143/* FIXME: Implement missing expressions. */
144
145CCExpr
146 : CCUnaryExpression { ctx->ccval = $1; YYACCEPT; }
147
148CCUnaryExpression
149 : tCCValue { $$ = $1; }
150 | '(' CCLogicalORExpression ')' { $$ = $2; }
151 | '!' CCUnaryExpression { $$ = ccval_bool(!get_ccbool($2)); };
152 | '~' CCUnaryExpression { FIXME("'~' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
153 | '+' CCUnaryExpression { FIXME("'+' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
154 | '-' CCUnaryExpression { FIXME("'-' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
155
156CCLogicalORExpression
157 : CCLogicalANDExpression { $$ = $1; }
158 | CCLogicalORExpression tOR CCLogicalANDExpression
159 { FIXME("'||' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
160
161CCLogicalANDExpression
162 : CCBitwiseORExpression { $$ = $1; }
163 | CCBitwiseANDExpression tAND CCBitwiseORExpression
164 { FIXME("'&&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
165
166CCBitwiseORExpression
167 : CCBitwiseXORExpression { $$ = $1; }
168 | CCBitwiseORExpression '|' CCBitwiseXORExpression
169 { FIXME("'|' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
170
171CCBitwiseXORExpression
172 : CCBitwiseANDExpression { $$ = $1; }
173 | CCBitwiseXORExpression '^' CCBitwiseANDExpression
174 { FIXME("'^' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
175
176CCBitwiseANDExpression
177 : CCEqualityExpression { $$ = $1; }
178 | CCBitwiseANDExpression '&' CCEqualityExpression
179 { FIXME("'&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
180
181CCEqualityExpression
182 : CCRelationalExpression { $$ = $1; }
183 | CCEqualityExpression tEQ CCRelationalExpression
184 { $$ = ccval_bool(get_ccnum($1) == get_ccnum($3)); }
185 | CCEqualityExpression tNEQ CCRelationalExpression
186 { $$ = ccval_bool(get_ccnum($1) != get_ccnum($3)); }
187 | CCEqualityExpression tEQEQ CCRelationalExpression
188 { FIXME("'===' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
189 | CCEqualityExpression tNEQEQ CCRelationalExpression
190 { FIXME("'!==' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
191
192CCRelationalExpression
193 : CCShiftExpression { $$ = $1; }
194 | CCRelationalExpression '<' CCShiftExpression
195 { $$ = ccval_bool(get_ccnum($1) < get_ccnum($3)); }
196 | CCRelationalExpression tLEQ CCShiftExpression
197 { $$ = ccval_bool(get_ccnum($1) <= get_ccnum($3)); }
198 | CCRelationalExpression '>' CCShiftExpression
199 { $$ = ccval_bool(get_ccnum($1) > get_ccnum($3)); }
200 | CCRelationalExpression tGEQ CCShiftExpression
201 { $$ = ccval_bool(get_ccnum($1) >= get_ccnum($3)); }
202
203CCShiftExpression
204 : CCAdditiveExpression { $$ = $1; }
205 | CCShiftExpression tLSHIFT CCAdditiveExpression
206 { FIXME("'<<' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
207 | CCShiftExpression tRSHIFT CCAdditiveExpression
208 { FIXME("'>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
209 | CCShiftExpression tRRSHIFT CCAdditiveExpression
210 { FIXME("'>>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
211
212CCAdditiveExpression
213 : CCMultiplicativeExpression { $$ = $1; }
214 | CCAdditiveExpression '+' CCMultiplicativeExpression
215 { $$ = ccval_num(get_ccnum($1) + get_ccnum($3)); }
216 | CCAdditiveExpression '-' CCMultiplicativeExpression
217 { $$ = ccval_num(get_ccnum($1) - get_ccnum($3)); }
218
219CCMultiplicativeExpression
220 : CCUnaryExpression { $$ = $1; }
221 | CCMultiplicativeExpression '*' CCUnaryExpression
222 { $$ = ccval_num(get_ccnum($1) * get_ccnum($3)); }
223 | CCMultiplicativeExpression '/' CCUnaryExpression
224 { $$ = ccval_num(get_ccnum($1) / get_ccnum($3)); }
225 | CCMultiplicativeExpression '%' CCUnaryExpression
226 { FIXME("'%%' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
227
228%%
229
230BOOL parse_cc_expr(parser_ctx_t *ctx)
231{
232 ctx->hres = S_OK;
233 cc_parser_parse(ctx);
234 return SUCCEEDED(ctx->hres);
235}