xref: /reactos/dll/win32/jscript/cc_parser.y (revision c2c66aff)
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 
23 %}
24 
25 %lex-param { parser_ctx_t *ctx }
26 %parse-param { parser_ctx_t *ctx }
27 %pure-parser
28 %start CCExpr
29 
30 %union {
31     ccval_t ccval;
32 }
33 
34 %token tEQ tEQEQ tNEQ tNEQEQ tLSHIFT tRSHIFT tRRSHIFT tOR tAND tLEQ tGEQ
35 %token <ccval> tCCValue
36 
37 %type <ccval> CCUnaryExpression CCLogicalORExpression CCLogicalANDExpression
38 %type <ccval> CCBitwiseORExpression CCBitwiseXORExpression CCBitwiseANDExpression
39 %type <ccval> CCEqualityExpression CCRelationalExpression CCShiftExpression CCAdditiveExpression CCMultiplicativeExpression
40 
41 %{
42 
43 static int cc_parser_error(parser_ctx_t *ctx, const char *str)
44 {
45     if(SUCCEEDED(ctx->hres)) {
46         WARN("%s\n", str);
47         ctx->hres = JS_E_SYNTAX;
48     }
49 
50     return 0;
51 }
52 
53 static int cc_parser_lex(void *lval, parser_ctx_t *ctx)
54 {
55     int r;
56 
57     r = try_parse_ccval(ctx, lval);
58     if(r)
59         return r > 0 ? tCCValue : -1;
60 
61     switch(*ctx->ptr) {
62     case '(':
63     case ')':
64     case '+':
65     case '-':
66     case '*':
67     case '/':
68     case '~':
69     case '%':
70     case '^':
71         return *ctx->ptr++;
72     case '=':
73          if(*++ctx->ptr == '=') {
74              if(*++ctx->ptr == '=') {
75                  ctx->ptr++;
76                  return tEQEQ;
77              }
78              return tEQ;
79          }
80          break;
81     case '!':
82         if(*++ctx->ptr == '=') {
83             if(*++ctx->ptr == '=') {
84                 ctx->ptr++;
85                 return tNEQEQ;
86             }
87             return tNEQ;
88         }
89         return '!';
90     case '<':
91         switch(*++ctx->ptr) {
92         case '<':
93             ctx->ptr++;
94             return tLSHIFT;
95         case '=':
96             ctx->ptr++;
97             return tLEQ;
98         default:
99             return '<';
100         }
101     case '>':
102         switch(*++ctx->ptr) {
103         case '>':
104             if(*++ctx->ptr == '>') {
105                 ctx->ptr++;
106                 return tRRSHIFT;
107             }
108             return tRSHIFT;
109         case '=':
110             ctx->ptr++;
111             return tGEQ;
112         default:
113             return '>';
114         }
115     case '|':
116         if(*++ctx->ptr == '|') {
117             ctx->ptr++;
118             return tOR;
119         }
120         return '|';
121     case '&':
122         if(*++ctx->ptr == '&') {
123             ctx->ptr++;
124             return tAND;
125         }
126         return '&';
127     }
128 
129     WARN("Failed to interpret %s\n", debugstr_w(ctx->ptr));
130     return -1;
131 }
132 
133 %}
134 
135 %%
136 
137 /* FIXME: Implement missing expressions. */
138 
139 CCExpr
140     : CCUnaryExpression { ctx->ccval = $1; YYACCEPT; }
141 
142 CCUnaryExpression
143     : tCCValue                      { $$ = $1; }
144     | '(' CCLogicalORExpression ')' { $$ = $2; }
145     | '!' CCUnaryExpression         { $$ = ccval_bool(!get_ccbool($2)); };
146     | '~' CCUnaryExpression         { FIXME("'~' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
147     | '+' CCUnaryExpression         { FIXME("'+' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
148     | '-' CCUnaryExpression         { FIXME("'-' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
149 
150 CCLogicalORExpression
151     : CCLogicalANDExpression        { $$ = $1; }
152     | CCLogicalORExpression tOR CCLogicalANDExpression
153                                     { FIXME("'||' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
154 
155 CCLogicalANDExpression
156     : CCBitwiseORExpression         { $$ = $1; }
157     | CCBitwiseANDExpression tAND CCBitwiseORExpression
158                                     { FIXME("'&&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
159 
160 CCBitwiseORExpression
161     : CCBitwiseXORExpression        { $$ = $1; }
162     | CCBitwiseORExpression '|' CCBitwiseXORExpression
163                                     { FIXME("'|' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
164 
165 CCBitwiseXORExpression
166     : CCBitwiseANDExpression        { $$ = $1; }
167     | CCBitwiseXORExpression '^' CCBitwiseANDExpression
168                                     { FIXME("'^' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
169 
170 CCBitwiseANDExpression
171     : CCEqualityExpression          { $$ = $1; }
172     | CCBitwiseANDExpression '&' CCEqualityExpression
173                                     { FIXME("'&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
174 
175 CCEqualityExpression
176     : CCRelationalExpression        { $$ = $1; }
177     | CCEqualityExpression tEQ CCRelationalExpression
178                                     { $$ = ccval_bool(get_ccnum($1) == get_ccnum($3)); }
179     | CCEqualityExpression tNEQ CCRelationalExpression
180                                     { $$ = ccval_bool(get_ccnum($1) != get_ccnum($3)); }
181     | CCEqualityExpression tEQEQ CCRelationalExpression
182                                     { FIXME("'===' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
183     | CCEqualityExpression tNEQEQ CCRelationalExpression
184                                     { FIXME("'!==' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
185 
186 CCRelationalExpression
187     : CCShiftExpression             { $$ = $1; }
188     | CCRelationalExpression '<' CCShiftExpression
189                                     { $$ = ccval_bool(get_ccnum($1) < get_ccnum($3)); }
190     | CCRelationalExpression tLEQ CCShiftExpression
191                                     { $$ = ccval_bool(get_ccnum($1) <= get_ccnum($3)); }
192     | CCRelationalExpression '>' CCShiftExpression
193                                     { $$ = ccval_bool(get_ccnum($1) > get_ccnum($3)); }
194     | CCRelationalExpression tGEQ CCShiftExpression
195                                     { $$ = ccval_bool(get_ccnum($1) >= get_ccnum($3)); }
196 
197 CCShiftExpression
198     : CCAdditiveExpression          { $$ = $1; }
199     | CCShiftExpression tLSHIFT CCAdditiveExpression
200                                     { FIXME("'<<' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
201     | CCShiftExpression tRSHIFT CCAdditiveExpression
202                                     { FIXME("'>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
203     | CCShiftExpression tRRSHIFT CCAdditiveExpression
204                                     { FIXME("'>>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
205 
206 CCAdditiveExpression
207     : CCMultiplicativeExpression    { $$ = $1; }
208     | CCAdditiveExpression '+' CCMultiplicativeExpression
209                                     { $$ = ccval_num(get_ccnum($1) + get_ccnum($3)); }
210     | CCAdditiveExpression '-' CCMultiplicativeExpression
211                                     { $$ = ccval_num(get_ccnum($1) - get_ccnum($3)); }
212 
213 CCMultiplicativeExpression
214     : CCUnaryExpression             { $$ = $1; }
215     | CCMultiplicativeExpression '*' CCUnaryExpression
216                                     { $$ = ccval_num(get_ccnum($1) * get_ccnum($3)); }
217     | CCMultiplicativeExpression '/' CCUnaryExpression
218                                     { $$ = ccval_num(get_ccnum($1) / get_ccnum($3)); }
219     | CCMultiplicativeExpression '%' CCUnaryExpression
220                                     { FIXME("'%%' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; }
221 
222 %%
223 
224 BOOL parse_cc_expr(parser_ctx_t *ctx)
225 {
226     ctx->hres = S_OK;
227     cc_parser_parse(ctx);
228     return SUCCEEDED(ctx->hres);
229 }
230