Giter VIP home page Giter VIP logo

Comments (7)

nikic avatar nikic commented on May 10, 2024

The same also applies to other expressions that accept only variables on the LHS, for example PHP interprets !$x instanceof Y as !($x instanceof Y), while the parser currently treats it as (!$x) instanceof Y.

from tolerant-php-parser.

mousetraps avatar mousetraps commented on May 10, 2024

Ahh, makes sense. Thanks for pointing that out! I was wondering why variables were called out separately from expressions in general.

For instanceof, I think I'm missing something because both the spec and yacc grammar seem to specify expression as LHS.

Looking back at my notes, my interpretation of the spec was that unary-expression takes precedence over instanceof-expression, which in turn takes precedence over multiplicative-expression, where both intanceof and multiplicative expressions are defined similarly, which led me to believe they're parsed similarly.

instanceof-expression:
   unary-expression
   instanceof-subject   instanceof   instanceof-type-designator

instanceof-subject:
   expression

multiplicative-expression:
   instanceof-expression
   multiplicative-expression   *   instanceof-expression
   multiplicative-expression   /   instanceof-expression
   multiplicative-expression   %   instanceof-expression

Should instanceof-subject be variable, rather than expression? And if so, how exactly does that get specified in the yacc grammar?

from tolerant-php-parser.

nikic avatar nikic commented on May 10, 2024

You're right about instanceof, I got confused there. The LHS is a normal expression, it's the RHS that is a (restricted) variable.

However, the spec is incorrect about the precedence of instanceof: It should have higher precedence than ! (but lower than ~, so different unary operator are treated differently here).

from tolerant-php-parser.

Hywan avatar Hywan commented on May 10, 2024

👍

from tolerant-php-parser.

mattacosta avatar mattacosta commented on May 10, 2024

I also happened to come across the following example that is related to this while looking at an RFC:

!$x = f() should be !($x = f()) instead of (!$x) = f()

from tolerant-php-parser.

mattacosta avatar mattacosta commented on May 10, 2024

@TysonAndre The affected operators with this restriction are:

  • All assignment operators (it looks like you got all of these)
  • Increment and decrement operators

The instanceof operator is not affected by the restriction. It only appears to be related because the ! operator has the wrong precedence. This means that the PR probably makes instanceof have an incorrect precedence as well, and that part of the change should be reverted.


Also, before anyone goes and thinks about closing this issue, note that the previous PR is just a workaround. It alters the precedence of those operators, but that isn't the cause of the issue. For example, the parser will still parse statements such as 1 = 2 without error.

from tolerant-php-parser.

TysonAndre avatar TysonAndre commented on May 10, 2024

The instanceof operator is not affected by the restriction. It only appears to be related because the ! operator has the wrong precedence.

That sounds right, after a few checks. I agree that this should be kept open.

I was basing my changes off of the comment from #19 (comment) . But that earlier comment now seems incorrect, according to https://secure.php.net/manual/en/language.operators.precedence.php (Which puts ! as lower precedence than instanceof)

You're right about instanceof, I got confused there. The LHS is a normal expression, it's the RHS that is a (restricted) variable.

I missed/misread the followup comment they made.

  • I had thought that ~$x instanceof T would be parsed as ~($x instanceof T), but it's actually parsed as (~$x) instanceof T. There's no special case. My change probably introduced a bug for ~$x instanceof T.

  • As mattacosta said, the precedence of instanceof (compared to unary operators) should be fixed.

    And more tests should be added.

php > $x = new stdClass();
php > var_export(~$x instanceof stdClass);

Warning: Uncaught Error: Unsupported operand types in php shell code:1

Also, I'd agree that it looks like 1 = 2; is a syntax error (e.g. for getDiagnostics()), not a semantics error. That may be easier to track in a separate ticket.

https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#assignment-operators limits the valid expression types for lhs

php > var_export(ast\parse_code('<?php 2 = 3;', 50));

Parse error: syntax error, unexpected '=' in string code on line 1

from tolerant-php-parser.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.