Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3937a10
feat(glr): 軽量 GLR モードの ParseMode 配線 (フェーズ1)
actbit Jul 10, 2026
b0723de
feat(glr): 軽量 GLR ドライバを Runtime に追加 (フェーズ2)
actbit Jul 10, 2026
f49f840
feat(glr): GlrParserEmitter 本体と生成コード検証 (フェーズ3)
actbit Jul 10, 2026
c0a1c2d
feat(glr): LightGlr モードの E2E 検証 (フェーズ4)
actbit Jul 10, 2026
4b14f98
feat(glr): ASTF001 抑制 + CSharpParser で fork 解決を検証 (フェーズ5)
actbit Jul 10, 2026
7977879
feat(glr): CSharpParser と Perf.CSharp を LightGlr に恒久適用
actbit Jul 11, 2026
6198bd7
feat(glr): GrammarSpec を [Rule] モデルに対応、Perf.Gen を修復 (B1)
actbit Jul 11, 2026
22e1464
feat(glr): LightGlrDriver にパニック回復を追加 (A1)
actbit Jul 11, 2026
9706a44
feat(glr): ParseResult.AmbiguousCandidates を追加 (A2)
actbit Jul 11, 2026
428353e
docs(glr): ParseMode/LightGlr と OnReduce 契約を文法リファレンスに追記 (A3+A4)
actbit Jul 11, 2026
7d55dc0
feat(glr): Corchuelo et al. のエラー修復 ER1/ER2/ER3 で panic mode を置換
actbit Jul 11, 2026
c07e417
docs(glr): Corchuelo エラー修復の既知の制限を ja/en docs に明記
actbit Jul 11, 2026
7fe2ed4
fix(glr): 挿入トークン NRE 対策 + SimulateForward の実際トークン値使用
actbit Jul 12, 2026
40b834e
refactor(glr): GlrParserEmitter を internal 化 + docs 整理
actbit Jul 12, 2026
7f15473
fix(glr): fork snapshot 修正 + Accept/Reject 統合 (LightGlr モード)
actbit Jul 12, 2026
dcdf11d
feat(glr): ErrorRepair 共通化 — LALR/LightGlr 両モードで Corchuelo 修復
actbit Jul 12, 2026
2a68bc9
refactor(glr): LightGlrDriver の dead code (古い Repair/SimulateForward)…
actbit Jul 12, 2026
b57599e
refactor(glr): ApplyReduce/LookaheadSym を ErrorRepair に集約 (重複解消)
actbit Jul 12, 2026
35b2c95
feat(glr): fork 収束時に MarkAccepted で経路確定を伝える
actbit Jul 12, 2026
03851de
fix(glr): MarkAccepted を reduce 時でなく「ルートが1つになった」タイミングに
actbit Jul 12, 2026
98b4ff4
feat(glr): partial void OnAccepted() — ルート確定時のコールバック
actbit Jul 12, 2026
aaea220
refactor(glr): MarkAccepted → NotifyAccepted (シンプル化)
actbit Jul 12, 2026
8bd4a7c
feat(glr): OnAccepted(ctx) — ルート確定コールバックに ctx を渡す
actbit Jul 12, 2026
3585be3
feat: OnReduce の ctx を読み取り専用に (破壊的変更・バージョン互換なし)
actbit Jul 12, 2026
f3ab692
docs: 破壊的変更 (0.4.0) の移行ガイドを ja/en docs に追加
actbit Jul 12, 2026
f37ef80
fix: OnAccepted 未呼出し (バグ1) + LALR の破壊的 List.Add (バグ2)
actbit Jul 12, 2026
22a9f94
fix: バグ3修正 + 回帰テスト追加 + 不要な goto panic 削除
actbit Jul 12, 2026
e1ce063
fix: LALR のパニックモード (スタック pop) を完全削除
actbit Jul 12, 2026
4b35ad1
fix: [OnReduce] 属性メソッドの ctx を SemanticContext に統一
actbit Jul 12, 2026
8e972a2
fix: OnAccepted の ctx を書き込み可能 (ユーザーの ctx 型) に変更
actbit Jul 12, 2026
017fdde
docs: OnAccepted が書き込み可能 ctx を受け取ることを明記
actbit Jul 12, 2026
a5edf8f
perf: LightGlrDriver の Clone を大幅削減 (in-place shift/reduce)
actbit Jul 12, 2026
99e94eb
perf: LightGlrDriver に fast path を追加 (単一スタック時 LALR に近い性能)
actbit Jul 12, 2026
38728f3
chore: バージョンを 0.3.0 → 0.4.0 にアップ
actbit Jul 12, 2026
17bfc07
docs: CHANGELOG.md 追加 (0.4.0 の破壊的変更・新機能・パフォーマンス)
actbit Jul 12, 2026
0275eff
docs: README (ja/en) を 0.4.0 に更新
actbit Jul 12, 2026
9fc0088
docs: ベンチマーク数値を 0.4.0 に更新 (PerfSummary + README)
actbit Jul 12, 2026
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
49 changes: 49 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Changelog

## 0.4.0 — 軽量 GLR (LightGlr) モード + 読み取り専用 OnReduce

### ⚠ 破壊的変更 (後方互換性なし)

0.3.0 から以下の API が変更されました。既存コードの修正が必要です。

- **OnReduce の ctx が読み取り専用**: `OnReduce(MyCtx ctx)` → `OnReduce(SemanticContext ctx)`。宣言 (TryDeclare) や診断追加 (Error) は不可。
- **SemanticContext.Symbols が読み取り専用**: `IReadOnlySymbolTable` を返す (Lookup のみ)。
- **SemanticContext.Diagnostics 削除**: Diagnostics は `BasicSemanticContext` に移動。
- **書き込みは [Enter]/[Exit] で**: `ctx.WritableSymbols.TryDeclare(...)` / `ctx.Diagnostics.Error(...)`。
- **LALR のパニックモード削除**: スタック pop の代わりに Corchuelo et al. ER1/ER2/ER3 を使用。
- **List が COW に**: 破壊的 `List.Add` → copy-on-write (ErrorRepair の probe 安全性)。

### 新機能

- **軽量 GLR (LightGlr) モード**: `[Grammar(ParseMode = ParseMode.LightGlr)]` で本質的曖昧性 (cast/paren, generic) を並行 fork で解決。
- **ErrorRepair (Corchuelo et al.)**: ER1 挿入 / ER2 削除 / ER3 Forward move。LALR・LightGlr 両モードで共通使用。トークンを捨てない高品質エラー回復。
- **OnAccepted(ctx)**: GLR の fork が収束 (ルート確定) した時に呼ばれるコールバック。ctx 書き込み可能。
- **AmbiguousCandidates**: `ParseResult.AmbiguousCandidates` で複数解釈を観察可能。
- **NotifyAccepted**: ルート確定を AST に通知する virtual メソッド。
- **IReadOnlySymbolTable**: 読み取り専用シンボル表インターフェース。
- **GrammarSpec の [Rule] モデル対応**: Perf.Gen が正しく [Rule] static メソッドを生成。

### パフォーマンス

- LightGlrDriver に fast path (単一スタック時 LALR に近い性能) を追加。
- 単一スタック時は List/Queue/HashSet をバイパス、アロケーションほぼゼロ。
- fork が必要なコンフリクト経路のみ Clone。

### 内部変更

- `AstFirst.Glr.ErrorRepair` クラス追加 (Corchuelo ER1/ER2/BR3 共通ロジック)。
- `AstFirst.Glr.GlrTables` クラス追加 (LALR テーブル参照ラッパ)。
- `AstFirst.Glr.LightGlrDriver` クラス追加 (Tomita-lite GLR ドライバ)。
- `GlrParserEmitter` クラス追加 (LightGlr 専用エミッタ)。
- `ParserEmitter` の panic モードを Corchuelo 修復に置換。

---

## 0.3.0 — 意味解析機能の拡充

- [Enter]/[Exit]/[OnReduce] 属性・汎用 Walker・型システム拡張
- AST ノードの Span を子から自動計算 (OnReduce で上書き可)

## 0.2.x — 初期リリース

- LALR(1) パーサ生成・Lexer・AST・[Rule] static モデル
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>0.3.0</Version>
<Version>0.4.0</Version>
<Authors>actbit</Authors>
<PackageProjectUrl>https://github.com/actbit/AstFirst</PackageProjectUrl>
<RepositoryUrl>https://github.com/actbit/AstFirst</RepositoryUrl>
Expand Down
30 changes: 15 additions & 15 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

日本語 / [English](README.md)

C# の**クラスと属性**で文法を書くと、Source Generator がコンパイル時に Lexer と LALR(1) Parser を生成するパーサジェネレータ。生成された Parser は意味解析(スコープ付きシンボル表・2パス目 Walker・型チェック・`Accept`/`Reject` による意味的曖昧性解決)を乗せられる AST を返す。
C# の**クラスと属性**で文法を書くと、Source Generator がコンパイル時に Lexer と LALR(1) / 軽量 GLR (LightGlr) Parser を生成するパーサジェネレータ。生成された Parser は意味解析(スコープ付きシンボル表・2パス目 Walker・型チェック・`Accept`/`Reject` による意味的曖昧性解決)を乗せられる AST を返す。

## 他のライブラリとの比較

Expand All @@ -17,13 +17,13 @@ AstFirst はパーサジェネレータ・パーサコンビネータと同じ
| コード生成 | **コンパイル時** (Source Generator) | ビルド時コード生成ツール | **しない** (実行時に解釈) | 該当なし |
| 実行時パースコスト | **ゼロ** — 静的テーブル・ディスパッチなし | 生成コード | 解釈実行 (パース毎にアロケーション/ディスパッチ) | 該当なし |
| AOT / Native AOT | ✓ 実行時コード生成なし | △ | ✓ | 該当なし |
| アルゴリズム | LALR(1) テーブル駆動 | LL(\*) / ALL(\*) | 再帰下降コンビネータ | 該当なし |
| エラー回復 | panic mode (組み込み) | あり | 自作が必要 | 該当なし |
| 文法の表現力 | LALR(1) — `[Precedence]` で衝突解決 | LL(\*) | **チューリング完全** (任意の C# で分岐) | 該当なし |
| アルゴリズム | LALR(1) + 軽量 GLR (LightGlr) | LL(\*) / ALL(\*) | 再帰下降コンビネータ | 該当なし |
| エラー回復 | Corchuelo et al. ER1/ER2/ER3 (組み込み) | あり | 自作が必要 | 該当なし |
| 文法の表現力 | LALR(1) + GLR — `[Precedence]` / fork で衝突解決 | LL(\*) | **チューリング完全** (任意の C# で分岐) | 該当なし |

**コンビネータ (Superpower/Pidgin) に対する強み**: パーサを*コンパイル時*に静的テーブルとして生成するため、解釈もディスパッチもパーサ構築も実行時に走らない。起動・パース毎のコストが事実上ゼロで、AOT/Native AOT にも綺麗に通る。panic mode のエラー回復を組み込み。文法は宣言的な C# なので、IDE のナビゲーションやリファクタリングが効く。
**コンビネータ (Superpower/Pidgin) に対する強み**: パーサを*コンパイル時*に静的テーブルとして生成するため、解釈もディスパッチもパーサ構築も実行時に走らない。起動・パース毎のコストが事実上ゼロで、AOT/Native AOT にも綺麗に通る。Corchuelo et al. の高品質エラー回復 (ER1 挿入 / ER2 削除 / ER3 Forward move) を組み込み。文法は宣言的な C# なので、IDE のナビゲーションやリファクタリングが効く。

**トレードオフ**: LALR(1) は `[Precedence]`/結合性で shift-reduce 衝突を解決する必要がある(コンビネータはパース中に任意の C# で分岐できて自由)。C# 専用のツールチェイン。
**トレードオフ**: LALR(1) は `[Precedence]`/結合性で shift-reduce 衝突を解決する必要がある。ただし LightGlr モード (`[Grammar(ParseMode = ParseMode.LightGlr)]`) で本質的曖昧性 (cast/paren・generic 等) を並行 fork で扱える。C# 専用のツールチェイン。

**なぜ Source Generator か**: Lexer/Parser/Walker はコンパイラが見る普通の C# で、IDE で開ける (`.g.cs` がプロジェクト内にあり、Go to Definition が効く)。実行時にパーサを*構築*することは一度もなく、文法のミス(未解決コンフリクト・到達不能規則)は初回 `Parse` ではなく**コンパイル時の警告**として出る。

Expand All @@ -32,12 +32,12 @@ AstFirst はパーサジェネレータ・パーサコンビネータと同じ
- **C# コードで文法定義**: クラスの継承ツリーで構文、`[Rule]` static メソッドの引数で右辺・字句ルール。特別な構文や DSL ファイルは不要。
- **Source Generator (`IIncrementalGenerator`)**: コンパイル時に Lexer / Parser / partial プロパティ の C# コードを生成。実行時コード生成なし。
- **正規表現ベースのレクサ**: 文字クラス圧縮、最長一致 + 優先度駆動、`{m,n}` 量指定子、Unicode 補助面に対応。トークンの**行・列**も計算。
- **LALR(1) 構文解析**: 優先度/結合性 (`[Precedence]`) で shift-reduce 衝突を解決(`*` > `+`、代入の右結合等)。
- **意味的曖昧性の解決 (Accept/Reject)**: reduce 時の `OnReduce` で `Reject()` すると、優先度順の別候補(別規則/shift)へフォールバック。cast vs 括弧式のような意味依存の曖昧性を構文解析で解決できる
- **LALR(1) + 軽量 GLR 構文解析**: デフォルトは LALR(1)。`[Grammar(ParseMode = ParseMode.LightGlr)]` で軽量 GLR に切り替え、本質的曖昧性 (cast/paren・generic) を並行 fork で解決。優先度/結合性 (`[Precedence]`) で shift-reduce 衝突を解決(`*` > `+`、代入の右結合等)。
- **高品質エラー回復 (Corchuelo et al.)**: ER1 挿入 / ER2 削除 / ER3 Forward move で構文エラー後も解析を継続。トークンを捨てない。LALR・GLR 両モードで共通使用
- **AST 構築 + 子の自動保持 + Span 自動計算**: reduce 時に Generator 生成の partial コンストラクタが子・終端をプロパティへ自動セットし、子の `Span` をマージしてノードの `Span` を設定してから `OnReduce` を呼ぶ。子の手動代入も Span 設定も不要(`OnReduce` で上書き可)。
- **2パス目の意味解析**: `Parse` 後に各ノードの `OnSecondPassEnter`/`OnSecondPassExit`(トップダウン)を自動呼出。スコープの Push/Pop 等の正確な意味解析が書ける。
- **意味解析ヘルパー**: `[Enter]`/`[Exit]`/`[OnReduce]` 属性ルール、汎用 Walker (`{Root}Walker`)、スコープ付きシンボル表 (`ScopedSymbolTable`)、シンボル解決 (`ResolveOrError`)、型システム (`TypeSymbol` / `FunctionTypeSymbol` / `ArrayTypeSymbol` / `OverloadResolver`)、束縛解析 (`AstNode.SetAnnotation`)、診断 (`ParseResult.Diagnostics`)。
- **エラー回復**: panic mode で構文エラー後も解析を継続し、`ParseResult` で AST + エラーリストを返す。
- **エラー回復**: Corchuelo et al. ER1/ER2/ER3 で構文エラー後も解析を継続し、`ParseResult` で AST + エラーリストを返す。

## クイックスタート

Expand Down Expand Up @@ -303,14 +303,14 @@ AST 構築成功(宣言/継承/generic クラス/enum/struct/interface/プロ

| 指標 | 値 |
|---|---|
| Parse_CSharp(50 クラス入力 ≈ 7KB) | 0.68 ms(≈ 10 MB/s)※ |
| Parse_CSharp アロケーション | 627 KB |
| Parse_CSharp(50 クラス入力 ≈ 7KB、LightGlr) | 11.4 ms(≈ 0.6 MB/s)※ |
| Parse_CSharp アロケーション | 1,931 KB |
| Build_CSharp(ModelToTable.Build 純粋時間) | 190 ms |
| クリーンビルド時間 | 11 s |
| クリーンビルド時間 | 12 s |
| LALR 状態数 / シンボル数 | 798 / 608 |
| 生成コードサイズ | 6.0 MB(8011 行) |
| 生成コードサイズ | 6.2 MB(15363 行) |

> ※ Parse 時間は [Rule] モデル移行後(Reject/TryFallback + Span スタック)の代表値。Build_CSharp 190 ms は Worklist アルゴリズム最適化後。詳細は [samples/Perf/PerfSummary.md](samples/Perf/PerfSummary.md) 参照。Parse のアロケーションは AST 構築(reduce ごとに `new`)が主
> ※ CSharpParser は LightGlr モードで運用 (cast/paren・generic の本質的曖昧性を fork で解決)。state 308 で識別子ごとに fork するため、LALR 単一スタック (0.68ms) より低速。LALR モードの文法 (DeepPrec 等) は単一スタックの fast path で LALR に近い性能を維持。詳細は [samples/Perf/PerfSummary.md](samples/Perf/PerfSummary.md) 参照。

### コンフリクト解決技術

Expand Down Expand Up @@ -365,7 +365,7 @@ AstFirst.slnx

## テスト

293 テスト(AstFirst.Tests 247 + Generator.Tests 46)。レクサ/DFA/LALR の各段階、エンドツーエンド、エラー回復意味解析(スコープ・2パス目・型チェック・ctx → `ParseResult.Diagnostics` の統合)、`Accept`/`Reject` フォールバック、位置情報(行・列)を検証。
352 テスト(AstFirst.Tests 299 + Generator.Tests 53)。レクサ/DFA/LALR の各段階、エンドツーエンド、エラー回復 (Corchuelo)、GLR fork/dedup、意味解析(スコープ・2パス目・型チェック・ctx → `ParseResult.Diagnostics` の統合)、`Accept`/`Reject` フォールバック、`OnAccepted` コールバック、位置情報(行・列)を検証。

## ライセンス

Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

[日本語](README.ja.md) / English

A parser generator where you write the grammar in **plain C# classes and attributes**, and a Source Generator emits a Lexer and an LALR(1) Parser at compile time. The generated Parser returns an AST you can layer semantic analysis on (scoped symbol table, two-pass Walker, type checking, and `Accept`/`Reject` to resolve semantic ambiguity).
A parser generator where you write the grammar in **plain C# classes and attributes**, and a Source Generator emits a Lexer and an LALR(1) / Lightweight GLR (LightGlr) Parser at compile time. The generated Parser returns an AST you can layer semantic analysis on (scoped symbol table, two-pass Walker, type checking, and `Accept`/`Reject` to resolve semantic ambiguity).

## How it compares

Expand All @@ -17,13 +17,13 @@ AstFirst sits in the same space as parser generators and combinator libraries, b
| Code generated | **compile time** (Source Generator) | build-time codegen tool | **never** — interpreted at runtime | n/a |
| Runtime parse cost | **zero** — static tables, no dispatch | generated code | interpreted (allocation/dispatch per parse) | n/a |
| AOT / Native AOT | ✓ no runtime codegen | △ | ✓ | n/a |
| Algorithm | LALR(1) table-driven | LL(\*) / ALL(\*) | recursive-descent combinators | n/a |
| Error recovery | panic mode (built-in) | yes | hand-rolled | n/a |
| Grammar power | LALR(1) — resolve conflicts with `[Precedence]` | LL(\*) | **Turing-complete** (branch on any C#) | n/a |
| Algorithm | LALR(1) + Lightweight GLR (LightGlr) | LL(\*) / ALL(\*) | recursive-descent combinators | n/a |
| Error recovery | Corchuelo et al. ER1/ER2/ER3 (built-in) | yes | hand-rolled | n/a |
| Grammar power | LALR(1) + GLR — resolve conflicts with `[Precedence]` / fork | LL(\*) | **Turing-complete** (branch on any C#) | n/a |

**Strengths vs combinators (Superpower/Pidgin)**: the parser is emitted *at compile time* as static tables — no interpretation, no delegate dispatch, no per-parse construction. Startup and per-parse cost are effectively zero, it AOTs / Native-AOTs cleanly, and panic-mode error recovery is built in. The grammar is declarative C#, so the IDE can navigate and refactor it.
**Strengths vs combinators (Superpower/Pidgin)**: the parser is emitted *at compile time* as static tables — no interpretation, no delegate dispatch, no per-parse construction. Startup and per-parse cost are effectively zero, it AOTs / Native-AOTs cleanly, and Corchuelo et al. error recovery (ER1 insert / ER2 delete / ER3 Forward move) is built in. The grammar is declarative C#, so the IDE can navigate and refactor it.

**Trade-offs**: LALR(1) needs `[Precedence]`/associativity to resolve shift-reduce conflicts — combinator libraries are freer (you can branch on arbitrary C# mid-parse). A C#-only toolchain.
**Trade-offs**: LALR(1) needs `[Precedence]`/associativity to resolve shift-reduce conflicts. However, LightGlr mode (`[Grammar(ParseMode = ParseMode.LightGlr)]`) handles inherent ambiguity (cast/paren, generics) via parallel fork. A C#-only toolchain.

**Why a Source Generator?** the Lexer/Parser/Walker are ordinary C# the compiler sees and the IDE can open (the `.g.cs` lives under your project, Go to Definition works). You never *build* the parser at runtime, and grammar mistakes (unresolved conflicts, unreachable rules) surface as **compile-time warnings**, not at the first `Parse`.

Expand All @@ -32,12 +32,12 @@ AstFirst sits in the same space as parser generators and combinator libraries, b
- **Grammar in C# code**: the inheritance tree expresses syntax; the parameters of a `[Rule]` static method express the RHS and lexical rules. No special DSL files.
- **Source Generator (`IIncrementalGenerator`)**: emits Lexer / Parser / partial properties C# code at compile time. No runtime code generation.
- **Regex-based lexer**: character-class compaction, longest-match + priority-driven, `{m,n}` quantifiers, Unicode supplementary planes. Computes **line/column** of each token.
- **LALR(1) parsing**: resolves shift-reduce conflicts with precedence/associativity (`[Precedence]`) (e.g. `*` > `+`, right-associative assignment).
- **Semantic ambiguity resolution (Accept/Reject)**: call `Reject()` in the reduce-time `OnReduce` to fall back to the next candidate (another rule / shift) in priority order. Resolves meaning-dependent ambiguity like cast vs. parenthesized expression during parsing.
- **LALR(1) + Lightweight GLR parsing**: default is LALR(1). Switch to Lightweight GLR with `[Grammar(ParseMode = ParseMode.LightGlr)]` to handle inherent ambiguity (cast/paren, generics) via parallel fork. Resolves shift-reduce conflicts with precedence/associativity (`[Precedence]`) (e.g. `*` > `+`, right-associative assignment).
- **High-quality error recovery (Corchuelo et al.)**: ER1 insert / ER2 delete / ER3 Forward move to continue parsing after syntax errors without discarding tokens. Used in both LALR and GLR modes.
- **AST construction + automatic child retention + automatic Span**: at reduce time a generator-emitted partial constructor sets children/terminals into properties automatically, merges their `Span`s into the node's `Span`, and then calls `OnReduce`. No manual child assignment or Span setup (overridable in `OnReduce`).
- **Two-pass semantic analysis**: after `Parse`, each node's `OnSecondPassEnter`/`OnSecondPassExit` (top-down) is called automatically. Accurate semantic analysis like scope Push/Pop is straightforward.
- **Semantic analysis helpers**: `[Enter]`/`[Exit]`/`[OnReduce]` attribute rules, a generic Walker (`{Root}Walker`), scoped symbol table (`ScopedSymbolTable`), symbol resolution (`ResolveOrError`), type system (`TypeSymbol` / `FunctionTypeSymbol` / `ArrayTypeSymbol` / `OverloadResolver`), binding (`AstNode.SetAnnotation`), diagnostics (`ParseResult.Diagnostics`).
- **Error recovery**: continues after syntax errors via panic mode; `ParseResult` carries the AST + error list.
- **Error recovery**: continues after syntax errors via Corchuelo et al. ER1/ER2/ER3; `ParseResult` carries the AST + error list.

## Quick start

Expand Down Expand Up @@ -316,7 +316,7 @@ Japanese versions are under `docs/ja/` and [README.md](README.md).

## Tests

293 tests (AstFirst.Tests 247 + Generator.Tests 46). Covers lexer/DFA/LALR stages, end-to-end, error recovery, semantic analysis (scopes, two-pass, type checking, ctx -> `ParseResult.Diagnostics` integration), `Accept`/`Reject` fallback, and positions (line/column).
352 tests (AstFirst.Tests 299 + Generator.Tests 53). Covers lexer/DFA/LALR stages, end-to-end, error recovery (Corchuelo), GLR fork/dedup, semantic analysis (scopes, two-pass, type checking, ctx -> `ParseResult.Diagnostics` integration), `Accept`/`Reject` fallback, `OnAccepted` callback, and positions (line/column).

## License

Expand Down
Loading
Loading