occam-dom 4.0.15 → 5.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/bin/main.js +15 -0
- package/example.js +37842 -0
- package/index.html +47 -0
- package/lib/constants.js +13 -0
- package/lib/example/utilities/token.js +28 -0
- package/lib/example/view/div/sizeable.js +39 -0
- package/lib/example/view/input/expressionString.js +142 -0
- package/lib/example/view/input/maximumDepth.js +143 -0
- package/lib/example/view/input.js +39 -0
- package/lib/example/view/subHeading.js +39 -0
- package/lib/example/view/textarea/content.js +142 -0
- package/lib/example/view/textarea/nodes.js +155 -0
- package/lib/example/view/textarea/parseTree.js +166 -0
- package/lib/example/view/textarea.js +39 -0
- package/lib/example/view.js +239 -0
- package/lib/example.js +19 -0
- package/lib/expression/bnf.js +14 -0
- package/lib/expression/entries.js +27 -0
- package/lib/expression/lexer.js +145 -0
- package/lib/expression/parser.js +134 -0
- package/lib/expression.js +113 -0
- package/lib/index.js +39 -0
- package/lib/path.js +69 -0
- package/lib/query.js +216 -0
- package/lib/ruleNames.js +54 -0
- package/lib/spread.js +113 -0
- package/lib/subExpression.js +101 -0
- package/lib/utilities/array.js +67 -0
- package/lib/utilities/node.js +334 -0
- package/lib/utilities/query.js +39 -0
- package/package.json +3 -3
- package/src/constants.js +3 -0
- package/src/example/utilities/token.js +19 -0
- package/src/example/view/div/sizeable.js +12 -0
- package/src/example/view/input/expressionString.js +33 -0
- package/src/example/view/input/maximumDepth.js +35 -0
- package/src/example/view/input.js +14 -0
- package/src/example/view/subHeading.js +16 -0
- package/src/example/view/textarea/content.js +33 -0
- package/src/example/view/textarea/nodes.js +55 -0
- package/src/example/view/textarea/parseTree.js +46 -0
- package/src/example/view/textarea.js +18 -0
- package/src/example/view.js +125 -0
- package/src/example.js +21 -0
- package/src/expression/bnf.js +63 -0
- package/src/expression/entries.js +18 -0
- package/src/expression/lexer.js +35 -0
- package/src/expression/parser.js +15 -0
- package/src/expression.js +82 -0
- package/src/index.js +7 -0
- package/src/path.js +32 -0
- package/src/query.js +207 -0
- package/src/ruleNames.js +12 -0
- package/src/spread.js +104 -0
- package/src/subExpression.js +52 -0
- package/src/utilities/array.js +30 -0
- package/src/utilities/node.js +454 -0
- package/src/utilities/query.js +22 -0
package/src/query.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { characters } from "necessary";
|
|
4
|
+
|
|
5
|
+
import Expression from "./expression";
|
|
6
|
+
|
|
7
|
+
import { push, clear, includes } from "./utilities/array";
|
|
8
|
+
|
|
9
|
+
const { WILDCARD_CHARACTER } = characters;
|
|
10
|
+
|
|
11
|
+
export default class Query {
|
|
12
|
+
constructor(spread, subQuery, ruleNames, tokenTypes, maximumDepth, infiniteDescent, intermediateNodes) {
|
|
13
|
+
this.spread = spread;
|
|
14
|
+
this.subQuery = subQuery;
|
|
15
|
+
this.ruleNames = ruleNames;
|
|
16
|
+
this.tokenTypes = tokenTypes;
|
|
17
|
+
this.maximumDepth = maximumDepth;
|
|
18
|
+
this.infiniteDescent = infiniteDescent;
|
|
19
|
+
this.intermediateNodes = intermediateNodes;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getSpread() {
|
|
23
|
+
return this.sprea;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getSubQuery() {
|
|
27
|
+
return this.subQuery;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getRuleNames() {
|
|
31
|
+
return this.ruleNames;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
getTokenTypes() {
|
|
35
|
+
return this.tokenTypes;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getMaximumDepth() {
|
|
39
|
+
return this.maximumDepth;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
isInfiniteDescent() {
|
|
43
|
+
return this.infiniteDescent;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getIntermediateNodes() {
|
|
47
|
+
return this.intermediateNodes;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
execute(node, depth = 0, maximumDepth = this.maximumDepth) {
|
|
51
|
+
const nodes = [];
|
|
52
|
+
|
|
53
|
+
this.clear();
|
|
54
|
+
|
|
55
|
+
this.find(node, depth, maximumDepth);
|
|
56
|
+
|
|
57
|
+
this.apply(nodes, depth, maximumDepth);
|
|
58
|
+
|
|
59
|
+
return nodes;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
clear() {
|
|
63
|
+
clear(this.intermediateNodes);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
find(node, depth, maximumDepth) {
|
|
67
|
+
if (depth > maximumDepth) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const nodeTerminalNode = node.isTerminalNode(),
|
|
72
|
+
nodeNonTerminalNode = !nodeTerminalNode;
|
|
73
|
+
|
|
74
|
+
let found;
|
|
75
|
+
|
|
76
|
+
if (nodeTerminalNode) {
|
|
77
|
+
const terminalNode = node, ///
|
|
78
|
+
types = this.tokenTypes, ///
|
|
79
|
+
type = terminalNode.getType();
|
|
80
|
+
|
|
81
|
+
found = includes(types, type, WILDCARD_CHARACTER);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (nodeNonTerminalNode) {
|
|
85
|
+
const nonTerminalNode = node, ///
|
|
86
|
+
ruleName = nonTerminalNode.getRuleName();
|
|
87
|
+
|
|
88
|
+
found = includes(this.ruleNames, ruleName, WILDCARD_CHARACTER);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (found) {
|
|
92
|
+
const intermediateNode = node; ///
|
|
93
|
+
|
|
94
|
+
this.intermediateNodes.push(intermediateNode);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (this.infiniteDescent) {
|
|
98
|
+
if (nodeNonTerminalNode) {
|
|
99
|
+
depth++;
|
|
100
|
+
|
|
101
|
+
const nonTerminalNode = node; ///
|
|
102
|
+
|
|
103
|
+
nonTerminalNode.forEachChildNode((childNode) => {
|
|
104
|
+
this.find(childNode, depth, maximumDepth);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
apply(nodes, depth, maximumDepth) {
|
|
111
|
+
this.spread.adjustNodes(this.intermediateNodes);
|
|
112
|
+
|
|
113
|
+
if (this.subQuery === null) {
|
|
114
|
+
push(nodes, this.intermediateNodes);
|
|
115
|
+
} else {
|
|
116
|
+
this.intermediateNodes.forEach((intermediateNode) => {
|
|
117
|
+
const intermediateNodeNonTerminalNode = intermediateNode.isNonTerminalNode();
|
|
118
|
+
|
|
119
|
+
if (intermediateNodeNonTerminalNode) {
|
|
120
|
+
depth++;
|
|
121
|
+
|
|
122
|
+
const nonTerminalNode = intermediateNode; ///
|
|
123
|
+
|
|
124
|
+
this.subQuery.clear();
|
|
125
|
+
|
|
126
|
+
nonTerminalNode.forEachChildNode((childNode) => {
|
|
127
|
+
this.subQuery.find(childNode, depth, maximumDepth);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
this.subQuery.apply(nodes, depth, maximumDepth);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static fromExpression(expression, maximumDepth = Infinity) {
|
|
137
|
+
const spread = expression.getSpread(),
|
|
138
|
+
subQuery = subQueryFromExpression(expression),
|
|
139
|
+
ruleNames = expression.getRuleNames(),
|
|
140
|
+
tokenTypes = expression.getTokenTypes(),
|
|
141
|
+
infiniteDescent = expression.isInfiniteDescent(),
|
|
142
|
+
intermediateNodes = [],
|
|
143
|
+
query = new Query(spread, subQuery, ruleNames, tokenTypes, maximumDepth, infiniteDescent, intermediateNodes);
|
|
144
|
+
|
|
145
|
+
return query;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
static fromSubExpression(subExpression) {
|
|
149
|
+
const spread = subExpression.getSpread(),
|
|
150
|
+
subQuery = subQueryFromSubExpression(subExpression),
|
|
151
|
+
ruleNames = subExpression.getRuleNames(),
|
|
152
|
+
tokenTypes = subExpression.getTokenTypes(),
|
|
153
|
+
maximumDepth = Infinity,
|
|
154
|
+
infiniteDescent = subExpression.isInfiniteDescent(),
|
|
155
|
+
intermediateNodes = [],
|
|
156
|
+
query = new Query(spread, subQuery, ruleNames, tokenTypes, maximumDepth, infiniteDescent, intermediateNodes);
|
|
157
|
+
|
|
158
|
+
return query;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static fromExpressionString(expressionString, maximumDepth = Infinity) {
|
|
162
|
+
let query = null;
|
|
163
|
+
|
|
164
|
+
const expression = Expression.fromExpressionString(expressionString);
|
|
165
|
+
|
|
166
|
+
if (expression !== null) {
|
|
167
|
+
const spread = expression.getSpread(),
|
|
168
|
+
subQuery = subQueryFromExpression(expression),
|
|
169
|
+
ruleNames = expression.getRuleNames(),
|
|
170
|
+
tokenTypes = expression.getTokenTypes(),
|
|
171
|
+
infiniteDescent = expression.isInfiniteDescent(),
|
|
172
|
+
intermediateNodes = [];
|
|
173
|
+
|
|
174
|
+
query = new Query(spread, subQuery, ruleNames, tokenTypes, maximumDepth, infiniteDescent, intermediateNodes);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return query;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function subQueryFromExpression(expression) {
|
|
182
|
+
let subQuery = null;
|
|
183
|
+
|
|
184
|
+
const subExpression = expression.getSubExpression();
|
|
185
|
+
|
|
186
|
+
if (subExpression !== null) {
|
|
187
|
+
const query = Query.fromSubExpression(subExpression);
|
|
188
|
+
|
|
189
|
+
subQuery = query; ///
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return subQuery;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function subQueryFromSubExpression(subExpression) {
|
|
196
|
+
let subQuery = null;
|
|
197
|
+
|
|
198
|
+
subExpression = subExpression.getSubExpression(); ///
|
|
199
|
+
|
|
200
|
+
if (subExpression !== null) {
|
|
201
|
+
const query = Query.fromSubExpression(subExpression);
|
|
202
|
+
|
|
203
|
+
subQuery = query; ///
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return subQuery;
|
|
207
|
+
}
|
package/src/ruleNames.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export const ERROR_RULE_NAME = "error";
|
|
4
|
+
export const INDEX_RULE_NAME = "index";
|
|
5
|
+
export const UNIQUE_RULE_NAME = "unique";
|
|
6
|
+
export const SPREAD_RULE_NAME = "spread";
|
|
7
|
+
export const END_INDEX_RULE_NAME = "endIndex";
|
|
8
|
+
export const RULE_NAME_RULE_NAME = "ruleName";
|
|
9
|
+
export const TOKEN_TYPE_RULE_NAME = "tokenType";
|
|
10
|
+
export const START_INDEX_RULE_NAME = "startIndex";
|
|
11
|
+
export const SUB_EXPRESSION_RULE_NAME = "subExpression";
|
|
12
|
+
export const INFINITE_DESCENT_RULE_NAME = "infiniteDescent";
|
package/src/spread.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { characters } from "necessary";
|
|
4
|
+
|
|
5
|
+
import { clear, trim, second, third, fourth } from "./utilities/array";
|
|
6
|
+
import { indexFromSpreadNode,
|
|
7
|
+
uniqueFromSpreadNode,
|
|
8
|
+
endIndexFromSpreadNode,
|
|
9
|
+
startIndexFromSpreadNode } from "./utilities/node";
|
|
10
|
+
|
|
11
|
+
const { EXCLAMATION_MARK_CHARACTER } = characters;
|
|
12
|
+
|
|
13
|
+
export default class Spread {
|
|
14
|
+
constructor(startIndex, endIndex, unique) {
|
|
15
|
+
this.startIndex = startIndex;
|
|
16
|
+
this.endIndex = endIndex;
|
|
17
|
+
this.unique = unique;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
adjustNodes(nodes) {
|
|
21
|
+
if (this.unique) {
|
|
22
|
+
const nodesLength = nodes.length;
|
|
23
|
+
|
|
24
|
+
if (nodesLength > 1) {
|
|
25
|
+
clear(nodes);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
trim(nodes, this.startIndex, this.endIndex);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static fromNothing() {
|
|
33
|
+
const startIndex = 0,
|
|
34
|
+
endIndex = Infinity,
|
|
35
|
+
unique = false,
|
|
36
|
+
spread = new Spread(startIndex, endIndex, unique);
|
|
37
|
+
|
|
38
|
+
return spread;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static fromSpreadNode(spreadNode) {
|
|
42
|
+
let startIndex = 0,
|
|
43
|
+
endIndex = Infinity,
|
|
44
|
+
unique = false;
|
|
45
|
+
|
|
46
|
+
if (spreadNode !== null) {
|
|
47
|
+
const index = indexFromSpreadNode(spreadNode);
|
|
48
|
+
|
|
49
|
+
if (index !== null) {
|
|
50
|
+
startIndex = index; ///
|
|
51
|
+
|
|
52
|
+
endIndex = index; ///
|
|
53
|
+
} else {
|
|
54
|
+
startIndex = startIndexFromSpreadNode(spreadNode);
|
|
55
|
+
|
|
56
|
+
endIndex = endIndexFromSpreadNode(spreadNode);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
unique = uniqueFromSpreadNode(spreadNode);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const spread = new Spread(startIndex, endIndex, unique);
|
|
63
|
+
|
|
64
|
+
return spread;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static fromSpreadExpression(spreadExpression) {
|
|
68
|
+
let startIndex = 0,
|
|
69
|
+
endIndex = Infinity,
|
|
70
|
+
unique = false;
|
|
71
|
+
|
|
72
|
+
if (spreadExpression !== null) {
|
|
73
|
+
if (spreadExpression === EXCLAMATION_MARK_CHARACTER) {
|
|
74
|
+
unique = true;
|
|
75
|
+
} else {
|
|
76
|
+
const regExp = /\[(-?\d+)?(\.\.\.)?(-?\d+)?]/,
|
|
77
|
+
matches = spreadExpression.match(regExp),
|
|
78
|
+
secondMatch = second(matches) || null,
|
|
79
|
+
thirdMatch = third(matches) || null,
|
|
80
|
+
fourthMatch = fourth(matches) || null;
|
|
81
|
+
|
|
82
|
+
if (secondMatch !== null) {
|
|
83
|
+
startIndex = parseInt(secondMatch);
|
|
84
|
+
|
|
85
|
+
if (thirdMatch === null) {
|
|
86
|
+
endIndex = startIndex; ///
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (fourthMatch !== null) {
|
|
91
|
+
endIndex = parseInt(fourthMatch);
|
|
92
|
+
|
|
93
|
+
if (thirdMatch === null) {
|
|
94
|
+
startIndex = endIndex; ///
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const spread = new Spread(startIndex, endIndex, unique);
|
|
101
|
+
|
|
102
|
+
return spread;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import Path from "./path";
|
|
4
|
+
import Spread from "./spread";
|
|
5
|
+
|
|
6
|
+
import { pathNodeFromSubExpressionNode, spreadNodeFromSubExpressionNode, subExpressionNodeFromSubExpressionNode } from "./utilities/node";
|
|
7
|
+
|
|
8
|
+
export default class SubExpression {
|
|
9
|
+
constructor(path, spread, subExpression) {
|
|
10
|
+
this.path = path;
|
|
11
|
+
this.spread = spread;
|
|
12
|
+
this.subExpression = subExpression;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getPath() {
|
|
16
|
+
return this.path;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getSpread() {
|
|
20
|
+
return this.spread;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getSubExpression() {
|
|
24
|
+
return this.subExpression;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getRuleNames() { return this.path.getRuleNames(); }
|
|
28
|
+
|
|
29
|
+
getTokenTypes() { return this.path.getTokenTypes(); }
|
|
30
|
+
|
|
31
|
+
isInfiniteDescent() { return this.path.isInfiniteDescent(); }
|
|
32
|
+
|
|
33
|
+
static fromSubExpressionNode(subExpressionNode) {
|
|
34
|
+
let subExpression = null;
|
|
35
|
+
|
|
36
|
+
if (subExpressionNode !== null) {
|
|
37
|
+
const pathNode = pathNodeFromSubExpressionNode(subExpressionNode),
|
|
38
|
+
spreadNode = spreadNodeFromSubExpressionNode(subExpressionNode);
|
|
39
|
+
|
|
40
|
+
subExpressionNode = subExpressionNodeFromSubExpressionNode(subExpressionNode); ///
|
|
41
|
+
|
|
42
|
+
const path = Path.fromPathNode(pathNode),
|
|
43
|
+
spread = Spread.fromSpreadNode(spreadNode);
|
|
44
|
+
|
|
45
|
+
subExpression = SubExpression.fromSubExpressionNode(subExpressionNode);
|
|
46
|
+
|
|
47
|
+
subExpression = new SubExpression(path, spread, subExpression); ///
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return subExpression;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { arrayUtilities } from "necessary";
|
|
4
|
+
|
|
5
|
+
export const { clear, push, first, second, third, fourth, fifth, last } = arrayUtilities;
|
|
6
|
+
|
|
7
|
+
export function trim(array, startIndex, endIndex) {
|
|
8
|
+
if (startIndex < 0) {
|
|
9
|
+
const length = array.length; ///
|
|
10
|
+
|
|
11
|
+
startIndex = length + startIndex; ///
|
|
12
|
+
|
|
13
|
+
endIndex = length + endIndex; ///
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (endIndex !== Infinity) {
|
|
17
|
+
const start = endIndex + 1;
|
|
18
|
+
|
|
19
|
+
array.splice(start);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const start = 0,
|
|
23
|
+
deleteCount = startIndex; ///
|
|
24
|
+
|
|
25
|
+
array.splice(start, deleteCount);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function includes(array, ...elements) {
|
|
29
|
+
return elements.some((element) => array.includes(element));
|
|
30
|
+
}
|