Skip to content

Statement parsing algorithm should be change #3882

Closed

Description

@key262yek

Feature

In CPython grammar (Grammar/python.gram) line 695, there are group expression type exists.

atom[expr_ty]:
    ...
     | &'(' (tuple | group | genexp)

The definition of group is at line 709 of same file

group[expr_ty]:
    | '(' a=(yield_expr | named_expression) ')' { a }
    | invalid_group

and of invalid group is at line 947

invalid_group:
    | '(' a=starred_expression ')' {
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use starred expression here") }
    | '(' a='**' expression ')' {
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use double starred expression here") }

Here, the first pattern in invalid_group is related to SyntaxError of del (*x) (pr #3879)
It should print cannot use starred expression here, but without group expression it makes cannot delete starred.

In parser/src/python.lalrpop at line 956, only tuple, yield, genexp are parsed.
Even, parenthesized-form is missing.

I think, we need to make group expression to parse parenthesized-form and handle error about starred epression,
or add equivalent parsing grammar into atom parser

Python Documentation

Maybe those are related things.
atom
parenthesized-forms

Activity

  1. changed the title [-]Expression Kind `Group` missing[/-] [+]Parenthesized-form Expression missing[/+] on Jul 14, 2022
  2. changed the title [-]Parenthesized-form Expression missing[/-] [+]Expression kind `group` missing[/+] on Jul 14, 2022
  3. key262yek commented on Jul 14, 2022

    @key262yek
    ContributorAuthor

    Since group is not actual expression kind, it is better to add equivalent parsing method for both parenthesized forms and starred expression

  4. changed the title [-]Expression kind `group` missing[/-] [+]Expression kind `parenth_form` missing[/+] on Jul 14, 2022
  5. key262yek commented on Jul 15, 2022

    @key262yek
    ContributorAuthor

    I think it is my mistake.
    followings are all fine, so parenth_form and starred expression works.
    Hence it's just about error in del statement.

    >>> x = [1, 2, 3]
    >>> ([*x])
    [1, 2, 3]
    >>> (*x)
    SyntaxError: cannot use starred expression here at line 1 column 2
    (*x)
     ^
  6. key262yek commented on Jul 15, 2022

    @key262yek
    ContributorAuthor

    I re-change my opinion.
    It is right that missing a group expression is a problem.

    In CPython, the expression (*x) raises SyntaxError in statement parsing level.
    However, in RustPython, we need to handle it in each statement block level which is too handy

    In CPython,

    >>> while (*x)
      File "<stdin>", line 1
        while (*x)
               ^^
    SyntaxError: cannot use starred expression here
    >>> if (*x)
      File "<stdin>", line 1
        if (*x)
            ^^
    SyntaxError: cannot use starred expression here

    But, in RustPython

    >>>>> while (*x)
    SyntaxError: invalid syntax. Got unexpected token Newline at line 1 column 11
    while (*x)
              ^
    >>>>> if (*x)
    SyntaxError: invalid syntax. Got unexpected token Newline at line 1 column 8
    if (*x)
           ^

    because they decide the SyntaxError of (*x) after compiler move into statement block

    >>>>> while (*x) == 1:
    .....  print(1)
    .....
    SyntaxError: cannot use starred expression here at line 1 column 8
    while (*x) == 1:
           ^

    In CPython, tuple expression matches when at least one comma , exists.

    tuple[expr_ty]:
        | '(' a=[y=star_named_expression ',' z=[star_named_expressions] { _PyPegen_seq_insert_in_front(p, y, z) } ] ')' {
            _PyAST_Tuple(a, Load, EXTRA) }
    

    they handle the singleton in parenthesis using group expression, and raise syntax error while parsing it.

    group[expr_ty]:
        | '(' a=(yield_expr | named_expression) ')' { a }
        | invalid_group
    invalid_group:
        | '(' a=starred_expression ')' {
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use starred expression here") }
        | '(' a='**' expression ')' {
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use double starred expression here") 
    

    In RustPython, Tuple takes items even if the result is a singleton not a tuple.
    We should stop using GenericList to Tuple, and add error handling code.

    // In definition of atom
    <location:@L> "(" <elements:TestOrStarNamedExprList?> ")" => {
            elements.unwrap_or(ast::Expr {
                 location,
                 custom: (),
                 node: ast::ExprKind::Tuple { elts: Vec::new(), ctx: ast::ExprContext::Load }
            })
        },
    
    TestOrStarNamedExprList: ast::Expr = {
        GenericList<TestOrStarNamedExpr>
    };
    GenericList<Element>: ast::Expr = {
        <location:@L> <elts:OneOrMore<Element>> <trailing_comma:","?> => {
            if elts.len() == 1 && trailing_comma.is_none() {
                elts.into_iter().next().unwrap()
            } else {
                ast::Expr {
                    location,
                    custom: (),
                    node: ast::ExprKind::Tuple { elts, ctx: ast::ExprContext::Load }
                }
            }
        }
    }
    
  7. changed the title [-]Expression kind `parenth_form` missing[/-] [+]Statement parsing algorithm should be change[/+] on Jul 15, 2022
  8. key262yek commented on Jul 20, 2022

    @key262yek
    ContributorAuthor

    It is resolved by pr #3879

  9. youknowone commented on Jul 20, 2022

    @youknowone
    Member

    we usually manage it opposite way. adding fix #3882 to the PR make it automatically close this issue when it is merged.

  10. key262yek commented on Jul 20, 2022

    @key262yek
    ContributorAuthor

    @youknowone Thanks for notice. then I need to reopen another one the pr will fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-compilerArea: compilerC-compatA discrepancy between RustPython and CPythonC-enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions