xref: /reactos/dll/win32/jscript/cc_parser.y (revision 3e1f4074)
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 
27 WINE_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 
49 static 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 
59 static 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 
145 CCExpr
146     : CCUnaryExpression { ctx->ccval = $1; YYACCEPT; }
147 
148 CCUnaryExpression
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 
156 CCLogicalORExpression
157     : CCLogicalANDExpression        { $$ = $1; }
158     | CCLogicalORExpression tOR CCLogicalANDExpression
159                                     { FIXME("'||' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
160 
161 CCLogicalANDExpression
162     : CCBitwiseORExpression         { $$ = $1; }
163     | CCBitwiseANDExpression tAND CCBitwiseORExpression
164                                     { FIXME("'&&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
165 
166 CCBitwiseORExpression
167     : CCBitwiseXORExpression        { $$ = $1; }
168     | CCBitwiseORExpression '|' CCBitwiseXORExpression
169                                     { FIXME("'|' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
170 
171 CCBitwiseXORExpression
172     : CCBitwiseANDExpression        { $$ = $1; }
173     | CCBitwiseXORExpression '^' CCBitwiseANDExpression
174                                     { FIXME("'^' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
175 
176 CCBitwiseANDExpression
177     : CCEqualityExpression          { $$ = $1; }
178     | CCBitwiseANDExpression '&' CCEqualityExpression
179                                     { FIXME("'&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
180 
181 CCEqualityExpression
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 
192 CCRelationalExpression
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 
203 CCShiftExpression
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 
212 CCAdditiveExpression
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 
219 CCMultiplicativeExpression
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 
230 BOOL parse_cc_expr(parser_ctx_t *ctx)
231 {
232     ctx->hres = S_OK;
233     cc_parser_parse(ctx);
234     return SUCCEEDED(ctx->hres);
235 }
236