Skip to content

Commit a74bb9e

Browse files
authored
Merge pull request #706 from wado-lang/claude/fix-gale-sqlite-parser-SAt2C
Add prediction engine and non-greedy repeat support to parser generator
2 parents 24c0da5 + 570f42b commit a74bb9e

File tree

13 files changed

+3348
-1630
lines changed

13 files changed

+3348
-1630
lines changed

docs/cheatsheet.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@ unreachable(); // trap
958958
959959
// core:cli
960960
use { println, eprintln, print, eprint, Stdout, Stderr } from "core:cli";
961+
use { log_stdout, log_stderr } from "core:cli"; // no effect required (debug only)
961962
962963
// core:collections - TreeMap, TreeSet
963964
use { TreeMap, TreeSet } from "core:collections";
@@ -1087,6 +1088,17 @@ let icon = #include_bytes("./icon.png"); // include file as Array<u8>
10871088

10881089
Paths in `#include_str` and `#include_bytes` are resolved relative to the source file. See [WEP: Compile-Time File Inclusion](./wep-2026-03-02-include-str.md).
10891090

1091+
## Debugging
1092+
1093+
```wado
1094+
use { log_stdout, log_stderr } from "core:cli";
1095+
1096+
log_stdout(`value = {x}`); // prints to stdout without Stdout effect
1097+
log_stderr(`value = {x}`); // prints to stderr without Stderr effect
1098+
```
1099+
1100+
`log_stdout` and `log_stderr` bypass the effect system. They are intended for temporary debugging output that can be called from any function regardless of its effect declarations.
1101+
10901102
## Attributes
10911103

10921104
```wado

package-gale/AGENTS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ Commit the updated golden files.
9797

9898
`runtime.wado` is included verbatim into every generated file via `#include_str` in `generator.wado`. It must remain self-contained (no imports from other source files). See [WEP: Compile-Time File Inclusion](../docs/wep-2026-03-02-include-str.md).
9999

100+
## Generated Parser Rules
101+
102+
- **No backtracking in new code.** Use static k-token lookahead prediction to disambiguate alternatives. If prediction cannot resolve within depth 5, file an issue rather than adding backtracking. Existing backtracking sites are being migrated to prediction; do not add new ones.
103+
100104
## On-Task-Done
101105

102106
When completing a task, run from the project root:

package-gale/src/g4/parser.wado

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,26 +180,32 @@ impl G4Parser {
180180
fn parse_postfix(&mut self, elem: Element) -> Result<Element, ParseError> {
181181
if self.is_kind(G4Token::Star) {
182182
self.advance();
183-
if self.is_kind(G4Token::Question) {
183+
let ng = if self.is_kind(G4Token::Question) {
184184
self.advance();
185-
}
185+
true
186+
} else {
187+
false
188+
};
186189
return Result::<Element, ParseError>::Ok(
187-
Element::Repeat(RepeatElement { kind: RepeatKind::Star, element: elem }),
190+
Element::Repeat(RepeatElement { kind: RepeatKind::Star, element: elem, non_greedy: ng }),
188191
);
189192
}
190193
if self.is_kind(G4Token::Plus) {
191194
self.advance();
192-
if self.is_kind(G4Token::Question) {
195+
let ng = if self.is_kind(G4Token::Question) {
193196
self.advance();
194-
}
197+
true
198+
} else {
199+
false
200+
};
195201
return Result::<Element, ParseError>::Ok(
196-
Element::Repeat(RepeatElement { kind: RepeatKind::Plus, element: elem }),
202+
Element::Repeat(RepeatElement { kind: RepeatKind::Plus, element: elem, non_greedy: ng }),
197203
);
198204
}
199205
if self.is_kind(G4Token::Question) {
200206
self.advance();
201207
return Result::<Element, ParseError>::Ok(
202-
Element::Repeat(RepeatElement { kind: RepeatKind::Optional, element: elem }),
208+
Element::Repeat(RepeatElement { kind: RepeatKind::Optional, element: elem, non_greedy: false }),
203209
);
204210
}
205211
return Result::<Element, ParseError>::Ok(elem);

package-gale/src/generator_test.wado

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,12 @@ test "generate repeat fields" {
141141
Element::Repeat(RepeatElement {
142142
kind: RepeatKind::Star,
143143
element: Element::RuleRef("item"),
144+
non_greedy: false,
144145
}),
145146
Element::Repeat(RepeatElement {
146147
kind: RepeatKind::Optional,
147148
element: Element::TokenRef("COMMA"),
149+
non_greedy: false,
148150
}),
149151
],
150152
},

package-gale/src/ir.wado

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub variant Element {
3030
pub struct RepeatElement {
3131
pub kind: RepeatKind,
3232
pub element: Element,
33+
pub non_greedy: bool,
3334
}
3435

3536
pub struct LabelElement {

package-gale/src/ir_test.wado

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ test "Element variants" {
3939
let repeat = Element::Repeat(RepeatElement {
4040
kind: RepeatKind::Star,
4141
element: Element::TokenRef("INT"),
42+
non_greedy: false,
4243
});
4344
let label = Element::Label(LabelElement {
4445
name: "op",

0 commit comments

Comments
 (0)