tethys-feature-service/node_modules/wkt-parser/parser.js
2023-10-02 15:04:02 +02:00

170 lines
3.8 KiB
JavaScript

export default parseString;
var NEUTRAL = 1;
var KEYWORD = 2;
var NUMBER = 3;
var QUOTED = 4;
var AFTERQUOTE = 5;
var ENDED = -1;
var whitespace = /\s/;
var latin = /[A-Za-z]/;
var keyword = /[A-Za-z84_]/;
var endThings = /[,\]]/;
var digets = /[\d\.E\-\+]/;
// const ignoredChar = /[\s_\-\/\(\)]/g;
function Parser(text) {
if (typeof text !== 'string') {
throw new Error('not a string');
}
this.text = text.trim();
this.level = 0;
this.place = 0;
this.root = null;
this.stack = [];
this.currentObject = null;
this.state = NEUTRAL;
}
Parser.prototype.readCharicter = function() {
var char = this.text[this.place++];
if (this.state !== QUOTED) {
while (whitespace.test(char)) {
if (this.place >= this.text.length) {
return;
}
char = this.text[this.place++];
}
}
switch (this.state) {
case NEUTRAL:
return this.neutral(char);
case KEYWORD:
return this.keyword(char)
case QUOTED:
return this.quoted(char);
case AFTERQUOTE:
return this.afterquote(char);
case NUMBER:
return this.number(char);
case ENDED:
return;
}
};
Parser.prototype.afterquote = function(char) {
if (char === '"') {
this.word += '"';
this.state = QUOTED;
return;
}
if (endThings.test(char)) {
this.word = this.word.trim();
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in afterquote yet, index ' + this.place);
};
Parser.prototype.afterItem = function(char) {
if (char === ',') {
if (this.word !== null) {
this.currentObject.push(this.word);
}
this.word = null;
this.state = NEUTRAL;
return;
}
if (char === ']') {
this.level--;
if (this.word !== null) {
this.currentObject.push(this.word);
this.word = null;
}
this.state = NEUTRAL;
this.currentObject = this.stack.pop();
if (!this.currentObject) {
this.state = ENDED;
}
return;
}
};
Parser.prototype.number = function(char) {
if (digets.test(char)) {
this.word += char;
return;
}
if (endThings.test(char)) {
this.word = parseFloat(this.word);
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in number yet, index ' + this.place);
};
Parser.prototype.quoted = function(char) {
if (char === '"') {
this.state = AFTERQUOTE;
return;
}
this.word += char;
return;
};
Parser.prototype.keyword = function(char) {
if (keyword.test(char)) {
this.word += char;
return;
}
if (char === '[') {
var newObjects = [];
newObjects.push(this.word);
this.level++;
if (this.root === null) {
this.root = newObjects;
} else {
this.currentObject.push(newObjects);
}
this.stack.push(this.currentObject);
this.currentObject = newObjects;
this.state = NEUTRAL;
return;
}
if (endThings.test(char)) {
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in keyword yet, index ' + this.place);
};
Parser.prototype.neutral = function(char) {
if (latin.test(char)) {
this.word = char;
this.state = KEYWORD;
return;
}
if (char === '"') {
this.word = '';
this.state = QUOTED;
return;
}
if (digets.test(char)) {
this.word = char;
this.state = NUMBER;
return;
}
if (endThings.test(char)) {
this.afterItem(char);
return;
}
throw new Error('havn\'t handled "' +char + '" in neutral yet, index ' + this.place);
};
Parser.prototype.output = function() {
while (this.place < this.text.length) {
this.readCharicter();
}
if (this.state === ENDED) {
return this.root;
}
throw new Error('unable to parse string "' +this.text + '". State is ' + this.state);
};
function parseString(txt) {
var parser = new Parser(txt);
return parser.output();
}