import { Token } from '../Lexer' ; import { apply } from './ApplyParser' ; import { betterError , ParseError , Parser , ParseResult , ParserOutput , resultOrError } from './ParserInterface' ; import { seq } from './SequencialParser' ; export function rep < TKind , TResult > ( p ) { const reprParser = repr ( p ) ; return { parse ( token ) { const output = reprParser . parse ( token ) ; if ( output . successful ) { return { candidates : output . candidates . reverse ( ) , successful : true , error : output . error } ; } else { return output ; } } } ; } export function rep_sc < TKind , TResult > ( p ) { return { parse ( token ) { let error ; let result = [ { firstToken : token , nextToken : token , result : [ ] } ] ; while ( true ) { const steps = result ; result = [ ] ; for ( const step of steps ) { const output = p . parse ( step . nextToken ) ; error = betterError ( error , output . error ) ; if ( output . successful ) { for ( const candidate of output . candidates ) { if ( candidate . nextToken !== step . nextToken ) { result . push ( { firstToken : step . firstToken , nextToken : candidate . nextToken , result : step . result . concat ( [ candidate . result ] ) } ) ; } } } } if ( result . length === 0 ) { result = steps ; break ; } } return resultOrError ( result , error , true ) ; } } ; } export function repr < TKind , TResult > ( p ) { return { parse ( token ) { let error ; const result = [ { firstToken : token , nextToken : token , result : [ ] } ] ; for ( let i = 0 ; i < result . length ; i ++ ) { const step = result [ i ] ; const output = p . parse ( step . nextToken ) ; error = betterError ( error , output . error ) ; if ( output . successful ) { for ( const candidate of output . candidates ) { if ( candidate . nextToken !== step . nextToken ) { result . push ( { firstToken : step . firstToken , nextToken : candidate . nextToken , result : step . result . concat ( [ candidate . result ] ) } ) ; } } } } return resultOrError ( result , error , true ) ; } } ; } function applyList < TResult , TSeparator > ( value ) { return [ value [ 0 ] ] . concat ( value [ 1 ] . map ( ( pair ) => { return pair [ 1 ] ; } ) ) ; } export function list < TKind , TResult , TSeparator > ( p , s ) { return apply ( seq ( p , rep ( seq ( s , p ) ) ) , applyList ) ; } export function list_sc < TKind , TResult , TSeparator > ( p , s ) { return apply ( seq ( p , rep_sc ( seq ( s , p ) ) ) , applyList ) ; } function applyLrec < TResult , TFirst extends TResult , TSecond > ( callback ) { return ( value ) : TResult => { let result = value [ 0 ] ; for ( const tail of value [ 1 ] ) { result = callback ( result , tail ) ; } return result ; } ; } export function lrec < TKind , TResult , TFirst extends TResult , TSecond > ( p , q , callback ) { return apply ( seq ( p , rep ( q ) ) , applyLrec ( callback ) ) ; } export function lrec_sc < TKind , TResult , TFirst extends TResult , TSecond > ( p , q , callback ) { return apply ( seq ( p , rep_sc ( q ) ) , applyLrec ( callback ) ) ; }