fluke.js
function splitNext(source, cb, rules) { 
  
  var matchPos = source.search( makeRegExp( joinProperties( rules ) ) );
  if (matchPos != -1) {
    var match = source.substr( 0, matchPos + 1 )
    for (property in rules) {
      var rule = rules[property]
        , re = makeRegExp( rule );
      if (source.search(re) == matchPos) {
        var token = source.match( re )
          , response = {
              lhs: source.substr( 0, matchPos ), 
              rhs: source.substr( matchPos + token[0].length ),
              token: token[0]
            };
        cb( property, response );
        return;
      }
    }
  }
  cb( 'end', { lhs: source } );
  
  function makeRegExp( rules ) {
    return new RegExp( '(' + rules + ')' ); 
  }

  function joinProperties(properties) {
    var result = [];
    for(property in properties) {
      result.push( properties[property] );
    }
    return result.join( '|' );
  }
}
function splitNext(source, cb, rules) { 
  
  var matchPos = source.search( makeRegExp( joinProperties( rules ) ) );
  if (matchPos != -1) {
    var match = source.substr( 0, matchPos + 1 )
    for (property in rules) {
      var rule = rules[property]
        , re = makeRegExp( rule );
      if (source.search(re) == matchPos) {
        var token = source.match( re )
          , response = {
              lhs: source.substr( 0, matchPos ), 
              rhs: source.substr( matchPos + token[0].length ),
              token: token[0]
            };
        cb( property, response );
        return;
      }
    }
  }
  cb( 'end', { lhs: source } );
  
  function makeRegExp( rules ) {
    return new RegExp( '(' + rules + ')' ); 
  }

  function joinProperties(properties) {
    var result = [];
    for(property in properties) {
      result.push( properties[property] );
    }
    return result.join( '|' );
  }
}
function splitNext ( source , cb , rules ) { var matchPos = source . search ( makeRegExp ( joinProperties ( rules ) ) ) ; if ( matchPos != - 1 ) { var match = source . substr ( 0 , matchPos + 1 ) for ( property in rules ) { var rule = rules [ property ] , re = makeRegExp ( rule ) ; if ( source . search ( re ) == matchPos ) { var token = source . match ( re ) , response = { lhs : source . substr ( 0 , matchPos ) , rhs : source . substr ( matchPos + token [ 0 ] . length ) , token : token [ 0 ] } ; cb ( property , response ) ; return ; } } } cb ( 'end' , { lhs : source } ) ; function makeRegExp ( rules ) { return new RegExp ( '(' + rules + ')' ) ; } function joinProperties ( properties ) { var result = [ ] ; for ( property in properties ) { result . push ( properties [ property ] ) ; } return result . join ( '|' ) ; } }
process next token in source
process next token in source