@scalenc/tmt-format
Version:
Library for handling TRUMPF TMT file format.
174 lines • 6.73 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
const Constants_1 = require("./Constants");
class Parser {
source;
pos;
get isOk() {
return this.pos < this.source.length;
}
get isAtLineEnd() {
return this.char === '\r' || this.char === '\n';
}
token = null;
char = null;
lineNumber;
constructor(source) {
this.source = source;
this.pos = -1;
this.lineNumber = 1;
this.readNextChar();
}
readRaw() {
this.assert(this.isAtLineEnd, `Expected to be at end of line before reading raw section`);
this.readNextChar();
const i0 = this.pos;
while (this.char && this.char !== Constants_1.Constants.SectionStart && this.char !== Constants_1.Constants.ClosingBrace) {
this.skipLine();
}
return this.source.substring(i0, this.pos);
}
read() {
const whitespace = this.readWhitespaces();
switch (this.char) {
case null:
case undefined:
this.token = null;
return false;
case Constants_1.Constants.OpeningBrace:
case Constants_1.Constants.ClosingBrace:
this.token = { whitespace, type: 'brace', text: this.char };
this.readNextChar();
return true;
case Constants_1.Constants.Semicolon:
this.token = { whitespace, type: 'semicolon', text: this.char };
this.readNextChar();
return true;
case Constants_1.Constants.SectionStart:
this.readNextChar();
this.token = { whitespace, type: 'section', text: this.readUntil(Constants_1.Constants.SectionEnd) };
this.assert(this.char === Constants_1.Constants.SectionEnd, `Expected end of section`);
this.readNextChar();
return true;
case Constants_1.Constants.StringDelimiter:
this.readNextChar();
this.token = { whitespace, type: 'string', text: this.readUntil(Constants_1.Constants.StringDelimiter, Constants_1.Constants.EscapeStringDelimiter) };
this.assert(this.char === Constants_1.Constants.StringDelimiter, `Expected end of string`);
this.readNextChar();
return true;
case Constants_1.Constants.RawStart: {
const line = this.readLine();
if (line.trim().startsWith(Constants_1.Constants.GeoStart)) {
this.token = { whitespace, type: 'geo', text: line + this.readLinesUntil(Constants_1.Constants.GeoEnd) };
}
else {
this.token = { whitespace, type: 'raw', text: line + this.readLinesUntil(line.trim() + Constants_1.Constants.RawEndPostfix) };
}
return true;
}
default:
if (Constants_1.Constants.NumberStart.test(this.char)) {
this.token = { whitespace, type: 'number', text: this.readWhile(Constants_1.Constants.NumberChar, true) };
return true;
}
else {
this.token = { whitespace, type: 'name', text: this.readWhile(Constants_1.Constants.NameChar) };
this.assert(this.token.text !== '', `Expected name but found end of file or unknown character`);
return true;
}
}
}
readLinesUntil(endLine) {
const i0 = this.pos;
while (this.char) {
const line = this.readLine().trim();
if (line === endLine)
return this.source.substring(i0, this.pos);
}
throw this.makeError(`Expected end of GEO content but found end of file`);
}
readLine() {
const iLine = this.pos;
this.skipLine();
return this.source.substring(iLine, this.pos);
}
readWhile(pattern, skipFirst) {
const i0 = this.pos;
if (skipFirst)
this.readNextChar();
while (this.char && pattern.test(this.char)) {
this.readNextChar();
}
return this.source.substring(i0, this.pos);
}
readUntil(delimiter, escape) {
const i0 = this.pos;
let prev = this.char;
while (this.char && (this.char !== delimiter || (escape && prev === escape))) {
prev = this.char;
this.readNextChar();
}
return this.source.substring(i0, this.pos);
}
skipLine() {
while (this.char && !this.isAtLineEnd) {
this.readNextChar();
}
this.readNextChar();
}
readWhitespaces() {
const i0 = this.pos;
while (this.char && (Constants_1.Constants.WhiteSpace.test(this.char) || this.skipComment())) {
this.readNextChar();
}
return this.source.substring(i0, this.pos);
}
skipComment() {
if (this.char === Constants_1.Constants.CommentStart[0] && this.source[this.pos + 1] === Constants_1.Constants.CommentStart[1]) {
this.readNextChar();
this.readNextChar();
while (this.char) {
if (this.char === Constants_1.Constants.CommentEnd[0] && this.source[this.pos + 1] === Constants_1.Constants.CommentEnd[1]) {
this.readNextChar();
// this.readNextChar(); is being called by caller readWhitespaces()
return true;
}
this.readNextChar();
}
throw this.makeError(`Expected end of comment but found end of file`);
}
return false;
}
readNextChar() {
if (this.isOk) {
if (++this.pos === this.source.length) {
this.char = null;
}
else {
let next = this.source[this.pos];
if (this.isAtLineEnd) {
++this.lineNumber;
if (this.char === '\r' && next === '\n') {
if (++this.pos === this.source.length) {
next = null;
}
else {
next = this.source[this.pos];
}
}
}
this.char = next;
}
}
}
assert(condition, message) {
if (!condition)
throw this.makeError(message);
}
makeError(message) {
return new Error(`In line ${this.lineNumber}: ${message}`);
}
}
exports.Parser = Parser;
//# sourceMappingURL=Parser.js.map