@@ -516,41 +516,42 @@ export class ContextFreeGrammar {
516516}
517517
518518public term ( ) :ContextFreeGrammar ;
519- public term ( step :( cfg : ContextFreeGrammar ) => void ) :ContextFreeGrammar ;
520- public term ( step ?:( cfg : ContextFreeGrammar ) => void ) :ContextFreeGrammar {
519+ public term ( step :StepCallback < ContextFreeGrammar > ) :ContextFreeGrammar ;
520+ public term ( step ?:StepCallback < ContextFreeGrammar > ) :ContextFreeGrammar {
521521const productions = new Map < string , Array < Array < Token > > > ( [ ...this . productions ] . map ( ( [ nt , p ] ) => [ nt , p . map ( s => [ ...s ] ) ] ) ) ;
522522
523523const terminalProductions = new Map < string , string > ( [ ...productions ]
524524. filter ( ( [ _ , p ] ) => p . length === 1 && p [ 0 ] . length === 1 && p [ 0 ] [ 0 ] . kind === TokenKind . Terminal )
525- . map ( ( [ nt , p ] ) => [ p [ 0 ] [ 0 ] . identifier , nt ] )
526- ) ;
525+ . map ( ( [ nt , p ] ) => [ p [ 0 ] [ 0 ] . identifier , nt ] ) ) ;
527526
528- for ( const [ _ , production ] of [ ...productions ] . sort ( ( [ a , _a ] , [ b , _b ] ) => sortBySymbolButFirst ( a , b , this . start ) ) ) {
529- let changeHappened = false ;
527+ for ( const [ nonTerminal , production ] of [ ...productions ] . sort ( ( [ a , _a ] , [ b , _b ] ) => sortBySymbolButFirst ( a , b , this . start ) ) ) {
530528for ( const sequence of production ) {
531529if ( sequence . length >= 2 ) {
532530for ( let i = 0 ; i < sequence . length ; i ++ ) {
533531if ( sequence [ i ] . kind === TokenKind . Terminal ) {
534- let replacement = terminalProductions . get ( sequence [ i ] . identifier ) ;
532+ const terminal = sequence [ i ] . identifier ;
533+ let isNew = false ;
534+ let replacement = terminalProductions . get ( terminal ) ;
535535if ( replacement == null ) {
536- replacement = countUpLetterSymbol ( "T" , s => ! productions . has ( s ) ) ;
537- terminalProductions . set ( sequence [ i ] . identifier , replacement ) ;
538- productions . set ( replacement , new Array < Array < Token > > ( new Array < Token > ( Token . terminal ( sequence [ i ] . identifier ) ) ) ) ;
536+ replacement = countUpLetterSymbol ( nonTerminal , s => ! productions . has ( s ) ) ;
537+ terminalProductions . set ( terminal , replacement ) ;
538+ productions . set ( replacement , new Array < Array < Token > > ( new Array < Token > ( Token . terminal ( terminal ) ) ) ) ;
539+ isNew = true ;
539540}
540541sequence . splice ( i , 1 , Token . nonTerminal ( replacement ) ) ;
541- changeHappened = true ;
542+ step ?.(
543+ new ContextFreeGrammar (
544+ productions . keys ( ) ,
545+ this . terminals ,
546+ productions ,
547+ this . start ,
548+ ) ,
549+ `Replaced a terminal "${ terminal } " in production${ nonTerminal } with the${ isNew ?"new " :"" } non-terminal${ replacement } .`
550+ ) ;
542551}
543552}
544553}
545554}
546- if ( changeHappened ) {
547- step ?.( new ContextFreeGrammar (
548- productions . keys ( ) ,
549- this . terminals ,
550- productions ,
551- this . start ,
552- ) ) ;
553- }
554555}
555556
556557return new ContextFreeGrammar (