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