Skip to content

Instantly share code, notes, and snippets.

@be5invis
Created February 27, 2014 16:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save be5invis/9254198 to your computer and use it in GitHub Desktop.
Save be5invis/9254198 to your computer and use it in GitHub Desktop.
var SequenceRule = function() {
var parts = arguments;
if(!parts.length) return function(phase, onmatch, onfail) {
return onmatch(phase, '')
}
var last = parts[parts.length - 1];
var trailing = function(phase, onmatch, onfail){
last(phase, function(phase1, result){ onmatch(phase1, [result]) }, onfail)
};
for(var j = parts.length - 2; j >= 0; j--) {
trailing = (function(trailing, part){
return function(phase, onmatch, onfail){
return part(phase, function(phase1, result){
return trailing(phase1, function(phase2, result2){
return onmatch(phase2, [result].concat(result2))
}, onfail)
}, function(reason){
return onfail(reason)
})
}
})(trailing, parts[j]);
}
return trailing;
}
var AlternateRule = function() {
var alternates = arguments;
if(!alternates.length) return function(phase, onmatch, onfail) {
return onfail(phase, '')
}
var last = alternates[alternates.length - 1];
var trailing = function(phase, onmatch, onfail){
last(phase, onmatch, onfail)
};
for(var j = alternates.length - 2; j >= 0; j--) {
trailing = (function(trailing, alternate){
return function(phase, onmatch, onfail){
return alternate(phase, function(phase1, result){
return onmatch(phase1, result)
}, function(reason){
return trailing(phase, onmatch, onfail)
})
}
})(trailing, alternates[j]);
}
return trailing;
}
var LiteralRule = function(lit){
return function(phase, onmatch, onfail){
if(phase.source.slice(phase.offset, phase.offset + lit.length) === lit){
return onmatch({source: phase.source, offset: phase.offset + lit.length}, lit)
} else {
return onfail("Expecting " + lit)
}
}
}
var ActionRule = function(rule, action){
return function(phase, onmatch, onfail){
rule(phase, function(phase1, result){
return onmatch(phase1, action(result))
}, onfail)
}
}
var Noun = AlternateRule(LiteralRule('car'), LiteralRule('plane'))
var Verb = AlternateRule(LiteralRule('runs'), LiteralRule('flys'))
var Adverb = AlternateRule(LiteralRule('fast'), LiteralRule('high'))
var Space = LiteralRule(' ')
var Spaces = function(p, m, f){
return Spaces(p, m, f);
};
Spaces = ActionRule(AlternateRule(SequenceRule(Space, Spaces), Space), function(){ return null });
var Setence = SequenceRule(Noun, Spaces, Verb, Spaces, Adverb)
Setence({source: 'car runs fast', offset: 0}, function(phase, result){ console.log(result) }, function(reason){ console.log(reason) })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment