Repository navigation
Complete the derived YAML tree-sitter target (grammar doesn't generate) #3
Description
Monogram derives four targets from each grammar definition: a TextMate grammar, a Monarch grammar, a tree-sitter grammar, and the CST parser. For yaml.ts, three of the four work — the TextMate highlighter (93.8% vs the parser oracle, ahead of RedCMD's 92.4%), the Monarch grammar, and the CST parser (src-coverage 73.4% vs the yaml package). The tree-sitter target is unfinished: tree-sitter/yaml/grammar.js does not generate.
This is not a regression and nothing depends on it today — CI builds and gates only the TypeScript and HTML tree-sitter grammars (the tree-sitter thesis is carried by TS at 95.9%, ahead of the official grammar), and the "generate every derived grammar" conflict gate in ci.yml explicitly excludes yaml. Filing this to track the work for if/when YAML-as-a-tree-sitter-target becomes a goal.
Three things block it
-
Structural indent tokens are emitted as
token(//)(invalid JS).INDENT/DEDENT/NEWLINEand the block-scalar body are engine-emitted placeholder tokens — their grammar pattern is the never-match(?!).sanitizeTreeSitterRegexstrips the zero-width assertion to empty, so they serialize astoken(//): an empty regex literal, which JS parses as a line comment, sogrammar.jswon't even load.
Fix: route them to tree-sitterexternals(the way the HTML markup path already handlesraw_text), keyed offgrammar.indentinplanScannerTokens(src/gen-treesitter.ts). Prototyped — it makesgrammar.jsload and keeps every other language byte-identical — but it is necessary, not sufficient (see Fix template interpolation opener scanning #2). -
The
noderule matches the empty string. A YAML node can be null (key:with no value), soNodeis nullable, andtree-sitter generaterejects empty-matching non-start rules: "the rulenodematches the empty string." Resolving it needs nullable-rule elimination — makenodenon-empty and wrap its references inoptional(...)— either by restructuringyaml.ts(must not regress the parser's 73.4% or the TextMate highlighter) or as a general transform ingen-treesitter.ts. Further conflicts may surface after this. -
The C external scanner is a stub.
tree-sitter/yaml/src/scanner.cdoes not implement YAML indentation —scan()returnsfalse. A real scanner needs an indent stack withserialize/deserialize, flow-collection suspension, and block-scalar bodies, mirroring the indentation logic insrc/gen-lexer.ts.
Why it would be worth doing
It extends the tree-sitter thesis proof to an indentation-sensitive grammar: the same non-deterministic grammar a flat-LR engine chokes on, tree-sitter's GLR absorbs — even for YAML's indentation. It would also let yaml join the CI conflict gate and remove the committed invalid-JS grammar.js.
Acceptance
cd tree-sitter/yaml && npx tree-sitter generate && npx tree-sitter build --wasm .succeeds.- yaml is added to the "generate every derived grammar" step in
ci.yml. - Ideally a yaml tree-sitter accuracy bench (there is none today; the only validation would be parse correctness over a corpus).
Activity
Scan YAML flow indicators with flow-depth — block-context `,` is cont…
Scan YAML document markers — `---`-led documents now parse (issue #3)
Fold multi-line plain scalars inside flow collections (issue #3)
Parse block keys with node properties / tags / aliases (issue #3)
Derive a working YAML tree-sitter target: generate, build, scan, 97.8% (
Two more structure bugs from the widened oracle; valid-only contract
Missing-nonterminal synthesis: the tsc "Expression expected" analog
await/yield fork: foundation — ctx markers + the name-fork transform