clarity-pattern-parser 8.4.14 → 9.0.0
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 +4 -1
- package/dist/grammar/Grammar.d.ts +18 -10
- package/dist/grammar/patterns/andLiteral.d.ts +2 -0
- package/dist/grammar/patterns/anonymousPattern.d.ts +2 -0
- package/dist/grammar/patterns/inlinePattern.d.ts +1 -0
- package/dist/grammar/patterns/literals.d.ts +3 -0
- package/dist/grammar/patterns/pattern.d.ts +2 -2
- package/dist/grammar/patterns.d.ts +2 -0
- package/dist/index.browser.js +472 -185
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +471 -186
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +472 -185
- package/dist/index.js.map +1 -1
- package/dist/patterns/And.d.ts +4 -1
- package/dist/patterns/Cursor.d.ts +5 -0
- package/dist/patterns/CursorHistory.d.ts +7 -0
- package/dist/patterns/FiniteRepeat.d.ts +4 -1
- package/dist/patterns/InfiniteRepeat.d.ts +5 -4
- package/dist/patterns/Literal.d.ts +6 -5
- package/dist/patterns/Not.d.ts +5 -4
- package/dist/patterns/Or.d.ts +5 -4
- package/dist/patterns/Pattern.d.ts +4 -2
- package/dist/patterns/Reference.d.ts +5 -4
- package/dist/patterns/Regex.d.ts +5 -4
- package/dist/patterns/Repeat.d.ts +3 -0
- package/dist/patterns/arePatternsEqual.d.ts +2 -0
- package/package.json +1 -1
- package/src/grammar/Grammar.test.ts +126 -72
- package/src/grammar/Grammar.ts +241 -158
- package/src/grammar/patterns/anonymousPattern.ts +23 -0
- package/src/grammar/patterns/body.ts +9 -6
- package/src/grammar/patterns/comment.ts +3 -2
- package/src/grammar/patterns/grammar.ts +15 -12
- package/src/grammar/patterns/import.ts +18 -12
- package/src/grammar/patterns/literal.ts +2 -3
- package/src/grammar/patterns/literals.ts +20 -0
- package/src/grammar/patterns/optionsLiteral.ts +19 -0
- package/src/grammar/patterns/pattern.ts +23 -9
- package/src/grammar/patterns/regexLiteral.ts +1 -0
- package/src/grammar/patterns/repeatLiteral.ts +30 -25
- package/src/grammar/patterns/sequenceLiteral.ts +24 -0
- package/src/grammar/patterns/spaces.ts +8 -6
- package/src/grammar/patterns/statement.ts +8 -20
- package/src/grammar/patterns.test.ts +38 -0
- package/src/grammar/patterns.ts +24 -0
- package/src/grammar/spec.md +4 -12
- package/src/index.ts +11 -5
- package/src/intellisense/AutoComplete.test.ts +41 -40
- package/src/intellisense/css/method.ts +2 -2
- package/src/intellisense/css/unit.ts +2 -2
- package/src/intellisense/css/value.ts +1 -1
- package/src/intellisense/javascript/Javascript.test.ts +31 -32
- package/src/intellisense/javascript/arrayLiteral.ts +7 -6
- package/src/intellisense/javascript/assignment.ts +6 -6
- package/src/intellisense/javascript/deleteStatement.ts +2 -2
- package/src/intellisense/javascript/escapedCharacter.ts +6 -6
- package/src/intellisense/javascript/exponent.ts +6 -6
- package/src/intellisense/javascript/expression.ts +18 -17
- package/src/intellisense/javascript/fraction.ts +3 -3
- package/src/intellisense/javascript/infixOperator.ts +10 -10
- package/src/intellisense/javascript/integer.ts +1 -1
- package/src/intellisense/javascript/invocation.ts +8 -7
- package/src/intellisense/javascript/literal.ts +3 -3
- package/src/intellisense/javascript/numberLiteral.ts +5 -4
- package/src/intellisense/javascript/objectAccess.ts +2 -3
- package/src/intellisense/javascript/objectLiteral.ts +8 -7
- package/src/intellisense/javascript/optionalSpaces.ts +2 -1
- package/src/intellisense/javascript/parameters.ts +5 -5
- package/src/intellisense/javascript/prefixOperator.ts +3 -4
- package/src/intellisense/javascript/propertyAccess.ts +9 -8
- package/src/intellisense/javascript/stringLiteral.ts +14 -15
- package/src/patterns/Cursor.ts +42 -4
- package/src/patterns/CursorHistory.ts +20 -4
- package/src/patterns/FiniteRepeat.test.ts +52 -51
- package/src/patterns/FiniteRepeat.ts +60 -38
- package/src/patterns/InfiniteRepeat.test.ts +36 -49
- package/src/patterns/InfiniteRepeat.ts +70 -37
- package/src/patterns/Literal.test.ts +16 -27
- package/src/patterns/Literal.ts +34 -27
- package/src/patterns/Not.test.ts +7 -7
- package/src/patterns/Not.ts +24 -6
- package/src/patterns/Optional.test.ts +164 -0
- package/src/patterns/Optional.ts +143 -0
- package/src/patterns/{Or.test.ts → Options.test.ts} +51 -49
- package/src/patterns/{Or.ts → Options.ts} +32 -23
- package/src/patterns/Pattern.ts +6 -5
- package/src/patterns/Reference.test.ts +21 -22
- package/src/patterns/Reference.ts +26 -15
- package/src/patterns/Regex.test.ts +15 -15
- package/src/patterns/Regex.ts +29 -19
- package/src/patterns/Repeat.test.ts +12 -22
- package/src/patterns/Repeat.ts +22 -21
- package/src/patterns/{And.test.ts → Sequence.test.ts} +78 -78
- package/src/patterns/{And.ts → Sequence.ts} +40 -29
- package/src/patterns/arePatternsEqual.ts +12 -0
- package/src/patterns/clonePatterns.ts +2 -2
- package/src/grammar/patterns/andLiteral.ts +0 -8
- package/src/grammar/patterns/orLiteral.ts +0 -8
|
@@ -1,31 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
2
2
|
import { Repeat } from "../../patterns/Repeat";
|
|
3
3
|
import { Literal } from "../../patterns/Literal";
|
|
4
4
|
import { Regex } from "../../patterns/Regex";
|
|
5
5
|
import { literal } from "./literal";
|
|
6
|
-
import {
|
|
6
|
+
import { Options } from "../../patterns/Options";
|
|
7
7
|
import { body } from "./body";
|
|
8
8
|
import { allSpaces, lineSpaces } from "./spaces";
|
|
9
|
+
import { Optional } from "../../patterns/Optional";
|
|
9
10
|
|
|
10
|
-
const optionalSpaces =
|
|
11
|
-
const optionalLineSpaces =
|
|
11
|
+
const optionalSpaces = new Optional("optional-spaces", allSpaces);
|
|
12
|
+
const optionalLineSpaces = new Optional("options-line-spaces", lineSpaces);
|
|
12
13
|
|
|
13
14
|
const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
|
|
15
|
+
importNameDivider.setTokens([", "]);
|
|
16
|
+
|
|
17
|
+
const name = new Regex("import-name", "[^}\\s,]+");
|
|
18
|
+
name.setTokens(["[IMPORT_NAME]"]);
|
|
19
|
+
|
|
14
20
|
const importKeyword = new Literal("import", "import");
|
|
15
21
|
const useParamsKeyword = new Literal("use-params", "use params");
|
|
16
22
|
const asKeyword = new Literal("as", "as");
|
|
17
23
|
const fromKeyword = new Literal("from", "from");
|
|
18
24
|
const openBracket = new Literal("open-bracket", "{");
|
|
19
25
|
const closeBracket = new Literal("close-bracket", "}");
|
|
20
|
-
|
|
26
|
+
|
|
21
27
|
const importNameAlias = name.clone("import-name-alias");
|
|
22
|
-
const importAlias = new
|
|
23
|
-
const importedNames = new Repeat("imported-names", new
|
|
28
|
+
const importAlias = new Sequence("import-alias", [name, lineSpaces, asKeyword, lineSpaces, importNameAlias]);
|
|
29
|
+
const importedNames = new Repeat("imported-names", new Options("import-names", [importAlias, name]), { divider: importNameDivider });
|
|
24
30
|
const paramName = name.clone("param-name");
|
|
25
31
|
const paramNames = new Repeat("param-names", paramName, { divider: importNameDivider });
|
|
26
32
|
const resource = literal.clone("resource");
|
|
27
33
|
|
|
28
|
-
const useParams = new
|
|
34
|
+
const useParams = new Sequence("import-params", [
|
|
29
35
|
useParamsKeyword,
|
|
30
36
|
optionalLineSpaces,
|
|
31
37
|
openBracket,
|
|
@@ -36,7 +42,7 @@ const useParams = new And("import-params", [
|
|
|
36
42
|
]);
|
|
37
43
|
|
|
38
44
|
const withParamsKeyword = new Literal("with-params", "with params");
|
|
39
|
-
const withParamsStatement = new
|
|
45
|
+
const withParamsStatement = new Optional("optional-with-params-statement", new Sequence("with-params-statement", [
|
|
40
46
|
withParamsKeyword,
|
|
41
47
|
optionalLineSpaces,
|
|
42
48
|
openBracket,
|
|
@@ -44,9 +50,9 @@ const withParamsStatement = new And("with-params-statement", [
|
|
|
44
50
|
body.clone("with-params-body"),
|
|
45
51
|
optionalSpaces,
|
|
46
52
|
closeBracket
|
|
47
|
-
]
|
|
53
|
+
]));
|
|
48
54
|
|
|
49
|
-
const importFromStatement = new
|
|
55
|
+
const importFromStatement = new Sequence("import-from", [
|
|
50
56
|
importKeyword,
|
|
51
57
|
optionalLineSpaces,
|
|
52
58
|
openBracket,
|
|
@@ -62,7 +68,7 @@ const importFromStatement = new And("import-from", [
|
|
|
62
68
|
withParamsStatement
|
|
63
69
|
]);
|
|
64
70
|
|
|
65
|
-
export const importStatement = new
|
|
71
|
+
export const importStatement = new Options("import-statement", [
|
|
66
72
|
useParams,
|
|
67
73
|
importFromStatement
|
|
68
74
|
]);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Options } from "../../patterns/Options";
|
|
2
|
+
import { Reference } from "../../patterns/Reference";
|
|
3
|
+
import { literal } from "./literal";
|
|
4
|
+
import { name } from "./name";
|
|
5
|
+
import { regexLiteral } from "./regexLiteral";
|
|
6
|
+
|
|
7
|
+
const patternName = name.clone("pattern-name");
|
|
8
|
+
|
|
9
|
+
export const anonymousLiterals = new Options("anonymous-literals", [
|
|
10
|
+
literal,
|
|
11
|
+
regexLiteral,
|
|
12
|
+
patternName,
|
|
13
|
+
new Reference("repeat-literal"),
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
export const anonymousWrappedLiterals = new Options("anonymous-wrapped-literals", [
|
|
17
|
+
new Reference("options-literal"),
|
|
18
|
+
new Reference("sequence-literal"),
|
|
19
|
+
new Reference("complex-anonymous-pattern")
|
|
20
|
+
]);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Repeat } from "../../patterns/Repeat";
|
|
2
|
+
import { Regex } from "../../patterns/Regex";
|
|
3
|
+
import { name } from "./name";
|
|
4
|
+
import { anonymousPattern } from "./anonymousPattern";
|
|
5
|
+
import { Options } from "../../patterns/Options";
|
|
6
|
+
|
|
7
|
+
const patternName = name.clone("pattern-name");
|
|
8
|
+
patternName.setTokens(["[PATTERN_NAME]"]);
|
|
9
|
+
|
|
10
|
+
const patterns = new Options("or-patterns", [patternName, anonymousPattern]);
|
|
11
|
+
const defaultDivider = new Regex("default-divider", "\\s*[|]\\s*");
|
|
12
|
+
defaultDivider.setTokens(["|"]);
|
|
13
|
+
|
|
14
|
+
const greedyDivider = new Regex("greedy-divider", "\\s*[<][|][>]\\s*");
|
|
15
|
+
greedyDivider.setTokens(["<|>"]);
|
|
16
|
+
|
|
17
|
+
const divider = new Options("options-divider", [defaultDivider, greedyDivider]);
|
|
18
|
+
|
|
19
|
+
export const optionsLiteral = new Repeat("options-literal", patterns, { divider, min: 2, trimDivider: true });
|
|
@@ -1,13 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Options } from "../../patterns/Options";
|
|
2
|
+
import { literal } from "./literal";
|
|
3
|
+
import { regexLiteral } from "./regexLiteral";
|
|
4
|
+
import { repeatLiteral } from "./repeatLiteral";
|
|
5
|
+
import { sequenceLiteral } from "./sequenceLiteral";
|
|
6
|
+
import { optionsLiteral } from "./optionsLiteral";
|
|
7
|
+
import { anonymousPattern } from "./anonymousPattern";
|
|
8
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
2
9
|
import { Literal } from "../../patterns/Literal";
|
|
3
10
|
import { name } from "./name";
|
|
11
|
+
import { Optional } from "../../patterns/Optional";
|
|
4
12
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const patternName = name.clone("pattern-name");
|
|
13
|
+
const aliasLiteral = name.clone("alias-literal");
|
|
14
|
+
aliasLiteral.setTokens(["[ALIAS_LITERAL]"]);
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const optionalIsOptional = new Optional("optional-flag", new Literal("is-optional", "?"));
|
|
17
|
+
const configurableAnonymousPattern = new Sequence("configurable-anonymous-pattern", [anonymousPattern, optionalIsOptional]);
|
|
18
|
+
|
|
19
|
+
export const pattern = new Options("pattern", [
|
|
20
|
+
literal,
|
|
21
|
+
regexLiteral,
|
|
22
|
+
repeatLiteral,
|
|
23
|
+
aliasLiteral,
|
|
24
|
+
optionsLiteral,
|
|
25
|
+
sequenceLiteral,
|
|
26
|
+
configurableAnonymousPattern,
|
|
27
|
+
], true);
|
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
2
2
|
import { Literal } from "../../patterns/Literal";
|
|
3
|
-
import {
|
|
3
|
+
import { Options } from "../../patterns/Options";
|
|
4
4
|
import { Regex } from "../../patterns/Regex";
|
|
5
|
+
import { anonymousPattern } from "./anonymousPattern";
|
|
5
6
|
import { name } from "./name";
|
|
6
|
-
import { spaces } from "./spaces";
|
|
7
|
-
|
|
8
|
-
const patternName = name.clone("pattern-name");
|
|
9
|
-
|
|
10
|
-
const optionalSpaces = spaces.clone("optional-spaces", true);
|
|
11
|
-
const dividerPattern = name.clone("divider-pattern");
|
|
7
|
+
import { lineSpaces, spaces } from "./spaces";
|
|
8
|
+
import { Optional } from "../../patterns/Optional";
|
|
12
9
|
|
|
10
|
+
const optionalSpaces = new Optional("optional-spaces", spaces);
|
|
13
11
|
const openBracket = new Literal("open-bracket", "{");
|
|
14
12
|
const closeBracket = new Literal("close-bracket", "}");
|
|
15
13
|
const comma = new Literal("comma", ",");
|
|
14
|
+
|
|
16
15
|
const integer = new Regex("integer", "([1-9][0-9]*)|0");
|
|
17
16
|
integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
|
|
18
17
|
|
|
19
|
-
const
|
|
18
|
+
const min = new Optional("optional-min", integer.clone("min"));
|
|
19
|
+
const max = new Optional("optional-max", integer.clone("max"));
|
|
20
|
+
const trimKeyword = new Literal("trim-keyword", "trim");
|
|
21
|
+
const trimFlag = new Optional("optional-trim-flag", new Sequence("trim-flag", [lineSpaces, trimKeyword]));
|
|
20
22
|
|
|
21
|
-
const bounds = new
|
|
23
|
+
const bounds = new Sequence("bounds", [
|
|
22
24
|
openBracket,
|
|
23
25
|
optionalSpaces,
|
|
24
|
-
|
|
26
|
+
min,
|
|
25
27
|
optionalSpaces,
|
|
26
28
|
comma,
|
|
27
29
|
optionalSpaces,
|
|
28
|
-
|
|
29
|
-
optionalSpaces,
|
|
30
|
+
max,
|
|
30
31
|
closeBracket
|
|
31
32
|
]);
|
|
32
33
|
|
|
33
|
-
const exactCount = new
|
|
34
|
+
const exactCount = new Sequence("exact-count", [
|
|
34
35
|
openBracket,
|
|
35
36
|
optionalSpaces,
|
|
36
37
|
integer,
|
|
@@ -40,27 +41,31 @@ const exactCount = new And("exact-count", [
|
|
|
40
41
|
|
|
41
42
|
const quantifierShorthand = new Regex("quantifier-shorthand", "\\*|\\+");
|
|
42
43
|
quantifierShorthand.setTokens(["*", "+"]);
|
|
43
|
-
|
|
44
|
+
|
|
45
|
+
const quantifier = new Options("quantifier", [
|
|
44
46
|
quantifierShorthand,
|
|
45
47
|
exactCount,
|
|
46
48
|
bounds
|
|
47
49
|
]);
|
|
48
50
|
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const openParen = new Literal("open-paren", "(");
|
|
52
|
-
const closeParen = new Literal("close-paren", ")");
|
|
51
|
+
const openParen = new Literal("repeat-open-paren", "(");
|
|
52
|
+
const closeParen = new Literal("repeat-close-paren", ")");
|
|
53
53
|
const dividerComma = new Regex("divider-comma", "\\s*,\\s*");
|
|
54
54
|
dividerComma.setTokens([", "]);
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
|
|
57
|
+
const patternName = name.clone("pattern-name");
|
|
58
|
+
const patterns = new Options("or-patterns", [patternName, anonymousPattern]);
|
|
59
|
+
const dividerPattern = patterns.clone("divider-pattern");
|
|
60
|
+
const dividerSection = new Sequence("divider-section", [dividerComma, dividerPattern, trimFlag]);
|
|
61
|
+
const optionalDividerSection = new Optional("optional-divider-section", dividerSection);
|
|
62
|
+
|
|
63
|
+
export const repeatLiteral = new Sequence("repeat-literal", [
|
|
57
64
|
openParen,
|
|
58
65
|
optionalSpaces,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
new And("optional-divider-section", [dividerComma, dividerPattern], true),
|
|
66
|
+
patterns,
|
|
67
|
+
optionalDividerSection,
|
|
62
68
|
optionalSpaces,
|
|
63
69
|
closeParen,
|
|
64
|
-
new
|
|
65
|
-
new And("optional-trim-divider-section", [spaces, trimDivider], true)
|
|
70
|
+
new Sequence("quantifier-section", [quantifier]),
|
|
66
71
|
]);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Repeat } from "../../patterns/Repeat";
|
|
2
|
+
import { Regex } from "../../patterns/Regex";
|
|
3
|
+
import { name } from "./name";
|
|
4
|
+
import { anonymousPattern } from "./anonymousPattern";
|
|
5
|
+
import { Options } from "../../patterns/Options";
|
|
6
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
7
|
+
import { Literal } from "../../patterns/Literal";
|
|
8
|
+
import { Optional } from "../../patterns/Optional";
|
|
9
|
+
|
|
10
|
+
const optionalNot = new Optional("optional-not", new Literal("not", "!"));
|
|
11
|
+
const optionalIsOptional = new Optional("optional-is-optional", new Literal("is-optional", "?"));
|
|
12
|
+
const patternName = name.clone("pattern-name");
|
|
13
|
+
const patterns = new Options("and-patterns", [patternName, anonymousPattern]);
|
|
14
|
+
|
|
15
|
+
export const pattern = new Sequence("and-child-pattern", [
|
|
16
|
+
optionalNot,
|
|
17
|
+
patterns,
|
|
18
|
+
optionalIsOptional,
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const divider = new Regex("and-divider", "\\s*[+]\\s*");
|
|
22
|
+
divider.setTokens([" + "]);
|
|
23
|
+
|
|
24
|
+
export const sequenceLiteral = new Repeat("sequence-literal", pattern, { divider, min: 2, trimDivider: true });
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Options } from "../../patterns/Options";
|
|
2
2
|
import { Regex } from "../../patterns/Regex";
|
|
3
3
|
import { Repeat } from "../../patterns/Repeat";
|
|
4
4
|
|
|
5
5
|
export const tabs = new Regex("tabs", "\\t+");
|
|
6
|
-
|
|
7
|
-
export const newLine = new Regex("new-line", "(\\r?\\n)+");
|
|
6
|
+
tabs.setTokens(["\t"]);
|
|
8
7
|
|
|
8
|
+
export const spaces = new Regex("spaces", "[ ]+");
|
|
9
9
|
spaces.setTokens([" "]);
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
export const newLine = new Regex("new-line", "(\\r?\\n)+");
|
|
11
12
|
newLine.setTokens(["\n"]);
|
|
12
13
|
|
|
13
|
-
export const lineSpaces = new Repeat("line-spaces", new
|
|
14
|
-
export const allSpaces = new Regex("all-spaces", "\\s+"
|
|
14
|
+
export const lineSpaces = new Repeat("line-spaces", new Options("line-space", [tabs, spaces]));
|
|
15
|
+
export const allSpaces = new Regex("all-spaces", "\\s+");
|
|
16
|
+
allSpaces.setTokens([" "]);
|
|
@@ -1,33 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
2
2
|
import { Literal } from "../../patterns/Literal";
|
|
3
|
-
import {
|
|
4
|
-
import { andLiteral } from "./andLiteral";
|
|
3
|
+
import { Options } from "../../patterns/Options";
|
|
5
4
|
import { name } from "./name";
|
|
6
|
-
import { orLiteral } from "./orLiteral";
|
|
7
|
-
import { regexLiteral } from "./regexLiteral";
|
|
8
|
-
import { repeatLiteral } from "./repeatLiteral";
|
|
9
5
|
import { spaces } from "./spaces";
|
|
10
|
-
import {
|
|
6
|
+
import { pattern } from "./pattern";
|
|
7
|
+
import { Optional } from "../../patterns/Optional";
|
|
11
8
|
|
|
12
|
-
const optionalSpaces =
|
|
9
|
+
const optionalSpaces = new Optional("optional-spaces", spaces);
|
|
13
10
|
const assignOperator = new Literal("assign-operator", "=");
|
|
14
11
|
|
|
15
|
-
const
|
|
16
|
-
literal,
|
|
17
|
-
regexLiteral,
|
|
18
|
-
orLiteral,
|
|
19
|
-
andLiteral,
|
|
20
|
-
repeatLiteral,
|
|
21
|
-
name.clone("alias-literal"),
|
|
22
|
-
]);
|
|
23
|
-
|
|
24
|
-
const assignStatement = new And("assign-statement", [
|
|
12
|
+
const assignStatement = new Sequence("assign-statement", [
|
|
25
13
|
optionalSpaces,
|
|
26
14
|
name,
|
|
27
15
|
optionalSpaces,
|
|
28
16
|
assignOperator,
|
|
29
17
|
optionalSpaces,
|
|
30
|
-
|
|
18
|
+
pattern
|
|
31
19
|
]);
|
|
32
20
|
|
|
33
|
-
export const statement = new
|
|
21
|
+
export const statement = new Options("statement", [assignStatement, name.clone("export-name")]);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { patterns } from "./patterns";
|
|
2
|
+
|
|
3
|
+
describe("Patterns String Template Literal", ()=>{
|
|
4
|
+
test("Baseline", ()=>{
|
|
5
|
+
const {fullName} = patterns`
|
|
6
|
+
first-name = "John"
|
|
7
|
+
last-name = "Doe"
|
|
8
|
+
space = /\\s+/
|
|
9
|
+
full-name = first-name + space + last-name
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
const result = fullName.exec("John Doe");
|
|
13
|
+
expect(result?.ast?.value).toBe("John Doe");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("Simple Markup", ()=>{
|
|
17
|
+
const {body} = patterns`
|
|
18
|
+
tag-name = /[a-zA-Z_-]+[a-zA-Z0-9_-]*/
|
|
19
|
+
space = /\\s+/
|
|
20
|
+
opening-tag = "<" + tag-name + space? + ">"
|
|
21
|
+
closing-tag = "</" + tag-name + space? + ">"
|
|
22
|
+
child = space? + element + space?
|
|
23
|
+
children = (child)*
|
|
24
|
+
element = opening-tag + children + closing-tag
|
|
25
|
+
body = space? + element + space?
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
debugger;
|
|
29
|
+
const result = body.exec(`
|
|
30
|
+
<div>
|
|
31
|
+
<div></div>
|
|
32
|
+
<div></div>
|
|
33
|
+
</div>
|
|
34
|
+
`, true);
|
|
35
|
+
result && result.ast && result.ast.findAll(n=>n.name.includes("space")).forEach(n=>n.remove());
|
|
36
|
+
expect(result?.ast?.value).toBe("<div><div></div><div></div></div>");
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Pattern } from "../patterns/Pattern";
|
|
2
|
+
import { Grammar } from "./Grammar";
|
|
3
|
+
|
|
4
|
+
const kebabRegex = /-([a-z])/g; // Define the regex once
|
|
5
|
+
|
|
6
|
+
function kebabToCamelCase(str: string) {
|
|
7
|
+
return str.replace(kebabRegex, (_, char) => char.toUpperCase());
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function patterns(strings: TemplateStringsArray, ...values: any) {
|
|
11
|
+
const combinedString = strings.reduce(
|
|
12
|
+
(result, str, i) => result + str + (values[i] || ''),
|
|
13
|
+
''
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const result: Record<string, Pattern> = {};
|
|
17
|
+
const patterns = Grammar.parseString(combinedString);
|
|
18
|
+
|
|
19
|
+
Object.keys(patterns).forEach(k => {
|
|
20
|
+
result[kebabToCamelCase(k)] = patterns[k];
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return result;
|
|
24
|
+
}
|
package/src/grammar/spec.md
CHANGED
|
@@ -79,7 +79,7 @@ digits = (digit, comma)*
|
|
|
79
79
|
```
|
|
80
80
|
digit = /\d/
|
|
81
81
|
comma = ","
|
|
82
|
-
digits = (digit, comma)
|
|
82
|
+
digits = (digit, comma){t}
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
This is a useful feature if you don't want the divider to be the last pattern found. Let's look at the example below to understand.
|
|
@@ -88,7 +88,7 @@ This is a useful feature if you don't want the divider to be the last pattern fo
|
|
|
88
88
|
const expression = `
|
|
89
89
|
digit = /\d/
|
|
90
90
|
comma = ","
|
|
91
|
-
digits = (digit, comma)
|
|
91
|
+
digits = (digit, comma){t}
|
|
92
92
|
`;
|
|
93
93
|
|
|
94
94
|
const { digits } = Gammar.parse(expression);
|
|
@@ -100,20 +100,12 @@ result = digits.exec("1,2,");
|
|
|
100
100
|
expect(result.ast).toBeNull();
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
### Zero Or More
|
|
103
|
+
### Zero Or More
|
|
104
104
|
|
|
105
105
|
```
|
|
106
106
|
digit = /\d/
|
|
107
107
|
comma = ","
|
|
108
|
-
digits = (digit
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### One Or More With Optional Repeated Pattern
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
digit = /\d/
|
|
115
|
-
comma = ","
|
|
116
|
-
digits = (digit?, comma)+
|
|
108
|
+
digits = (digit, comma)*
|
|
117
109
|
```
|
|
118
110
|
|
|
119
111
|
### Upper Limit
|
package/src/index.ts
CHANGED
|
@@ -5,10 +5,11 @@ import { SuggestionOption } from "./intellisense/SuggestionOption";
|
|
|
5
5
|
import { AutoComplete, AutoCompleteOptions } from './intellisense/AutoComplete';
|
|
6
6
|
import { Cursor } from "./patterns/Cursor";
|
|
7
7
|
import { Regex } from "./patterns/Regex";
|
|
8
|
-
import {
|
|
8
|
+
import { Sequence } from "./patterns/Sequence";
|
|
9
9
|
import { Literal } from "./patterns/Literal";
|
|
10
10
|
import { Not } from "./patterns/Not";
|
|
11
|
-
import {
|
|
11
|
+
import { Options } from "./patterns/Options";
|
|
12
|
+
import { Optional } from "./patterns/Optional";
|
|
12
13
|
import { Repeat } from "./patterns/Repeat";
|
|
13
14
|
import { ParseError } from "./patterns/ParseError";
|
|
14
15
|
import { Pattern } from "./patterns/Pattern";
|
|
@@ -16,6 +17,8 @@ import { Reference } from "./patterns/Reference";
|
|
|
16
17
|
import { CursorHistory, Match } from "./patterns/CursorHistory";
|
|
17
18
|
import { ParseResult } from "./patterns/ParseResult";
|
|
18
19
|
import { grammar } from "./grammar/patterns/grammar";
|
|
20
|
+
import { arePatternsEqual } from "./patterns/arePatternsEqual";
|
|
21
|
+
import { patterns } from "./grammar/patterns";
|
|
19
22
|
|
|
20
23
|
export {
|
|
21
24
|
Node,
|
|
@@ -24,18 +27,21 @@ export {
|
|
|
24
27
|
AutoCompleteOptions,
|
|
25
28
|
Suggestion,
|
|
26
29
|
SuggestionOption,
|
|
27
|
-
|
|
30
|
+
Sequence,
|
|
28
31
|
Cursor,
|
|
29
32
|
CursorHistory,
|
|
30
33
|
Match,
|
|
31
34
|
Literal,
|
|
32
35
|
Not,
|
|
33
|
-
|
|
36
|
+
Options,
|
|
37
|
+
Optional,
|
|
34
38
|
ParseError,
|
|
35
39
|
ParseResult,
|
|
36
40
|
Pattern,
|
|
37
41
|
Reference,
|
|
38
42
|
Regex,
|
|
39
43
|
Repeat,
|
|
40
|
-
grammar
|
|
44
|
+
grammar,
|
|
45
|
+
arePatternsEqual,
|
|
46
|
+
patterns,
|
|
41
47
|
};
|