cppfront icon indicating copy to clipboard operation
cppfront copied to clipboard

[DOCS] Assorted comments on the grammar productions

Open JohelEGP opened this issue 2 years ago • 9 comments
trafficstars

Table of contents

  • Fixes
    • alt-name
    • declaration
    • return-list
    • string-literal
    • template-argument-list
  • Need fixing
    • name-specifier
    • integer-suffix
    • interpolation
  • Simplifications
    • type-id
    • is-as-expression-target
  • Others
    • parameterized-statement
  • Outdated //G comments
    • parameter-declaration
    • punctuator
    • unqualified-id
    • operator
    • selection-statement

See also: #71, #392, #408.

JohelEGP avatar Apr 21 '23 00:04 JohelEGP

Fixes

alt-name: The proposal uses identifiers here. Template arguments don't make sense here.

 //G alt-name:
-//G     unqualified-id :
+//G     identifier :

declaration:

Although some declarations can be without an initializer, the grammar doesn't permit the ending ;. A statement is currently required.

+//G declaration-initializer:
+//G     '=' statement
+//G     ';'
+//G
 //G unnamed-declaration:
-//G     ':' meta-functions-list? template-parameter-declaration-list? function-type requires-clause? '=' statement
-//G     ':' meta-functions-list? template-parameter-declaration-list? type-id? requires-clause? '=' statement
+//G     ':' meta-functions-list? template-parameter-declaration-list? function-type requires-clause? declaration-initializer
+//G     ':' meta-functions-list? template-parameter-declaration-list? type-id? requires-clause? declaration-initializer
 //G     ':' meta-functions-list? template-parameter-declaration-list? type-id
-//G     ':' meta-functions-list? template-parameter-declaration-list? 'final'? 'type' requires-clause? '=' statement
+//G     ':' meta-functions-list? template-parameter-declaration-list? 'final'? 'type' requires-clause? declaration-initializer
 //G     ':' 'namespace' '=' statement

meta-functions-list:

According to https://eel.is/c++draft/syntax#2.4, this shouldn't be a -list, but a -seq.

return-list:

According to https://eel.is/c++draft/syntax#2.4, this shouldn't be a -list.

Commit 785c44d29bdb2cc6ee9edcd0ab2047d7c1367217 changed the syntax:

     //G return-list:
-    //G     expression-statement
+    //G     expression ';'?
     //G     '->' return-direction? type-id
     //G     '->' parameter-declaration-list
Resolved

by #726.

Return-by move and forward:

 //G return-list:
-//G     '->' type-id
+//G     '->' parameter-direction? type-id

string-literal:

#251 didn't add $ for interpolated raw string literals.

It also added encoding-prefixes with 'R'. These should be removed, as the 'R' is in the pertaining production of string-literal and can't apply to the other.

 //G encoding-prefix: one of
-//G     'u8' 'u' 'uR' 'u8R' 'U' 'UR' 'L' 'LR' 'R'
+//G     'u8' 'u' 'U' 'L'

 //G string-literal:
 //G     encoding-prefix? '"' s-char-seq? '"'
-//G     encoding-prefix? 'R"' d-char-seq? '(' s-char-seq? ')' d-char-seq? '"'
+//G     encoding-prefix? '$'? 'R"' d-char-seq? '(' s-char-seq? ')' d-char-seq? '"'

template-argument-list: The single argument alternative is missing.

 //G template-argument-list:
 //G     template-argument-list ',' template-argument
+//G     template-argument

Need fixing

name-specifier:

The *-name-specifier of qualified-id lack recursion. N::M::A<int, int>::B<42>::f<int, 43> (from regression-tests/pure2-types-order-independence-and-nesting.cpp2) is not a qualified-id.

//G qualified-id:
//G     nested-name-specifier unqualified-id
//G     member-name-specifier unqualified-id
//G
//G nested-name-specifier:
//G     '::'
//G     unqualified-id '::'
//G
//G member-name-specifier:
//G     unqualified-id '.'

integer-suffix:

The suffixes need to be factored out into their own production, like Cpp1. z and Z (C++23) are missing. Alternatively, the ud-suffixes of literal could be generalized to a literal-suffix.

//G integer-literal:
//G     binary-literal
//G     hexadecimal-literal
//G     decimal-literal
//G
//G binary-literal:
//G     '0b' binary-digit
//G     '0B' binary-digit
//G     binary-literal binary-digit
//G     binary-literal ''' binary-digit
//G
//G hexadecimal-literal:
//G     '0x' hexadecimal-digit
//G     '0X' hexadecimal-digit
//G     hexadecimal-literal hexadecimal-digit
//G     hexadecimal-literal ''' hexadecimal-digit
//G
//G
//G decimal-literal:
//G     digit [uU][lL][lL]
//G     decimal-literal digit [uU][lL][lL]
//G     decimal-literal ''' digit [uU][lL][lL]

interpolation:

Commit e38838e678a2f52f1c811cf7cb7f819ab3925d62 didn't add grammar.

Seems like a string-literal can't end in an interpolation.

//G string-literal:
//G     encoding-prefix? '"' s-char-seq? '"'
//G     encoding-prefix? 'R"' d-char-seq? '(' s-char-seq? ')' d-char-seq? '"'
//G
//G s-char-seq:
//G     interpolation? s-char
//G     interpolation? s-char-seq s-char

JohelEGP avatar Apr 24 '23 20:04 JohelEGP

Simplifications

type-id:

id-expression can be used to simplify type-id.

 //G type-id:
-//G     type-qualifier-seq? qualified-id
-//G     type-qualifier-seq? unqualified-id
+//G     type-qualifier-seq? id-expression

 //G id-expression
 //G     qualified-id
 //G     unqualified-id

See also parameter-declaration-list.

is-as-expression-target:

It's possible to factor out an is-as-expression-target production.

+//G is-as-expression-target:
+//G     is-type-constraint
+//G     is-value-constraint
+//G     as-type-cast

 //G is-as-expression:
 //G     prefix-expression
-//G     is-as-expression is-type-constraint
-//G     is-as-expression is-value-constraint
-//G     is-as-expression as-type-cast
+//G     is-as-expression is-as-expression-target
 //GTODO     type-id is-type-constraint

 //G alternative:
-//G     alt-name? is-type-constraint '=' statement
-//G     alt-name? is-value-constraint '=' statement
-//G     alt-name? as-type-cast '=' statement
+//G     alt-name? is-as-expression-target '=' statement
 //G
 //G alt-name:
 //G     unqualified-id :
 //G
 //G inspect-expression:
 //G     'inspect' 'constexpr'? expression '{' alternative-seq? '}'
 //G     'inspect' 'constexpr'? expression '->' type-id '{' alternative-seq? '}'
 //G
 //G alternative-seq:
 //G     alternative
 //G     alternative-seq alternative

JohelEGP avatar Apr 24 '23 20:04 JohelEGP

Proposals

parameter-declaration-list:

Resolved by #526.

//G return-list:
//G     '->' type-id
//G     '->' parameter_declaration_list

The '->' parameter_declaration_list is target of #343.

#343 can be fixed by making the function-type a type-id and allowing to omit a parameter's identifier.

The order of parameter-declaration's productions means that:

  • The copy in (copy: T) is a parameter-direction.
  • A by-in parameter named after a parameter-direction needs the in explicitly spelled out.
Visualized

See https://highlight-cpp2.godbolt.org/z/K9nvoqKdh. 1685200243

See also parameter-declaration, type-id, inspect. See also https://github.com/hsutter/cppfront/issues/387#issuecomment-1522621543, https://github.com/hsutter/cppfront/issues/387#issuecomment-1534970681, https://github.com/hsutter/cppfront/issues/397#issuecomment-1529146926. See also alternatives designs https://github.com/hsutter/cppfront/issues/456#issuecomment-1556074853, https://github.com/hsutter/cppfront/issues/456#issuecomment-1566161667, https://github.com/hsutter/cppfront/issues/305#issuecomment-1589908132 (also provides a short summary of each alternative).

 //G type-id:
-//G     type-qualifier-seq? qualified-id
-//G     type-qualifier-seq? unqualified-id
+//G     type-qualifier-seq? id-expression
+//G     type-qualifier-seq? function-type

 //G parameter-declaration:
+//G     parameter-direction? unnamed-declaration
 //G     this-specifier? parameter-direction? declaration
+//G     this-specifier? parameter-direction? identifier

 //G return-list:
 //G     '->' type-id
-//G     '->' parameter_declaration_list

inspect:

inspect should be able to result in a pointer to a function type. Maybe it's just out of date.

 //G inspect-expression:
-//G     'inspect' 'constexpr'? expression '{' alternative-seq? '}'
-//G     'inspect' 'constexpr'? expression '->' type-id '{' alternative-seq? '}'
+//G     'inspect' 'constexpr'? expression return-list? '{' alternative-seq? '}'

See also parameter-declaration-list.

Others

parameterized-statement:

Commit 928186e4db6f7c3fba7b8df8b4ff9648e1c938e9 didn't add grammar nor updated for's. My guess:

 //G iteration-statement:
 //G     label? 'while' logical-or-expression next-clause? compound-statement
 //G     label? 'do' compound-statement 'while' logical-or-expression next-clause? ';'
-//G     label? 'for' expression next-clause? 'do' unnamed-declaration
+//G     label? 'for' expression next-clause? 'do' parameterized-statement

+//G parameterized-statement:
+//G     parameter-declaration-list statement

 //G statement:
 //G     selection-statement
 //G     inspect-expression
 //G     return-statement
 //G     jump-statement
 //G     iteration-statement
 //G     compound-statement
 //G     declaration
+//G     parameterized-statement
 //G     expression-statement
 //G     contract
 //GTODO     try-block

primary-expression:

Although the Cpp2 grammar doesn't seem to treat true, false, and nullptr specially, writing a highlighter that does, and follows the order of productions, results in those not being highlighted. 1684190334 1684190342

 //G primary-expression:
 //G     inspect-expression
-//G     id-expression
 //G     literal
+//G     id-expression
 //G     '(' expression-list ')'
 //G     '{' expression-list '}'
 //G     unnamed-declaration

JohelEGP avatar Apr 24 '23 20:04 JohelEGP

Beyond C++20

See also integer-suffix.

operator[]:

Resolved

by #483. Maybe cppfront doesn't handle this yet.

 //G postfix-expression:
 //G     primary-expression
 //G     postfix-expression postfix-operator     [Note: without whitespace before the operator]
-//G     postfix-expression '[' expression-list ']'
+//G     postfix-expression '[' expression-list? ']'
 //G     postfix-expression '(' expression-list? ')'
 //G     postfix-expression '.' id-expression

Outdated comments

parameter-declaration:

The P in f: (P) = { } or f: <P> () = { } is accepted as a parameter-declaration but is not a declaration.

 //G parameter-declaration:
 //G     this-specifier? parameter-direction? declaration
+//G     this-specifier? parameter-direction? identifier '...'?

See also parameter-declaration-list.

punctuator:

Commit d8c1a50f22c1b171a50e87ccdb609fb05f41c021 didn't add '@'.

 //G punctuator: one of
 //G     '...' '.'
 //G     '::' ':'
-//G     '{' '}' '(' ')' '[' ']' ';' ',' '?' '$'
+//G     '{' '}' '(' ')' '[' ']' ';' ',' '?' '$' '@'

unqualified-id:

The TODO is done by identifier's 'operator' operator production.

 //G identifier:
 //G     identifier-start
 //G     identifier identifier-continue
 //G     'operator' operator

 //G unqualified-id:
 //G     identifier
 //G     template-id
-//GTODO     operator-function-id

operator:

Commit ab3670a19da35ce91bc094be474d82967b162346 didn't add '()' '[]'. ||=, &&=, and ~= are not operators.

 //G operator: one of
 //G     '/=' '/'
 //G     '<<=' '<<' '<=>' '<=' '<'
 //G     '>>=' '>>' '>=' '>'
 //G     '++' '+=' '+'
 //G     '--' '-=' '->' '-'
-//G     '||=' '||' '|=' '|'
-//G     '&&=' '&&' '&=' '&'
+//G     '||' '|=' '|'
+//G     '&&' '&=' '&'
 //G     '*=' '*'
 //G     '%=' '%'
 //G     '^=' '^'
-//G     '~=' '~'
+//G     '~'
 //G     '==' '='
 //G     '!=' '!'
+//G     '()' '[]'

selection-statement:

#366 didn't update the grammar.

 //G selection-statement:
 //G     'if' 'constexpr'? logical-or-expression compound-statement
 //G     'if' 'constexpr'? logical-or-expression compound-statement 'else' compound-statement
+//G     'if' 'constexpr'? logical-or-expression compound-statement 'else' selection-statement

JohelEGP avatar Apr 24 '23 20:04 JohelEGP

Doubts

  • What is the primary-expression '{' expression-list '}' used for?

JohelEGP avatar Apr 24 '23 20:04 JohelEGP

Now I understand that the '->' parameter_declaration_list alternative of return-type is for anonymous return type support. The suggestion I made for parameter-declaration-list and it's following inspect (to make a (pointer to a) function type a type-id) would mean changing some grammar guarantees for checks during semantic analysis. An anonymous return type looks like a function-type, after all.

JohelEGP avatar Apr 26 '23 01:04 JohelEGP

With regards to parameter-declaration-list, which makes (x) grammatically a function type. a is (x) matches is-as-expression is-type-constraint. But in a type context, (x) can never be a type (there's no Cpp1 void (auto) function type). So I think this should be semantically disambiguated as an expression. See also https://github.com/hsutter/cppfront/issues/456#issuecomment-1556074853, https://github.com/hsutter/cppfront/issues/456#issuecomment-1566161667.

JohelEGP avatar May 04 '23 15:05 JohelEGP