Skip to main content
Module

x/ohm_js/src/Matcher.js

A library and language for building parsers, interpreters, compilers, etc.
Go to Latest
File
'use strict';
// --------------------------------------------------------------------// Imports// --------------------------------------------------------------------
const MatchState = require('./MatchState');
const pexprs = require('./pexprs');
// --------------------------------------------------------------------// Private stuff// --------------------------------------------------------------------
function Matcher(grammar) { this.grammar = grammar; this.memoTable = []; this.input = '';}
Matcher.prototype.getInput = function() { return this.input;};
Matcher.prototype.setInput = function(str) { if (this.input !== str) { this.replaceInputRange(0, this.input.length, str); } return this;};
Matcher.prototype.replaceInputRange = function(startIdx, endIdx, str) { const currentInput = this.input; if ( startIdx < 0 || startIdx > currentInput.length || endIdx < 0 || endIdx > currentInput.length || startIdx > endIdx ) { throw new Error('Invalid indices: ' + startIdx + ' and ' + endIdx); }
// update input this.input = currentInput.slice(0, startIdx) + str + currentInput.slice(endIdx);
// update memo table (similar to the above) const restOfMemoTable = this.memoTable.slice(endIdx); this.memoTable.length = startIdx; for (let idx = 0; idx < str.length; idx++) { this.memoTable.push(undefined); } restOfMemoTable.forEach(function(posInfo) { this.memoTable.push(posInfo); }, this);
// Invalidate memoRecs for (let pos = 0; pos < startIdx; pos++) { const posInfo = this.memoTable[pos]; if (posInfo) { posInfo.clearObsoleteEntries(pos, startIdx); } }
return this;};
Matcher.prototype.match = function(optStartApplicationStr) { return this._match(this._getStartExpr(optStartApplicationStr), false);};
Matcher.prototype.trace = function(optStartApplicationStr) { return this._match(this._getStartExpr(optStartApplicationStr), true);};
Matcher.prototype._match = function(startExpr, tracing, optPositionToRecordFailures) { const state = new MatchState(this, startExpr, optPositionToRecordFailures); return tracing ? state.getTrace() : state.getMatchResult();};
/* Returns the starting expression for this Matcher's associated grammar. If `optStartApplicationStr` is specified, it is a string expressing a rule application in the grammar. If not specified, the grammar's default start rule will be used.*/Matcher.prototype._getStartExpr = function(optStartApplicationStr) { const applicationStr = optStartApplicationStr || this.grammar.defaultStartRule; if (!applicationStr) { throw new Error('Missing start rule argument -- the grammar has no default start rule.'); }
const startApp = this.grammar.parseApplication(applicationStr); return new pexprs.Seq([startApp, pexprs.end]);};
// --------------------------------------------------------------------// Exports// --------------------------------------------------------------------
module.exports = Matcher;