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