Skip to content

Commit

Permalink
Add save/restore (and rewind)
Browse files Browse the repository at this point in the history
Closes #221
  • Loading branch information
tjvr committed Apr 17, 2017
1 parent 1443a47 commit b64ffe6
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 4 deletions.
32 changes: 32 additions & 0 deletions lib/nearley.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@ Parser.prototype.feed = function(chunk) {
throw err;
}

// maybe save lexer state
if (this.options.keepHistory) {
column.lexerState = lexer.save()
}

this.current++;
}
if (column) {
Expand All @@ -334,6 +339,33 @@ Parser.prototype.feed = function(chunk) {
return this;
};

Parser.prototype.save = function() {
var column = this.table[this.current];
column.lexerState = this.lexerState;
return column;
};

Parser.prototype.restore = function(column) {
var index = column.index;
this.current = index;
this.table[index] = column;
this.table.splice(index + 1);
this.lexerState = column.lexerState;

// Incrementally keep track of results
this.results = this.finish();
};

// nb. deprecated: use save/restore instead!
Parser.prototype.rewind = function(index) {
if (!this.options.keepHistory) {
throw new Error('set option `keepHistory` to enable rewinding')
}
// nb. recall column (table) indicies fall between token indicies.
// col 0 -- token 0 -- col 1
this.restore(this.table[index]);
};

Parser.prototype.finish = function() {
// Return the possible parsings
var considerations = [];
Expand Down
48 changes: 44 additions & 4 deletions test/launch.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,20 @@ describe('Parser', function() {
)
})

// TODO: save/restore

/*
var tosh = compile(read("examples/tosh.ne"));

it('can save state', function() {
let first = "say 'hello'";
let second = " for 2 secs";
let p = new nearley.Parser(tosh, { keepHistory: true });
p.feed(first);
p.current.should.equal(11)
p.table.length.should.equal(12)
var col = p.save();
col.index.should.equal(11)
col.lexerState.col.should.equal(first.length)
});

it('can rewind', function() {
let first = "say 'hello'";
let second = " for 2 secs";
Expand All @@ -184,6 +193,7 @@ describe('Parser', function() {
p.feed(second);

p.rewind(first.length);

p.current.should.equal(11)
p.table.length.should.equal(12)

Expand All @@ -194,6 +204,36 @@ describe('Parser', function() {
let p = new nearley.Parser(tosh, {});
p.rewind.should.throw();
})
*/

it('restores line numbers', function() {
let p = new nearley.Parser(testGrammar);
p.feed('abc\n')
p.save().lexerState.line.should.equal(2)
p.feed('123\n')
var col = p.save();
col.lexerState.line.should.equal(3)
p.feed('q')
p.restore(col);
p.lexer.line.should.equal(3)
p.feed('z')
});

it('restores column number', function() {
let p = new nearley.Parser(testGrammar);
p.feed('foo\nbar')
var col = p.save();
col.lexerState.line.should.equal(2)
col.lexerState.col.should.equal(3)
p.feed('123');
p.lexerState.col.should.equal(6)

p.restore(col);
p.lexerState.line.should.equal(2)
p.lexerState.col.should.equal(3)
p.feed('456')
p.lexerState.col.should.equal(6)
});

// TODO: moo save/restore

});

0 comments on commit b64ffe6

Please sign in to comment.