Fix rr.Or matcher inifite loop bug.
This commit is contained in:
@@ -56,6 +56,7 @@ rr.Literal_ = function(value) {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.Literal_.prototype.match = function(context) {
|
rr.Literal_.prototype.match = function(context) {
|
||||||
|
console.log('Literal.match:', this.value_);
|
||||||
if (context.stringAfter(this.value_.length) == this.value_) {
|
if (context.stringAfter(this.value_.length) == this.value_) {
|
||||||
return rr.iterableFromArray_([{
|
return rr.iterableFromArray_([{
|
||||||
'context': context.advance(this.value_.length),
|
'context': context.advance(this.value_.length),
|
||||||
@@ -101,6 +102,7 @@ rr.Ref_ = function(key) {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.Ref_.prototype.match = function(context) {
|
rr.Ref_.prototype.match = function(context) {
|
||||||
|
console.log('Ref.match:', this.key_);
|
||||||
return context.rules[this.key_].match(context);
|
return context.rules[this.key_].match(context);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,9 +143,11 @@ rr.Node_ = function(name, child) {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.Node_.prototype.match = function(context) {
|
rr.Node_.prototype.match = function(context) {
|
||||||
|
console.log('Node.match');
|
||||||
var iterator = this.child_.match(context);
|
var iterator = this.child_.match(context);
|
||||||
return {
|
return {
|
||||||
'next': function() {
|
'next': function() {
|
||||||
|
console.log('Node.next');
|
||||||
var next = iterator.next();
|
var next = iterator.next();
|
||||||
if (next['done']) {
|
if (next['done']) {
|
||||||
return { 'done': true };
|
return { 'done': true };
|
||||||
@@ -191,6 +195,7 @@ rr.EndOfLine_ = function() {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.EndOfLine_.prototype.match = function(context) {
|
rr.EndOfLine_.prototype.match = function(context) {
|
||||||
|
console.log('EndOfLine.match');
|
||||||
if (context.atEnd()) {
|
if (context.atEnd()) {
|
||||||
return rr.iterableFromArray_([{
|
return rr.iterableFromArray_([{
|
||||||
'context': context,
|
'context': context,
|
||||||
@@ -243,6 +248,7 @@ rr.EndOfText_ = function() {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.EndOfText_.prototype.match = function(context) {
|
rr.EndOfText_.prototype.match = function(context) {
|
||||||
|
console.log('EndOfText.match');
|
||||||
if (context.atEnd()) {
|
if (context.atEnd()) {
|
||||||
return rr.iterableFromArray_([{
|
return rr.iterableFromArray_([{
|
||||||
'context': context,
|
'context': context,
|
||||||
@@ -284,9 +290,11 @@ rr.MultiLineText_ = function() {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.MultiLineText_.prototype.match = function(context) {
|
rr.MultiLineText_.prototype.match = function(context) {
|
||||||
|
console.log('MultiLineText.match');
|
||||||
var i = 1;
|
var i = 1;
|
||||||
return {
|
return {
|
||||||
'next': function() {
|
'next': function() {
|
||||||
|
console.log('MultiLineText.next:', i);
|
||||||
if (i <= context.remaining()) {
|
if (i <= context.remaining()) {
|
||||||
var newNode = document.createTextNode(context.stringAfter(i));
|
var newNode = document.createTextNode(context.stringAfter(i));
|
||||||
var ret = {
|
var ret = {
|
||||||
@@ -338,27 +346,28 @@ rr.Or_ = function(options) {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.Or_.prototype.match = function(context) {
|
rr.Or_.prototype.match = function(context) {
|
||||||
var i = 0;
|
console.log('Or.match');
|
||||||
|
var optionIndex = 0;
|
||||||
var lastIterator = null;
|
var lastIterator = null;
|
||||||
return {
|
return {
|
||||||
'next': function() {
|
'next': function() {
|
||||||
|
console.log('Or.next');
|
||||||
|
while (true) {
|
||||||
if (lastIterator) {
|
if (lastIterator) {
|
||||||
|
console.log('Or.next: still consuming child iterator', optionIndex);
|
||||||
var next = lastIterator.next();
|
var next = lastIterator.next();
|
||||||
if (!next['done']) {
|
if (!next['done']) {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; i < this.options_.length; i++) {
|
console.log('Or.next: moving on to next option', optionIndex);
|
||||||
var option = this.options_[i];
|
var option = this.options_[optionIndex++];
|
||||||
lastIterator = option.match(context);
|
if (!option) {
|
||||||
var next = lastIterator.next();
|
console.log('Or.next: returning done');
|
||||||
if (next['done']) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { 'done': true };
|
return { 'done': true };
|
||||||
|
}
|
||||||
|
lastIterator = option.match(context);
|
||||||
|
}
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -387,9 +396,11 @@ rr.SingleLineText_ = function() {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.SingleLineText_.prototype.match = function(context) {
|
rr.SingleLineText_.prototype.match = function(context) {
|
||||||
|
console.log('SingleLineText.match');
|
||||||
var i = 1;
|
var i = 1;
|
||||||
return {
|
return {
|
||||||
'next': function() {
|
'next': function() {
|
||||||
|
console.log('SingleLineText.next');
|
||||||
if (i <= context.remaining()) {
|
if (i <= context.remaining()) {
|
||||||
var newString = context.stringAfter(i);
|
var newString = context.stringAfter(i);
|
||||||
if (newString.indexOf('\n') != -1) {
|
if (newString.indexOf('\n') != -1) {
|
||||||
@@ -443,6 +454,7 @@ rr.StartOfLine_ = function() {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.StartOfLine_.prototype.match = function(context) {
|
rr.StartOfLine_.prototype.match = function(context) {
|
||||||
|
console.log('StartOfLine.match');
|
||||||
if (context.atStart()) {
|
if (context.atStart()) {
|
||||||
return rr.iterableFromArray_([{
|
return rr.iterableFromArray_([{
|
||||||
'context': context,
|
'context': context,
|
||||||
@@ -497,6 +509,7 @@ rr.ZeroOrMore_ = function(child) {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.ZeroOrMore_.prototype.match = function(context) {
|
rr.ZeroOrMore_.prototype.match = function(context) {
|
||||||
|
console.log('ZeroOrMore.match');
|
||||||
// Yield:
|
// Yield:
|
||||||
// 1) The results of SequentialPair(child, this)
|
// 1) The results of SequentialPair(child, this)
|
||||||
// 2) An empty result
|
// 2) An empty result
|
||||||
@@ -508,6 +521,7 @@ rr.ZeroOrMore_.prototype.match = function(context) {
|
|||||||
var iterator = this.pair_.match(context);
|
var iterator = this.pair_.match(context);
|
||||||
return {
|
return {
|
||||||
'next': function() {
|
'next': function() {
|
||||||
|
console.log('ZeroOrMore.next');
|
||||||
if (!iterator) {
|
if (!iterator) {
|
||||||
return { 'done': true };
|
return { 'done': true };
|
||||||
}
|
}
|
||||||
@@ -559,11 +573,13 @@ rr.SequentialPair_ = function(child1, child2) {
|
|||||||
* @return {rr.typeIterator}
|
* @return {rr.typeIterator}
|
||||||
*/
|
*/
|
||||||
rr.SequentialPair_.prototype.match = function(context) {
|
rr.SequentialPair_.prototype.match = function(context) {
|
||||||
|
console.log('SequentialPair.match');
|
||||||
var child1Iterator = this.child1_.match(context);
|
var child1Iterator = this.child1_.match(context);
|
||||||
var child1Value = null;
|
var child1Value = null;
|
||||||
var child2Iterator = null;
|
var child2Iterator = null;
|
||||||
return {
|
return {
|
||||||
'next': function() {
|
'next': function() {
|
||||||
|
console.log('SequentialPair.next');
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!child1Value) {
|
if (!child1Value) {
|
||||||
child1Value = child1Iterator.next();
|
child1Value = child1Iterator.next();
|
||||||
@@ -702,5 +718,6 @@ rr.Context.prototype.advance = function(numChars) {
|
|||||||
}
|
}
|
||||||
var context = this.copy();
|
var context = this.copy();
|
||||||
context.inputIndex += numChars;
|
context.inputIndex += numChars;
|
||||||
|
console.log('New context: ', context.stringAfter());
|
||||||
return context;
|
return context;
|
||||||
};
|
};
|
||||||
|
|||||||
2
test.js
2
test.js
@@ -3,7 +3,7 @@ QUnit.test('Simple', function(assert) {
|
|||||||
var context = new rr.Context(mediawiki,
|
var context = new rr.Context(mediawiki,
|
||||||
'=== Heading ===\n' +
|
'=== Heading ===\n' +
|
||||||
'This is a wiki doc.\n' +
|
'This is a wiki doc.\n' +
|
||||||
"How about some '''bold and <i>bold italic</i>'''.\n" +
|
"How about some '''bold and ''bold italic'''''.\n" +
|
||||||
'I would also love some <nowiki>nowiki <b>foo</b></nowiki>');
|
'I would also love some <nowiki>nowiki <b>foo</b></nowiki>');
|
||||||
var iterable = context.rules['wikidoc'].match(context);
|
var iterable = context.rules['wikidoc'].match(context);
|
||||||
assert.equal(iterable.next().value.nodes[0].innerHTML,
|
assert.equal(iterable.next().value.nodes[0].innerHTML,
|
||||||
|
|||||||
Reference in New Issue
Block a user