relative-time-expression
Version:
Parser for relative time expression
132 lines (131 loc) • 4.13 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var error_1 = require("./error");
var Parser = /** @class */ (function () {
function Parser(tokens, options) {
if (options === void 0) { options = {}; }
this.tokens = tokens;
this.options = options;
this.iter = 0;
}
Parser.parse = function (tokens, options) {
return new Parser(tokens, options).parse();
};
Object.defineProperty(Parser.prototype, "pop", {
get: function () {
return this.tokens[this.iter++];
},
enumerable: true,
configurable: true
});
Object.defineProperty(Parser.prototype, "top", {
get: function () {
return this.tokens[this.iter];
},
enumerable: true,
configurable: true
});
Parser.prototype.parse = function () {
this.parseWs();
this.parseNow();
this.parseWs();
var manipulations = [];
while (this.iter < this.tokens.length) {
manipulations.push(this.parseManipulation());
this.parseWs();
}
return {
type: 'Expression',
body: manipulations,
start: 0,
end: this.tokens.length > 0 ? this.tokens[this.tokens.length - 1].end : 0,
};
};
Parser.prototype.parseWs = function () {
if (this.top && this.top.type === 'ws') {
return this.pop;
}
};
Parser.prototype.parseNow = function () {
var token = this.top;
if (token && token.type === 'keyword' && token.raw.toLowerCase() === 'now') {
return this.pop;
}
};
Parser.prototype.parseManipulation = function () {
var token = this.top;
if (token.type === 'op') {
if (token.raw === '+' || token.raw === '-') {
return this.parseOffset();
}
else if (token.raw === '/' || token.raw === '\\') {
return this.parsePeriod();
}
}
return this.unexpect('operator(+, -, /, \\)', token);
};
Parser.prototype.parseOffset = function () {
var start = this.top.start;
var op = this.pop.raw;
this.parseWs();
if (!this.top) {
return this.unexpect('integer or unit(e.g. s, m, h, d, ...)');
}
var number = 1;
if (this.top.type === 'number') {
number = parseInt(this.pop.raw, 10);
}
this.parseWs();
var unitToken = this.parseUnit();
return {
type: 'Offset',
op: op,
number: number,
unit: unitToken.raw,
start: start,
end: unitToken.end,
};
};
Parser.prototype.parsePeriod = function () {
var start = this.top.start;
var op = this.pop.raw;
this.parseWs();
var number = 1;
if (this.options.customPeriod && this.top.type === 'number') {
number = parseInt(this.pop.raw, 10);
}
this.parseWs();
var unitToken = this.parseUnit();
return {
type: 'Period',
op: op,
number: number,
unit: unitToken.raw,
start: start,
end: unitToken.end,
};
};
Parser.prototype.parseUnit = function () {
if (this.top && this.top.type === 'unit') {
return this.pop;
}
return this.unexpect('unit(e.g. s, m, h, d, ...)', this.top);
};
Parser.prototype.unexpect = function (required, found) {
if (found) {
throw error_1.createError({
expect: required,
actual: found.raw,
start: found.start,
end: found.end,
});
}
else {
throw error_1.createError({
expect: required,
});
}
};
return Parser;
}());
exports.default = Parser;