Rewrite ZeroOrMore to produce all options instead of just the first.
This commit is contained in:
@@ -488,7 +488,7 @@ rr.StartOfLine.cache = new rr.StartOfLine_();
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
rr.ZeroOrMore_ = function(child) {
|
rr.ZeroOrMore_ = function(child) {
|
||||||
this.child_ = child;
|
this.pair_ = rr.SequentialPair(child, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -497,19 +497,37 @@ rr.ZeroOrMore_ = function(child) {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.ZeroOrMore_.prototype.match = function(context) {
|
rr.ZeroOrMore_.prototype.match = function(context) {
|
||||||
var nodes = [];
|
// Yield:
|
||||||
while (!context.atEnd()) {
|
// 1) The results of SequentialPair(child, this)
|
||||||
var next = this.child_.match(context).next();
|
// 2) An empty result
|
||||||
if (next['done']) {
|
// 3) Done
|
||||||
break;
|
//
|
||||||
}
|
// We must check for results from 1 that don't reduce context.remaining();
|
||||||
context = next['value']['context'];
|
// that means infinite recursion.
|
||||||
Array.prototype.push.apply(nodes, next['value']['nodes']);
|
|
||||||
}
|
var iterator = this.pair_.match(context);
|
||||||
return rr.iterableFromArray_([{
|
return {
|
||||||
'context': context,
|
'next': function() {
|
||||||
'nodes': nodes
|
if (!iterator) {
|
||||||
}]);
|
return { 'done': true };
|
||||||
|
}
|
||||||
|
var next = iterator.next();
|
||||||
|
if (next['done']) {
|
||||||
|
iterator = null;
|
||||||
|
return {
|
||||||
|
'done': false,
|
||||||
|
'value': {
|
||||||
|
'context': context,
|
||||||
|
'nodes': []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (next['value']['context'].remaining() == context.remaining()) {
|
||||||
|
throw "Child of ZeroOrMore didn't consume input; grammar bug?";
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}.bind(this)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -679,6 +697,9 @@ rr.Context.prototype.remaining = function() {
|
|||||||
* @return {rr.Context}
|
* @return {rr.Context}
|
||||||
*/
|
*/
|
||||||
rr.Context.prototype.advance = function(numChars) {
|
rr.Context.prototype.advance = function(numChars) {
|
||||||
|
if (!numChars) {
|
||||||
|
throw "Context.advance(0) called";
|
||||||
|
}
|
||||||
var context = this.copy();
|
var context = this.copy();
|
||||||
context.inputIndex += numChars;
|
context.inputIndex += numChars;
|
||||||
return context;
|
return context;
|
||||||
|
|||||||
Reference in New Issue
Block a user