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,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
2
2
|
import { Literal } from "../../patterns/Literal";
|
|
3
3
|
import { Regex } from "../../patterns/Regex";
|
|
4
4
|
|
|
5
5
|
const period = new Literal("period", ".");
|
|
6
6
|
const digit = new Regex("digit", "\\d+");
|
|
7
|
-
const fraction = new
|
|
7
|
+
const fraction = new Sequence("fraction", [period, digit]);
|
|
8
8
|
|
|
9
9
|
export {
|
|
10
10
|
fraction
|
|
11
|
-
}
|
|
11
|
+
};
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { Literal } from "../../patterns/Literal"
|
|
2
|
-
import {
|
|
1
|
+
import { Literal } from "../../patterns/Literal";
|
|
2
|
+
import { Options } from "../../patterns/Options";
|
|
3
3
|
|
|
4
4
|
const multiply = new Literal("multiply", "*");
|
|
5
5
|
const divide = new Literal("divide", "/");
|
|
6
6
|
const remainder = new Literal("remainder", "%");
|
|
7
7
|
const add = new Literal("add", "+");
|
|
8
8
|
const subtract = new Literal("subtract", "-");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const greaterOptionsEqual = new Literal("greater-or-equal", ">=");
|
|
10
|
+
const lessOptionsEqual = new Literal("less-or-equal", "<=");
|
|
11
11
|
const greater = new Literal("greater", ">");
|
|
12
12
|
const less = new Literal("less", "<");
|
|
13
13
|
const equal = new Literal("equal", "==");
|
|
14
14
|
const notEqual = new Literal("not-equal", "!=");
|
|
15
15
|
const strictEqual = new Literal("strict-equal", "===");
|
|
16
16
|
const strictNotEqual = new Literal("strict-not-equal", "!==");
|
|
17
|
-
const
|
|
17
|
+
const logicalOptions = new Literal("logical-or", "||");
|
|
18
18
|
const logicalAnd = new Literal("logical-and", "&&");
|
|
19
19
|
|
|
20
|
-
const infixOperator = new
|
|
20
|
+
const infixOperator = new Options("infix-operator", [
|
|
21
21
|
multiply,
|
|
22
22
|
divide,
|
|
23
23
|
remainder,
|
|
24
24
|
add,
|
|
25
25
|
subtract,
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
greaterOptionsEqual,
|
|
27
|
+
lessOptionsEqual,
|
|
28
28
|
greater,
|
|
29
29
|
less,
|
|
30
30
|
strictEqual,
|
|
31
31
|
strictNotEqual,
|
|
32
32
|
equal,
|
|
33
33
|
notEqual,
|
|
34
|
-
|
|
34
|
+
logicalOptions,
|
|
35
35
|
logicalAnd
|
|
36
36
|
]);
|
|
37
37
|
|
|
38
|
-
export { infixOperator }
|
|
38
|
+
export { infixOperator };
|
|
39
39
|
|
|
40
40
|
|
|
@@ -1,28 +1,29 @@
|
|
|
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 { Reference } from "../../patterns/Reference";
|
|
5
5
|
import { Regex } from "../../patterns/Regex";
|
|
6
6
|
import { Repeat } from "../../patterns/Repeat";
|
|
7
7
|
import { optionalSpaces } from "./optionalSpaces";
|
|
8
|
+
import { Optional } from "../../patterns/Optional";
|
|
8
9
|
|
|
9
10
|
const divider = new Regex("invocation-divider", "\\s*,\\s*");
|
|
10
11
|
|
|
11
|
-
const invocationWithArguments = new
|
|
12
|
+
const invocationWithArguments = new Sequence("invocation-with-arguments", [
|
|
12
13
|
new Literal("open-paren", "("),
|
|
13
14
|
optionalSpaces,
|
|
14
|
-
new Repeat("expressions", new Reference("expression"), { divider
|
|
15
|
+
new Optional("optional-expression", new Repeat("expressions", new Reference("expression"), { divider })),
|
|
15
16
|
optionalSpaces,
|
|
16
17
|
new Literal("close-paren", ")"),
|
|
17
18
|
]);
|
|
18
19
|
|
|
19
|
-
const emptyInvocation = new
|
|
20
|
+
const emptyInvocation = new Sequence("empty-invocation", [
|
|
20
21
|
new Literal("open-paren", "("),
|
|
21
22
|
optionalSpaces,
|
|
22
23
|
new Literal("close-paren", ")"),
|
|
23
24
|
]);
|
|
24
25
|
|
|
25
|
-
export const invocation = new
|
|
26
|
+
export const invocation = new Options("invocation", [
|
|
26
27
|
emptyInvocation,
|
|
27
28
|
invocationWithArguments
|
|
28
|
-
])
|
|
29
|
+
]);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Options } from "../../patterns/Options";
|
|
2
2
|
import { arrayLiteral } from "./arrayLiteral";
|
|
3
3
|
import { numberLiteral } from "./numberLiteral";
|
|
4
4
|
import { objectLiteral } from "./objectLiteral";
|
|
5
5
|
import { stringLiteral } from "./stringLiteral";
|
|
6
6
|
|
|
7
|
-
const literal = new
|
|
7
|
+
const literal = new Options("literal", [
|
|
8
8
|
numberLiteral,
|
|
9
9
|
stringLiteral,
|
|
10
10
|
arrayLiteral,
|
|
11
11
|
objectLiteral,
|
|
12
12
|
]);
|
|
13
13
|
|
|
14
|
-
export { literal }
|
|
14
|
+
export { literal };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Optional } from "../../patterns/Optional";
|
|
2
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
2
3
|
import { exponent } from "./exponent";
|
|
3
4
|
import { fraction } from "./fraction";
|
|
4
5
|
import { integer } from "./integer";
|
|
5
6
|
|
|
6
|
-
export const numberLiteral = new
|
|
7
|
+
export const numberLiteral = new Sequence("number-literal", [
|
|
7
8
|
integer,
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
new Optional("number-fraction", fraction),
|
|
10
|
+
new Optional("number-exponent", exponent)
|
|
10
11
|
]);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Reference } from "../../patterns/Reference";
|
|
1
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
3
2
|
import { name } from "./name";
|
|
4
3
|
import { propertyAccess } from "./propertyAccess";
|
|
5
4
|
|
|
6
|
-
export const objectAccess = new
|
|
5
|
+
export const objectAccess = new Sequence("object-access", [
|
|
7
6
|
name.clone("variable-name"),
|
|
8
7
|
propertyAccess,
|
|
9
8
|
]);
|
|
@@ -1,15 +1,16 @@
|
|
|
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 { Reference } from "../../patterns/Reference";
|
|
5
5
|
import { Regex } from "../../patterns/Regex";
|
|
6
6
|
import { Repeat } from "../../patterns/Repeat";
|
|
7
7
|
import { name } from "./name";
|
|
8
8
|
import { optionalSpaces } from "./optionalSpaces";
|
|
9
9
|
import { stringLiteral } from "./stringLiteral";
|
|
10
|
+
import { Optional } from "../../patterns/Optional";
|
|
10
11
|
|
|
11
|
-
const propertyName = new
|
|
12
|
-
const property = new
|
|
12
|
+
const propertyName = new Options("property-name", [stringLiteral.clone("object-property"), name.clone("object-property")]);
|
|
13
|
+
const property = new Sequence("property", [
|
|
13
14
|
propertyName,
|
|
14
15
|
optionalSpaces,
|
|
15
16
|
new Literal("colon", ":"),
|
|
@@ -17,9 +18,9 @@ const property = new And("property", [
|
|
|
17
18
|
new Reference("expression"),
|
|
18
19
|
]);
|
|
19
20
|
const divider = new Regex("property-divider", "\\s*,\\s*");
|
|
20
|
-
const optionalProperties = new Repeat("properties", property, { divider
|
|
21
|
+
const optionalProperties = new Optional("optional-properties", new Repeat("properties", property, { divider}));
|
|
21
22
|
|
|
22
|
-
const objectLiteral = new
|
|
23
|
+
const objectLiteral = new Sequence("object-literal", [
|
|
23
24
|
new Literal("open-curly-bracket", "{"),
|
|
24
25
|
optionalSpaces,
|
|
25
26
|
optionalProperties,
|
|
@@ -27,4 +28,4 @@ const objectLiteral = new And("object-literal", [
|
|
|
27
28
|
new Literal("close-curly-bracket", "}"),
|
|
28
29
|
]);
|
|
29
30
|
|
|
30
|
-
export { objectLiteral }
|
|
31
|
+
export { objectLiteral };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Optional } from "../../patterns/Optional";
|
|
1
2
|
import { Regex } from "../../patterns/Regex";
|
|
2
3
|
|
|
3
|
-
export const optionalSpaces = new Regex("optional-spaces", "\\s+"
|
|
4
|
+
export const optionalSpaces = new Optional("optional-spaces", new Regex("optional-spaces", "\\s+"));
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Sequence } from "../../patterns/Sequence";
|
|
2
2
|
import { Literal } from "../../patterns/Literal";
|
|
3
3
|
import { Regex } from "../../patterns/Regex";
|
|
4
4
|
import { Repeat } from "../../patterns/Repeat";
|
|
5
5
|
import { name } from "./name";
|
|
6
|
+
import { optionalSpaces } from "./optionalSpaces";
|
|
6
7
|
|
|
7
8
|
const divider = new Regex(",", "\\s*[,]\\s*");
|
|
8
9
|
divider.setTokens([", "]);
|
|
9
10
|
|
|
10
|
-
const optionalSpace = new Regex("optional-space", "\\s", true)
|
|
11
11
|
|
|
12
|
-
const parameters = new
|
|
12
|
+
const parameters = new Sequence("parameters", [
|
|
13
13
|
new Literal("open-paren", "("),
|
|
14
|
-
|
|
14
|
+
optionalSpaces,
|
|
15
15
|
new Repeat("arguments", name, { divider, trimDivider: true }),
|
|
16
|
-
|
|
16
|
+
optionalSpaces,
|
|
17
17
|
new Literal("close-paren", ")"),
|
|
18
18
|
]);
|
|
19
19
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { Literal } from "../../patterns/Literal";
|
|
2
|
-
import {
|
|
3
|
-
import { Regex } from "../../patterns/Regex";
|
|
2
|
+
import { Options } from "../../patterns/Options";
|
|
4
3
|
|
|
5
|
-
const prefixOperator = new
|
|
4
|
+
const prefixOperator = new Options("prefix-operator", [
|
|
6
5
|
new Literal("typeof", "typeof "),
|
|
7
6
|
new Literal("to-number", "+"),
|
|
8
7
|
new Literal("negate", "-"),
|
|
9
8
|
new Literal("logical-not", "!"),
|
|
10
9
|
]);
|
|
11
10
|
|
|
12
|
-
export { prefixOperator }
|
|
11
|
+
export { prefixOperator };
|
|
13
12
|
|
|
@@ -1,28 +1,29 @@
|
|
|
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 { Reference } from "../../patterns/Reference";
|
|
5
5
|
import { name } from "./name";
|
|
6
|
+
import { Optional } from "../../patterns/Optional";
|
|
6
7
|
|
|
7
|
-
const dotPropertyAccess = new
|
|
8
|
+
const dotPropertyAccess = new Sequence("dot-property-access", [
|
|
8
9
|
new Literal("period", "."),
|
|
9
10
|
name.clone("property-name")
|
|
10
11
|
]);
|
|
11
12
|
|
|
12
|
-
const bracketPropertyAccess = new
|
|
13
|
+
const bracketPropertyAccess = new Sequence("bracket-property-access", [
|
|
13
14
|
new Literal("open-square-bracket", "["),
|
|
14
15
|
new Reference("expression"),
|
|
15
16
|
new Literal("close-square-bracket", "]"),
|
|
16
17
|
]);
|
|
17
18
|
|
|
18
|
-
const propertyAccessTypes = new
|
|
19
|
+
const propertyAccessTypes = new Options("property-access-types", [
|
|
19
20
|
dotPropertyAccess,
|
|
20
21
|
bracketPropertyAccess
|
|
21
22
|
]);
|
|
22
23
|
|
|
23
|
-
const propertyAccess = new
|
|
24
|
+
const propertyAccess = new Sequence("property-access", [
|
|
24
25
|
propertyAccessTypes,
|
|
25
|
-
new
|
|
26
|
+
new Optional("optional-property-access", new Reference("property-access"))
|
|
26
27
|
]);
|
|
27
28
|
|
|
28
|
-
export { propertyAccess }
|
|
29
|
+
export { propertyAccess };
|
|
@@ -1,34 +1,33 @@
|
|
|
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
5
|
import { Repeat } from "../../patterns/Repeat";
|
|
6
6
|
import { escapedCharacter } from "./escapedCharacter";
|
|
7
|
+
import { Optional } from "../../patterns/Optional";
|
|
7
8
|
|
|
8
|
-
const doubleQuoteStringLiteral = new
|
|
9
|
+
const doubleQuoteStringLiteral = new Sequence("double-string-literal", [
|
|
9
10
|
new Literal("double-quote", "\""),
|
|
10
|
-
new Repeat("characters",
|
|
11
|
-
new
|
|
11
|
+
new Optional("optional-characters", new Repeat("characters",
|
|
12
|
+
new Options("characters", [
|
|
12
13
|
new Regex("normal-characters", "[^\\\"]+"),
|
|
13
14
|
escapedCharacter
|
|
14
|
-
])
|
|
15
|
-
|
|
16
|
-
),
|
|
15
|
+
])
|
|
16
|
+
)),
|
|
17
17
|
new Literal("double-quote", "\""),
|
|
18
18
|
]);
|
|
19
19
|
|
|
20
|
-
const singleQuoteStringLiteral = new
|
|
20
|
+
const singleQuoteStringLiteral = new Sequence("single-string-literal", [
|
|
21
21
|
new Literal("single-quote", "'"),
|
|
22
|
-
new Repeat("characters",
|
|
23
|
-
new
|
|
22
|
+
new Optional("optional-characters", new Repeat("characters",
|
|
23
|
+
new Options("characters", [
|
|
24
24
|
new Regex("normal-characters", "[^\\']+"),
|
|
25
25
|
escapedCharacter
|
|
26
26
|
]),
|
|
27
|
-
|
|
28
|
-
),
|
|
27
|
+
)),
|
|
29
28
|
new Literal("single-quote", "'"),
|
|
30
29
|
]);
|
|
31
30
|
|
|
32
|
-
const stringLiteral = new
|
|
31
|
+
const stringLiteral = new Options("string-literal", [doubleQuoteStringLiteral, singleQuoteStringLiteral]);
|
|
33
32
|
|
|
34
|
-
export { stringLiteral }
|
|
33
|
+
export { stringLiteral };
|
package/src/patterns/Cursor.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node } from "../ast/Node";
|
|
2
|
-
import { CursorHistory, Match } from "./CursorHistory";
|
|
2
|
+
import { CursorHistory, Match, Trace } from "./CursorHistory";
|
|
3
3
|
import { ParseError } from "./ParseError";
|
|
4
4
|
import { Pattern } from "./Pattern";
|
|
5
5
|
|
|
@@ -8,6 +8,7 @@ export class Cursor {
|
|
|
8
8
|
private _index: number;
|
|
9
9
|
private _length: number;
|
|
10
10
|
private _history: CursorHistory;
|
|
11
|
+
private _stackTrace: Trace[];
|
|
11
12
|
|
|
12
13
|
get text(): string {
|
|
13
14
|
return this._text;
|
|
@@ -66,11 +67,11 @@ export class Cursor {
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
get hasError(): boolean {
|
|
69
|
-
return this._history.error != null
|
|
70
|
+
return this._history.error != null;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
get currentChar(): string {
|
|
73
|
-
return this._text[this._index]
|
|
74
|
+
return this._text[this._index];
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
constructor(text: string) {
|
|
@@ -78,6 +79,7 @@ export class Cursor {
|
|
|
78
79
|
this._index = 0;
|
|
79
80
|
this._length = text.length;
|
|
80
81
|
this._history = new CursorHistory();
|
|
82
|
+
this._stackTrace = [];
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
hasNext(): boolean {
|
|
@@ -131,7 +133,7 @@ export class Cursor {
|
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
resolveError(): void {
|
|
134
|
-
this._history.resolveError()
|
|
136
|
+
this._history.resolveError();
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
startRecording(): void {
|
|
@@ -142,4 +144,40 @@ export class Cursor {
|
|
|
142
144
|
this._history.stopRecording();
|
|
143
145
|
}
|
|
144
146
|
|
|
147
|
+
startParseWith(pattern: Pattern) {
|
|
148
|
+
const patternName = pattern.name;
|
|
149
|
+
|
|
150
|
+
const trace = {
|
|
151
|
+
pattern,
|
|
152
|
+
cursorIndex: this.index
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
if (this._stackTrace.find(t => t.pattern.id === pattern.id && this.index === t.cursorIndex)) {
|
|
156
|
+
throw new Error(`Cyclical Pattern: ${this._stackTrace.map(t => `${t.pattern.name}#${t.pattern.id}{${t.cursorIndex}}`).join(" -> ")} -> ${patternName}#${pattern.id}{${this.index}}.`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
this._history.pushStackTrace(trace);
|
|
160
|
+
this._stackTrace.push(trace);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
endParse() {
|
|
164
|
+
this._stackTrace.pop();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
audit() {
|
|
168
|
+
return this._history.trace.map(t => {
|
|
169
|
+
const onChar = this.getChars(t.cursorIndex, t.cursorIndex);
|
|
170
|
+
const restChars = this.getChars(t.cursorIndex + 1, t.cursorIndex + 5);
|
|
171
|
+
const context = `{${t.cursorIndex}}[${onChar}]${restChars}`;
|
|
172
|
+
return `${this._buildPatternContext(t.pattern)}-->${context}`;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private _buildPatternContext(pattern: Pattern) {
|
|
177
|
+
if (pattern.parent != null) {
|
|
178
|
+
return `${pattern.parent.name}.${pattern.name}`;
|
|
179
|
+
}
|
|
180
|
+
return pattern.name;
|
|
181
|
+
}
|
|
182
|
+
|
|
145
183
|
}
|
|
@@ -2,6 +2,11 @@ import { Node } from "../ast/Node";
|
|
|
2
2
|
import { ParseError } from "./ParseError";
|
|
3
3
|
import { Pattern } from "./Pattern";
|
|
4
4
|
|
|
5
|
+
export interface Trace {
|
|
6
|
+
pattern: Pattern;
|
|
7
|
+
cursorIndex: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
export interface Match {
|
|
6
11
|
pattern: Pattern | null;
|
|
7
12
|
node: Node | null;
|
|
@@ -16,6 +21,7 @@ export class CursorHistory {
|
|
|
16
21
|
private _patterns: Pattern[] = [];
|
|
17
22
|
private _nodes: Node[] = [];
|
|
18
23
|
private _errors: ParseError[] = [];
|
|
24
|
+
private _trace: Trace[] = [];
|
|
19
25
|
|
|
20
26
|
get isRecording(): boolean {
|
|
21
27
|
return this._isRecording;
|
|
@@ -42,7 +48,7 @@ export class CursorHistory {
|
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
get error(): ParseError | null {
|
|
45
|
-
return this._currentError
|
|
51
|
+
return this._currentError;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
get nodes(): Node[] {
|
|
@@ -53,6 +59,10 @@ export class CursorHistory {
|
|
|
53
59
|
return this._patterns;
|
|
54
60
|
}
|
|
55
61
|
|
|
62
|
+
get trace(): Trace[] {
|
|
63
|
+
return this._trace;
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
recordMatch(pattern: Pattern, node: Node): void {
|
|
57
67
|
if (this._isRecording) {
|
|
58
68
|
this._patterns.push(pattern);
|
|
@@ -67,7 +77,7 @@ export class CursorHistory {
|
|
|
67
77
|
leafMatch.node === null || node.lastIndex > leafMatch.node.lastIndex;
|
|
68
78
|
|
|
69
79
|
const isSameIndexMatch =
|
|
70
|
-
leafMatch.node === null || node.lastIndex === leafMatch.node.lastIndex
|
|
80
|
+
leafMatch.node === null || node.lastIndex === leafMatch.node.lastIndex;
|
|
71
81
|
|
|
72
82
|
if (isFurthestMatch) {
|
|
73
83
|
// This is to save on GC churn.
|
|
@@ -85,10 +95,10 @@ export class CursorHistory {
|
|
|
85
95
|
if (parent === pattern.parent) {
|
|
86
96
|
return true;
|
|
87
97
|
}
|
|
88
|
-
parent = parent.parent
|
|
98
|
+
parent = parent.parent;
|
|
89
99
|
}
|
|
90
100
|
return false;
|
|
91
|
-
})
|
|
101
|
+
});
|
|
92
102
|
|
|
93
103
|
if (!isAncestor) {
|
|
94
104
|
this._leafMatches.unshift({ pattern, node });
|
|
@@ -121,4 +131,10 @@ export class CursorHistory {
|
|
|
121
131
|
this._currentError = null;
|
|
122
132
|
}
|
|
123
133
|
|
|
134
|
+
pushStackTrace(trace: Trace) {
|
|
135
|
+
if (this._isRecording) {
|
|
136
|
+
this._trace.push(trace);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
}
|