import { SimpleASTAlt , SimpleASTNode , SimpleASTSeq , factorLeft , fixLeftRecursion , } from './simplifier' ; const alt = ( ... exprs ) : SimpleASTAlt => ( { type : 'alt' , exprs , } ) ; const seq = ( ... exprs ) : SimpleASTSeq => ( { type : 'seq' , exprs , } ) ; const nt = ( value ) : SimpleASTNode => ( { type : 'nonterminal' , value } ) ; const lit = ( value ) : SimpleASTNode => ( { type : 'literal' , value } ) ; test ( 'factorLeft' , ( ) => { const root = Symbol ( 'root' ) ; const rules = new Map ( [ [ root , alt ( seq ( lit ( 'x' ) , lit ( 'a' ) ) , seq ( lit ( 'x' ) , lit ( 'b' ) ) , seq ( lit ( 'x' ) ) , seq ( lit ( 'c' ) ) ) , ] , ] ) ; factorLeft ( rules ) ; const next = ( rules . get ( root ) ! . exprs [ 0 ] . exprs [ 1 ] as SimpleASTNode & { type : 'nonterminal' ; } ) . value ; expect ( rules ) . toEqual ( new Map ( [ [ root , alt ( seq ( lit ( 'x' ) , nt ( next ) ) , seq ( lit ( 'c' ) ) ) ] , [ next , alt ( seq ( lit ( 'a' ) ) , seq ( lit ( 'b' ) ) , seq ( ) ) ] , ] ) ) ; } ) ; test ( 'fixLeftRecursion' , ( ) => { const Expr = Symbol ( 'Expr' ) ; const Factor = Symbol ( 'Factor' ) ; const Term = Symbol ( 'Term' ) ; const rules = new Map ( [ [ Expr , alt ( seq ( nt ( Expr ) , lit ( '+' ) , nt ( Factor ) ) , seq ( nt ( Expr ) , lit ( '-' ) , nt ( Factor ) ) , seq ( nt ( Factor ) ) ) ] , [ Factor , alt ( seq ( nt ( Factor ) , lit ( '*' ) , nt ( Term ) ) , seq ( nt ( Factor ) , lit ( '/' ) , nt ( Term ) ) , seq ( nt ( Term ) ) ) ] , [ Term , alt ( seq ( lit ( '(' ) , nt ( Expr ) , lit ( ')' ) ) , seq ( { type : "value" } ) ) ] ] ) ; fixLeftRecursion ( rules ) ; const ExprNext = ( rules . get ( Expr ) ! . exprs [ 0 ] . exprs [ 1 ] as SimpleASTNode & { type : 'nonterminal' ; } ) . value ; const FactorNext = ( rules . get ( Factor ) ! . exprs [ 0 ] . exprs [ 1 ] as SimpleASTNode & { type : 'nonterminal' ; } ) . value ; expect ( rules ) . toEqual ( new Map ( [ [ Expr , alt ( seq ( nt ( Factor ) , nt ( ExprNext ) ) ) ] , [ ExprNext , alt ( seq ( lit ( '+' ) , nt ( Factor ) , nt ( ExprNext ) ) , seq ( lit ( '-' ) , nt ( Factor ) , nt ( ExprNext ) ) , seq ( ) ) ] , [ Factor , alt ( seq ( nt ( Term ) , nt ( FactorNext ) ) ) ] , [ FactorNext , alt ( seq ( lit ( '*' ) , nt ( Term ) , nt ( FactorNext ) ) , seq ( lit ( '/' ) , nt ( Term ) , nt ( FactorNext ) ) , seq ( ) ) ] , [ Term , alt ( seq ( lit ( '(' ) , nt ( Expr ) , lit ( ')' ) ) , seq ( { type : "value" } ) ) ] ] ) ) ; } ) ;