Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitkeep
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# .gitkeep file auto-generated at 2026-08-28T06:09:39.810Z for PR creation at branch issue-288-cc91e23553e8 for issue https://github.com/link-foundation/links-notation/issues/288
# Updated: 2026-08-28T07:33:05.436Z
# Updated: 2026-08-28T11:11:17.987Z
# Updated: 2026-08-28T12:23:46.151Z
# Updated: 2026-08-28T12:23:46.151Z
# Updated: 2026-09-05T15:58:22.114Z
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
NuGet, Maven Central, Packagist and proxy.golang.org are each polled for the
version just released, and the GitHub release is created only once the
registry confirms it ([#290](https://github.com/link-foundation/links-notation/issues/290))
- Rust: `ParseError::SyntaxError` carries where a document stopped parsing —
`offset`, `line`, `column`, `expected`, `found` and the offending line — and
`SyntaxError::summary()` and `SyntaxError::snippet()` render it. The crate
also exports `parse_document_with_diagnostics`, and
`cargo run --example parse_error_positions` prints what several broken
documents report ([#302](https://github.com/link-foundation/links-notation/issues/302))
- JavaScript: `ParseError`, exported from the package, thrown by
`Parser.parse` when a document does not parse. It carries `offset`, `line`,
`column`, `found`, `lineText`, `snippet`, the generated parser's `location`
and the original error as `cause` ([#302](https://github.com/link-foundation/links-notation/issues/302))
- C#: `ParseException`, thrown by `Parser.Parse`, carrying `Offset`, `Line`,
`Column`, `Found`, `LineText`, `Summary` and `Snippet`. The Pegasus grammar
turns on `@trace true` so `FurthestFailureTracer` can record the furthest
position any rule reached, which is the only position that says where a
backtracking parser gave up ([#302](https://github.com/link-foundation/links-notation/issues/302))
- `experiments/issue-302/run.sh` asks all seven implementations about the same
five documents, four of which do not parse, and prints the answers next to
each other ([#302](https://github.com/link-foundation/links-notation/issues/302))

### Changed
- Every manifest checked against what the registries publish today and updated:
Expand Down Expand Up @@ -143,6 +161,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
where a cancelled run should not continue ([#290](https://github.com/link-foundation/links-notation/issues/290))
- C# packaging and DocFX configuration are vendored in the repository instead of
being fetched at run time ([#290](https://github.com/link-foundation/links-notation/issues/290))
- Rust, JavaScript and C# report a failed parse the same way: a first line
saying the position and what was expected, then the offending line with a
caret under it. All three agree on the offset of every defect the comparison
script checks ([#302](https://github.com/link-foundation/links-notation/issues/302))
- Rust: `lino!` used to panic with a fixed sentence that named neither the
reason nor the position when text that balances its parentheses is refused by
the parser at runtime; it now panics with the parse error ([#302](https://github.com/link-foundation/links-notation/issues/302))
- C#: `Parser.Parse` throws `ParseException` rather than the generated parser's
`FormatException`. `ParseException` derives from `FormatException`, so callers
that catch the base type keep working ([#302](https://github.com/link-foundation/links-notation/issues/302))

### Fixed
- Docs: nested contexts were described in the English READMEs and in the root
Expand Down Expand Up @@ -237,6 +265,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`experiments/test_coverage_data.json` into the `go` flag ([#290](https://github.com/link-foundation/links-notation/issues/290))
- Docs website: `docs/website/package.json` declares `"type": "module"`, so the ESM `vite.config.js`
is no longer loaded as CommonJS and every build no longer warns ([#290](https://github.com/link-foundation/links-notation/issues/290))
- Rust: a failed parse printed the raw `nom` error —
`Error(Error { input: "<the whole rest of the document>", code: Eof })` —
which named no line, no column and nothing that was expected, and grew with
the size of the document. It now says
`line 2, column 8: expected "(", a reference or end of line, found ":"` and
quotes one line. The reported position is the furthest any alternative
reached, so it points at the defect rather than at the start of the line the
parser last accepted ([#302](https://github.com/link-foundation/links-notation/issues/302))
- C#: a failed parse said `Failed to parse 'document'.` and pinned its cursor at
line 1, column 1, because the generated parser backtracks out of the start
rule before it throws. It now reports the position the document really stopped
at ([#302](https://github.com/link-foundation/links-notation/issues/302))
- JavaScript: the generated parser reported the position on the error object but
not in the message, so a caller that printed the message lost it
([#302](https://github.com/link-foundation/links-notation/issues/302))

## [0.11.2] - 2024-XX-XX

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,9 @@ All seven language implementations (C#, JavaScript, Rust, Python, Go, Java, PHP)
| Language | Tests | Test categories |
| --- | --- | --- |
| Python | 146 | 14 |
| JavaScript | 204 | 16 |
| Rust | 283 | 18 |
| C# | 196 | 17 |
| JavaScript | 214 | 17 |
| Rust | 299 | 19 |
| C# | 207 | 18 |
| Go | 86 | 10 |
| Java | 133 | 9 |
| PHP | 183 | 16 |
Expand Down
6 changes: 3 additions & 3 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,9 @@ value (
| Язык | Тестов | Категорий тестов |
| --- | --- | --- |
| Python | 146 | 14 |
| JavaScript | 204 | 16 |
| Rust | 283 | 18 |
| C# | 196 | 17 |
| JavaScript | 214 | 17 |
| Rust | 299 | 19 |
| C# | 207 | 18 |
| Go | 86 | 10 |
| Java | 133 | 9 |
| PHP | 183 | 16 |
Expand Down
180 changes: 170 additions & 10 deletions TEST_CASE_COMPARISON.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ Go keeps most of its tests in a single file rather than one file per category, s
| Language | Total Tests | Test Categories |
|----------|-------------|----------------|
| Python | 146 | 14 |
| JavaScript | 204 | 16 |
| Rust | 283 | 18 |
| C# | 196 | 17 |
| JavaScript | 214 | 17 |
| Rust | 299 | 19 |
| C# | 207 | 18 |
| Go | 86 | 10 |
| Java | 133 | 9 |
| PHP | 183 | 16 |
Expand Down Expand Up @@ -473,6 +473,35 @@ Go keeps most of its tests in a single file rather than one file per category, s

**Category totals:** Python: 2, JavaScript: 2, Rust: 2, C#: 2, Go: 0, Java: 0, PHP: 2

## Parse Error Position

| Test Name | Python | JavaScript | Rust | C# | Go | Java | PHP |
|-----------|---|---|---|---|---|---|---|
| a document that parses reports nothing | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L107) | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L178) | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L134) | ❌ | ❌ | ❌ |
| both entry points report the same position | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L155) | ❌ | ❌ | ❌ | ❌ |
| column counts characters rather than bytes | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L167) | ❌ | ❌ | ❌ | ❌ |
| does not mention the grammar internals test | ❌ | ❌ | ❌ | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L125) | ❌ | ❌ | ❌ |
| error display starts with the position | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L136) | ❌ | ❌ | ❌ | ❌ |
| keeps catching code that expects a format exception working test | ❌ | ❌ | ❌ | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L114) | ❌ | ❌ | ❌ |
| message of a long line stays a message | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L89) | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L119) | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L101) | ❌ | ❌ | ❌ |
| message points a caret at the offending character test | ❌ | ❌ | ❌ | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L76) | ❌ | ❌ | ❌ |
| message quotes one line rather than the rest of the document | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L79) | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L105) | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L88) | ❌ | ❌ | ❌ |
| message says where the document broke | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L70) | ❌ | ❌ | ❌ | ❌ | ❌ |
| nom internals stay out of the message | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L146) | ❌ | ❌ | ❌ | ❌ |
| offset agrees with the javascript port | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L29) | ❌ | ❌ | ❌ | ❌ |
| offset agrees with the other implementations | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L34) | ❌ | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L32) | ❌ | ❌ | ❌ |
| points at the defect rather than at the line it starts on | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L39) | ❌ | ❌ | ❌ | ❌ |
| reports an unmatched closing parenthesis | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L61) | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L77) | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L65) | ❌ | ❌ | ❌ |
| reports the end of the document when a group is never closed | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L51) | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L65) | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L53) | ❌ | ❌ | ❌ |
| reports the line a late defect is on | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L43) | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L49) | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L43) | ❌ | ❌ | ❌ |
| reports the line and column of the defect | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L24) | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L18) | [✅](csharp/Link.Foundation.Links.Notation.Tests/ParseErrorPositionTests.cs#L20) | ❌ | ❌ | ❌ |
| says what could have stood there | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L58) | ❌ | ❌ | ❌ | ❌ |
| snippet points a caret at the offending character | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L98) | ❌ | ❌ | ❌ | ❌ |
| summary reads as a sentence | ❌ | ❌ | [✅](rust/links-notation/tests/parse_error_position_tests.rs#L88) | ❌ | ❌ | ❌ | ❌ |
| the location the parser used to report is still there | ❌ | [✅](js/tests/ParseErrorPosition.test.js#L100) | ❌ | ❌ | ❌ | ❌ | ❌ |

**Category totals:** Python: 0, JavaScript: 10, Rust: 16, C#: 11, Go: 0, Java: 0, PHP: 0

## Single Line Parser

| Test Name | Python | JavaScript | Rust | C# | Go | Java | PHP |
Expand Down Expand Up @@ -821,6 +850,30 @@ Go keeps most of its tests in a single file rather than one file per category, s
- nestedlinknoid
- nestedlinkwithquotedvalues

**Parse Error Position** (22 missing):
- adocumentthatparsesreportsnothing
- bothentrypointsreportthesameposition
- columncountscharactersratherthanbytes
- doesnotmentionthegrammarinternals
- errordisplaystartswiththeposition
- keepscatchingcodethatexpectsaformatexceptionworking
- messageofalonglinestaysamessage
- messagepointsacaretattheoffendingcharacter
- messagequotesonelineratherthantherestofthedocument
- messagesayswherethedocumentbroke
- nominternalsstayoutofthemessage
- offsetagreeswiththejavascriptport
- offsetagreeswiththeotherimplementations
- pointsatthedefectratherthanatthelineitstartson
- reportsanunmatchedclosingparenthesis
- reportstheendofthedocumentwhenagroupisneverclosed
- reportsthelinealatedefectison
- reportsthelineandcolumnofthedefect
- sayswhatcouldhavestoodthere
- snippetpointsacaretattheoffendingcharacter
- summaryreadsasasentence
- thelocationtheparserusedtoreportisstillthere

**Single Line Parser** (4 missing):
- parsequotedreferencesvalues
- quotedreferencesinlink
Expand Down Expand Up @@ -878,7 +931,7 @@ Go keeps most of its tests in a single file rather than one file per category, s
- vecstringtoanonymouslink
- vecstrtoanonymouslink

**Total missing: 264 tests**
**Total missing: 286 tests**

### JavaScript Missing Tests

Expand Down Expand Up @@ -1062,6 +1115,20 @@ Go keeps most of its tests in a single file rather than one file per category, s
- nestedlinknoid
- nestedlinkwithquotedvalues

**Parse Error Position** (12 missing):
- bothentrypointsreportthesameposition
- columncountscharactersratherthanbytes
- doesnotmentionthegrammarinternals
- errordisplaystartswiththeposition
- keepscatchingcodethatexpectsaformatexceptionworking
- messagepointsacaretattheoffendingcharacter
- nominternalsstayoutofthemessage
- offsetagreeswiththejavascriptport
- pointsatthedefectratherthanatthelineitstartson
- sayswhatcouldhavestoodthere
- snippetpointsacaretattheoffendingcharacter
- summaryreadsasasentence

**Single Line Parser** (4 missing):
- parsequotedreferencesvalues
- quotedreferencesinlink
Expand Down Expand Up @@ -1119,7 +1186,7 @@ Go keeps most of its tests in a single file rather than one file per category, s
- vecstringtoanonymouslink
- vecstrtoanonymouslink

**Total missing: 207 tests**
**Total missing: 219 tests**

### Rust Missing Tests

Expand Down Expand Up @@ -1265,6 +1332,14 @@ Go keeps most of its tests in a single file rather than one file per category, s
- nestedlinknoid
- nestedlinkwithquotedvalues

**Parse Error Position** (6 missing):
- doesnotmentionthegrammarinternals
- keepscatchingcodethatexpectsaformatexceptionworking
- messagepointsacaretattheoffendingcharacter
- messagesayswherethedocumentbroke
- offsetagreeswiththeotherimplementations
- thelocationtheparserusedtoreportisstillthere

**Single Line Parser** (4 missing):
- parsequotedreferencesvalues
- quotedreferencesinlink
Expand All @@ -1275,7 +1350,7 @@ Go keeps most of its tests in a single file rather than one file per category, s
- namedtupletolink
- tupletolink

**Total missing: 128 tests**
**Total missing: 134 tests**

### C# Missing Tests

Expand Down Expand Up @@ -1469,6 +1544,19 @@ Go keeps most of its tests in a single file rather than one file per category, s
- nestedlinknoid
- nestedlinkwithquotedvalues

**Parse Error Position** (11 missing):
- bothentrypointsreportthesameposition
- columncountscharactersratherthanbytes
- errordisplaystartswiththeposition
- messagesayswherethedocumentbroke
- nominternalsstayoutofthemessage
- offsetagreeswiththejavascriptport
- pointsatthedefectratherthanatthelineitstartson
- sayswhatcouldhavestoodthere
- snippetpointsacaretattheoffendingcharacter
- summaryreadsasasentence
- thelocationtheparserusedtoreportisstillthere

**Single Line Parser** (3 missing):
- parsequotedreferencesvalues
- quotedreferencesinlink
Expand Down Expand Up @@ -1523,7 +1611,7 @@ Go keeps most of its tests in a single file rather than one file per category, s
- vecstringtoanonymouslink
- vecstrtoanonymouslink

**Total missing: 214 tests**
**Total missing: 225 tests**

### Go Missing Tests

Expand Down Expand Up @@ -1806,6 +1894,30 @@ Go keeps most of its tests in a single file rather than one file per category, s
- nestedselfreferencedobjectinpairvalue
- selfreferenceasdirectchildworkscorrectly

**Parse Error Position** (22 missing):
- adocumentthatparsesreportsnothing
- bothentrypointsreportthesameposition
- columncountscharactersratherthanbytes
- doesnotmentionthegrammarinternals
- errordisplaystartswiththeposition
- keepscatchingcodethatexpectsaformatexceptionworking
- messageofalonglinestaysamessage
- messagepointsacaretattheoffendingcharacter
- messagequotesonelineratherthantherestofthedocument
- messagesayswherethedocumentbroke
- nominternalsstayoutofthemessage
- offsetagreeswiththejavascriptport
- offsetagreeswiththeotherimplementations
- pointsatthedefectratherthanatthelineitstartson
- reportsanunmatchedclosingparenthesis
- reportstheendofthedocumentwhenagroupisneverclosed
- reportsthelinealatedefectison
- reportsthelineandcolumnofthedefect
- sayswhatcouldhavestoodthere
- snippetpointsacaretattheoffendingcharacter
- summaryreadsasasentence
- thelocationtheparserusedtoreportisstillthere

**Single Line Parser** (26 missing):
- bugtest 1
- linkwithid
Expand Down Expand Up @@ -1885,7 +1997,7 @@ Go keeps most of its tests in a single file rather than one file per category, s
- vecstringtoanonymouslink
- vecstrtoanonymouslink

**Total missing: 320 tests**
**Total missing: 342 tests**

### Java Missing Tests

Expand Down Expand Up @@ -2142,6 +2254,30 @@ Go keeps most of its tests in a single file rather than one file per category, s
- nestedselfreferencedobjectinpairvalue
- selfreferenceasdirectchildworkscorrectly

**Parse Error Position** (22 missing):
- adocumentthatparsesreportsnothing
- bothentrypointsreportthesameposition
- columncountscharactersratherthanbytes
- doesnotmentionthegrammarinternals
- errordisplaystartswiththeposition
- keepscatchingcodethatexpectsaformatexceptionworking
- messageofalonglinestaysamessage
- messagepointsacaretattheoffendingcharacter
- messagequotesonelineratherthantherestofthedocument
- messagesayswherethedocumentbroke
- nominternalsstayoutofthemessage
- offsetagreeswiththejavascriptport
- offsetagreeswiththeotherimplementations
- pointsatthedefectratherthanatthelineitstartson
- reportsanunmatchedclosingparenthesis
- reportstheendofthedocumentwhenagroupisneverclosed
- reportsthelinealatedefectison
- reportsthelineandcolumnofthedefect
- sayswhatcouldhavestoodthere
- snippetpointsacaretattheoffendingcharacter
- summaryreadsasasentence
- thelocationtheparserusedtoreportisstillthere

**Single Line Parser** (9 missing):
- linkwithoutidmultiline
- linkwithoutidsingleline
Expand Down Expand Up @@ -2204,7 +2340,7 @@ Go keeps most of its tests in a single file rather than one file per category, s
- vecstringtoanonymouslink
- vecstrtoanonymouslink

**Total missing: 277 tests**
**Total missing: 299 tests**

### PHP Missing Tests

Expand Down Expand Up @@ -2396,6 +2532,30 @@ Go keeps most of its tests in a single file rather than one file per category, s
- nestedlinknoid
- nestedlinkwithquotedvalues

**Parse Error Position** (22 missing):
- adocumentthatparsesreportsnothing
- bothentrypointsreportthesameposition
- columncountscharactersratherthanbytes
- doesnotmentionthegrammarinternals
- errordisplaystartswiththeposition
- keepscatchingcodethatexpectsaformatexceptionworking
- messageofalonglinestaysamessage
- messagepointsacaretattheoffendingcharacter
- messagequotesonelineratherthantherestofthedocument
- messagesayswherethedocumentbroke
- nominternalsstayoutofthemessage
- offsetagreeswiththejavascriptport
- offsetagreeswiththeotherimplementations
- pointsatthedefectratherthanatthelineitstartson
- reportsanunmatchedclosingparenthesis
- reportstheendofthedocumentwhenagroupisneverclosed
- reportsthelinealatedefectison
- reportsthelineandcolumnofthedefect
- sayswhatcouldhavestoodthere
- snippetpointsacaretattheoffendingcharacter
- summaryreadsasasentence
- thelocationtheparserusedtoreportisstillthere

**Single Line Parser** (16 missing):
- linkwithoutidmultiline
- linkwithoutidsingleline
Expand Down Expand Up @@ -2465,5 +2625,5 @@ Go keeps most of its tests in a single file rather than one file per category, s
- vecstringtoanonymouslink
- vecstrtoanonymouslink

**Total missing: 227 tests**
**Total missing: 249 tests**

2 changes: 1 addition & 1 deletion benchmarks/BENCHMARK_RESULTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,4 @@ Sequences of unlimited length (N-tuples). Shape: Tuples. Source: [`datasets/sequ
- **The rest of the prompt.** Only the document is counted: no system prompt, no code fence, no schema description and no instructions. Those add a cost every format pays alike.
- **Speed and memory.** This is a size benchmark. How fast each format parses is a separate question with a separate answer.

Generated by `links-notation-benchmark` against `links-notation` 0.17.0.
Generated by `links-notation-benchmark` against `links-notation` 0.18.0.
Loading
Loading