clarity-pattern-parser 8.2.1 → 8.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/.vscode/settings.json +5 -1
- package/README.md +2 -2
- package/dist/grammar/Grammar.d.ts +22 -3
- package/dist/grammar/patterns/import.d.ts +2 -0
- package/dist/index.browser.js +182 -50
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +182 -51
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +182 -50
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ast/Node.ts +1 -1
- package/src/grammar/Grammar.test.ts +66 -20
- package/src/grammar/Grammar.ts +116 -9
- package/src/grammar/patterns/grammar.ts +9 -6
- package/src/grammar/patterns/import.ts +29 -0
- package/src/grammar/spec.md +26 -2
- package/src/index.ts +2 -0
- package/src/patterns/And.ts +1 -5
- package/src/patterns/FiniteRepeat.ts +2 -1
- package/src/patterns/InfiniteRepeat.test.ts +9 -23
- package/src/patterns/InfiniteRepeat.ts +7 -2
package/.vscode/settings.json
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"typescript.tsdk": "node_modules/typescript/lib"
|
|
2
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
3
|
+
"typescript.preferences.importModuleSpecifierEnding": "minimal",
|
|
4
|
+
"javascript.preferences.importModuleSpecifierEnding": "minimal",
|
|
5
|
+
"typescript.preferences.importModuleSpecifier": "relative",
|
|
6
|
+
"javascript.preferences.importModuleSpecifier": "relative"
|
|
3
7
|
}
|
package/README.md
CHANGED
|
@@ -129,14 +129,14 @@ ast.toJson(2); // Look Below for output
|
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
## Or
|
|
132
|
-
The `Or` pattern
|
|
132
|
+
The `Or` pattern matches any of the patterns given to the constructor.
|
|
133
133
|
```ts
|
|
134
134
|
import { Or, Literal } from "clarity-pattern-parser";
|
|
135
135
|
|
|
136
136
|
const jane = new Literal("jane", "Jane");
|
|
137
137
|
const john = new Literal("john", "John");
|
|
138
138
|
const firstName = new Or("first-name", [jane, john]);
|
|
139
|
-
const { ast }= firstName.exec("Jane");
|
|
139
|
+
const { ast } = firstName.exec("Jane");
|
|
140
140
|
|
|
141
141
|
ast.toJson(2)
|
|
142
142
|
```
|
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
import { Pattern } from "../patterns/Pattern";
|
|
2
|
+
export interface GrammarMeta {
|
|
3
|
+
originPath?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface GrammarFile {
|
|
6
|
+
path: string;
|
|
7
|
+
expression: string;
|
|
8
|
+
}
|
|
9
|
+
export interface GrammarOptions {
|
|
10
|
+
resolveImport?: (path: string, originPath: string | null) => Promise<GrammarFile>;
|
|
11
|
+
meta?: GrammarMeta | null;
|
|
12
|
+
}
|
|
2
13
|
export declare class Grammar {
|
|
14
|
+
private _meta;
|
|
15
|
+
private _resolveImport;
|
|
3
16
|
private _parseContext;
|
|
4
17
|
private _autoComplete;
|
|
5
|
-
constructor();
|
|
6
|
-
|
|
18
|
+
constructor(options?: GrammarOptions);
|
|
19
|
+
import(path: string): Promise<Map<string, Pattern>>;
|
|
20
|
+
parse(expression: string): Promise<Map<string, Pattern>>;
|
|
21
|
+
parseString(expression: string): Map<string, Pattern>;
|
|
7
22
|
private _tryToParse;
|
|
23
|
+
private _hasImports;
|
|
8
24
|
private _cleanAst;
|
|
9
25
|
private _buildPatterns;
|
|
26
|
+
private _resolveImports;
|
|
10
27
|
private _buildLiteral;
|
|
11
28
|
private _buildRegex;
|
|
12
29
|
private _buildOr;
|
|
@@ -14,5 +31,7 @@ export declare class Grammar {
|
|
|
14
31
|
private _buildAnd;
|
|
15
32
|
private _buildRepeat;
|
|
16
33
|
private _buildAlias;
|
|
17
|
-
static parse(expression: string): Map<string, Pattern
|
|
34
|
+
static parse(expression: string, options?: GrammarOptions): Promise<Map<string, Pattern>>;
|
|
35
|
+
static import(path: string, options?: GrammarOptions): Promise<Map<string, Pattern>>;
|
|
36
|
+
static parseString(expression: string): Map<string, Pattern>;
|
|
18
37
|
}
|
package/dist/index.browser.js
CHANGED
|
@@ -182,6 +182,36 @@
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
/******************************************************************************
|
|
186
|
+
Copyright (c) Microsoft Corporation.
|
|
187
|
+
|
|
188
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
189
|
+
purpose with or without fee is hereby granted.
|
|
190
|
+
|
|
191
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
192
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
193
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
194
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
195
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
196
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
197
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
198
|
+
***************************************************************************** */
|
|
199
|
+
|
|
200
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
201
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
202
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
203
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
204
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
205
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
206
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
211
|
+
var e = new Error(message);
|
|
212
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
213
|
+
};
|
|
214
|
+
|
|
185
215
|
class ParseError {
|
|
186
216
|
constructor(startIndex, endIndex, pattern) {
|
|
187
217
|
this.startIndex = startIndex;
|
|
@@ -976,8 +1006,9 @@
|
|
|
976
1006
|
}
|
|
977
1007
|
}
|
|
978
1008
|
if (matchCount < this._min) {
|
|
1009
|
+
const lastIndex = cursor.index;
|
|
979
1010
|
cursor.moveTo(startIndex);
|
|
980
|
-
cursor.recordErrorAt(startIndex,
|
|
1011
|
+
cursor.recordErrorAt(startIndex, lastIndex, this);
|
|
981
1012
|
return null;
|
|
982
1013
|
}
|
|
983
1014
|
else if (nodes.length === 0) {
|
|
@@ -1094,10 +1125,10 @@
|
|
|
1094
1125
|
const divider = options.divider;
|
|
1095
1126
|
let children;
|
|
1096
1127
|
if (divider != null) {
|
|
1097
|
-
children = [pattern.clone(), divider.clone(divider.name, false)];
|
|
1128
|
+
children = [pattern.clone(pattern.name, false), divider.clone(divider.name, false)];
|
|
1098
1129
|
}
|
|
1099
1130
|
else {
|
|
1100
|
-
children = [pattern.clone()];
|
|
1131
|
+
children = [pattern.clone(pattern.name, false)];
|
|
1101
1132
|
}
|
|
1102
1133
|
this._assignChildrenToParent(children);
|
|
1103
1134
|
this._type = "infinite-repeat";
|
|
@@ -1217,6 +1248,10 @@
|
|
|
1217
1248
|
const dividerNode = this._nodes.pop();
|
|
1218
1249
|
cursor.moveTo(dividerNode.firstIndex);
|
|
1219
1250
|
}
|
|
1251
|
+
// if (this._nodes.length === 0) {
|
|
1252
|
+
// cursor.moveTo(this._firstIndex);
|
|
1253
|
+
// return null;
|
|
1254
|
+
// }
|
|
1220
1255
|
const lastIndex = this._nodes[this._nodes.length - 1].lastIndex;
|
|
1221
1256
|
cursor.moveTo(lastIndex);
|
|
1222
1257
|
return new Node(this._type, this._name, this._firstIndex, lastIndex, this._nodes);
|
|
@@ -1548,7 +1583,6 @@
|
|
|
1548
1583
|
createNode(cursor) {
|
|
1549
1584
|
const children = filterOutNull(this._nodes);
|
|
1550
1585
|
const lastIndex = children[children.length - 1].lastIndex;
|
|
1551
|
-
cursor.getChars(this._firstIndex, lastIndex);
|
|
1552
1586
|
cursor.moveTo(lastIndex);
|
|
1553
1587
|
return new Node("and", this._name, this._firstIndex, lastIndex, children);
|
|
1554
1588
|
}
|
|
@@ -1590,9 +1624,6 @@
|
|
|
1590
1624
|
let index = -1;
|
|
1591
1625
|
for (let i = 0; i < this._children.length; i++) {
|
|
1592
1626
|
if (this._children[i] === childReference) {
|
|
1593
|
-
if (i + 1 < this._children.length) {
|
|
1594
|
-
this._children[i + 1];
|
|
1595
|
-
}
|
|
1596
1627
|
nextSiblingIndex = i + 1;
|
|
1597
1628
|
index = i;
|
|
1598
1629
|
break;
|
|
@@ -1634,11 +1665,11 @@
|
|
|
1634
1665
|
}
|
|
1635
1666
|
}
|
|
1636
1667
|
|
|
1637
|
-
const name = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
|
|
1668
|
+
const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
|
|
1638
1669
|
|
|
1639
1670
|
const optionalNot = new Literal("not", "!", true);
|
|
1640
1671
|
const optionalIsOptional$1 = new Literal("is-optional", "?", true);
|
|
1641
|
-
const patternName$1 = name.clone("pattern-name");
|
|
1672
|
+
const patternName$1 = name$1.clone("pattern-name");
|
|
1642
1673
|
const pattern$1 = new And("pattern", [
|
|
1643
1674
|
optionalNot,
|
|
1644
1675
|
patternName$1,
|
|
@@ -1651,44 +1682,44 @@
|
|
|
1651
1682
|
|
|
1652
1683
|
const divider = new Regex("or-divider", "\\s*[|]\\s*");
|
|
1653
1684
|
divider.setTokens([" | "]);
|
|
1654
|
-
const orLiteral = new Repeat("or-literal", name.clone("pattern-name"), { divider, min: 2 });
|
|
1685
|
+
const orLiteral = new Repeat("or-literal", name$1.clone("pattern-name"), { divider, min: 2 });
|
|
1655
1686
|
|
|
1656
1687
|
const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
|
|
1657
1688
|
|
|
1658
|
-
const spaces = new Regex("spaces", "[ \\t]+");
|
|
1659
|
-
spaces.setTokens([" "]);
|
|
1689
|
+
const spaces$1 = new Regex("spaces", "[ \\t]+");
|
|
1690
|
+
spaces$1.setTokens([" "]);
|
|
1660
1691
|
|
|
1661
1692
|
const optionalIsOptional = new Literal("is-optional", "?", true);
|
|
1662
|
-
const patternName = name.clone("pattern-name");
|
|
1693
|
+
const patternName = name$1.clone("pattern-name");
|
|
1663
1694
|
const pattern = new And("pattern", [
|
|
1664
1695
|
patternName,
|
|
1665
1696
|
optionalIsOptional,
|
|
1666
1697
|
]);
|
|
1667
|
-
const optionalSpaces$
|
|
1668
|
-
const dividerPattern = name.clone("divider-pattern");
|
|
1669
|
-
const openBracket = new Literal("open-bracket", "{");
|
|
1670
|
-
const closeBracket = new Literal("close-bracket", "}");
|
|
1698
|
+
const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
|
|
1699
|
+
const dividerPattern = name$1.clone("divider-pattern");
|
|
1700
|
+
const openBracket$1 = new Literal("open-bracket", "{");
|
|
1701
|
+
const closeBracket$1 = new Literal("close-bracket", "}");
|
|
1671
1702
|
const comma = new Literal("comma", ",");
|
|
1672
1703
|
const integer = new Regex("integer", "([1-9][0-9]*)|0");
|
|
1673
1704
|
integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
|
|
1674
1705
|
const optionalInteger = integer.clone("integer", true);
|
|
1675
1706
|
const bounds = new And("bounds", [
|
|
1676
|
-
openBracket,
|
|
1677
|
-
optionalSpaces$
|
|
1707
|
+
openBracket$1,
|
|
1708
|
+
optionalSpaces$2,
|
|
1678
1709
|
optionalInteger.clone("min"),
|
|
1679
|
-
optionalSpaces$
|
|
1710
|
+
optionalSpaces$2,
|
|
1680
1711
|
comma,
|
|
1681
|
-
optionalSpaces$
|
|
1712
|
+
optionalSpaces$2,
|
|
1682
1713
|
optionalInteger.clone("max"),
|
|
1683
|
-
optionalSpaces$
|
|
1684
|
-
closeBracket
|
|
1714
|
+
optionalSpaces$2,
|
|
1715
|
+
closeBracket$1
|
|
1685
1716
|
]);
|
|
1686
1717
|
const exactCount = new And("exact-count", [
|
|
1687
|
-
openBracket,
|
|
1688
|
-
optionalSpaces$
|
|
1718
|
+
openBracket$1,
|
|
1719
|
+
optionalSpaces$2,
|
|
1689
1720
|
integer,
|
|
1690
|
-
optionalSpaces$
|
|
1691
|
-
closeBracket,
|
|
1721
|
+
optionalSpaces$2,
|
|
1722
|
+
closeBracket$1,
|
|
1692
1723
|
]);
|
|
1693
1724
|
const quantifierShorthand = new Regex("quantifier-shorthand", "\\*|\\+");
|
|
1694
1725
|
quantifierShorthand.setTokens(["*", "+"]);
|
|
@@ -1705,19 +1736,19 @@
|
|
|
1705
1736
|
dividerComma.setTokens([", "]);
|
|
1706
1737
|
const repeatLiteral = new And("repeat-literal", [
|
|
1707
1738
|
openParen,
|
|
1708
|
-
optionalSpaces$
|
|
1739
|
+
optionalSpaces$2,
|
|
1709
1740
|
pattern,
|
|
1710
1741
|
optional,
|
|
1711
1742
|
new And("optional-divider-section", [dividerComma, dividerPattern], true),
|
|
1712
|
-
optionalSpaces$
|
|
1743
|
+
optionalSpaces$2,
|
|
1713
1744
|
closeParen,
|
|
1714
|
-
new And("quantifier-section", [optionalSpaces$
|
|
1715
|
-
new And("optional-trim-divider-section", [spaces, trimDivider], true)
|
|
1745
|
+
new And("quantifier-section", [optionalSpaces$2, quantifier]),
|
|
1746
|
+
new And("optional-trim-divider-section", [spaces$1, trimDivider], true)
|
|
1716
1747
|
]);
|
|
1717
1748
|
|
|
1718
1749
|
const literal = new Regex("literal", "\"(?:\\\\[\"\\\\]|[^\n\"\\\\])*\"");
|
|
1719
1750
|
|
|
1720
|
-
const optionalSpaces = spaces.clone("optional-spaces", true);
|
|
1751
|
+
const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
|
|
1721
1752
|
const assignOperator = new Literal("assign-operator", "=");
|
|
1722
1753
|
const optionalComment = comment.clone("inline-comment", true);
|
|
1723
1754
|
const statements = new Or("statements", [
|
|
@@ -1726,30 +1757,55 @@
|
|
|
1726
1757
|
orLiteral,
|
|
1727
1758
|
andLiteral,
|
|
1728
1759
|
repeatLiteral,
|
|
1729
|
-
name.clone("alias-literal"),
|
|
1760
|
+
name$1.clone("alias-literal"),
|
|
1730
1761
|
]);
|
|
1731
1762
|
const statement = new And("statement", [
|
|
1732
|
-
optionalSpaces,
|
|
1733
|
-
name,
|
|
1734
|
-
optionalSpaces,
|
|
1763
|
+
optionalSpaces$1,
|
|
1764
|
+
name$1,
|
|
1765
|
+
optionalSpaces$1,
|
|
1735
1766
|
assignOperator,
|
|
1736
|
-
optionalSpaces,
|
|
1767
|
+
optionalSpaces$1,
|
|
1737
1768
|
statements,
|
|
1738
|
-
optionalSpaces,
|
|
1769
|
+
optionalSpaces$1,
|
|
1739
1770
|
optionalComment,
|
|
1771
|
+
optionalSpaces$1,
|
|
1772
|
+
]);
|
|
1773
|
+
|
|
1774
|
+
const spaces = new Regex("spaces", "\\s+", true);
|
|
1775
|
+
const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
|
|
1776
|
+
const importKeyword = new Literal("import", "import");
|
|
1777
|
+
const fromKeyword = new Literal("from", "from");
|
|
1778
|
+
const openBracket = new Literal("open-bracket", "{");
|
|
1779
|
+
const closeBracket = new Literal("close-bracket", "}");
|
|
1780
|
+
const name = new Regex("import-name", "[^}\\s,]+");
|
|
1781
|
+
const importedNames = new Repeat("imported-names", name, { divider: importNameDivider });
|
|
1782
|
+
const optionalSpaces = spaces.clone("optional-spaces", true);
|
|
1783
|
+
const importStatement = new And("import-statement", [
|
|
1784
|
+
importKeyword,
|
|
1785
|
+
optionalSpaces,
|
|
1786
|
+
openBracket,
|
|
1740
1787
|
optionalSpaces,
|
|
1788
|
+
importedNames,
|
|
1789
|
+
optionalSpaces,
|
|
1790
|
+
closeBracket,
|
|
1791
|
+
optionalSpaces,
|
|
1792
|
+
fromKeyword,
|
|
1793
|
+
spaces,
|
|
1794
|
+
literal.clone("url"),
|
|
1741
1795
|
]);
|
|
1742
1796
|
|
|
1743
|
-
const whitespace = new Regex("whitespace", "[ \\t]+");
|
|
1797
|
+
const whitespace = new Regex("whitespace", "[ \\t]+((\\r?\\n)+)?");
|
|
1744
1798
|
const newLine = new Regex("new-line", "(\\r?\\n)+");
|
|
1745
1799
|
whitespace.setTokens([" "]);
|
|
1746
1800
|
newLine.setTokens(["\n"]);
|
|
1747
1801
|
const line = new Or("line", [
|
|
1802
|
+
newLine,
|
|
1803
|
+
whitespace,
|
|
1748
1804
|
comment,
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
]
|
|
1752
|
-
const grammar = new Repeat("
|
|
1805
|
+
importStatement,
|
|
1806
|
+
statement
|
|
1807
|
+
]);
|
|
1808
|
+
const grammar = new Repeat("grammer", line);
|
|
1753
1809
|
|
|
1754
1810
|
class Not {
|
|
1755
1811
|
get type() {
|
|
@@ -2046,10 +2102,16 @@
|
|
|
2046
2102
|
class ParseContext {
|
|
2047
2103
|
constructor() {
|
|
2048
2104
|
this.patternsByName = new Map();
|
|
2105
|
+
this.importedPatternsByName = new Map();
|
|
2049
2106
|
}
|
|
2050
2107
|
}
|
|
2108
|
+
function defaultImportResolver(_path, _basePath) {
|
|
2109
|
+
throw new Error("No import resolver supplied.");
|
|
2110
|
+
}
|
|
2051
2111
|
class Grammar {
|
|
2052
|
-
constructor() {
|
|
2112
|
+
constructor(options = {}) {
|
|
2113
|
+
this._meta = options.meta == null ? null : options.meta;
|
|
2114
|
+
this._resolveImport = options.resolveImport == null ? defaultImportResolver : options.resolveImport;
|
|
2053
2115
|
this._parseContext = new ParseContext();
|
|
2054
2116
|
this._autoComplete = new AutoComplete(grammar, {
|
|
2055
2117
|
greedyPatternNames: ["spaces", "optional-spaces", "whitespace", "new-line"],
|
|
@@ -2061,9 +2123,31 @@
|
|
|
2061
2123
|
}
|
|
2062
2124
|
});
|
|
2063
2125
|
}
|
|
2126
|
+
import(path) {
|
|
2127
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2128
|
+
const grammarFile = yield this._resolveImport(path, null);
|
|
2129
|
+
const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
|
|
2130
|
+
return grammar.parse(grammarFile.expression);
|
|
2131
|
+
});
|
|
2132
|
+
}
|
|
2064
2133
|
parse(expression) {
|
|
2134
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2135
|
+
this._parseContext = new ParseContext();
|
|
2136
|
+
const ast = this._tryToParse(expression);
|
|
2137
|
+
yield this._resolveImports(ast);
|
|
2138
|
+
this._buildPatterns(ast);
|
|
2139
|
+
this._cleanAst(ast);
|
|
2140
|
+
return this._parseContext.patternsByName;
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
parseString(expression) {
|
|
2065
2144
|
this._parseContext = new ParseContext();
|
|
2066
|
-
this._tryToParse(expression);
|
|
2145
|
+
const ast = this._tryToParse(expression);
|
|
2146
|
+
if (this._hasImports(ast)) {
|
|
2147
|
+
throw new Error("Cannot use imports on parseString, use parse instead.");
|
|
2148
|
+
}
|
|
2149
|
+
this._buildPatterns(ast);
|
|
2150
|
+
this._cleanAst(ast);
|
|
2067
2151
|
return this._parseContext.patternsByName;
|
|
2068
2152
|
}
|
|
2069
2153
|
_tryToParse(expression) {
|
|
@@ -2080,8 +2164,14 @@
|
|
|
2080
2164
|
throw new Error(message);
|
|
2081
2165
|
}
|
|
2082
2166
|
// If it is complete it will always have a node. So we have to cast it.
|
|
2083
|
-
|
|
2084
|
-
|
|
2167
|
+
return ast;
|
|
2168
|
+
}
|
|
2169
|
+
_hasImports(ast) {
|
|
2170
|
+
const importBlock = ast.find(n => n.name === "import-block");
|
|
2171
|
+
if (importBlock == null) {
|
|
2172
|
+
return false;
|
|
2173
|
+
}
|
|
2174
|
+
return importBlock && importBlock.children.length > 0;
|
|
2085
2175
|
}
|
|
2086
2176
|
_cleanAst(ast) {
|
|
2087
2177
|
ast.findAll(n => n.name === "spaces" ||
|
|
@@ -2122,6 +2212,36 @@
|
|
|
2122
2212
|
}
|
|
2123
2213
|
});
|
|
2124
2214
|
}
|
|
2215
|
+
_resolveImports(ast) {
|
|
2216
|
+
var _a;
|
|
2217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2218
|
+
const parseContext = this._parseContext;
|
|
2219
|
+
const importStatements = ast.findAll(n => n.name === "import-statement");
|
|
2220
|
+
for (const importStatement of importStatements) {
|
|
2221
|
+
const urlNode = importStatement.find(n => n.name === "url");
|
|
2222
|
+
const url = urlNode.value.slice(1, -1);
|
|
2223
|
+
const grammarFile = yield this._resolveImport(url, ((_a = this._meta) === null || _a === void 0 ? void 0 : _a.originPath) || null);
|
|
2224
|
+
const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
|
|
2225
|
+
try {
|
|
2226
|
+
const patterns = yield grammar.parse(grammarFile.expression);
|
|
2227
|
+
const importNames = importStatement.findAll(n => n.name === "import-name").map(n => n.value);
|
|
2228
|
+
importNames.forEach((importName) => {
|
|
2229
|
+
if (parseContext.importedPatternsByName.has(importName)) {
|
|
2230
|
+
throw new Error(`'${importName}' was already used within another import.`);
|
|
2231
|
+
}
|
|
2232
|
+
const pattern = patterns.get(importName);
|
|
2233
|
+
if (pattern == null) {
|
|
2234
|
+
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${url}.`);
|
|
2235
|
+
}
|
|
2236
|
+
parseContext.importedPatternsByName.set(importName, pattern);
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
catch (e) {
|
|
2240
|
+
throw new Error(`Failed loading expression from: "${url}". Error details: "${e.message}"`);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2125
2245
|
_buildLiteral(statementNode) {
|
|
2126
2246
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2127
2247
|
const literalNode = statementNode.find(n => n.name === "literal");
|
|
@@ -2148,7 +2268,10 @@
|
|
|
2148
2268
|
this._parseContext.patternsByName.set(name, or);
|
|
2149
2269
|
}
|
|
2150
2270
|
_getPattern(name) {
|
|
2151
|
-
|
|
2271
|
+
let pattern = this._parseContext.patternsByName.get(name);
|
|
2272
|
+
if (pattern == null) {
|
|
2273
|
+
pattern = this._parseContext.importedPatternsByName.get(name);
|
|
2274
|
+
}
|
|
2152
2275
|
if (pattern == null) {
|
|
2153
2276
|
return new Reference(name);
|
|
2154
2277
|
}
|
|
@@ -2233,10 +2356,18 @@
|
|
|
2233
2356
|
const alias = pattern.clone(name);
|
|
2234
2357
|
this._parseContext.patternsByName.set(name, alias);
|
|
2235
2358
|
}
|
|
2236
|
-
static parse(expression) {
|
|
2237
|
-
const grammar = new Grammar();
|
|
2359
|
+
static parse(expression, options) {
|
|
2360
|
+
const grammar = new Grammar(options);
|
|
2238
2361
|
return grammar.parse(expression);
|
|
2239
2362
|
}
|
|
2363
|
+
static import(path, options) {
|
|
2364
|
+
const grammar = new Grammar(options);
|
|
2365
|
+
return grammar.import(path);
|
|
2366
|
+
}
|
|
2367
|
+
static parseString(expression) {
|
|
2368
|
+
const grammar = new Grammar();
|
|
2369
|
+
return grammar.parseString(expression);
|
|
2370
|
+
}
|
|
2240
2371
|
}
|
|
2241
2372
|
|
|
2242
2373
|
exports.And = And;
|
|
@@ -2252,6 +2383,7 @@
|
|
|
2252
2383
|
exports.Reference = Reference;
|
|
2253
2384
|
exports.Regex = Regex;
|
|
2254
2385
|
exports.Repeat = Repeat;
|
|
2386
|
+
exports.grammar = grammar;
|
|
2255
2387
|
|
|
2256
2388
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2257
2389
|
|