Make ZeroOrMore non-greedy to make it nestable without exponential behavior.

This commit is contained in:
Ian Gulliver
2014-06-29 17:39:24 -07:00
parent 2f03f4d9ff
commit 78cc56dc46
3 changed files with 13 additions and 12 deletions

View File

@@ -493,22 +493,18 @@ rr.ZeroOrMore_ = function(child) {
*/
rr.ZeroOrMore_.prototype.match = function(context) {
// Yield:
// 1) The results of SequentialPair(child, this)
// 2) An empty result
// 1) An empty result
// 2) The results of SequentialPair(child, this)
// 3) Done
//
// We must check for results from 1 that don't reduce context.remaining();
// We must check for results from 2 that don't reduce context.remaining();
// that means infinite recursion.
var iterator = this.pair_.match(context);
var iterator = null;
return {
'next': function() {
if (!iterator) {
return { 'done': true };
}
var next = iterator.next();
if (next['done']) {
iterator = null;
iterator = this.pair_.match(context);
return {
'done': false,
'value': {
@@ -517,6 +513,10 @@ rr.ZeroOrMore_.prototype.match = function(context) {
}
};
}
var next = iterator.next();
if (next['done']) {
return { 'done': true };
}
if (next['value']['context'].remaining() == context.remaining()) {
throw "Child of ZeroOrMore didn't consume input; grammar bug?";
}