Skip to content

Commit d4cc5ac

Browse files
committed
YAML detectors: one safe positional fix, three confirmed deliberate (#51)
Worked the YAML region detectors semantics-aware (not the audit's heuristic). Key finding: the audit's "route through expandAlts" fix is WRONG for these — they match STRUCTURAL nodes (a `(Newline item)*` quantifier, config-keyed bracket pairs), and expandAlts EXPANDS the very quantifier they depend on. - detectBlockSequence — the one genuine positional rigidity: it matched the `[item, (Newline item)*]` pattern only at items[0]/items[1]. Now scanned pairwise (any adjacent k), so a leading element before the sequence does not hide it. NOT routed through expandAlts (that would expand the quantifier). yaml byte-identical; the full yaml gate group (depth-witnesses, deepest-sibling, compact-nest-sites, flow-sites, blockscalar-depth, issue12) stays green. - detectFold — its visit is ALREADY pairwise; its refsLeaf stopping at a leaf token (not following a rule-ref) is the DELIBERATE fold-vs-sibling distinction (an Indent+rule-ref is a sibling node). No change. - detectExplicitKey — the indicator at items[0] is intrinsic (an explicit-key entry is headed by `?`); the inner already unwraps a quantifier. No change. - detectFlowCollections — topLits is positional-agnostic and unwraps quantifier/group/sep, deliberately stopping at alt/ref to read THIS rule's own structure. No change. So the fixed-window fragility class is closed: 13 detectors made shape-robust where the rigidity was accidental; the rest is deliberate YAML semantics that the heuristic over-flagged. Not every fixed shape is fragility.
1 parent 24cccf1 commit d4cc5ac

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

src/gen-tm.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,10 +3626,13 @@ function detectBlockSequence(grammar: CstGrammar): { indicator: string } | null
36263626
let indicator: string | null = null;
36273627
const visit = (e: RuleExpr): void => {
36283628
if (e.type === 'seq') {
3629-
// `[item, (Newline item)*]`: first element + a `*`/`+` over a `[Newline, item]` seq
3630-
if (e.items.length >= 2) {
3631-
const head = e.items[0];
3632-
const q = e.items[1];
3629+
// `[…, item, (Newline item)*, …]`: an item ADJACENT to a `*`/`+` over a `[Newline, item]` seq.
3630+
// Scanned pairwise (any k, not only items[0]/items[1]) so a leading element before the
3631+
// sequence pattern does not hide it. NOT routed through expandAlts on purpose — that would
3632+
// expand the `(Newline item)*` quantifier this match depends on.
3633+
for (let k = 0; k + 1 < e.items.length; k++) {
3634+
const head = e.items[k];
3635+
const q = e.items[k + 1];
36333636
if (q.type === 'quantifier' && (q.kind === '*' || q.kind === '+') && q.body.type === 'seq'
36343637
&& q.body.items.length >= 2 && q.body.items[0].type === 'ref' && q.body.items[0].name === newlineToken) {
36353638
const ind = itemIndicator(head);

0 commit comments

Comments
 (0)