tree-sitter-delphi13 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -11
- package/grammar.js +33 -2
- package/package.json +1 -1
- package/src/grammar.json +52 -8
- package/src/node-types.json +4 -0
- package/src/parser.c +341297 -327896
package/README.md
CHANGED
|
@@ -5,27 +5,37 @@
|
|
|
5
5
|
|
|
6
6
|
Tree-sitter grammar pipeline focused on **Delphi 13 (RAD Studio 37.0 / Florence)** and the surrounding modern Delphi ecosystem.
|
|
7
7
|
|
|
8
|
-
**
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
**v1.2.1: 100.000% pass rate on compilable Delphi 13** (zero ERROR nodes), measured
|
|
9
|
+
on an 11,722-unique-file corpus spanning the RAD Studio 13 RTL/VCL (including
|
|
10
|
+
`System.pas`), DevExpress, Spring4D, EurekaLog, Indy, FireDAC, AsyncPro/Orpheus,
|
|
11
|
+
mORMot-era community code and a full production application. Every failure that
|
|
12
|
+
remains is individually diagnosed, dcc32-cross-checked, and *supposed* to fail
|
|
13
|
+
(see [CORPUS-CEILING-REPORT.md](CORPUS-CEILING-REPORT.md)).
|
|
14
|
+
|
|
15
|
+
| measurement basis | pass rate |
|
|
11
16
|
|---|---|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
| Embarcadero RAD Studio 13 RTL/VCL | 99.24% |
|
|
17
|
+
| orchestrated pipeline (preprocessor → pure), all rows | 99.82% |
|
|
18
|
+
| deduplicated files | 99.74% |
|
|
19
|
+
| deduplicated, valid-Delphi-13-only (excludes broken fixtures, FPC/.NET files) | **100.000%** |
|
|
20
|
+
| own production code (ORM3, drag-lint) | **100.00%** |
|
|
17
21
|
|
|
18
|
-
The
|
|
22
|
+
The 30 files that still fail are intentionally broken test fixtures,
|
|
23
|
+
truncated/corrupted files, FreePascal- or .NET-only sources, and vendor files with
|
|
24
|
+
genuine syntax errors that dcc32 rejects too — a parser that accepted them would be
|
|
25
|
+
wrong. Zero known gaps on valid Delphi 13 remain ([TODO.md](TODO.md) tracks the
|
|
26
|
+
watchlist).
|
|
19
27
|
|
|
20
28
|
## Three packages, one repo
|
|
21
29
|
|
|
22
30
|
| Package | What it does |
|
|
23
31
|
|---|---|
|
|
24
|
-
| **`tree-sitter-delphi13`** *(this directory)* | Master grammar — Delphi-13 syntax, all proven fixes from upstream merged + new extensions. Self-contained "THEN-wins" parser (
|
|
32
|
+
| **`tree-sitter-delphi13`** *(this directory)* | Master grammar — Delphi-13 syntax, all proven fixes from upstream merged + new extensions. Self-contained "THEN-wins" parser (98.6% raw on its own). |
|
|
25
33
|
| **[`tree-sitter-delphi13-pure`](pure/)** | Simpler sub-grammar that drops `pp_*` tokens entirely. Expects preprocessor-resolved source. |
|
|
26
34
|
| **[`delphi13-preprocessor`](preprocessor/)** | Standalone JavaScript library that resolves `{$IFDEF}` / `{$IF}` / `{$DEFINE}` / `{$I X.inc}` directives as a text transformation. |
|
|
27
35
|
|
|
28
|
-
The full pipeline `preprocessor → pure → AST` is what reaches **99.
|
|
36
|
+
The full pipeline `preprocessor → pure → AST` is what reaches **99.97%** on valid
|
|
37
|
+
Delphi 13. Use the master grammar alone (98.6% raw) if you don't need
|
|
38
|
+
conditional-compilation awareness; use the pipeline if you do.
|
|
29
39
|
|
|
30
40
|
## Architecture
|
|
31
41
|
|
package/grammar.js
CHANGED
|
@@ -448,6 +448,14 @@ module.exports = grammar({
|
|
|
448
448
|
// `_procAttributeNoExt` groups while both interpretations are still
|
|
449
449
|
// live (`function F; stdcall; forward;` — forward only decides later).
|
|
450
450
|
[$._declProcLenient, $._procAttributeNoExt],
|
|
451
|
+
// Iter 2026-07-16 (Register as a field name): after `Foo: T;` the
|
|
452
|
+
// token `Register` is either the previous field's trailing callconv
|
|
453
|
+
// (`; register;`) or the NEXT field's name (`Register: UINT;`) —
|
|
454
|
+
// `;` vs `:` one token later decides; GLR forks across the
|
|
455
|
+
// declField/declFieldNoSemi boundary AND within declField itself
|
|
456
|
+
// (trailing-callconv slot vs end-of-field).
|
|
457
|
+
[$.declFieldNoSemi, $.declField],
|
|
458
|
+
[$.declField],
|
|
451
459
|
// The following conflict rules are only needed because "public" can be
|
|
452
460
|
// a visibility or an attribute. *sigh*
|
|
453
461
|
// TODO: We would probably avoid this by having separate decl* clauses
|
|
@@ -915,7 +923,19 @@ module.exports = grammar({
|
|
|
915
923
|
typeref: $ => seq(
|
|
916
924
|
...enable_if(fpc, field('_dummy', optional($.kSpecialize))),
|
|
917
925
|
$._typeref,
|
|
918
|
-
|
|
926
|
+
// Trailing declaration hints on the type reference itself. The
|
|
927
|
+
// kDeprecated+message form predates this note; kPlatform (bare)
|
|
928
|
+
// added 2026-07-16 for the hint-BEFORE-initializer pattern
|
|
929
|
+
// Default8087CW: Word platform = $033F; (System.pas, x6)
|
|
930
|
+
// — with the hint absorbed here, declVar's `= expr` defaultValue
|
|
931
|
+
// follows naturally. A hint-then-value ARM inside declVar itself
|
|
932
|
+
// was tried first and is a bisect-confirmed generate table bomb
|
|
933
|
+
// (see TODO.md); this mirrors the existing kDeprecated role-set
|
|
934
|
+
// instead, which the tables already accommodate.
|
|
935
|
+
...enable_if(delphi, optional(choice(
|
|
936
|
+
seq($.kDeprecated, $._expr),
|
|
937
|
+
$.kPlatform,
|
|
938
|
+
))),
|
|
919
939
|
),
|
|
920
940
|
|
|
921
941
|
_typeref: $ => choice(
|
|
@@ -1632,7 +1652,18 @@ module.exports = grammar({
|
|
|
1632
1652
|
|
|
1633
1653
|
declField: $ => seq(
|
|
1634
1654
|
...enable_if(rtti, optional($.rttiAttributes)),
|
|
1635
|
-
field
|
|
1655
|
+
// Iter 2026-07-16: `Register` as a FIELD NAME after a prior field
|
|
1656
|
+
// (`Name: PAnsiChar; Register: UINT;` — Winapi.D3D10 shader
|
|
1657
|
+
// reflection records). Without the alias, the trailing-callconv
|
|
1658
|
+
// slot below ate `Register` and choked on the `:`. ONLY kRegister
|
|
1659
|
+
// is aliased — the 2026-07-06 attempt aliased all 7 callconv
|
|
1660
|
+
// keywords into BOTH declField and declFieldNoSemi and blew up
|
|
1661
|
+
// the tables; the narrow form + one-token lookahead (`:` vs `;`)
|
|
1662
|
+
// is all D3D10 needs.
|
|
1663
|
+
field('name', delimited1(choice(
|
|
1664
|
+
$.identifier,
|
|
1665
|
+
alias($.kRegister, $.identifier),
|
|
1666
|
+
))),
|
|
1636
1667
|
':',
|
|
1637
1668
|
// Iter 2026-07-06: a record/class field type may be a subrange, same
|
|
1638
1669
|
// as declVar already allows. `FtrListCount: 0 .. FTRRECMAXCOUNT;`
|
package/package.json
CHANGED
package/src/grammar.json
CHANGED
|
@@ -5358,15 +5358,24 @@
|
|
|
5358
5358
|
"type": "CHOICE",
|
|
5359
5359
|
"members": [
|
|
5360
5360
|
{
|
|
5361
|
-
"type": "
|
|
5361
|
+
"type": "CHOICE",
|
|
5362
5362
|
"members": [
|
|
5363
5363
|
{
|
|
5364
|
-
"type": "
|
|
5365
|
-
"
|
|
5364
|
+
"type": "SEQ",
|
|
5365
|
+
"members": [
|
|
5366
|
+
{
|
|
5367
|
+
"type": "SYMBOL",
|
|
5368
|
+
"name": "kDeprecated"
|
|
5369
|
+
},
|
|
5370
|
+
{
|
|
5371
|
+
"type": "SYMBOL",
|
|
5372
|
+
"name": "_expr"
|
|
5373
|
+
}
|
|
5374
|
+
]
|
|
5366
5375
|
},
|
|
5367
5376
|
{
|
|
5368
5377
|
"type": "SYMBOL",
|
|
5369
|
-
"name": "
|
|
5378
|
+
"name": "kPlatform"
|
|
5370
5379
|
}
|
|
5371
5380
|
]
|
|
5372
5381
|
},
|
|
@@ -9635,8 +9644,22 @@
|
|
|
9635
9644
|
"type": "SEQ",
|
|
9636
9645
|
"members": [
|
|
9637
9646
|
{
|
|
9638
|
-
"type": "
|
|
9639
|
-
"
|
|
9647
|
+
"type": "CHOICE",
|
|
9648
|
+
"members": [
|
|
9649
|
+
{
|
|
9650
|
+
"type": "SYMBOL",
|
|
9651
|
+
"name": "identifier"
|
|
9652
|
+
},
|
|
9653
|
+
{
|
|
9654
|
+
"type": "ALIAS",
|
|
9655
|
+
"content": {
|
|
9656
|
+
"type": "SYMBOL",
|
|
9657
|
+
"name": "kRegister"
|
|
9658
|
+
},
|
|
9659
|
+
"named": true,
|
|
9660
|
+
"value": "identifier"
|
|
9661
|
+
}
|
|
9662
|
+
]
|
|
9640
9663
|
},
|
|
9641
9664
|
{
|
|
9642
9665
|
"type": "STRING",
|
|
@@ -9652,8 +9675,22 @@
|
|
|
9652
9675
|
]
|
|
9653
9676
|
},
|
|
9654
9677
|
{
|
|
9655
|
-
"type": "
|
|
9656
|
-
"
|
|
9678
|
+
"type": "CHOICE",
|
|
9679
|
+
"members": [
|
|
9680
|
+
{
|
|
9681
|
+
"type": "SYMBOL",
|
|
9682
|
+
"name": "identifier"
|
|
9683
|
+
},
|
|
9684
|
+
{
|
|
9685
|
+
"type": "ALIAS",
|
|
9686
|
+
"content": {
|
|
9687
|
+
"type": "SYMBOL",
|
|
9688
|
+
"name": "kRegister"
|
|
9689
|
+
},
|
|
9690
|
+
"named": true,
|
|
9691
|
+
"value": "identifier"
|
|
9692
|
+
}
|
|
9693
|
+
]
|
|
9657
9694
|
}
|
|
9658
9695
|
]
|
|
9659
9696
|
}
|
|
@@ -13045,6 +13082,13 @@
|
|
|
13045
13082
|
"_declProcLenient",
|
|
13046
13083
|
"_procAttributeNoExt"
|
|
13047
13084
|
],
|
|
13085
|
+
[
|
|
13086
|
+
"declFieldNoSemi",
|
|
13087
|
+
"declField"
|
|
13088
|
+
],
|
|
13089
|
+
[
|
|
13090
|
+
"declField"
|
|
13091
|
+
],
|
|
13048
13092
|
[
|
|
13049
13093
|
"declProcFwd"
|
|
13050
13094
|
],
|