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.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
//! `WalkContext` — per-walk mutable state that flows through the
|
||||
//! walker (ADR-0024 §WalkContext).
|
||||
//!
|
||||
//! Phase A keeps this minimal: app-lifecycle commands have no
|
||||
//! schema dependency. The `current_table`, `current_table_columns`,
|
||||
//! and schema-cache pointer become populated as Phase B-D land
|
||||
//! the schema-aware DDL/data commands.
|
||||
|
||||
/// Per-walk state. Cheap to construct; `default()` is the right
|
||||
/// shape for app-lifecycle commands.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct WalkContext {
|
||||
/// Table whose name an `Ident { source: Tables, writes_table:
|
||||
/// true }` matched earlier in the walk. Phase B+ writes this.
|
||||
pub current_table: Option<String>,
|
||||
|
||||
/// Columns of `current_table`, resolved against the schema
|
||||
/// cache when the table identifier matched. Phase D+ uses
|
||||
/// this to drive the dynamic `column_value_list` sub-grammar.
|
||||
#[allow(dead_code)]
|
||||
pub current_table_columns: Option<Vec<ColumnInfo>>,
|
||||
|
||||
/// For `set col=…` and `where col=…`, the column whose value
|
||||
/// is about to be consumed. Phase D+ writes this so the value
|
||||
/// slot picks the right typed sub-grammar.
|
||||
#[allow(dead_code)]
|
||||
pub current_column: Option<ColumnInfo>,
|
||||
}
|
||||
|
||||
impl WalkContext {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Schema info for a single column. Phase D+ populates this from
|
||||
/// the schema cache; Phase A leaves it unused.
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct ColumnInfo {
|
||||
pub name: String,
|
||||
pub user_type: crate::dsl::types::Type,
|
||||
}
|
||||
Reference in New Issue
Block a user