tree-sitter-delphi13 1.2.1 → 1.2.2
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 +18 -9
- package/grammar.js +23 -1
- package/package.json +1 -1
- package/prebuilds/win32-x64/tree-sitter-delphi13.node +0 -0
- package/src/grammar.json +72 -2
- package/src/parser.c +346693 -345532
package/README.md
CHANGED
|
@@ -2,15 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/tree-sitter-delphi13)
|
|
4
4
|
[](LICENSE)
|
|
5
|
+
[](CORPUS-CEILING-REPORT.md)
|
|
6
|
+
[](CORPUS-CEILING-REPORT.md)
|
|
5
7
|
|
|
6
8
|
Tree-sitter grammar pipeline focused on **Delphi 13 (RAD Studio 37.0 / Florence)** and the surrounding modern Delphi ecosystem.
|
|
7
9
|
|
|
8
|
-
**v1.2.
|
|
9
|
-
on
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
remains is individually diagnosed, dcc32-cross-checked, and *supposed*
|
|
13
|
-
(see [CORPUS-CEILING-REPORT.md](CORPUS-CEILING-REPORT.md)).
|
|
10
|
+
**v1.2.2: 100.000% pass rate on compilable Delphi 13** (zero ERROR nodes), measured
|
|
11
|
+
on a corpus spanning the RAD Studio 13 RTL/VCL (including `System.pas`), DevExpress,
|
|
12
|
+
Spring4D, EurekaLog, Indy, FireDAC, AsyncPro/Orpheus, **JCL/JVCL (JEDI)**, mORMot-era
|
|
13
|
+
community code and a full production application — 23,385 deduplicated files. Every
|
|
14
|
+
failure that remains is individually diagnosed, dcc32-cross-checked, and *supposed*
|
|
15
|
+
to fail (see [CORPUS-CEILING-REPORT.md](CORPUS-CEILING-REPORT.md)).
|
|
16
|
+
|
|
17
|
+
v1.2.2 added the JEDI (JCL + JVCL) libraries to the corpus and closed the three
|
|
18
|
+
valid-Delphi-13 gaps they surfaced: a subrange bound that is a nested constant-expr
|
|
19
|
+
call (`2..Succ(High(T))`), the `at` soft keyword as an `inherited` method name
|
|
20
|
+
(`inherited At(...)`), and `Operator` used as a record/class field name.
|
|
14
21
|
|
|
15
22
|
| measurement basis | pass rate |
|
|
16
23
|
|---|---|
|
|
@@ -31,9 +38,9 @@ watchlist).
|
|
|
31
38
|
|---|---|
|
|
32
39
|
| **`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). |
|
|
33
40
|
| **[`tree-sitter-delphi13-pure`](pure/)** | Simpler sub-grammar that drops `pp_*` tokens entirely. Expects preprocessor-resolved source. |
|
|
34
|
-
| **[`delphi13-preprocessor`](preprocessor/)** | Standalone JavaScript library that resolves `{$IFDEF}` / `{$IF}` / `{$DEFINE}` / `{$I X.inc}` directives as a text transformation. |
|
|
41
|
+
| **[`delphi13-preprocessor`](preprocessor/)** | Standalone JavaScript library that resolves `{$IFDEF}` / `{$IF}` / `{$DEFINE}` / `{$I X.inc}` directives as a text transformation. The **canonical** preprocessor is now a pure-Delphi port of this library (shipping inside drag-lint); this JS package remains the byte-for-byte oracle and the drop-in choice for JavaScript consumers. |
|
|
35
42
|
|
|
36
|
-
The full pipeline `preprocessor → pure → AST` is what reaches **
|
|
43
|
+
The full pipeline `preprocessor → pure → AST` is what reaches **100.000%** on valid
|
|
37
44
|
Delphi 13. Use the master grammar alone (98.6% raw) if you don't need
|
|
38
45
|
conditional-compilation awareness; use the pipeline if you do.
|
|
39
46
|
|
|
@@ -138,7 +145,9 @@ node-gyp rebuild
|
|
|
138
145
|
|
|
139
146
|
- **Inline `asm` blocks** treated as opaque text by design. Not tree-sitter-asm.
|
|
140
147
|
- **`{$IF declared(SymName)}`** always evaluates to `false` — no symbol table. ~10 corpus files use this. A lightweight symbol pre-scan would address most cases.
|
|
141
|
-
- **Include
|
|
148
|
+
- **Include resolution** is nearest-first (same directory, its subdirectories, then
|
|
149
|
+
up to 3 parent levels with their subdirectories — v1.1.0 of the preprocessor).
|
|
150
|
+
Arbitrary project search paths still need the `includePaths` option.
|
|
142
151
|
- **FreePascal-specific extensions** (operator overloading variants, `{$mode ObjFPC}` directives, macOS PasCocoa namespaces) are not covered. A separate `tree-sitter-delphi-plus-fp` repo is planned.
|
|
143
152
|
|
|
144
153
|
## Acknowledgements
|
package/grammar.js
CHANGED
|
@@ -756,7 +756,16 @@ module.exports = grammar({
|
|
|
756
756
|
field('body', choice(tr($, 'block'), tr($, 'asm'))),
|
|
757
757
|
),
|
|
758
758
|
|
|
759
|
-
inherited: $ => prec.right(seq($.kInherited, optional(
|
|
759
|
+
inherited: $ => prec.right(seq($.kInherited, optional(choice(
|
|
760
|
+
$.identifier,
|
|
761
|
+
// Soft keyword `at` (the raise-with-address `raise E at Addr`
|
|
762
|
+
// keyword) used as an INHERITED method name: `inherited At(Offset)`
|
|
763
|
+
// (JCL JclCLR.pas). `At` already works as a plain/dotted call and a
|
|
764
|
+
// field name; only the inherited slot lost it to the kAtWord token.
|
|
765
|
+
// Aliased to identifier so the call-args attach exactly as for
|
|
766
|
+
// `inherited Foo(x)`. Narrow — only the corpus-confirmed kAtWord.
|
|
767
|
+
alias($.kAtWord, $.identifier),
|
|
768
|
+
)))),
|
|
760
769
|
|
|
761
770
|
exprDot: $ => choice(
|
|
762
771
|
op.infix(5, $._ref, $.kDot, $._ref),
|
|
@@ -1288,6 +1297,13 @@ module.exports = grammar({
|
|
|
1288
1297
|
// conflicts with typerefDot in this position.)
|
|
1289
1298
|
seq($.identifier, '.', $.identifier),
|
|
1290
1299
|
seq($.identifier, '(', $.identifier, ')'),
|
|
1300
|
+
// Iter 2026-07-17: nested const-expr call bound —
|
|
1301
|
+
// `2 .. Succ(High(TDigitValue))` (JCL JclSysUtils TNumericSystemBase).
|
|
1302
|
+
// dcc accepts any constant ordinal expression as a bound; the grammar
|
|
1303
|
+
// stays with the narrow corpus-driven enumeration (a wide `_expr`
|
|
1304
|
+
// bound blows the parser tables, see above), adding just the one
|
|
1305
|
+
// real shape: `Ident( Ident(Ident) )`, one level of call nesting.
|
|
1306
|
+
seq($.identifier, '(', seq($.identifier, '(', $.identifier, ')'), ')'),
|
|
1291
1307
|
// `hid - 1`, `MaxN + 2` — narrow `identifier OP integer` form for
|
|
1292
1308
|
// real-corpus patterns like `TNmbrRange = 0 .. hid - 1;`.
|
|
1293
1309
|
// Kept narrow (no full _expr) to avoid the conflict cascade hit
|
|
@@ -1663,6 +1679,12 @@ module.exports = grammar({
|
|
|
1663
1679
|
field('name', delimited1(choice(
|
|
1664
1680
|
$.identifier,
|
|
1665
1681
|
alias($.kRegister, $.identifier),
|
|
1682
|
+
// Iter 2026-07-17: `Operator` as a FIELD NAME
|
|
1683
|
+
// (`Operator: TJvXmlSQLOperator;` — JVCL JvXmlDatabase). The
|
|
1684
|
+
// `operator` token otherwise starts _declOperator; GLR splits
|
|
1685
|
+
// on the follow token (`:` -> field, operator-name -> class
|
|
1686
|
+
// operator). Same narrow one-keyword alias as kRegister above.
|
|
1687
|
+
alias($.kOperator, $.identifier),
|
|
1666
1688
|
))),
|
|
1667
1689
|
':',
|
|
1668
1690
|
// Iter 2026-07-06: a record/class field type may be a subrange, same
|
package/package.json
CHANGED
|
Binary file
|
package/src/grammar.json
CHANGED
|
@@ -3671,8 +3671,22 @@
|
|
|
3671
3671
|
"type": "CHOICE",
|
|
3672
3672
|
"members": [
|
|
3673
3673
|
{
|
|
3674
|
-
"type": "
|
|
3675
|
-
"
|
|
3674
|
+
"type": "CHOICE",
|
|
3675
|
+
"members": [
|
|
3676
|
+
{
|
|
3677
|
+
"type": "SYMBOL",
|
|
3678
|
+
"name": "identifier"
|
|
3679
|
+
},
|
|
3680
|
+
{
|
|
3681
|
+
"type": "ALIAS",
|
|
3682
|
+
"content": {
|
|
3683
|
+
"type": "SYMBOL",
|
|
3684
|
+
"name": "kAtWord"
|
|
3685
|
+
},
|
|
3686
|
+
"named": true,
|
|
3687
|
+
"value": "identifier"
|
|
3688
|
+
}
|
|
3689
|
+
]
|
|
3676
3690
|
},
|
|
3677
3691
|
{
|
|
3678
3692
|
"type": "BLANK"
|
|
@@ -7195,6 +7209,44 @@
|
|
|
7195
7209
|
}
|
|
7196
7210
|
]
|
|
7197
7211
|
},
|
|
7212
|
+
{
|
|
7213
|
+
"type": "SEQ",
|
|
7214
|
+
"members": [
|
|
7215
|
+
{
|
|
7216
|
+
"type": "SYMBOL",
|
|
7217
|
+
"name": "identifier"
|
|
7218
|
+
},
|
|
7219
|
+
{
|
|
7220
|
+
"type": "STRING",
|
|
7221
|
+
"value": "("
|
|
7222
|
+
},
|
|
7223
|
+
{
|
|
7224
|
+
"type": "SEQ",
|
|
7225
|
+
"members": [
|
|
7226
|
+
{
|
|
7227
|
+
"type": "SYMBOL",
|
|
7228
|
+
"name": "identifier"
|
|
7229
|
+
},
|
|
7230
|
+
{
|
|
7231
|
+
"type": "STRING",
|
|
7232
|
+
"value": "("
|
|
7233
|
+
},
|
|
7234
|
+
{
|
|
7235
|
+
"type": "SYMBOL",
|
|
7236
|
+
"name": "identifier"
|
|
7237
|
+
},
|
|
7238
|
+
{
|
|
7239
|
+
"type": "STRING",
|
|
7240
|
+
"value": ")"
|
|
7241
|
+
}
|
|
7242
|
+
]
|
|
7243
|
+
},
|
|
7244
|
+
{
|
|
7245
|
+
"type": "STRING",
|
|
7246
|
+
"value": ")"
|
|
7247
|
+
}
|
|
7248
|
+
]
|
|
7249
|
+
},
|
|
7198
7250
|
{
|
|
7199
7251
|
"type": "SEQ",
|
|
7200
7252
|
"members": [
|
|
@@ -9658,6 +9710,15 @@
|
|
|
9658
9710
|
},
|
|
9659
9711
|
"named": true,
|
|
9660
9712
|
"value": "identifier"
|
|
9713
|
+
},
|
|
9714
|
+
{
|
|
9715
|
+
"type": "ALIAS",
|
|
9716
|
+
"content": {
|
|
9717
|
+
"type": "SYMBOL",
|
|
9718
|
+
"name": "kOperator"
|
|
9719
|
+
},
|
|
9720
|
+
"named": true,
|
|
9721
|
+
"value": "identifier"
|
|
9661
9722
|
}
|
|
9662
9723
|
]
|
|
9663
9724
|
},
|
|
@@ -9689,6 +9750,15 @@
|
|
|
9689
9750
|
},
|
|
9690
9751
|
"named": true,
|
|
9691
9752
|
"value": "identifier"
|
|
9753
|
+
},
|
|
9754
|
+
{
|
|
9755
|
+
"type": "ALIAS",
|
|
9756
|
+
"content": {
|
|
9757
|
+
"type": "SYMBOL",
|
|
9758
|
+
"name": "kOperator"
|
|
9759
|
+
},
|
|
9760
|
+
"named": true,
|
|
9761
|
+
"value": "identifier"
|
|
9692
9762
|
}
|
|
9693
9763
|
]
|
|
9694
9764
|
}
|