Add a Pair matcher. Turn Sequence into a Pair factory instead of a real matcher.

This commit is contained in:
Ian Gulliver
2014-06-28 00:05:46 -07:00
parent 049382a744
commit 1e13b75ad4

View File

@@ -526,16 +526,13 @@ rr.ZeroOrMore = function(child) {
/** /**
* @constructor * @constructor
* *
* @param {Array.<rr.typeMatcher>} children * @param {rr.typeMatcher} child1
* @param {rr.typeMatcher} child2
* @private * @private
*/ */
rr.Sequence_ = function(children) { rr.Pair_ = function(child1, child2) {
this.child_ = children[0]; this.child1_ = child1;
if (children.length > 1) { this.child2_ = child2;
this.next_ = rr.Sequence.apply(null, children.slice(1));
} else {
this.next_ = null;
}
}; };
@@ -543,38 +540,35 @@ rr.Sequence_ = function(children) {
* @param {rr.Context} context * @param {rr.Context} context
* @return {rr.typeIterator} * @return {rr.typeIterator}
*/ */
rr.Sequence_.prototype.match = function(context) { rr.Pair_.prototype.match = function(context) {
var childIterator = this.child_.match(context); var child1Iterator = this.child1_.match(context);
if (!this.next_) { var child1Value = null;
return childIterator; var child2Iterator = null;
}
var currentChildValue = null;
var nextIterator = null;
return { return {
'next': function() { 'next': function() {
while (true) { while (true) {
if (!currentChildValue) { if (!child1Value) {
currentChildValue = childIterator.next(); child1Value = child1Iterator.next();
if (currentChildValue['done']) { if (child1Value['done']) {
return { 'done': true }; return { 'done': true };
} }
nextIterator = null; child2Iterator = null;
} }
if (!nextIterator) { if (!child2Iterator) {
nextIterator = this.next_.match( child2Iterator = this.child2_.match(
currentChildValue['value']['context']); child1Value['value']['context']);
} }
var nextAppendValue = nextIterator.next(); var child2Value = child2Iterator.next();
if (nextAppendValue['done']) { if (child2Value['done']) {
currentChildValue = null; child1Value = null;
continue; continue;
} }
return { return {
'done': false, 'done': false,
'value': { 'value': {
'context': nextAppendValue['value']['context'], 'context': child2Value['value']['context'],
'nodes': currentChildValue['value']['nodes'].concat( 'nodes': child1Value['value']['nodes'].concat(
nextAppendValue['value']['nodes']) child2Value['value']['nodes'])
} }
}; };
} }
@@ -584,10 +578,24 @@ rr.Sequence_.prototype.match = function(context) {
/** /**
* @return {rr.Sequence_} * @param {rr.typeMatcher} child1
* @param {rr.typeMatcher} child2
* @return {rr.Pair_}
*/
rr.Pair = function(child1, child2) {
return new rr.Pair_(child1, child2);
};
/**
* @return {rr.Pair_|rr.typeMatcher}
*/ */
rr.Sequence = function() { rr.Sequence = function() {
return new rr.Sequence_(Array.prototype.slice.call(arguments)); var children = Array.prototype.slice.call(arguments);
if (children.length == 1) {
return children[0];
}
return rr.Pair(children[0], rr.Sequence.apply(null, children.slice(1)));
}; };