@@ -582,7 +582,16 @@ export function buildToyCorpus(seed = 0x5a2_2026): { src: string; source: string
582582 }
583583 if ( r < .50 ) return `txn ${ pick ( ids ) } ${ rng ( ) < .6 ? `:${ pick ( ids ) } ` : '' } ${ pick ( [ '!' , '.' , '?' ] ) } ` ;
584584 if ( r < .58 ) return `line ${ pick ( ids ) } ${ pick ( ids ) } ` ;
585- if ( r < .66 ) return `noplus ${ atom ( ) } +${ atom ( ) } ` ;
585+ // SH3-1b: suppress only disables literal LEDs — binary `*`/`/` must still parse
586+ // under exclude('*', Expr). Mix ops + grouping so the arm is not `+`-only.
587+ if ( r < .66 ) {
588+ const op = pick ( [ '+' , '-' , '*' , '/' , '+' , '*' ] ) ;
589+ const form = rng ( ) ;
590+ if ( form < .35 ) return `noplus ${ atom ( ) } ${ op } ${ atom ( ) } ` ;
591+ if ( form < .55 ) return `noplus ${ atom ( ) } ${ op } ${ atom ( ) } ${ op } ${ atom ( ) } ` ;
592+ if ( form < .75 ) return `noplus (${ atom ( ) } ${ op } ${ atom ( ) } )` ;
593+ return `noplus ${ atom ( ) } ${ op } (${ atom ( ) } ${ op } ${ atom ( ) } )` ;
594+ }
586595 if ( r < .75 ) {
587596 const n = 2 + Math . floor ( rng ( ) * 5 ) ;
588597 return `repeat ${ Array . from ( { length : n } , atom ) . join ( ' ' ) } ` ;
@@ -591,9 +600,16 @@ export function buildToyCorpus(seed = 0x5a2_2026): { src: string; source: string
591600 const n = Math . floor ( rng ( ) * 5 ) ;
592601 return `maybe${ n ? ' ' + Array . from ( { length : n } , atom ) . join ( ' ' ) : '' } ` ;
593602 }
603+ // SH3-1b: sep(alt([Ident,':',Number], Number)) — include multi-pair + trailing
604+ // delim; incomplete `id:` forms are CST-over-accept (see SH3-1b reply), not emitted.
594605 if ( r < .90 ) {
595606 const n = Math . floor ( rng ( ) * 4 ) ;
596- const pairs = Array . from ( { length : n } , ( ) => rng ( ) < .55 ? `${ pick ( ids ) } :${ pick ( nums ) } ` : pick ( nums ) ) ;
607+ const pairs = Array . from ( { length : n } , ( ) => {
608+ const k = rng ( ) ;
609+ if ( k < .45 ) return `${ pick ( ids ) } :${ pick ( nums ) } ` ;
610+ if ( k < .75 ) return pick ( nums ) ;
611+ return `${ pick ( ids ) } : ${ pick ( nums ) } ` ;
612+ } ) ;
597613 return `pairs(${ pairs . join ( ',' ) } ${ n && rng ( ) < .3 ? ',' : '' } )` ;
598614 }
599615 if ( r < .95 ) return `notany ${ pick ( ids . filter ( ( x ) => x !== 'bad' && x !== 'worse' ) ) } ` ;
@@ -637,6 +653,11 @@ export function buildToyCorpus(seed = 0x5a2_2026): { src: string; source: string
637653 'txn a:b?;' , 'txn a:b!;' , 'txn a.;' , 'line a b;' , 'line a\nb;' ,
638654 'noplus 1+2;' , 'repeat a 1 b 2;' , 'maybe;' , 'maybe a 1;' ,
639655 'pairs();' , 'pairs(a:1,2,b:3,);' , 'notany good;' , 'notany bad;' ,
656+ // SH3-1b: suppress must not block prec-binary `*` (LED-only exclude)
657+ 'noplus 1 * 2;' , 'noplus 1 * 2 * 3;' , 'noplus (1*2);' , 'noplus 1*2;' ,
658+ 'noplus 1/2;' , 'noplus 1*2+3;' , 'noplus (1*2)*3;' , 'noplus 1*(2*3);' ,
659+ // SH3-1b: well-formed sep+alt (incomplete `pairs(a:)` is CST-over-accept — not here)
660+ 'pairs(a:1);' , 'pairs(1, a:2);' , 'pairs(a:1, 2, b:3);' , 'pairs( a : 1 , );' ,
640661 // SH2-0b: choice-arm nested groups + multi-stmt
641662 'tag x=(1);' , 'tag x=((1));' , 'tag y=(((2)));' , 'tag z:(3);' , 'tag z:((a));' ,
642663 'tag x:1;tag y=2;' , 'bang!x;tag z;' , 'tag x=(1);tag y=2;tag z;' ,
0 commit comments