[PATCH v6 0/1] MR10317: vbscript: Allow Not operator as operand of comparison expressions.
vbscript: Allow Not operator as operand of comparison expressions. The Not operator was only reachable from the NotExpression grammar rule, which sat above EqualityExpression in the precedence chain. This meant expressions like "a <> Not b" caused a syntax error because the right-hand side of a comparison could not contain Not. Fold Not directly into EqualityExpression as a unary prefix and use bison precedence declarations to resolve the resulting ambiguity: %right tNOT at lower precedence than %left comparison operators ensures "Not 1 = 2" parses as "Not(1 = 2)" while "a <> Not b = c" correctly lets Not capture the comparison on its right. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55093 -- v6: vbscript: Allow Not operator as operand of comparison expressions. https://gitlab.winehq.org/wine/wine/-/merge_requests/10317
From: Francis De Brabandere <francisdb@gmail.com> The Not operator was only reachable from the NotExpression grammar rule, which sat above EqualityExpression in the precedence chain. This meant expressions like "a <> Not b" caused a syntax error because the right-hand side of a comparison could not contain Not. Fold Not directly into EqualityExpression as a unary prefix and use bison precedence declarations to resolve the resulting ambiguity: %right tNOT at lower precedence than %left comparison operators ensures "Not 1 = 2" parses as "Not(1 = 2)" while "a <> Not b = c" correctly lets Not capture the comparison on its right. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55093 --- dlls/vbscript/parser.y | 30 +++++++++++++++--------------- dlls/vbscript/tests/lang.vbs | 12 ++++++++++++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index ecd6cc7502f..c1a5b944268 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -136,11 +136,14 @@ static statement_t *link_statements(statement_t*,statement_t*); %token <dbl> tDouble %token <date> tDate +%right tNOT +%left '=' tNEQ '>' '<' tGTEQ tLTEQ tIS + %type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt BodyStatements IfStatement Else_opt %type <statement> GlobalDimDeclaration StatementsBody StatementsBody_opt %type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression -%type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression SignExpression +%type <expression> UnaryExpression AndExpression OrExpression XorExpression EqvExpression SignExpression %type <expression> ConstExpression NumericLiteralExpression %type <member> MemberExpression %type <expression> Arguments ArgumentList ArgumentList_opt Step_opt ExpressionList @@ -391,22 +394,19 @@ OrExpression | OrExpression tOR AndExpression { $$ = new_binary_expression(ctx, EXPR_OR, $1, $3); CHECK_ERROR; } AndExpression - : NotExpression { $$ = $1; } - | AndExpression tAND NotExpression { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); CHECK_ERROR; } - -NotExpression - : EqualityExpression { $$ = $1; } - | tNOT NotExpression { $$ = new_unary_expression(ctx, EXPR_NOT, $2); CHECK_ERROR; } + : EqualityExpression { $$ = $1; } + | AndExpression tAND EqualityExpression { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); CHECK_ERROR; } EqualityExpression - : ConcatExpression { $$ = $1; } - | EqualityExpression '=' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_EQUAL, $1, $3); CHECK_ERROR; } - | EqualityExpression tNEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_NEQUAL, $1, $3); CHECK_ERROR; } - | EqualityExpression '>' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GT, $1, $3); CHECK_ERROR; } - | EqualityExpression '<' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; } - | EqualityExpression tGTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; } - | EqualityExpression tLTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; } - | EqualityExpression tIS ConcatExpression { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; } + : ConcatExpression { $$ = $1; } + | tNOT EqualityExpression { $$ = new_unary_expression(ctx, EXPR_NOT, $2); CHECK_ERROR; } + | EqualityExpression '=' EqualityExpression { $$ = new_binary_expression(ctx, EXPR_EQUAL, $1, $3); CHECK_ERROR; } + | EqualityExpression tNEQ EqualityExpression { $$ = new_binary_expression(ctx, EXPR_NEQUAL, $1, $3); CHECK_ERROR; } + | EqualityExpression '>' EqualityExpression { $$ = new_binary_expression(ctx, EXPR_GT, $1, $3); CHECK_ERROR; } + | EqualityExpression '<' EqualityExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; } + | EqualityExpression tGTEQ EqualityExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; } + | EqualityExpression tLTEQ EqualityExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; } + | EqualityExpression tIS EqualityExpression { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; } ConcatExpression : AdditiveExpression { $$ = $1; } diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 055a63047c0..6dcdb3b1114 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -106,6 +106,18 @@ Call ok(not(false = true = ""), "false = true = """" is true") Call ok(not (false = false <> false = false), "false = false <> false = false is true") Call ok(not ("" <> false = false), """"" <> false = false is true") +Call ok(true <> Not true, "true <> Not true should be true") +Call ok(false <> Not false, "false <> Not false should be true") +Call ok(true = Not false, "true = Not false should be true") +Call ok(Not false = true, "Not false = true should be true") +Call ok(Not true <> true, "Not true <> true should be true") +Call ok(Not true = false, "Not true = false should be true") +Call ok(Not 1 > 2, "Not 1 > 2 should be true") +Call ok(1 <> Not 0 = 0, "1 <> Not 0 = 0 should be true") +Call ok(0 = Not 1 = 1, "0 = Not 1 = 1 should be true") +Call ok(1 > Not 5 > 3, "1 > Not 5 > 3 should be true") +Call ok(Not false And false = false, "Not false And false should be false") + Call ok(getVT(false) = "VT_BOOL", "getVT(false) is not VT_BOOL") Call ok(getVT(true) = "VT_BOOL", "getVT(true) is not VT_BOOL") Call ok(getVT("") = "VT_BSTR", "getVT("""") is not VT_BSTR") -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10317
This merge request was approved by Jacek Caban. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10317
participants (3)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb) -
Jacek Caban (@jacek)