-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathwkt2_tokenizer.js
More file actions
105 lines (93 loc) · 2.28 KB
/
wkt2_tokenizer.js
File metadata and controls
105 lines (93 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* Tokenizer for WKT2 strings.
*/
class Tokenizer {
/**
* @param {string} input
*/
constructor(input) {
this.input = input;
this.length = input.length;
this.pos = 0;
}
/** @returns {Token|null} */
nextToken() {
this._skipWhitespace();
if (this.pos >= this.length) return null;
const char = this.input[this.pos];
// Punctuation
if (char === '[' || char === ']' || char === ',') {
this.pos++;
return {
type: 'punctuation',
value: char,
position: this.pos - 1,
};
}
// Quoted string
if (char === '"') {
const start = this.pos++;
let str = '';
while (this.pos < this.length && this.input[this.pos] !== '"') {
str += this.input[this.pos++];
}
if (this.input[this.pos] !== '"') {
throw new WKTParsingError('Unterminated string', start);
}
this.pos++; // skip closing quote
return {
type: 'string',
value: str,
position: start,
};
}
// Number (int or float)
if (char.match(/[0-9\.\-]/)) {
const start = this.pos;
let num = '';
while (this.pos < this.length && this.input[this.pos].match(/[0-9eE\.\+\-]/)) {
num += this.input[this.pos++];
}
return {
type: 'number',
value: num,
position: start,
};
}
// Keyword (identifiers)
if (char.match(/[A-Z_]/i)) {
const start = this.pos;
let ident = '';
while (this.pos < this.length && this.input[this.pos].match(/[A-Z0-9_]/i)) {
ident += this.input[this.pos++];
}
return {
type: 'keyword',
value: ident,
position: start,
};
}
throw new WKTParsingError(`Unexpected character '${char}'`, this.pos);
}
/** @returns {Token|null} */
peekToken() {
const savedPos = this.pos;
try {
return this.nextToken();
} finally {
this.pos = savedPos;
}
}
_skipWhitespace() {
while (this.pos < this.length && this.input[this.pos].match(/\s/)) {
this.pos++;
}
}
}
export default Tokenizer;
// example usage
// const tokenizer = new Tokenizer(`GEODCRS["WGS 84", DATUM["World Geodetic System 1984"]]`);
// let token;
// while ((token = tokenizer.nextToken())) {
// console.log(token);
// }