clarity-pattern-parser 8.4.9 → 8.4.11
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/TODO.md +12 -2
- package/dist/grammar/Grammar.d.ts +8 -8
- package/dist/grammar/patterns/body.d.ts +2 -0
- package/dist/grammar/patterns/grammar.d.ts +2 -2
- package/dist/grammar/patterns/import.d.ts +2 -2
- package/dist/grammar/patterns/spaces.d.ts +5 -0
- package/dist/grammar/patterns/statement.d.ts +2 -2
- package/dist/index.browser.js +172 -52
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +172 -52
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +172 -52
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/grammar/Grammar.test.ts +96 -7
- package/src/grammar/Grammar.ts +113 -36
- package/src/grammar/patterns/body.ts +19 -0
- package/src/grammar/patterns/grammar.ts +26 -9
- package/src/grammar/patterns/import.ts +49 -8
- package/src/grammar/patterns/spaces.ts +12 -2
- package/src/grammar/patterns/statement.ts +5 -8
- package/src/grammar/spec.md +24 -0
package/dist/index.js
CHANGED
|
@@ -1688,6 +1688,17 @@ class And {
|
|
|
1688
1688
|
}
|
|
1689
1689
|
}
|
|
1690
1690
|
|
|
1691
|
+
const literal = new Regex("literal", "\"(?:\\\\[\"\\\\]|[^\n\"\\\\])*\"");
|
|
1692
|
+
|
|
1693
|
+
const tabs$1 = new Regex("tabs", "\\t+");
|
|
1694
|
+
const spaces$1 = new Regex("spaces", "[ ]+");
|
|
1695
|
+
const newLine$1 = new Regex("new-line", "(\\r?\\n)+");
|
|
1696
|
+
spaces$1.setTokens([" "]);
|
|
1697
|
+
tabs$1.setTokens(["\t"]);
|
|
1698
|
+
newLine$1.setTokens(["\n"]);
|
|
1699
|
+
const lineSpaces$1 = new Repeat("line-spaces", new Or("line-space", [tabs$1, spaces$1]));
|
|
1700
|
+
const allSpaces = new Regex("all-spaces", "\\s+", true);
|
|
1701
|
+
|
|
1691
1702
|
const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
|
|
1692
1703
|
|
|
1693
1704
|
const optionalNot = new Literal("not", "!", true);
|
|
@@ -1709,9 +1720,6 @@ const orLiteral = new Repeat("or-literal", name$1.clone("pattern-name"), { divid
|
|
|
1709
1720
|
|
|
1710
1721
|
const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
|
|
1711
1722
|
|
|
1712
|
-
const spaces$1 = new Regex("spaces", "[ \\t]+");
|
|
1713
|
-
spaces$1.setTokens([" "]);
|
|
1714
|
-
|
|
1715
1723
|
const patternName = name$1.clone("pattern-name");
|
|
1716
1724
|
const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
|
|
1717
1725
|
const dividerPattern = name$1.clone("divider-pattern");
|
|
@@ -1764,11 +1772,8 @@ const repeatLiteral = new And("repeat-literal", [
|
|
|
1764
1772
|
new And("optional-trim-divider-section", [spaces$1, trimDivider], true)
|
|
1765
1773
|
]);
|
|
1766
1774
|
|
|
1767
|
-
const literal = new Regex("literal", "\"(?:\\\\[\"\\\\]|[^\n\"\\\\])*\"");
|
|
1768
|
-
|
|
1769
1775
|
const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
|
|
1770
1776
|
const assignOperator = new Literal("assign-operator", "=");
|
|
1771
|
-
const optionalComment = comment.clone("inline-comment", true);
|
|
1772
1777
|
const statements = new Or("statements", [
|
|
1773
1778
|
literal,
|
|
1774
1779
|
regexLiteral,
|
|
@@ -1777,53 +1782,106 @@ const statements = new Or("statements", [
|
|
|
1777
1782
|
repeatLiteral,
|
|
1778
1783
|
name$1.clone("alias-literal"),
|
|
1779
1784
|
]);
|
|
1780
|
-
const
|
|
1785
|
+
const assignStatement = new And("assign-statement", [
|
|
1781
1786
|
optionalSpaces$1,
|
|
1782
1787
|
name$1,
|
|
1783
1788
|
optionalSpaces$1,
|
|
1784
1789
|
assignOperator,
|
|
1785
1790
|
optionalSpaces$1,
|
|
1786
|
-
statements
|
|
1787
|
-
optionalSpaces$1,
|
|
1788
|
-
optionalComment,
|
|
1789
|
-
optionalSpaces$1,
|
|
1791
|
+
statements
|
|
1790
1792
|
]);
|
|
1793
|
+
const statement = new Or("statement", [assignStatement, name$1.clone("export-name")]);
|
|
1791
1794
|
|
|
1792
|
-
const
|
|
1795
|
+
const bodyLineContent = new Or("body-line-content", [
|
|
1796
|
+
comment,
|
|
1797
|
+
statement
|
|
1798
|
+
]);
|
|
1799
|
+
const bodyLine = new And("body-line", [
|
|
1800
|
+
lineSpaces$1.clone("line-spaces", true),
|
|
1801
|
+
bodyLineContent,
|
|
1802
|
+
lineSpaces$1.clone("line-spaces", true),
|
|
1803
|
+
]);
|
|
1804
|
+
const body = new Repeat("body", bodyLine, { divider: newLine$1, min: 0 });
|
|
1805
|
+
|
|
1806
|
+
const optionalSpaces = allSpaces.clone("optional-spaces", true);
|
|
1807
|
+
const optionalLineSpaces = lineSpaces$1.clone("options-line-spaces", true);
|
|
1793
1808
|
const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
|
|
1794
1809
|
const importKeyword = new Literal("import", "import");
|
|
1810
|
+
const useParamsKeyword = new Literal("use-params", "use params");
|
|
1811
|
+
const asKeyword = new Literal("as", "as");
|
|
1795
1812
|
const fromKeyword = new Literal("from", "from");
|
|
1796
1813
|
const openBracket = new Literal("open-bracket", "{");
|
|
1797
1814
|
const closeBracket = new Literal("close-bracket", "}");
|
|
1798
1815
|
const name = new Regex("import-name", "[^}\\s,]+");
|
|
1799
|
-
const
|
|
1800
|
-
const
|
|
1801
|
-
const
|
|
1802
|
-
|
|
1816
|
+
const importNameAlias = name.clone("import-name-alias");
|
|
1817
|
+
const importAlias = new And("import-alias", [name, lineSpaces$1, asKeyword, lineSpaces$1, importNameAlias]);
|
|
1818
|
+
const importedNames = new Repeat("imported-names", new Or("import-names", [importAlias, name]), { divider: importNameDivider });
|
|
1819
|
+
const paramName = name.clone("param-name");
|
|
1820
|
+
const paramNames = new Repeat("param-names", paramName, { divider: importNameDivider });
|
|
1821
|
+
const resource = literal.clone("resource");
|
|
1822
|
+
const useParams = new And("import-params", [
|
|
1823
|
+
useParamsKeyword,
|
|
1824
|
+
optionalLineSpaces,
|
|
1825
|
+
openBracket,
|
|
1826
|
+
optionalSpaces,
|
|
1827
|
+
paramNames,
|
|
1803
1828
|
optionalSpaces,
|
|
1829
|
+
closeBracket
|
|
1830
|
+
]);
|
|
1831
|
+
const withParamsKeyword = new Literal("with-params", "with params");
|
|
1832
|
+
const withParamsStatement = new And("with-params-statement", [
|
|
1833
|
+
withParamsKeyword,
|
|
1834
|
+
optionalLineSpaces,
|
|
1835
|
+
openBracket,
|
|
1836
|
+
optionalSpaces,
|
|
1837
|
+
body.clone("with-params-body"),
|
|
1838
|
+
optionalSpaces,
|
|
1839
|
+
closeBracket
|
|
1840
|
+
], true);
|
|
1841
|
+
const importFromStatement = new And("import-from", [
|
|
1842
|
+
importKeyword,
|
|
1843
|
+
optionalLineSpaces,
|
|
1804
1844
|
openBracket,
|
|
1805
1845
|
optionalSpaces,
|
|
1806
1846
|
importedNames,
|
|
1807
1847
|
optionalSpaces,
|
|
1808
1848
|
closeBracket,
|
|
1809
|
-
|
|
1849
|
+
optionalLineSpaces,
|
|
1810
1850
|
fromKeyword,
|
|
1811
|
-
|
|
1812
|
-
|
|
1851
|
+
optionalLineSpaces,
|
|
1852
|
+
resource,
|
|
1853
|
+
optionalLineSpaces,
|
|
1854
|
+
withParamsStatement
|
|
1855
|
+
]);
|
|
1856
|
+
const importStatement = new Or("import-statement", [
|
|
1857
|
+
useParams,
|
|
1858
|
+
importFromStatement
|
|
1813
1859
|
]);
|
|
1814
1860
|
|
|
1815
|
-
const
|
|
1861
|
+
const tabs = new Regex("tabs", "\\t+");
|
|
1862
|
+
const spaces = new Regex("spaces", "[ ]+");
|
|
1816
1863
|
const newLine = new Regex("new-line", "(\\r?\\n)+");
|
|
1817
|
-
|
|
1864
|
+
spaces.setTokens([" "]);
|
|
1865
|
+
tabs.setTokens(["\t"]);
|
|
1818
1866
|
newLine.setTokens(["\n"]);
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1821
|
-
whitespace,
|
|
1867
|
+
const lineSpaces = new Repeat("line-spaces", new Or("line-space", [tabs, spaces]));
|
|
1868
|
+
const headLineContent = new Or("head-line-content", [
|
|
1822
1869
|
comment,
|
|
1823
|
-
importStatement
|
|
1824
|
-
|
|
1870
|
+
importStatement
|
|
1871
|
+
]);
|
|
1872
|
+
const headLine = new And("head-line-content", [
|
|
1873
|
+
lineSpaces.clone("line-spaces", true),
|
|
1874
|
+
headLineContent,
|
|
1875
|
+
lineSpaces.clone("line-spaces", true),
|
|
1876
|
+
]);
|
|
1877
|
+
const head = new Repeat("head", headLine, { divider: newLine, min: 0 });
|
|
1878
|
+
const grammar = new And("grammar", [
|
|
1879
|
+
allSpaces,
|
|
1880
|
+
head,
|
|
1881
|
+
allSpaces,
|
|
1882
|
+
body,
|
|
1883
|
+
allSpaces
|
|
1825
1884
|
]);
|
|
1826
|
-
const grammar = new Repeat("grammer", line);
|
|
1827
1885
|
|
|
1828
1886
|
class Not {
|
|
1829
1887
|
get type() {
|
|
@@ -2126,9 +2184,11 @@ function getFurthestOptions(options) {
|
|
|
2126
2184
|
}
|
|
2127
2185
|
|
|
2128
2186
|
class ParseContext {
|
|
2129
|
-
constructor() {
|
|
2187
|
+
constructor(params) {
|
|
2130
2188
|
this.patternsByName = new Map();
|
|
2131
2189
|
this.importedPatternsByName = new Map();
|
|
2190
|
+
this.paramsByName = new Map();
|
|
2191
|
+
params.forEach(p => this.paramsByName.set(p.name, p));
|
|
2132
2192
|
}
|
|
2133
2193
|
}
|
|
2134
2194
|
function defaultImportResolver(_path, _basePath) {
|
|
@@ -2136,9 +2196,10 @@ function defaultImportResolver(_path, _basePath) {
|
|
|
2136
2196
|
}
|
|
2137
2197
|
class Grammar {
|
|
2138
2198
|
constructor(options = {}) {
|
|
2139
|
-
this.
|
|
2199
|
+
this._params = (options === null || options === void 0 ? void 0 : options.params) == null ? [] : options.params;
|
|
2200
|
+
this._originResource = (options === null || options === void 0 ? void 0 : options.originResource) == null ? null : options.originResource;
|
|
2140
2201
|
this._resolveImport = options.resolveImport == null ? defaultImportResolver : options.resolveImport;
|
|
2141
|
-
this._parseContext = new ParseContext();
|
|
2202
|
+
this._parseContext = new ParseContext(this._params);
|
|
2142
2203
|
this._autoComplete = new AutoComplete(grammar, {
|
|
2143
2204
|
greedyPatternNames: ["spaces", "optional-spaces", "whitespace", "new-line"],
|
|
2144
2205
|
customTokens: {
|
|
@@ -2152,13 +2213,17 @@ class Grammar {
|
|
|
2152
2213
|
import(path) {
|
|
2153
2214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2154
2215
|
const grammarFile = yield this._resolveImport(path, null);
|
|
2155
|
-
const grammar = new Grammar({
|
|
2216
|
+
const grammar = new Grammar({
|
|
2217
|
+
resolveImport: this._resolveImport,
|
|
2218
|
+
originResource: grammarFile.resource,
|
|
2219
|
+
params: this._params
|
|
2220
|
+
});
|
|
2156
2221
|
return grammar.parse(grammarFile.expression);
|
|
2157
2222
|
});
|
|
2158
2223
|
}
|
|
2159
2224
|
parse(expression) {
|
|
2160
2225
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2161
|
-
this._parseContext = new ParseContext();
|
|
2226
|
+
this._parseContext = new ParseContext(this._params);
|
|
2162
2227
|
const ast = this._tryToParse(expression);
|
|
2163
2228
|
yield this._resolveImports(ast);
|
|
2164
2229
|
this._buildPatterns(ast);
|
|
@@ -2166,7 +2231,7 @@ class Grammar {
|
|
|
2166
2231
|
});
|
|
2167
2232
|
}
|
|
2168
2233
|
parseString(expression) {
|
|
2169
|
-
this._parseContext = new ParseContext();
|
|
2234
|
+
this._parseContext = new ParseContext(this._params);
|
|
2170
2235
|
const ast = this._tryToParse(expression);
|
|
2171
2236
|
if (this._hasImports(ast)) {
|
|
2172
2237
|
throw new Error("Cannot use imports on parseString, use parse instead.");
|
|
@@ -2198,9 +2263,13 @@ class Grammar {
|
|
|
2198
2263
|
return importBlock && importBlock.children.length > 0;
|
|
2199
2264
|
}
|
|
2200
2265
|
_buildPatterns(ast) {
|
|
2201
|
-
ast.
|
|
2266
|
+
const body = ast.find(n => n.name === "body");
|
|
2267
|
+
if (body == null) {
|
|
2268
|
+
return;
|
|
2269
|
+
}
|
|
2270
|
+
body.findAll(n => n.name === "assign-statement" || n.name === "export-name").forEach((n) => {
|
|
2202
2271
|
const typeNode = n.find(n => n.name.includes("literal"));
|
|
2203
|
-
const type = (typeNode === null || typeNode === void 0 ? void 0 : typeNode.name) || "unknown";
|
|
2272
|
+
const type = n.name === "export-name" ? "export-name" : (typeNode === null || typeNode === void 0 ? void 0 : typeNode.name) || "unknown";
|
|
2204
2273
|
switch (type) {
|
|
2205
2274
|
case "literal": {
|
|
2206
2275
|
this._buildLiteral(n);
|
|
@@ -2226,39 +2295,87 @@ class Grammar {
|
|
|
2226
2295
|
this._buildAlias(n);
|
|
2227
2296
|
break;
|
|
2228
2297
|
}
|
|
2298
|
+
case "export-name": {
|
|
2299
|
+
const pattern = this._getPattern(n.value);
|
|
2300
|
+
this._parseContext.patternsByName.set(n.value, pattern);
|
|
2301
|
+
break;
|
|
2302
|
+
}
|
|
2229
2303
|
}
|
|
2230
2304
|
});
|
|
2231
2305
|
}
|
|
2232
2306
|
_resolveImports(ast) {
|
|
2233
|
-
var _a;
|
|
2234
2307
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2235
2308
|
const parseContext = this._parseContext;
|
|
2236
|
-
const importStatements = ast.findAll(n => n.name === "import-
|
|
2309
|
+
const importStatements = ast.findAll(n => n.name === "import-from");
|
|
2237
2310
|
for (const importStatement of importStatements) {
|
|
2238
|
-
const
|
|
2239
|
-
const
|
|
2240
|
-
const
|
|
2241
|
-
const
|
|
2311
|
+
const resourceNode = importStatement.find(n => n.name === "resource");
|
|
2312
|
+
const params = this._getParams(importStatement);
|
|
2313
|
+
const resource = resourceNode.value.slice(1, -1);
|
|
2314
|
+
const grammarFile = yield this._resolveImport(resource, this._originResource || null);
|
|
2315
|
+
const grammar = new Grammar({
|
|
2316
|
+
resolveImport: this._resolveImport,
|
|
2317
|
+
originResource: grammarFile.resource,
|
|
2318
|
+
params
|
|
2319
|
+
});
|
|
2242
2320
|
try {
|
|
2243
2321
|
const patterns = yield grammar.parse(grammarFile.expression);
|
|
2244
|
-
const
|
|
2245
|
-
|
|
2246
|
-
if (
|
|
2247
|
-
|
|
2322
|
+
const importStatements = importStatement.findAll(n => n.name === "import-name" || n.name === "import-alias");
|
|
2323
|
+
importStatements.forEach((node) => {
|
|
2324
|
+
if (node.name === "import-name") {
|
|
2325
|
+
const importName = node.value;
|
|
2326
|
+
if (parseContext.importedPatternsByName.has(importName)) {
|
|
2327
|
+
throw new Error(`'${importName}' was already used within another import.`);
|
|
2328
|
+
}
|
|
2329
|
+
const pattern = patterns.get(importName);
|
|
2330
|
+
if (pattern == null) {
|
|
2331
|
+
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${resource}.`);
|
|
2332
|
+
}
|
|
2333
|
+
parseContext.importedPatternsByName.set(importName, pattern);
|
|
2248
2334
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2335
|
+
else {
|
|
2336
|
+
const importNameNode = node.find(n => n.name === "import-name");
|
|
2337
|
+
const importName = importNameNode.value;
|
|
2338
|
+
const aliasNode = node.find(n => n.name === "import-name-alias");
|
|
2339
|
+
const alias = aliasNode.value;
|
|
2340
|
+
if (parseContext.importedPatternsByName.has(alias)) {
|
|
2341
|
+
throw new Error(`'${alias}' was already used within another import.`);
|
|
2342
|
+
}
|
|
2343
|
+
const pattern = patterns.get(importName);
|
|
2344
|
+
if (pattern == null) {
|
|
2345
|
+
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${resource}.`);
|
|
2346
|
+
}
|
|
2347
|
+
parseContext.importedPatternsByName.set(alias, pattern);
|
|
2252
2348
|
}
|
|
2253
|
-
parseContext.importedPatternsByName.set(importName, pattern);
|
|
2254
2349
|
});
|
|
2255
2350
|
}
|
|
2256
2351
|
catch (e) {
|
|
2257
|
-
throw new Error(`Failed loading expression from: "${
|
|
2352
|
+
throw new Error(`Failed loading expression from: "${resource}". Error details: "${e.message}"`);
|
|
2258
2353
|
}
|
|
2259
2354
|
}
|
|
2260
2355
|
});
|
|
2261
2356
|
}
|
|
2357
|
+
_getParams(importStatement) {
|
|
2358
|
+
let params = [];
|
|
2359
|
+
const paramsStatement = importStatement.find(n => n.name === "with-params-statement");
|
|
2360
|
+
if (paramsStatement != null) {
|
|
2361
|
+
const statements = paramsStatement.find(n => n.name === "with-params-body");
|
|
2362
|
+
if (statements != null) {
|
|
2363
|
+
const expression = statements.toString();
|
|
2364
|
+
const importedValues = Array.from(this
|
|
2365
|
+
._parseContext
|
|
2366
|
+
.importedPatternsByName
|
|
2367
|
+
.values());
|
|
2368
|
+
const grammar = new Grammar({
|
|
2369
|
+
params: importedValues,
|
|
2370
|
+
originResource: this._originResource,
|
|
2371
|
+
resolveImport: this._resolveImport
|
|
2372
|
+
});
|
|
2373
|
+
const patterns = grammar.parseString(expression);
|
|
2374
|
+
params = Array.from(patterns.values());
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
return params;
|
|
2378
|
+
}
|
|
2262
2379
|
_buildLiteral(statementNode) {
|
|
2263
2380
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2264
2381
|
const literalNode = statementNode.find(n => n.name === "literal");
|
|
@@ -2289,6 +2406,9 @@ class Grammar {
|
|
|
2289
2406
|
if (pattern == null) {
|
|
2290
2407
|
pattern = this._parseContext.importedPatternsByName.get(name);
|
|
2291
2408
|
}
|
|
2409
|
+
if (pattern == null) {
|
|
2410
|
+
pattern = this._parseContext.paramsByName.get(name);
|
|
2411
|
+
}
|
|
2292
2412
|
if (pattern == null) {
|
|
2293
2413
|
return new Reference(name);
|
|
2294
2414
|
}
|
|
@@ -2380,8 +2500,8 @@ class Grammar {
|
|
|
2380
2500
|
const grammar = new Grammar(options);
|
|
2381
2501
|
return grammar.import(path);
|
|
2382
2502
|
}
|
|
2383
|
-
static parseString(expression) {
|
|
2384
|
-
const grammar = new Grammar();
|
|
2503
|
+
static parseString(expression, options) {
|
|
2504
|
+
const grammar = new Grammar(options);
|
|
2385
2505
|
return grammar.parseString(expression);
|
|
2386
2506
|
}
|
|
2387
2507
|
}
|