UNPKG

@scalenc/tmt-format

Version:

Library for handling TRUMPF TMT file format.

174 lines 6.73 kB
"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