Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse error on Private Type definition #6194

Closed
huaca2 opened this issue Jan 24, 2024 · 6 comments
Closed

Parse error on Private Type definition #6194

huaca2 opened this issue Jan 24, 2024 · 6 comments

Comments

@huaca2
Copy link

huaca2 commented Jan 24, 2024

Write a Type Definition in a class module of the form:

Private Type Ficha
     FMT(0 To 2)
     AUT(0 To 2)
     ...

Throws a Parse Error at the end of FMT(0 To 2)

extraneous input '\r\n' expecting {WS.LINE_CONTINUATION}
@retailcoder
Copy link
Member

Looks like an oversight in the parser grammar around UDT member definitions.
Thanks for the report!

@retailcoder
Copy link
Member

Seems to be taken into account though:

// 5.2.3.3 User Defined Type Declarations
// member list includes trailing endOfStatement
udtDeclaration : (visibility whiteSpace)? TYPE whiteSpace untypedIdentifier endOfStatement udtMemberList END_TYPE;  
udtMemberList : (udtMember endOfStatement)+; 
udtMember : reservedNameMemberDeclaration | untypedNameMemberDeclaration;
untypedNameMemberDeclaration : untypedIdentifier whiteSpace? optionalArrayClause;
reservedNameMemberDeclaration : unrestrictedIdentifier whiteSpace asTypeClause;
optionalArrayClause : (arrayDim whiteSpace)? asTypeClause;

Specifically:

untypedNameMemberDeclaration : untypedIdentifier whiteSpace? optionalArrayClause;

Just to be sure, the END_TYPE token (i.e. End Type) is indeed present, yeah? The parse error is legit without that token, since the parser rule (which encodes section 5.2.3.3 of the language specifications) understands it's looking at a UDT definition by matching the source code against the grammar tokens:

udtDeclaration : (visibility whiteSpace)? TYPE whiteSpace untypedIdentifier endOfStatement udtMemberList END_TYPE;

In other words, in order to parse a udtDeclaration the source code must look like Type SomeIdentifierName with a mandatory udtMemberList on at least one more line, followed by End Type on another line.

@huaca2
Copy link
Author

huaca2 commented Jan 25, 2024

Yes, my Type Definition ends correctly with the "End Type" token in the last line.

 Private Type Ficha
       FMT(0 To 2)
       AUT(0 To 2)
       ...
 End Type

@tommy9
Copy link
Member

tommy9 commented Jan 26, 2024

It looks like the VBA language specification does not allow user defined types to include array members without an AS type clause at the end. However, the VBA editor does allow array members but only when declared using both explicit lower and upper bounds e.g. FM(0 to 2). In other words it won't accept FM(2) even though that is identical in meaning.

Private Type X
    A(2) As Variant         'This is fine
    B(0 To 2) As Variant    'This is fine
    C (2)                   'VBA will not compile this (the VBA editor inserts the space between the identifier and array)
    D(0 To 2)               'VBA will compile and work as expected but Rubberduck has a parse error
End Type

In the above example, the 4 members should be identical i.e. arrays of variants with lower bound 0 and upper bound 2. However, VBA will only allow cases A, B and D. Rubberduck only allows A and B.

So to support the reality of what works in VBA, we would need to change the VBAParser.g4 definition to explicitly allow UDT members to have an array with both lower and upper bounds but not a type. An odd special case.

@retailcoder
Copy link
Member

So this is one of the few areas where the VBE implementation mismatches its own specifications.
In the spirit of RD being able to flag the untyped member declaration as such, indeed it would be necessary to address this, at least in 2.x (and then we carry the grammar into v3).
RD3 would merely be reporting a syntax error there if it's not addressed in the v3 grammar, so no biggie, but confusing enough to warrant aligning with the VBE implementation.

tommy9 added a commit to tommy9/Rubberduck that referenced this issue Jan 27, 2024
@tommy9
Copy link
Member

tommy9 commented Jan 27, 2024

Submitted a fix which allow Rubberduck to parse cases where there is an array member of the UDT which doesn't have an explicit type declaration. It still requires a type declaration for non-array members as that is consistent with both the language specification and implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants