clarity-pattern-parser 8.4.8 → 8.4.10

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.
@@ -1,17 +1,16 @@
1
1
  import { Pattern } from "../patterns/Pattern";
2
- export interface GrammarMeta {
3
- originPath?: string;
4
- }
5
2
  export interface GrammarFile {
6
- path: string;
3
+ resource: string;
7
4
  expression: string;
8
5
  }
9
6
  export interface GrammarOptions {
10
- resolveImport?: (path: string, originPath: string | null) => Promise<GrammarFile>;
11
- meta?: GrammarMeta | null;
7
+ resolveImport?: (resource: string, originResource: string | null) => Promise<GrammarFile>;
8
+ originResource?: string | null;
9
+ params?: Pattern[];
12
10
  }
13
11
  export declare class Grammar {
14
- private _meta;
12
+ private _params;
13
+ private _originResource?;
15
14
  private _resolveImport;
16
15
  private _parseContext;
17
16
  private _autoComplete;
@@ -23,6 +22,7 @@ export declare class Grammar {
23
22
  private _hasImports;
24
23
  private _buildPatterns;
25
24
  private _resolveImports;
25
+ private _getParams;
26
26
  private _buildLiteral;
27
27
  private _buildRegex;
28
28
  private _buildOr;
@@ -32,5 +32,5 @@ export declare class Grammar {
32
32
  private _buildAlias;
33
33
  static parse(expression: string, options?: GrammarOptions): Promise<Map<string, Pattern>>;
34
34
  static import(path: string, options?: GrammarOptions): Promise<Map<string, Pattern>>;
35
- static parseString(expression: string): Map<string, Pattern>;
35
+ static parseString(expression: string, options?: GrammarOptions): Map<string, Pattern>;
36
36
  }
@@ -0,0 +1,2 @@
1
+ import { Repeat } from "../../patterns/Repeat";
2
+ export declare const body: Repeat;
@@ -1,2 +1,2 @@
1
- import { Repeat } from "../../patterns/Repeat";
2
- export declare const grammar: Repeat;
1
+ import { And } from "../../patterns/And";
2
+ export declare const grammar: And;
@@ -1,2 +1,2 @@
1
- import { And } from "../../patterns/And";
2
- export declare const importStatement: And;
1
+ import { Or } from "../../patterns/Or";
2
+ export declare const importStatement: Or;
@@ -1,2 +1,7 @@
1
1
  import { Regex } from "../../patterns/Regex";
2
+ import { Repeat } from "../../patterns/Repeat";
3
+ export declare const tabs: Regex;
2
4
  export declare const spaces: Regex;
5
+ export declare const newLine: Regex;
6
+ export declare const lineSpaces: Repeat;
7
+ export declare const allSpaces: Regex;
@@ -1690,6 +1690,17 @@
1690
1690
  }
1691
1691
  }
1692
1692
 
1693
+ const literal = new Regex("literal", "\"(?:\\\\[\"\\\\]|[^\n\"\\\\])*\"");
1694
+
1695
+ const tabs$1 = new Regex("tabs", "\\t+");
1696
+ const spaces$1 = new Regex("spaces", "[ ]+");
1697
+ const newLine$1 = new Regex("new-line", "(\\r?\\n)+");
1698
+ spaces$1.setTokens([" "]);
1699
+ tabs$1.setTokens(["\t"]);
1700
+ newLine$1.setTokens(["\n"]);
1701
+ const lineSpaces$1 = new Repeat("line-spaces", new Or("line-space", [tabs$1, spaces$1]));
1702
+ const allSpaces = new Regex("all-spaces", "\\s+", true);
1703
+
1693
1704
  const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
1694
1705
 
1695
1706
  const optionalNot = new Literal("not", "!", true);
@@ -1703,17 +1714,14 @@
1703
1714
 
1704
1715
  const divider$1 = new Regex("and-divider", "\\s*[&]\\s*");
1705
1716
  divider$1.setTokens([" & "]);
1706
- const andLiteral = new Repeat("and-literal", pattern, { divider: divider$1, min: 2 });
1717
+ const andLiteral = new Repeat("and-literal", pattern, { divider: divider$1, min: 2, trimDivider: true });
1707
1718
 
1708
1719
  const divider = new Regex("or-divider", "\\s*[|]\\s*");
1709
1720
  divider.setTokens([" | "]);
1710
- const orLiteral = new Repeat("or-literal", name$1.clone("pattern-name"), { divider, min: 2 });
1721
+ const orLiteral = new Repeat("or-literal", name$1.clone("pattern-name"), { divider, min: 2, trimDivider: true });
1711
1722
 
1712
1723
  const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
1713
1724
 
1714
- const spaces$1 = new Regex("spaces", "[ \\t]+");
1715
- spaces$1.setTokens([" "]);
1716
-
1717
1725
  const patternName = name$1.clone("pattern-name");
1718
1726
  const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
1719
1727
  const dividerPattern = name$1.clone("divider-pattern");
@@ -1766,11 +1774,8 @@
1766
1774
  new And("optional-trim-divider-section", [spaces$1, trimDivider], true)
1767
1775
  ]);
1768
1776
 
1769
- const literal = new Regex("literal", "\"(?:\\\\[\"\\\\]|[^\n\"\\\\])*\"");
1770
-
1771
1777
  const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
1772
1778
  const assignOperator = new Literal("assign-operator", "=");
1773
- const optionalComment = comment.clone("inline-comment", true);
1774
1779
  const statements = new Or("statements", [
1775
1780
  literal,
1776
1781
  regexLiteral,
@@ -1785,47 +1790,96 @@
1785
1790
  optionalSpaces$1,
1786
1791
  assignOperator,
1787
1792
  optionalSpaces$1,
1788
- statements,
1789
- optionalSpaces$1,
1790
- optionalComment,
1791
- optionalSpaces$1,
1793
+ statements
1792
1794
  ]);
1793
1795
 
1794
- const spaces = new Regex("spaces", "\\s+", true);
1796
+ const bodyLineContent = new Or("body-line-content", [
1797
+ comment,
1798
+ statement
1799
+ ]);
1800
+ const bodyLine = new And("body-line", [
1801
+ lineSpaces$1.clone("line-spaces", true),
1802
+ bodyLineContent,
1803
+ lineSpaces$1.clone("line-spaces", true),
1804
+ ]);
1805
+ const body = new Repeat("body", bodyLine, { divider: newLine$1, min: 0 });
1806
+
1795
1807
  const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
1796
1808
  const importKeyword = new Literal("import", "import");
1809
+ const useParamsKeyword = new Literal("use-params", "use params");
1797
1810
  const fromKeyword = new Literal("from", "from");
1798
1811
  const openBracket = new Literal("open-bracket", "{");
1799
1812
  const closeBracket = new Literal("close-bracket", "}");
1800
1813
  const name = new Regex("import-name", "[^}\\s,]+");
1801
1814
  const importedNames = new Repeat("imported-names", name, { divider: importNameDivider });
1802
- const optionalSpaces = spaces.clone("optional-spaces", true);
1803
- const importStatement = new And("import-statement", [
1804
- importKeyword,
1815
+ const paramName = name.clone("param-name");
1816
+ const paramNames = new Repeat("param-names", paramName, { divider: importNameDivider });
1817
+ const optionalSpaces = allSpaces.clone("optional-spaces", true);
1818
+ const optionalLineSpaces = lineSpaces$1.clone("options-line-spaces", true);
1819
+ const resource = literal.clone("resource");
1820
+ const useParams = new And("import-params", [
1821
+ useParamsKeyword,
1822
+ optionalLineSpaces,
1823
+ openBracket,
1824
+ optionalSpaces,
1825
+ paramNames,
1805
1826
  optionalSpaces,
1827
+ closeBracket
1828
+ ]);
1829
+ const withParamsKeyword = new Literal("with-params", "with params");
1830
+ const withParamsStatement = new And("with-params-statement", [
1831
+ withParamsKeyword,
1832
+ optionalLineSpaces,
1833
+ openBracket,
1834
+ optionalSpaces,
1835
+ body,
1836
+ optionalSpaces,
1837
+ closeBracket
1838
+ ], true);
1839
+ const importFromStatement = new And("import-from", [
1840
+ importKeyword,
1841
+ optionalLineSpaces,
1806
1842
  openBracket,
1807
1843
  optionalSpaces,
1808
1844
  importedNames,
1809
1845
  optionalSpaces,
1810
1846
  closeBracket,
1811
- optionalSpaces,
1847
+ optionalLineSpaces,
1812
1848
  fromKeyword,
1813
- spaces,
1814
- literal.clone("url"),
1849
+ optionalLineSpaces,
1850
+ resource,
1851
+ optionalLineSpaces,
1852
+ withParamsStatement
1853
+ ]);
1854
+ const importStatement = new Or("import-statement", [
1855
+ useParams,
1856
+ importFromStatement
1815
1857
  ]);
1816
1858
 
1817
- const whitespace = new Regex("whitespace", "[ \\t]+((\\r?\\n)+)?");
1859
+ const tabs = new Regex("tabs", "\\t+");
1860
+ const spaces = new Regex("spaces", "[ ]+");
1818
1861
  const newLine = new Regex("new-line", "(\\r?\\n)+");
1819
- whitespace.setTokens([" "]);
1862
+ spaces.setTokens([" "]);
1863
+ tabs.setTokens(["\t"]);
1820
1864
  newLine.setTokens(["\n"]);
1821
- const line = new Or("line", [
1822
- newLine,
1823
- whitespace,
1865
+ const lineSpaces = new Repeat("line-spaces", new Or("line-space", [tabs, spaces]));
1866
+ const headLineContent = new Or("head-line-content", [
1824
1867
  comment,
1825
- importStatement,
1826
- statement
1868
+ importStatement
1869
+ ]);
1870
+ const headLine = new And("head-line-content", [
1871
+ lineSpaces.clone("line-spaces", true),
1872
+ headLineContent,
1873
+ lineSpaces.clone("line-spaces", true),
1874
+ ]);
1875
+ const head = new Repeat("head", headLine, { divider: newLine, min: 0 });
1876
+ const grammar = new And("grammar", [
1877
+ allSpaces,
1878
+ head,
1879
+ allSpaces,
1880
+ body,
1881
+ allSpaces
1827
1882
  ]);
1828
- const grammar = new Repeat("grammer", line);
1829
1883
 
1830
1884
  class Not {
1831
1885
  get type() {
@@ -2128,9 +2182,11 @@
2128
2182
  }
2129
2183
 
2130
2184
  class ParseContext {
2131
- constructor() {
2185
+ constructor(params) {
2132
2186
  this.patternsByName = new Map();
2133
2187
  this.importedPatternsByName = new Map();
2188
+ this.paramsByName = new Map();
2189
+ params.forEach(p => this.paramsByName.set(p.name, p));
2134
2190
  }
2135
2191
  }
2136
2192
  function defaultImportResolver(_path, _basePath) {
@@ -2138,9 +2194,10 @@
2138
2194
  }
2139
2195
  class Grammar {
2140
2196
  constructor(options = {}) {
2141
- this._meta = options.meta == null ? null : options.meta;
2197
+ this._params = (options === null || options === void 0 ? void 0 : options.params) == null ? [] : options.params;
2198
+ this._originResource = (options === null || options === void 0 ? void 0 : options.originResource) == null ? null : options.originResource;
2142
2199
  this._resolveImport = options.resolveImport == null ? defaultImportResolver : options.resolveImport;
2143
- this._parseContext = new ParseContext();
2200
+ this._parseContext = new ParseContext(this._params);
2144
2201
  this._autoComplete = new AutoComplete(grammar, {
2145
2202
  greedyPatternNames: ["spaces", "optional-spaces", "whitespace", "new-line"],
2146
2203
  customTokens: {
@@ -2154,13 +2211,17 @@
2154
2211
  import(path) {
2155
2212
  return __awaiter(this, void 0, void 0, function* () {
2156
2213
  const grammarFile = yield this._resolveImport(path, null);
2157
- const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
2214
+ const grammar = new Grammar({
2215
+ resolveImport: this._resolveImport,
2216
+ originResource: grammarFile.resource,
2217
+ params: this._params
2218
+ });
2158
2219
  return grammar.parse(grammarFile.expression);
2159
2220
  });
2160
2221
  }
2161
2222
  parse(expression) {
2162
2223
  return __awaiter(this, void 0, void 0, function* () {
2163
- this._parseContext = new ParseContext();
2224
+ this._parseContext = new ParseContext(this._params);
2164
2225
  const ast = this._tryToParse(expression);
2165
2226
  yield this._resolveImports(ast);
2166
2227
  this._buildPatterns(ast);
@@ -2168,7 +2229,7 @@
2168
2229
  });
2169
2230
  }
2170
2231
  parseString(expression) {
2171
- this._parseContext = new ParseContext();
2232
+ this._parseContext = new ParseContext(this._params);
2172
2233
  const ast = this._tryToParse(expression);
2173
2234
  if (this._hasImports(ast)) {
2174
2235
  throw new Error("Cannot use imports on parseString, use parse instead.");
@@ -2200,7 +2261,7 @@
2200
2261
  return importBlock && importBlock.children.length > 0;
2201
2262
  }
2202
2263
  _buildPatterns(ast) {
2203
- ast.children.forEach((n) => {
2264
+ ast.findAll(n => n.name === "statement").forEach((n) => {
2204
2265
  const typeNode = n.find(n => n.name.includes("literal"));
2205
2266
  const type = (typeNode === null || typeNode === void 0 ? void 0 : typeNode.name) || "unknown";
2206
2267
  switch (type) {
@@ -2232,15 +2293,19 @@
2232
2293
  });
2233
2294
  }
2234
2295
  _resolveImports(ast) {
2235
- var _a;
2236
2296
  return __awaiter(this, void 0, void 0, function* () {
2237
2297
  const parseContext = this._parseContext;
2238
- const importStatements = ast.findAll(n => n.name === "import-statement");
2298
+ const importStatements = ast.findAll(n => n.name === "import-from");
2239
2299
  for (const importStatement of importStatements) {
2240
- const urlNode = importStatement.find(n => n.name === "url");
2241
- const url = urlNode.value.slice(1, -1);
2242
- const grammarFile = yield this._resolveImport(url, ((_a = this._meta) === null || _a === void 0 ? void 0 : _a.originPath) || null);
2243
- const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
2300
+ const resourceNode = importStatement.find(n => n.name === "resource");
2301
+ const params = this._getParams(importStatement);
2302
+ const resource = resourceNode.value.slice(1, -1);
2303
+ const grammarFile = yield this._resolveImport(resource, this._originResource || null);
2304
+ const grammar = new Grammar({
2305
+ resolveImport: this._resolveImport,
2306
+ originResource: grammarFile.resource,
2307
+ params
2308
+ });
2244
2309
  try {
2245
2310
  const patterns = yield grammar.parse(grammarFile.expression);
2246
2311
  const importNames = importStatement.findAll(n => n.name === "import-name").map(n => n.value);
@@ -2250,17 +2315,39 @@
2250
2315
  }
2251
2316
  const pattern = patterns.get(importName);
2252
2317
  if (pattern == null) {
2253
- throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${url}.`);
2318
+ throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${resource}.`);
2254
2319
  }
2255
2320
  parseContext.importedPatternsByName.set(importName, pattern);
2256
2321
  });
2257
2322
  }
2258
2323
  catch (e) {
2259
- throw new Error(`Failed loading expression from: "${url}". Error details: "${e.message}"`);
2324
+ throw new Error(`Failed loading expression from: "${resource}". Error details: "${e.message}"`);
2260
2325
  }
2261
2326
  }
2262
2327
  });
2263
2328
  }
2329
+ _getParams(importStatement) {
2330
+ let params = [];
2331
+ const paramsStatement = importStatement.find(n => n.name === "with-params-statement");
2332
+ if (paramsStatement != null) {
2333
+ const statements = paramsStatement.find(n => n.name === "body");
2334
+ if (statements != null) {
2335
+ const expression = statements.toString();
2336
+ const importedValues = Array.from(this
2337
+ ._parseContext
2338
+ .importedPatternsByName
2339
+ .values());
2340
+ const grammar = new Grammar({
2341
+ params: importedValues,
2342
+ originResource: this._originResource,
2343
+ resolveImport: this._resolveImport
2344
+ });
2345
+ const patterns = grammar.parseString(expression);
2346
+ params = Array.from(patterns.values());
2347
+ }
2348
+ }
2349
+ return params;
2350
+ }
2264
2351
  _buildLiteral(statementNode) {
2265
2352
  const nameNode = statementNode.find(n => n.name === "name");
2266
2353
  const literalNode = statementNode.find(n => n.name === "literal");
@@ -2291,6 +2378,9 @@
2291
2378
  if (pattern == null) {
2292
2379
  pattern = this._parseContext.importedPatternsByName.get(name);
2293
2380
  }
2381
+ if (pattern == null) {
2382
+ pattern = this._parseContext.paramsByName.get(name);
2383
+ }
2294
2384
  if (pattern == null) {
2295
2385
  return new Reference(name);
2296
2386
  }
@@ -2382,8 +2472,8 @@
2382
2472
  const grammar = new Grammar(options);
2383
2473
  return grammar.import(path);
2384
2474
  }
2385
- static parseString(expression) {
2386
- const grammar = new Grammar();
2475
+ static parseString(expression, options) {
2476
+ const grammar = new Grammar(options);
2387
2477
  return grammar.parseString(expression);
2388
2478
  }
2389
2479
  }