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. Adding Not as a unary operator in SignExpression (alongside unary minus and plus) allows it to be used within comparison operands. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55093 --- dlls/vbscript/parser.y | 22 +++++++++++++--------- dlls/vbscript/tests/lang.vbs | 8 ++++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 42df9afaf8f..aab8ebc04ff 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -140,7 +140,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %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> NotExpression NotConcatExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression SignExpression %type <expression> ConstExpression NumericLiteralExpression %type <member> MemberExpression %type <expression> Arguments ArgumentList ArgumentList_opt Step_opt ExpressionList @@ -399,14 +399,18 @@ NotExpression | tNOT NotExpression { $$ = new_unary_expression(ctx, EXPR_NOT, $2); 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; } + | EqualityExpression '=' NotConcatExpression { $$ = new_binary_expression(ctx, EXPR_EQUAL, $1, $3); CHECK_ERROR; } + | EqualityExpression tNEQ NotConcatExpression { $$ = new_binary_expression(ctx, EXPR_NEQUAL, $1, $3); CHECK_ERROR; } + | EqualityExpression '>' NotConcatExpression { $$ = new_binary_expression(ctx, EXPR_GT, $1, $3); CHECK_ERROR; } + | EqualityExpression '<' NotConcatExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; } + | EqualityExpression tGTEQ NotConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; } + | EqualityExpression tLTEQ NotConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; } + | EqualityExpression tIS NotConcatExpression { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; } + +NotConcatExpression + : ConcatExpression { $$ = $1; } + | tNOT NotConcatExpression { $$ = new_unary_expression(ctx, EXPR_NOT, $2); CHECK_ERROR; } ConcatExpression : AdditiveExpression { $$ = $1; } diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 4374d7b1f25..936b8df3537 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -92,6 +92,14 @@ 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(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