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 %pure-parser 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