| /* |
| * Copyright 2014 Jacek Caban for CodeWeavers |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| %{ |
| |
| #include "jscript.h" |
| #include "engine.h" |
| #include "parser.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(jscript); |
| |
| %} |
| |
| %lex-param { parser_ctx_t *ctx } |
| %parse-param { parser_ctx_t *ctx } |
| %pure-parser |
| %start CCExpr |
| |
| %union { |
| ccval_t ccval; |
| } |
| |
| %token tEQ tEQEQ tNEQ tNEQEQ tLSHIFT tRSHIFT tRRSHIFT tOR tAND tLEQ tGEQ |
| %token <ccval> tCCValue |
| |
| %type <ccval> CCUnaryExpression CCLogicalORExpression CCLogicalANDExpression |
| %type <ccval> CCBitwiseORExpression CCBitwiseXORExpression CCBitwiseANDExpression |
| %type <ccval> CCEqualityExpression CCRelationalExpression CCShiftExpression CCAdditiveExpression CCMultiplicativeExpression |
| |
| %{ |
| |
| static int cc_parser_error(parser_ctx_t *ctx, const char *str) |
| { |
| if(SUCCEEDED(ctx->hres)) { |
| WARN("%s\n", str); |
| ctx->hres = JS_E_SYNTAX; |
| } |
| |
| return 0; |
| } |
| |
| static int cc_parser_lex(void *lval, parser_ctx_t *ctx) |
| { |
| int r; |
| |
| r = try_parse_ccval(ctx, lval); |
| if(r) |
| return r > 0 ? tCCValue : -1; |
| |
| switch(*ctx->ptr) { |
| case '(': |
| case ')': |
| case '+': |
| case '-': |
| case '*': |
| case '/': |
| case '~': |
| case '%': |
| case '^': |
| return *ctx->ptr++; |
| case '=': |
| if(*++ctx->ptr == '=') { |
| if(*++ctx->ptr == '=') { |
| ctx->ptr++; |
| return tEQEQ; |
| } |
| return tEQ; |
| } |
| break; |
| case '!': |
| if(*++ctx->ptr == '=') { |
| if(*++ctx->ptr == '=') { |
| ctx->ptr++; |
| return tNEQEQ; |
| } |
| return tNEQ; |
| } |
| return '!'; |
| case '<': |
| switch(*++ctx->ptr) { |
| case '<': |
| ctx->ptr++; |
| return tLSHIFT; |
| case '=': |
| ctx->ptr++; |
| return tLEQ; |
| default: |
| return '<'; |
| } |
| case '>': |
| switch(*++ctx->ptr) { |
| case '>': |
| if(*++ctx->ptr == '>') { |
| ctx->ptr++; |
| return tRRSHIFT; |
| } |
| return tRSHIFT; |
| case '=': |
| ctx->ptr++; |
| return tGEQ; |
| default: |
| return '>'; |
| } |
| case '|': |
| if(*++ctx->ptr == '|') { |
| ctx->ptr++; |
| return tOR; |
| } |
| return '|'; |
| case '&': |
| if(*++ctx->ptr == '&') { |
| ctx->ptr++; |
| return tAND; |
| } |
| return '&'; |
| } |
| |
| WARN("Failed to interpret %s\n", debugstr_w(ctx->ptr)); |
| return -1; |
| } |
| |
| %} |
| |
| %% |
| |
| /* FIXME: Implement missing expressions. */ |
| |
| CCExpr |
| : CCUnaryExpression { ctx->ccval = $1; YYACCEPT; } |
| |
| CCUnaryExpression |
| : tCCValue { $$ = $1; } |
| | '(' CCLogicalORExpression ')' { $$ = $2; } |
| | '!' CCUnaryExpression { $$ = ccval_bool(!get_ccbool($2)); }; |
| | '~' CCUnaryExpression { FIXME("'~' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| | '+' CCUnaryExpression { FIXME("'+' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| | '-' CCUnaryExpression { FIXME("'-' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCLogicalORExpression |
| : CCLogicalANDExpression { $$ = $1; } |
| | CCLogicalORExpression tOR CCLogicalANDExpression |
| { FIXME("'||' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCLogicalANDExpression |
| : CCBitwiseORExpression { $$ = $1; } |
| | CCBitwiseANDExpression tAND CCBitwiseORExpression |
| { FIXME("'&&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCBitwiseORExpression |
| : CCBitwiseXORExpression { $$ = $1; } |
| | CCBitwiseORExpression '|' CCBitwiseXORExpression |
| { FIXME("'|' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCBitwiseXORExpression |
| : CCBitwiseANDExpression { $$ = $1; } |
| | CCBitwiseXORExpression '^' CCBitwiseANDExpression |
| { FIXME("'^' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCBitwiseANDExpression |
| : CCEqualityExpression { $$ = $1; } |
| | CCBitwiseANDExpression '&' CCEqualityExpression |
| { FIXME("'&' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCEqualityExpression |
| : CCRelationalExpression { $$ = $1; } |
| | CCEqualityExpression tEQ CCRelationalExpression |
| { $$ = ccval_bool(get_ccnum($1) == get_ccnum($3)); } |
| | CCEqualityExpression tNEQ CCRelationalExpression |
| { $$ = ccval_bool(get_ccnum($1) != get_ccnum($3)); } |
| | CCEqualityExpression tEQEQ CCRelationalExpression |
| { FIXME("'===' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| | CCEqualityExpression tNEQEQ CCRelationalExpression |
| { FIXME("'!==' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCRelationalExpression |
| : CCShiftExpression { $$ = $1; } |
| | CCRelationalExpression '<' CCShiftExpression |
| { $$ = ccval_bool(get_ccnum($1) < get_ccnum($3)); } |
| | CCRelationalExpression tLEQ CCShiftExpression |
| { $$ = ccval_bool(get_ccnum($1) <= get_ccnum($3)); } |
| | CCRelationalExpression '>' CCShiftExpression |
| { $$ = ccval_bool(get_ccnum($1) > get_ccnum($3)); } |
| | CCRelationalExpression tGEQ CCShiftExpression |
| { $$ = ccval_bool(get_ccnum($1) >= get_ccnum($3)); } |
| |
| CCShiftExpression |
| : CCAdditiveExpression { $$ = $1; } |
| | CCShiftExpression tLSHIFT CCAdditiveExpression |
| { FIXME("'<<' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| | CCShiftExpression tRSHIFT CCAdditiveExpression |
| { FIXME("'>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| | CCShiftExpression tRRSHIFT CCAdditiveExpression |
| { FIXME("'>>>' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| CCAdditiveExpression |
| : CCMultiplicativeExpression { $$ = $1; } |
| | CCAdditiveExpression '+' CCMultiplicativeExpression |
| { $$ = ccval_num(get_ccnum($1) + get_ccnum($3)); } |
| | CCAdditiveExpression '-' CCMultiplicativeExpression |
| { $$ = ccval_num(get_ccnum($1) - get_ccnum($3)); } |
| |
| CCMultiplicativeExpression |
| : CCUnaryExpression { $$ = $1; } |
| | CCMultiplicativeExpression '*' CCUnaryExpression |
| { $$ = ccval_num(get_ccnum($1) * get_ccnum($3)); } |
| | CCMultiplicativeExpression '/' CCUnaryExpression |
| { $$ = ccval_num(get_ccnum($1) / get_ccnum($3)); } |
| | CCMultiplicativeExpression '%' CCUnaryExpression |
| { FIXME("'%%' expression not implemented\n"); ctx->hres = E_NOTIMPL; YYABORT; } |
| |
| %% |
| |
| BOOL parse_cc_expr(parser_ctx_t *ctx) |
| { |
| ctx->hres = S_OK; |
| cc_parser_parse(ctx); |
| return SUCCEEDED(ctx->hres); |
| } |