050b36391e2a863efba12ac170e6e3ac4c53ecd5
53 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6bb688251b |
ADR-0024 Phase C: create table with column-list value literals
Migrate `create table <Name> [with pk [<col>:<type>[, ...]]]`
to the walker. Exercises Repeated{separator: Some(Punct(','))}
for the first time — the with-pk column-spec list.
Walker behaviour changes:
- Optional now backtracks on partial-match failure (Incomplete
or Failed-Mismatch from a Seq mid-shape). Path / per-byte
state rolls back to before the partial attempt; the inner's
expected-set propagates as `skipped` so callers see "what
would have completed it". Matches chumsky's `or_not`
semantics. ValidationFailed (content errors) does NOT
backtrack — the user means to fix those.
- Bridge: ValidationFailed errors now classify as
`at_eof = true`, mirroring the chumsky-side custom-error
convention. This is what lets `create table Customers`
classify as IncompleteAtEof rather than DefiniteErrorAt
(the user can still continue typing `with pk …`).
Grammar:
- src/dsl/grammar/ddl.rs gains CREATE: shape is
Seq(Word("table"), Ident{NewName,table_name}, Optional(WITH_PK))
where WITH_PK = Seq(Word("with"), Word("pk"),
Optional(Repeated{COL_SPEC, separator: Punct(','), min:1})).
AST builder enforces `with pk needs at least one column`
with the existing parse.custom.create_table_needs_pk catalog
wording; `with pk` alone defaults to id:serial.
Tests:
- 6 new walker-specific tests for create_table: with-pk
default, named typed PK, compound PK, whitespace tolerance
around `:` and `,`, bare-create-table-errors-with-with-pk-
hint, case-insensitive keywords.
- Total: 825 passed, 0 failed, 1 ignored (was 819 / 1).
- cargo clippy --all-targets -- -D warnings clean.
|
||
|
|
7e79ca865a |
ADR-0024 Phase B: DDL commands without value literals
Migrate the five DDL commands at four entry words: drop (drop
table / drop column / drop relationship), add (add column /
add 1:n relationship), rename (rename column), change (change
column). The walker route now owns these end-to-end; chumsky
declarations remain unreachable for these inputs but stay
until Phase F.
Walker extensions:
- New node kinds: NumberLit (with optional content validator)
and Literal(&str) (verbatim byte sequence with word-boundary
lookahead — used for the `1` in `add 1:n …` so it surfaces
as `\`1\`` in the expected-set, matching the existing
parse_error_pedagogy contract).
- Flag (--name) terminal — Phase A stubbed; now wired to the
walker driver with consume_flag() in lex_helpers.
- Repeated combinator with optional separator and `min` floor.
Used by referential clauses (0..2 `on <delete|update>` runs)
and change-column flags (0..N --force-conversion /
--dont-convert; AST builder enforces mutual exclusion).
- Optional now propagates its inner's expectations as a
`skipped` field on the Matched result. Seq accumulates these
across children so the next failure's expected-set surfaces
the full union — closes the keyword-completion regression
(`add column ` must offer `to`, `table`, plus the table-name
identifier slot).
- Expectation::Ident gained a `source: IdentSource` field; the
parser-side bridge maps Tables/Columns/Relationships/Types
to the IdentSlot::expected_label strings ("table name",
"column name", …) so the existing completion engine's
schema-cache lookup still resolves.
- Walker error wording now includes "after `<consumed>`,
expected …" framing — matches the chumsky-side test
contract for structural errors mid-shape.
- AST-builder validation errors now propagate as
WalkOutcome::ValidationFailed (not the generic "AST builder
failed" fallback), so `change column … --force-conversion
--dont-convert` and repeated `on delete` clauses surface
their friendly catalog wording verbatim.
Grammar additions:
- src/dsl/grammar/shared.rs: type-name validator (TYPE_VALIDATOR
uses Type::from_str via parse.custom.unknown_type catalog),
qualified_column sub-grammar, referential action keyword
(`cascade`/`restrict`/`set null`/`no action`), repeated
on-clauses.
- src/dsl/grammar/ddl.rs: drop/add/rename/change CommandNodes
with inline shapes (per-use-site `role` annotations let the
AST builder discriminate parent vs child columns, etc.).
The four entry words each have one CommandNode whose `shape`
is a Choice across sub-forms.
Tests:
- 14 new walker-specific tests covering all DDL forms (bare
drop table, drop column with optional connectives, drop
relationship by name and by endpoints, add column with type
validator, rename column, change column with each flag form
+ mutual-exclusion check, add 1:n relationship minimal /
full, repeated-clause-twice rejection).
- Total: 819 passed, 0 failed, 1 ignored (was 805 / 1).
- cargo clippy --all-targets -- -D warnings clean.
|
||
|
|
50b3542050 |
ADR-0024 Phase A: walker framework + app-lifecycle commands
Stand up the unified-grammar tree walker alongside the existing
chumsky parser and migrate the eleven app-lifecycle commands
(quit, help, rebuild, save / save as, new, load, export, import,
mode, messages) end-to-end. The router in parse_tokens consults
the walker first; non-migrated commands still fall through to
chumsky.
Scope:
- src/dsl/grammar/{mod,app}.rs: Node enum (13 kinds), Word /
IdentSource / HintMode / HighlightClass / ValidationError /
CommandNode types, REGISTRY of the eleven app commands.
- src/dsl/walker/{mod,driver,context,outcome,lex_helpers}.rs:
scannerless byte-level walker, per-node-kind dispatch with
Choice/Seq/Optional backtracking, WalkContext (Phase B-D
schema fields stubbed), WalkOutcome with Match/Incomplete/
Mismatch/ValidationFailed.
- src/dsl/parser.rs: try_walker_route() runs first in
parse_tokens; bridge converts WalkOutcome to ParseError
preserving catalog wording (mode.unknown / messages.unknown
surface verbatim via friendly::translate). Legacy
try_parse_app_path_command deleted; chumsky's bare-keyword
app branches remain unreachable until Phase F sweep.
Walker design choices worth noting:
- mode <value> / messages <value> use Choice(Word, Word, Ident)
so known keywords appear in the expected-set; the trailing
Ident catch-all funnels unknown values into the friendly
validator that always errors with the catalog wording.
- save / save as is one CommandNode (Optional(Word("as"))) -
closes the round-5 "save Tab can't offer as" limitation
structurally.
- Path-bearing UX shipped per ADR-0024: BarePath terminates at
whitespace; paths with spaces use the (not-yet-wired) quoted
form. Existing tests pass on the new shape.
Tests:
- 28 new walker-specific tests in dsl::walker::tests covering
every app-lifecycle command, friendly-error wording for
mode/messages unknown values, trailing-garbage detection,
whitespace tolerance, and routing fall-through.
- Total: 805 passed, 0 failed, 1 ignored (was 777 / 1).
- cargo clippy --all-targets -- -D warnings clean.
|