Skip to content

fix(grammar): parse real-world VB.NET - #1

Merged
RaghavChamadiya merged 3 commits into
mainfrom
grammar/real-world
Sep 4, 2026
Merged

RaghavChamadiya merged 3 commits into
mainfrom
grammar/real-world

Conversation

@RaghavChamadiya

Copy link
Copy Markdown
Member

Parsing two real VB.NET repositories with 0.2.0 showed almost every file
carrying a parse error: 312 of 320 files in SCrawler and 200 of 200 in
FFmpegFreeUI. This fixes the grammar against those corpora.

Cause Before After
Imports / Option only accepted as the first node broke 134 / 2 files fixed
ASCII-only identifiers, no BOM handling 0 / 195 fixed
#Region / #End Region and other directives outside a procedure 73 fixed
Generic parameters and type arguments (Sub Bar(Of T)(), Foo.Bar(Of Integer)()) 56 / 46 fixed
Handles (and Implements) clauses on members 34 / 54 fixed
From {} initialisers, omitted arguments part of 89 / 3 fixed
XML literals part of 89 / 3 still unsupported

Three further causes turned up while measuring, each costing more files than
any of the above:

  • A file that ends right after End Class with no trailing newline was
    missing a statement terminator. Nearly every SCrawler file ends that way.
  • Keywords outranked longer identifiers, because lexical precedence is
    weighed before match length, so Domains lexed as Do + mains. A word
    token now drives keyword extraction.
  • REM had no word boundary, so RemoveAll(x) became a comment.

The same pass adds what the corpora leaned on: implicit line continuations,
single-line If ... Then ... Else, LINQ queries, Await, TypeOf ... Is,
nullable and tuple types, operator and Custom Event declarations, event
wiring statements, array bounds in a declarator and Async lambdas.

Files with any parse error, over both corpora:

Corpus Before After
SCrawler (320 files) 312 (97.5%) 15 (4.7%)
FFmpegFreeUI (200 files) 200 (100%) 24 (12.0%)

No existing node type or field was renamed. Shape changes worth knowing:

  • option_statements now wraps one Option line and may repeat, instead of
    one node covering every leading Option line.
  • Nested types inside a type are children of the enclosing block directly,
    not wrapped in type_declaration (which already carries
    delegate_declaration and would clash with it).
  • New nodes: handles_clause, query_expression, query_range,
    query_clause, tuple_type, tuple_element, operator_declaration,
    type_of_expression, await_expression, with_member_access,
    array_bounds, inline_statements, inline_statement, and the
    event-wiring statements.

https://claude.ai/code/session_016BpMYrS81wxdJznMPXTTue

Parsing the SCrawler and FFmpegFreeUI corpora (520 files) with 0.2.0 left
312/320 and 200/200 files carrying a parse error. The causes, in rough order
of how many files they cost:

- A file that ends right after `End Class`, with no trailing newline, was
  missing a statement terminator. Nearly every SCrawler file ends that way.
- Keywords outranked longer identifiers, because lexical precedence is
  weighed before match length: `Domains` lexed as `Do` + `mains`. A `word`
  token now drives keyword extraction, and the precedence hack is gone.
- `REM` had no word boundary, so `RemoveAll(x)` became a comment to the end
  of the line.
- `Imports` and `Option` were only accepted as the very first node, so a
  leading comment or blank line broke the next one.
- Identifiers were ASCII-only; VB.NET follows the same Unicode classes as
  C#. A leading BOM is skipped as whitespace.
- `#Region` / `#End Region` and other directives were only allowed inside a
  procedure body, and nested types were not allowed inside a type at all.
- Type parameter lists had no parentheses (`Sub Bar(Of T)()`), and an
  invocation could not carry type arguments. `(Of` now lexes as one token:
  with a bare `(` the parser cannot tell a type argument list from a
  constructor argument list until it has read a second token.
- `Handles` and `Implements` clauses on members were unsupported.
- `New Point(0, 0)` read its arguments as an array rank specifier.

The same pass adds the constructs the corpora leaned on: implicit line
continuations after an operator, a comma, `=`, an open paren or a trailing
dot; single-line `If ... Then ... Else ...`; LINQ query expressions; event
wiring, operator and Custom Event declarations; `Await`, `TypeOf ... Is`,
nullable and tuple types, `From {}` initialisers, omitted arguments, array
bounds in a declarator, `Async` lambdas and generic constraint lists.

XML literals remain a known gap.

Claude-Session: https://claude.ai/code/session_016BpMYrS81wxdJznMPXTTue
One corpus case per class of failure found in the SCrawler and
FFmpegFreeUI corpora, including a file that ends without a newline.

Claude-Session: https://claude.ai/code/session_016BpMYrS81wxdJznMPXTTue
@RaghavChamadiya
RaghavChamadiya merged commit 4e002ba into main Sep 4, 2026
8 checks passed
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

Successfully merging this pull request may close these issues.

1 participant