@lbdudc/gp-gis-dsl 0.2.6 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/grammar/GISGrammar.g4 +75 -2
- package/package.json +1 -1
- package/src/GISVisitor.js +73 -8
- package/src/GISVisitorHelper.js +93 -93
- package/src/cli.js +34 -34
- package/src/error/ErrorListener.js +26 -26
- package/src/error/SyntaxGenericError.js +18 -18
- package/src/features.js +1 -0
- package/src/index.js +26 -26
- package/src/lib/GISGrammar.interp +39 -1
- package/src/lib/GISGrammar.tokens +40 -28
- package/src/lib/GISGrammarLexer.interp +38 -1
- package/src/lib/GISGrammarLexer.js +322 -265
- package/src/lib/GISGrammarLexer.tokens +40 -28
- package/src/lib/GISGrammarListener.js +126 -0
- package/src/lib/GISGrammarParser.js +2253 -964
- package/src/lib/GISGrammarVisitor.js +84 -0
- package/src/spl/GIS.js +234 -234
- package/src/spl/GeoJSONLayer.js +21 -21
- package/src/spl/GeoJSONLayerStyle.js +14 -14
- package/src/spl/Map.js +2 -0
- package/src/spl/TileLayer.js +16 -16
- package/src/spl/WMSLayer.js +30 -30
- package/src/spl/WMSServiceLayer.js +40 -0
- package/src/spl/WMSStyle.js +13 -13
- package/src/spl/WMSStyleCustom.js +22 -22
- package/src/store.js +74 -74
package/grammar/GISGrammar.g4
CHANGED
|
@@ -58,7 +58,66 @@ createWmsLayer: WMS_SYMBOL LAYER_SYMBOL identifier (AS_SYMBOL text)? OPAR_SYMBOL
|
|
|
58
58
|
wmsSubLayer (COMMA_SYMBOL wmsSubLayer)*
|
|
59
59
|
CPAR_SYMBOL SCOL_SYMBOL;
|
|
60
60
|
|
|
61
|
-
wmsSubLayer:
|
|
61
|
+
wmsSubLayer:
|
|
62
|
+
identifier identifier
|
|
63
|
+
| (wmsUrl wmsLayerName wmsFormatName? wmsCrs? wmsStyles? wmsQueryable? wmsAttribution? wmsBboxGroup? wmsVersion?)
|
|
64
|
+
;
|
|
65
|
+
|
|
66
|
+
wmsUrl:
|
|
67
|
+
URL_WMS_SYMBOL text
|
|
68
|
+
;
|
|
69
|
+
|
|
70
|
+
wmsLayerName:
|
|
71
|
+
COMMA_SYMBOL LAYERNAME_SYMBOL text
|
|
72
|
+
;
|
|
73
|
+
|
|
74
|
+
wmsFormatName:
|
|
75
|
+
COMMA_SYMBOL FORMAT_SYMBOL text
|
|
76
|
+
;
|
|
77
|
+
|
|
78
|
+
wmsCrs:
|
|
79
|
+
COMMA_SYMBOL CRS_SYMBOL text
|
|
80
|
+
;
|
|
81
|
+
|
|
82
|
+
wmsBboxCrs:
|
|
83
|
+
COMMA_SYMBOL BBOX_CRS_SYMBOL text
|
|
84
|
+
;
|
|
85
|
+
|
|
86
|
+
wmsMinX:
|
|
87
|
+
COMMA_SYMBOL MINX_SYMBOL floatNumber
|
|
88
|
+
;
|
|
89
|
+
|
|
90
|
+
wmsMinY:
|
|
91
|
+
COMMA_SYMBOL MINY_SYMBOL floatNumber
|
|
92
|
+
;
|
|
93
|
+
|
|
94
|
+
wmsMaxX:
|
|
95
|
+
COMMA_SYMBOL MAXX_SYMBOL floatNumber
|
|
96
|
+
;
|
|
97
|
+
|
|
98
|
+
wmsMaxY:
|
|
99
|
+
COMMA_SYMBOL MAXY_SYMBOL floatNumber
|
|
100
|
+
;
|
|
101
|
+
|
|
102
|
+
wmsBboxGroup:
|
|
103
|
+
wmsBboxCrs wmsMinX wmsMinY wmsMaxX wmsMaxY
|
|
104
|
+
;
|
|
105
|
+
|
|
106
|
+
wmsStyles:
|
|
107
|
+
COMMA_SYMBOL STYLE_SYMBOL text
|
|
108
|
+
;
|
|
109
|
+
|
|
110
|
+
wmsQueryable:
|
|
111
|
+
COMMA_SYMBOL QUERYABLE_SYMBOL text
|
|
112
|
+
;
|
|
113
|
+
|
|
114
|
+
wmsAttribution:
|
|
115
|
+
COMMA_SYMBOL ATTRIBUTION_SYMBOL text
|
|
116
|
+
;
|
|
117
|
+
|
|
118
|
+
wmsVersion:
|
|
119
|
+
COMMA_SYMBOL VERSION_SYMBOL text
|
|
120
|
+
;
|
|
62
121
|
|
|
63
122
|
createSortableMap: SORTABLE_SYMBOL createMap;
|
|
64
123
|
|
|
@@ -159,6 +218,7 @@ fragment LETTER_WITHOUT_FLOAT_PART: [a-df-zA-DF-Z_$\u0080-\uffff];
|
|
|
159
218
|
|
|
160
219
|
fragment UNDERLINE_SYMBOL: '_';
|
|
161
220
|
fragment QUOTE_SYMBOL: '"';
|
|
221
|
+
fragment MINUS_SYMBOL: '-';
|
|
162
222
|
|
|
163
223
|
CREATE_SYMBOL: C R E A T E;
|
|
164
224
|
GIS_SYMBOL: G I S;
|
|
@@ -194,6 +254,19 @@ MAP_SYMBOL: M A P;
|
|
|
194
254
|
SET_SYMBOL: S E T;
|
|
195
255
|
DEPLOYMENT_SYMBOL: D E P L O Y M E N T;
|
|
196
256
|
|
|
257
|
+
URL_WMS_SYMBOL: U R L W M S;
|
|
258
|
+
LAYERNAME_SYMBOL: L A Y E R N A M E;
|
|
259
|
+
FORMAT_SYMBOL: F O R M A T;
|
|
260
|
+
CRS_SYMBOL: C R S;
|
|
261
|
+
BBOX_CRS_SYMBOL: B B O X C R S;
|
|
262
|
+
MINX_SYMBOL: M I N X;
|
|
263
|
+
MINY_SYMBOL: M I N Y;
|
|
264
|
+
MAXX_SYMBOL: M A X X;
|
|
265
|
+
MAXY_SYMBOL: M A X Y;
|
|
266
|
+
QUERYABLE_SYMBOL: Q U E R Y A B L E;
|
|
267
|
+
ATTRIBUTION_SYMBOL: A T T R I B U T I O N;
|
|
268
|
+
VERSION_SYMBOL: V E R S I O N;
|
|
269
|
+
|
|
197
270
|
ZERO_ONE_SYMBOL: '0..1';
|
|
198
271
|
ONE_ONE_SYMBOL: '1..1';
|
|
199
272
|
ZERO_MANY_SYMBOL: '0..*';
|
|
@@ -224,7 +297,7 @@ SCOL_SYMBOL : ';';
|
|
|
224
297
|
|
|
225
298
|
HEX_COLOR: POUND_SYMBOL HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT;
|
|
226
299
|
INT_NUMBER: DIGITS;
|
|
227
|
-
FLOAT_NUMBER: (DIGITS? DOT_SYMBOL)? DIGITS;
|
|
300
|
+
FLOAT_NUMBER: MINUS_SYMBOL? (DIGITS? DOT_SYMBOL)? DIGITS;
|
|
228
301
|
|
|
229
302
|
COMMENT: '//' ~[\r\n]* -> skip;
|
|
230
303
|
//SPACE: [ \t]+ -> skip;
|
package/package.json
CHANGED
package/src/GISVisitor.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
Map,
|
|
9
9
|
GeoJSONLayerStyle,
|
|
10
10
|
WMSStyleCustom,
|
|
11
|
+
WMSServiceLayer,
|
|
11
12
|
} from "./spl/Map.js";
|
|
12
13
|
import { transformation, getPropertyParams } from "./GISVisitorHelper.js";
|
|
13
14
|
// import { generateProduct } from "./project-generator.js";
|
|
@@ -256,8 +257,75 @@ class Visitor extends GISGrammarVisitor {
|
|
|
256
257
|
|
|
257
258
|
visitCreateWmsLayer(ctx) {
|
|
258
259
|
const id = ctx.getChild(2).getText();
|
|
259
|
-
let label = id
|
|
260
|
-
|
|
260
|
+
let label = id;
|
|
261
|
+
|
|
262
|
+
const isWmsService = ctx
|
|
263
|
+
.getChild(6)
|
|
264
|
+
.getText()
|
|
265
|
+
.toLowerCase()
|
|
266
|
+
.startsWith("urlwms");
|
|
267
|
+
|
|
268
|
+
const layer = isWmsService
|
|
269
|
+
? this._createWmsServiceLayer(ctx, id, label)
|
|
270
|
+
: this._createStandardLayer(ctx, id, label);
|
|
271
|
+
|
|
272
|
+
this.log(`visitCreateWmsLayer ${id} - ${label}`);
|
|
273
|
+
|
|
274
|
+
this.store.getCurrentProduct().addLayer(layer);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
_getCleanText = (node) => node?.text()?.getText().replace(/"/g, "") || null;
|
|
278
|
+
|
|
279
|
+
_createWmsServiceLayer(ctx, id, label) {
|
|
280
|
+
const sub = ctx.wmsSubLayer(0);
|
|
281
|
+
const clean = this._getCleanText;
|
|
282
|
+
|
|
283
|
+
const url = clean(sub.wmsUrl());
|
|
284
|
+
const layerName = clean(sub.wmsLayerName());
|
|
285
|
+
const format = clean(sub.wmsFormatName());
|
|
286
|
+
const crs = clean(sub.wmsCrs());
|
|
287
|
+
const version = clean(sub.wmsVersion());
|
|
288
|
+
const attribution = clean(sub.wmsAttribution());
|
|
289
|
+
|
|
290
|
+
const styles = sub.wmsStyles()
|
|
291
|
+
? clean(sub.wmsStyles())
|
|
292
|
+
.split(",")
|
|
293
|
+
.map((s) => s.trim())
|
|
294
|
+
: [];
|
|
295
|
+
|
|
296
|
+
const queryable = sub.wmsQueryable()
|
|
297
|
+
? clean(sub.wmsQueryable()).toLowerCase() === "true"
|
|
298
|
+
: false;
|
|
299
|
+
|
|
300
|
+
let bbox = null;
|
|
301
|
+
const bboxNode = sub.wmsBboxGroup();
|
|
302
|
+
if (bboxNode) {
|
|
303
|
+
bbox = {
|
|
304
|
+
crs: clean(bboxNode.wmsBboxCrs()),
|
|
305
|
+
minx: parseFloat(bboxNode.wmsMinX().floatNumber().getText()),
|
|
306
|
+
miny: parseFloat(bboxNode.wmsMinY().floatNumber().getText()),
|
|
307
|
+
maxx: parseFloat(bboxNode.wmsMaxX().floatNumber().getText()),
|
|
308
|
+
maxy: parseFloat(bboxNode.wmsMaxY().floatNumber().getText()),
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return new WMSServiceLayer({
|
|
313
|
+
id,
|
|
314
|
+
label,
|
|
315
|
+
url,
|
|
316
|
+
layerName,
|
|
317
|
+
format,
|
|
318
|
+
crs,
|
|
319
|
+
bbox,
|
|
320
|
+
styles,
|
|
321
|
+
queryable,
|
|
322
|
+
attribution,
|
|
323
|
+
version,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
_createStandardLayer(ctx, id, label) {
|
|
328
|
+
let from = 4,
|
|
261
329
|
i,
|
|
262
330
|
aux,
|
|
263
331
|
entity,
|
|
@@ -269,10 +337,9 @@ class Visitor extends GISGrammarVisitor {
|
|
|
269
337
|
label = ctx.getChild(4).getText().slice(1, -1);
|
|
270
338
|
from = 6;
|
|
271
339
|
}
|
|
272
|
-
|
|
273
340
|
const layer = new WMSLayer(id, label);
|
|
274
341
|
|
|
275
|
-
for (i = from; i < ctx.getChildCount() - 2; i
|
|
342
|
+
for (i = from; i < ctx.getChildCount() - 2; i += 2) {
|
|
276
343
|
aux = ctx.getChild(i);
|
|
277
344
|
auxEntityName = aux.getChild(0).getText();
|
|
278
345
|
entity = this.store.getCurrentProduct().getEntity(auxEntityName);
|
|
@@ -282,7 +349,7 @@ class Visitor extends GISGrammarVisitor {
|
|
|
282
349
|
if (entity) {
|
|
283
350
|
layer.addSubLayer(entity.name, styleName);
|
|
284
351
|
} else {
|
|
285
|
-
// GeoTIFF
|
|
352
|
+
// GeoTIFF: no entity
|
|
286
353
|
const normalizedId = id
|
|
287
354
|
.replace(/Layer$/, "")
|
|
288
355
|
.replace(/^(\d+)([A-Z][a-z]+)/, "$1_$2")
|
|
@@ -291,9 +358,7 @@ class Visitor extends GISGrammarVisitor {
|
|
|
291
358
|
}
|
|
292
359
|
}
|
|
293
360
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
this.store.getCurrentProduct().addLayer(layer);
|
|
361
|
+
return layer;
|
|
297
362
|
}
|
|
298
363
|
|
|
299
364
|
visitCreateMap(ctx, sortable) {
|
package/src/GISVisitorHelper.js
CHANGED
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import features from "./features.js";
|
|
2
|
-
|
|
3
|
-
function transformation(spec) {
|
|
4
|
-
_relationships(spec);
|
|
5
|
-
const newSpec = {
|
|
6
|
-
features: features,
|
|
7
|
-
basicData: {
|
|
8
|
-
name: spec.name,
|
|
9
|
-
},
|
|
10
|
-
data: {
|
|
11
|
-
dataModel: {
|
|
12
|
-
entities: spec.entities,
|
|
13
|
-
enums: [],
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
mapViewer: {
|
|
17
|
-
maps: spec.maps,
|
|
18
|
-
layers: spec.layers,
|
|
19
|
-
styles: spec.styles,
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
if (spec.extra) {
|
|
24
|
-
newSpec.basicData.extra = spec.extra;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return newSpec;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function _relationships(spec) {
|
|
31
|
-
let source, target;
|
|
32
|
-
|
|
33
|
-
spec.relationships.forEach((r) => {
|
|
34
|
-
source = spec.getEntity(r.source);
|
|
35
|
-
target = spec.getEntity(r.target);
|
|
36
|
-
let sourceOwner = false;
|
|
37
|
-
let targetOwner = false;
|
|
38
|
-
let sourceMultiple = _multiple(r.sourceOpts.multiplicity);
|
|
39
|
-
let targetMultiple = _multiple(r.targetOpts.multiplicity);
|
|
40
|
-
if (sourceMultiple && !targetMultiple) {
|
|
41
|
-
targetOwner = true;
|
|
42
|
-
} else {
|
|
43
|
-
sourceOwner = true;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
source.properties.push({
|
|
47
|
-
name: r.sourceOpts.label,
|
|
48
|
-
class: target.name,
|
|
49
|
-
owner: sourceOwner,
|
|
50
|
-
bidirectional: r.targetOpts.label,
|
|
51
|
-
multiple: sourceMultiple,
|
|
52
|
-
required: _required(r.sourceOpts.multiplicity),
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
target.properties.push({
|
|
56
|
-
name: r.targetOpts.label,
|
|
57
|
-
class: source.name,
|
|
58
|
-
owner: targetOwner,
|
|
59
|
-
bidirectional: r.sourceOpts.label,
|
|
60
|
-
multiple: targetMultiple,
|
|
61
|
-
required: _required(r.targetOpts.multiplicity),
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function _multiple(multiplicity) {
|
|
67
|
-
return ["1..1", "0..1"].find((a) => a == multiplicity) == null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function _required(multiplicity) {
|
|
71
|
-
return ["1..1", "1..*"].find((a) => a == multiplicity) != null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function getPropertyParams(symbols) {
|
|
75
|
-
if (!symbols.length) return null;
|
|
76
|
-
|
|
77
|
-
const ret = {};
|
|
78
|
-
if (symbols.includes("identifier")) {
|
|
79
|
-
ret.pk = true;
|
|
80
|
-
}
|
|
81
|
-
if (symbols.includes("required")) {
|
|
82
|
-
ret.required = true;
|
|
83
|
-
}
|
|
84
|
-
if (symbols.includes("unique")) {
|
|
85
|
-
ret.unique = true;
|
|
86
|
-
}
|
|
87
|
-
if (symbols.includes("display_string")) {
|
|
88
|
-
ret.displayString = true;
|
|
89
|
-
}
|
|
90
|
-
return ret;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export { transformation, getPropertyParams };
|
|
1
|
+
import features from "./features.js";
|
|
2
|
+
|
|
3
|
+
function transformation(spec) {
|
|
4
|
+
_relationships(spec);
|
|
5
|
+
const newSpec = {
|
|
6
|
+
features: features,
|
|
7
|
+
basicData: {
|
|
8
|
+
name: spec.name,
|
|
9
|
+
},
|
|
10
|
+
data: {
|
|
11
|
+
dataModel: {
|
|
12
|
+
entities: spec.entities,
|
|
13
|
+
enums: [],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
mapViewer: {
|
|
17
|
+
maps: spec.maps,
|
|
18
|
+
layers: spec.layers,
|
|
19
|
+
styles: spec.styles,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
if (spec.extra) {
|
|
24
|
+
newSpec.basicData.extra = spec.extra;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return newSpec;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function _relationships(spec) {
|
|
31
|
+
let source, target;
|
|
32
|
+
|
|
33
|
+
spec.relationships.forEach((r) => {
|
|
34
|
+
source = spec.getEntity(r.source);
|
|
35
|
+
target = spec.getEntity(r.target);
|
|
36
|
+
let sourceOwner = false;
|
|
37
|
+
let targetOwner = false;
|
|
38
|
+
let sourceMultiple = _multiple(r.sourceOpts.multiplicity);
|
|
39
|
+
let targetMultiple = _multiple(r.targetOpts.multiplicity);
|
|
40
|
+
if (sourceMultiple && !targetMultiple) {
|
|
41
|
+
targetOwner = true;
|
|
42
|
+
} else {
|
|
43
|
+
sourceOwner = true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
source.properties.push({
|
|
47
|
+
name: r.sourceOpts.label,
|
|
48
|
+
class: target.name,
|
|
49
|
+
owner: sourceOwner,
|
|
50
|
+
bidirectional: r.targetOpts.label,
|
|
51
|
+
multiple: sourceMultiple,
|
|
52
|
+
required: _required(r.sourceOpts.multiplicity),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
target.properties.push({
|
|
56
|
+
name: r.targetOpts.label,
|
|
57
|
+
class: source.name,
|
|
58
|
+
owner: targetOwner,
|
|
59
|
+
bidirectional: r.sourceOpts.label,
|
|
60
|
+
multiple: targetMultiple,
|
|
61
|
+
required: _required(r.targetOpts.multiplicity),
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function _multiple(multiplicity) {
|
|
67
|
+
return ["1..1", "0..1"].find((a) => a == multiplicity) == null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function _required(multiplicity) {
|
|
71
|
+
return ["1..1", "1..*"].find((a) => a == multiplicity) != null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getPropertyParams(symbols) {
|
|
75
|
+
if (!symbols.length) return null;
|
|
76
|
+
|
|
77
|
+
const ret = {};
|
|
78
|
+
if (symbols.includes("identifier")) {
|
|
79
|
+
ret.pk = true;
|
|
80
|
+
}
|
|
81
|
+
if (symbols.includes("required")) {
|
|
82
|
+
ret.required = true;
|
|
83
|
+
}
|
|
84
|
+
if (symbols.includes("unique")) {
|
|
85
|
+
ret.unique = true;
|
|
86
|
+
}
|
|
87
|
+
if (symbols.includes("display_string")) {
|
|
88
|
+
ret.displayString = true;
|
|
89
|
+
}
|
|
90
|
+
return ret;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { transformation, getPropertyParams };
|
package/src/cli.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import meow from "meow";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
import gisdslParser from "./index.js";
|
|
6
|
-
import path from "path";
|
|
7
|
-
|
|
8
|
-
const usage = "Usage: gisdsl input output";
|
|
9
|
-
|
|
10
|
-
const cli = meow(usage, {
|
|
11
|
-
importMeta: import.meta,
|
|
12
|
-
flags: {
|
|
13
|
-
debug: {
|
|
14
|
-
type: "boolean",
|
|
15
|
-
default: false,
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
if (cli.input.length < 2) {
|
|
21
|
-
cli.showHelp();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const inputPath = path.resolve(process.cwd(), cli.input.at(0));
|
|
25
|
-
const input = fs.readFileSync(inputPath, {
|
|
26
|
-
encoding: "utf-8",
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const spec = gisdslParser(input, cli.flags.debug);
|
|
30
|
-
|
|
31
|
-
const outputPath = path.resolve(process.cwd(), cli.input.at(1));
|
|
32
|
-
fs.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf8");
|
|
33
|
-
|
|
34
|
-
console.log(`File ${cli.input.at(1)} generated`);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import meow from "meow";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import gisdslParser from "./index.js";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
const usage = "Usage: gisdsl input output";
|
|
9
|
+
|
|
10
|
+
const cli = meow(usage, {
|
|
11
|
+
importMeta: import.meta,
|
|
12
|
+
flags: {
|
|
13
|
+
debug: {
|
|
14
|
+
type: "boolean",
|
|
15
|
+
default: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (cli.input.length < 2) {
|
|
21
|
+
cli.showHelp();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const inputPath = path.resolve(process.cwd(), cli.input.at(0));
|
|
25
|
+
const input = fs.readFileSync(inputPath, {
|
|
26
|
+
encoding: "utf-8",
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const spec = gisdslParser(input, cli.flags.debug);
|
|
30
|
+
|
|
31
|
+
const outputPath = path.resolve(process.cwd(), cli.input.at(1));
|
|
32
|
+
fs.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf8");
|
|
33
|
+
|
|
34
|
+
console.log(`File ${cli.input.at(1)} generated`);
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import antlr4 from "antlr4";
|
|
2
|
-
|
|
3
|
-
import SyntaxGenericError from "./SyntaxGenericError.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Custom Error Listener
|
|
7
|
-
*
|
|
8
|
-
* @returns {object}
|
|
9
|
-
*/
|
|
10
|
-
class ErrorListener extends antlr4.error.ErrorListener {
|
|
11
|
-
/**
|
|
12
|
-
* Checks syntax error
|
|
13
|
-
*
|
|
14
|
-
* @param {object} recognizer The parsing support code essentially. Most of it is error recovery stuff
|
|
15
|
-
* @param {object} symbol Offending symbol
|
|
16
|
-
* @param {int} line Line of offending symbol
|
|
17
|
-
* @param {int} column Position in line of offending symbol
|
|
18
|
-
* @param {string} message Error message
|
|
19
|
-
* @param {string} payload Stack trace
|
|
20
|
-
*/
|
|
21
|
-
syntaxError(recognizer, symbol, line, column, message) {
|
|
22
|
-
throw new SyntaxGenericError({ line, column, message });
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export default ErrorListener;
|
|
1
|
+
import antlr4 from "antlr4";
|
|
2
|
+
|
|
3
|
+
import SyntaxGenericError from "./SyntaxGenericError.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Custom Error Listener
|
|
7
|
+
*
|
|
8
|
+
* @returns {object}
|
|
9
|
+
*/
|
|
10
|
+
class ErrorListener extends antlr4.error.ErrorListener {
|
|
11
|
+
/**
|
|
12
|
+
* Checks syntax error
|
|
13
|
+
*
|
|
14
|
+
* @param {object} recognizer The parsing support code essentially. Most of it is error recovery stuff
|
|
15
|
+
* @param {object} symbol Offending symbol
|
|
16
|
+
* @param {int} line Line of offending symbol
|
|
17
|
+
* @param {int} column Position in line of offending symbol
|
|
18
|
+
* @param {string} message Error message
|
|
19
|
+
* @param {string} payload Stack trace
|
|
20
|
+
*/
|
|
21
|
+
syntaxError(recognizer, symbol, line, column, message) {
|
|
22
|
+
throw new SyntaxGenericError({ line, column, message });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default ErrorListener;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
export default class SyntaxGenericError extends Error {
|
|
2
|
-
constructor(payload) {
|
|
3
|
-
super(payload);
|
|
4
|
-
|
|
5
|
-
this.code = "E_SYNTAX_GENERIC";
|
|
6
|
-
this.message = "Something went wrong";
|
|
7
|
-
|
|
8
|
-
if (typeof payload !== "undefined") {
|
|
9
|
-
this.message = payload.message || this.message;
|
|
10
|
-
this.payload = payload;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
console.error(
|
|
14
|
-
`line ${this.payload.line}, col ${this.payload.column}: ${this.payload.message}`,
|
|
15
|
-
);
|
|
16
|
-
Error.captureStackTrace(this, SyntaxGenericError);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
1
|
+
export default class SyntaxGenericError extends Error {
|
|
2
|
+
constructor(payload) {
|
|
3
|
+
super(payload);
|
|
4
|
+
|
|
5
|
+
this.code = "E_SYNTAX_GENERIC";
|
|
6
|
+
this.message = "Something went wrong";
|
|
7
|
+
|
|
8
|
+
if (typeof payload !== "undefined") {
|
|
9
|
+
this.message = payload.message || this.message;
|
|
10
|
+
this.payload = payload;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
console.error(
|
|
14
|
+
`line ${this.payload.line}, col ${this.payload.column}: ${this.payload.message}`,
|
|
15
|
+
);
|
|
16
|
+
Error.captureStackTrace(this, SyntaxGenericError);
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/features.js
CHANGED
package/src/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import antlr4 from "antlr4";
|
|
2
|
-
import GISGrammarLexer from "./lib/GISGrammarLexer.js";
|
|
3
|
-
import GISGrammarParser from "./lib/GISGrammarParser.js";
|
|
4
|
-
import ErrorListener from "./error/ErrorListener.js";
|
|
5
|
-
import GISVisitor from "./GISVisitor.js";
|
|
6
|
-
import store from "./store.js";
|
|
7
|
-
|
|
8
|
-
export default function parse(inputStr, debug = false) {
|
|
9
|
-
const chars = new antlr4.InputStream(inputStr);
|
|
10
|
-
const lexer = new GISGrammarLexer(chars);
|
|
11
|
-
lexer.strictMode = false; // do not use js strictMode
|
|
12
|
-
|
|
13
|
-
const tokens = new antlr4.CommonTokenStream(lexer);
|
|
14
|
-
const parser = new GISGrammarParser(tokens);
|
|
15
|
-
|
|
16
|
-
const errorListener = new ErrorListener();
|
|
17
|
-
// Do this after creating the parser and before running it
|
|
18
|
-
parser.removeErrorListeners(); // Remove default ConsoleErrorListener
|
|
19
|
-
parser.addErrorListener(errorListener); // Add custom error listener
|
|
20
|
-
|
|
21
|
-
const visitor = new GISVisitor(store, debug);
|
|
22
|
-
const tree = parser.parse();
|
|
23
|
-
visitor.start(tree);
|
|
24
|
-
|
|
25
|
-
return store.getLastGeneratedProduct();
|
|
26
|
-
}
|
|
1
|
+
import antlr4 from "antlr4";
|
|
2
|
+
import GISGrammarLexer from "./lib/GISGrammarLexer.js";
|
|
3
|
+
import GISGrammarParser from "./lib/GISGrammarParser.js";
|
|
4
|
+
import ErrorListener from "./error/ErrorListener.js";
|
|
5
|
+
import GISVisitor from "./GISVisitor.js";
|
|
6
|
+
import store from "./store.js";
|
|
7
|
+
|
|
8
|
+
export default function parse(inputStr, debug = false) {
|
|
9
|
+
const chars = new antlr4.InputStream(inputStr);
|
|
10
|
+
const lexer = new GISGrammarLexer(chars);
|
|
11
|
+
lexer.strictMode = false; // do not use js strictMode
|
|
12
|
+
|
|
13
|
+
const tokens = new antlr4.CommonTokenStream(lexer);
|
|
14
|
+
const parser = new GISGrammarParser(tokens);
|
|
15
|
+
|
|
16
|
+
const errorListener = new ErrorListener();
|
|
17
|
+
// Do this after creating the parser and before running it
|
|
18
|
+
parser.removeErrorListeners(); // Remove default ConsoleErrorListener
|
|
19
|
+
parser.addErrorListener(errorListener); // Add custom error listener
|
|
20
|
+
|
|
21
|
+
const visitor = new GISVisitor(store, debug);
|
|
22
|
+
const tree = parser.parse();
|
|
23
|
+
visitor.start(tree);
|
|
24
|
+
|
|
25
|
+
return store.getLastGeneratedProduct();
|
|
26
|
+
}
|