grammar-composer 0.6.2 → 0.7.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/README.md +27 -19
- package/dist/parser/Builder.d.ts +3 -3
- package/dist/parser/Builder.d.ts.map +1 -1
- package/dist/parser/Builder.js +37 -37
- package/dist/parser/Builder.js.map +1 -1
- package/dist/parser/Grammar.d.ts +28 -28
- package/dist/parser/Grammar.d.ts.map +1 -1
- package/dist/parser/Grammar.js +19 -19
- package/dist/parser/Grammar.js.map +1 -1
- package/dist/parser/ParseError.js +6 -6
- package/dist/parser/ParseError.js.map +1 -1
- package/dist/parser/Parser.d.ts.map +1 -1
- package/dist/parser/Parser.js +36 -36
- package/dist/parser/Parser.js.map +1 -1
- package/dist/parser/StaticAnalysis.d.ts +5 -5
- package/dist/parser/StaticAnalysis.d.ts.map +1 -1
- package/dist/parser/StaticAnalysis.js +8 -8
- package/dist/parser/StaticAnalysis.js.map +1 -1
- package/dist/parser/{TerminalToText.d.ts → TerminalFormatter.d.ts} +4 -4
- package/dist/parser/TerminalFormatter.d.ts.map +1 -0
- package/dist/parser/{TerminalToText.js → TerminalFormatter.js} +2 -2
- package/dist/parser/TerminalFormatter.js.map +1 -0
- package/dist/tests/Test.js +6 -6
- package/dist/tests/Test.js.map +1 -1
- package/dist/tests/test-grammars/JsonGrammar.d.ts +3 -3
- package/dist/tests/test-grammars/JsonGrammar.d.ts.map +1 -1
- package/dist/tests/test-grammars/JsonGrammar.js +2 -2
- package/dist/tests/test-grammars/JsonGrammar.js.map +1 -1
- package/dist/tests/test-grammars/RegExpGrammar.d.ts +11 -11
- package/dist/tests/test-grammars/RegExpGrammar.d.ts.map +1 -1
- package/dist/tests/test-grammars/RegExpGrammar.js +2 -2
- package/dist/tests/test-grammars/RegExpGrammar.js.map +1 -1
- package/dist/tests/test-grammars/XmlGrammar.d.ts +1 -1
- package/dist/tests/test-grammars/XmlGrammar.d.ts.map +1 -1
- package/dist/tests/test-grammars/XmlGrammar.js +2 -2
- package/dist/tests/test-grammars/XmlGrammar.js.map +1 -1
- package/package.json +3 -3
- package/src/parser/Builder.ts +42 -42
- package/src/parser/Grammar.ts +46 -46
- package/src/parser/ParseError.ts +6 -6
- package/src/parser/Parser.ts +38 -38
- package/src/parser/StaticAnalysis.ts +24 -22
- package/src/parser/{TerminalToText.ts → TerminalFormatter.ts} +3 -3
- package/src/tests/Test.ts +6 -6
- package/src/tests/test-grammars/JsonGrammar.ts +3 -3
- package/src/tests/test-grammars/RegExpGrammar.ts +2 -2
- package/src/tests/test-grammars/XmlGrammar.ts +2 -2
- package/dist/parser/TerminalToText.d.ts.map +0 -1
- package/dist/parser/TerminalToText.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ A library to define, build and efficiently parse context-free grammars.
|
|
|
5
5
|
* Grammars are defined using TypeScript class declarations
|
|
6
6
|
* No tokenization stage. The generated parser accepts raw characters as input, meaning it's a form of lexer-free, hybrid parser, supporting contextual low-level parsing. This means low-level character patterns, recognized by a regular language, can be specialized to various high-level parser contexts, and sub-patterns captured in low-level regular expressions are directly embedded as part of the resulting parse tree
|
|
7
7
|
* Raw character parsing is defined as part of the grammar via embedded `Pattern` objects that are internally processed through the [`regexp-composer`](https://github.com/rotemdan/regexp-composer) regular expression library. This means that any subset of the grammar that can be stated as a regular grammar can be moved to be parsed using the highly optimized native JavaScript RegExp engine, instead of being parsed via the slower context-free parser
|
|
8
|
-
* Top-down parsing (roughly equivalent to PEG parsing), with optional "packrat" caching that can be enabled or disabled for individual productions or more specific grammar
|
|
8
|
+
* Top-down parsing (roughly equivalent to PEG parsing), with optional "packrat" caching that can be enabled or disabled for individual productions or more specific grammar expressions
|
|
9
9
|
* Supports right-recursion, but will currently error when left-recursion is detected
|
|
10
10
|
* Uses sophisticated static analysis to automatically identify and annotate optional productions
|
|
11
11
|
* Provides useful parse-time error reporting, identifying the exact production involved and most likely alternatives at the failed position
|
|
@@ -179,9 +179,17 @@ const quotedString = R.anyOf(
|
|
|
179
179
|
)
|
|
180
180
|
|
|
181
181
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
182
|
-
//
|
|
182
|
+
// Unfolded nonterminal list
|
|
183
|
+
//
|
|
184
|
+
// Nonterminals placed here will be "transparent" in the resulting parse tree.
|
|
185
|
+
//
|
|
186
|
+
// Their content would be absorbed by their parent.
|
|
187
|
+
//
|
|
188
|
+
// This is useful for the purpose of simplifying the resulting parse tree, and
|
|
189
|
+
// removing non-semantic "technical" nodes used for things like grammar optimization
|
|
190
|
+
// and refactoring.
|
|
183
191
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
184
|
-
export const
|
|
192
|
+
export const xmlGrammarUnfoldedNonterminalNames: G.GrammarNonterminalNames<XmlGrammar> = [
|
|
185
193
|
'openingTagStart',
|
|
186
194
|
'tagEnd',
|
|
187
195
|
'declarationTagOpening',
|
|
@@ -192,7 +200,7 @@ export const xmlGrammarUnwrappedNonterminalNames: G.GrammarNonterminalNames<XmlG
|
|
|
192
200
|
|
|
193
201
|
```ts
|
|
194
202
|
import { buildGrammar } from 'grammar-composer'
|
|
195
|
-
import { XmlGrammar,
|
|
203
|
+
import { XmlGrammar, xmlGrammarUnfoldedNonterminalNames } from './XmlGrammar.js'
|
|
196
204
|
|
|
197
205
|
const xmlString = `
|
|
198
206
|
<!DOCTYPE web-app>
|
|
@@ -213,7 +221,7 @@ const grammar = buildGrammar(RegExpGrammar, 'root', {
|
|
|
213
221
|
// "passed through" when the parse tree is built,
|
|
214
222
|
// meaning they would not appear in the parse tree
|
|
215
223
|
// and their child nodes would be absorbed into their ancestor nodes.
|
|
216
|
-
|
|
224
|
+
unfoldedNonterminalNames: xmlGrammarUnfoldedNonterminalNames
|
|
217
225
|
})
|
|
218
226
|
|
|
219
227
|
// Parse the XML string with the built grammar
|
|
@@ -417,37 +425,37 @@ The resulting parse tree looks like:
|
|
|
417
425
|
|
|
418
426
|
Context-free operators are mostly named similarly to the ones in [`regexp-composer`](https://github.com/rotemdan/regexp-composer).
|
|
419
427
|
|
|
420
|
-
### `zeroOrMore(
|
|
428
|
+
### `zeroOrMore(grammarExpression)`
|
|
421
429
|
|
|
422
|
-
Match the grammar
|
|
430
|
+
Match the grammar expression zero or more times.
|
|
423
431
|
|
|
424
|
-
### `oneOrMore(
|
|
432
|
+
### `oneOrMore(grammarExpression)`
|
|
425
433
|
|
|
426
|
-
Match the grammar
|
|
434
|
+
Match the grammar expression one or more times.
|
|
427
435
|
|
|
428
|
-
### `anyOf(
|
|
436
|
+
### `anyOf(grammarExpression1, grammarExpression2, grammarExpression3, ...)`
|
|
429
437
|
|
|
430
|
-
Match any of the grammar
|
|
438
|
+
Match any of the grammar expressions. The first successful match, in order, would be accepted without trying subsequent ones.
|
|
431
439
|
|
|
432
|
-
### `bestOf(
|
|
440
|
+
### `bestOf(grammarExpression1, grammarExpression2, grammarExpression3, ...)`
|
|
433
441
|
|
|
434
|
-
Match the best grammar
|
|
442
|
+
Match the best grammar expression. All possibilities would be tried, and the the longest match (in terms of character count) would be chosen.
|
|
435
443
|
|
|
436
|
-
### `possibly(
|
|
444
|
+
### `possibly(grammarExpression)`
|
|
437
445
|
|
|
438
|
-
Optionally accept the grammar
|
|
446
|
+
Optionally accept the grammar expression, or skip if it doesn't match.
|
|
439
447
|
|
|
440
448
|
### `pattern(regexpPattern)`
|
|
441
449
|
|
|
442
450
|
Accept a regular expression pattern compatible with `regexp-composer` `Pattern` type (either a simple string, pattern object, or array of pattern objects).
|
|
443
451
|
|
|
444
|
-
### `cached(
|
|
452
|
+
### `cached(grammarExpression)`
|
|
445
453
|
|
|
446
|
-
Store the result of
|
|
454
|
+
Store the parsed result of this grammar expression and reuse it when it's subsequently evaluated **at the same text position**.
|
|
447
455
|
|
|
448
|
-
### `uncached(
|
|
456
|
+
### `uncached(grammarExpression)`
|
|
449
457
|
|
|
450
|
-
Don't cache this grammar
|
|
458
|
+
Don't cache this grammar expression.
|
|
451
459
|
|
|
452
460
|
## License
|
|
453
461
|
|
package/dist/parser/Builder.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Grammar,
|
|
1
|
+
import { Grammar, GrammarNode, GrammarExpression } from './Grammar.js';
|
|
2
2
|
export declare function buildGrammar<T extends GrammarDefinition>(definitionObject: T | (new () => T), startProductionName: keyof T, options?: GrammarBuilderOptions<T>): Grammar<T>;
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function grammarExpressionToNode(grammarExpression: GrammarExpression): GrammarNode;
|
|
4
4
|
export interface GrammarBuilderOptions<T> {
|
|
5
|
-
|
|
5
|
+
unfoldedNonterminalNames?: GrammarNonterminalNames<T>;
|
|
6
6
|
}
|
|
7
7
|
export type GrammarNonterminalNames<T> = (keyof T)[];
|
|
8
8
|
export type GrammarDefinition = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Builder.d.ts","sourceRoot":"","sources":["../../src/parser/Builder.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAe,
|
|
1
|
+
{"version":3,"file":"Builder.d.ts","sourceRoot":"","sources":["../../src/parser/Builder.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAe,WAAW,EAAkD,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAKnI,wBAAgB,YAAY,CAAC,CAAC,SAAS,iBAAiB,EACvD,gBAAgB,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EACnC,mBAAmB,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAsF/C;AAqID,wBAAgB,uBAAuB,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,WAAW,CAYzF;AAKD,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACvC,wBAAwB,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAA;CACrD;AAED,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAA;AAEpD,MAAM,MAAM,iBAAiB,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAA"}
|
package/dist/parser/Builder.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Grammar } from './Grammar.js';
|
|
|
6
6
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
7
7
|
export function buildGrammar(definitionObject, startProductionName, options) {
|
|
8
8
|
options = {
|
|
9
|
-
|
|
9
|
+
unfoldedNonterminalNames: [],
|
|
10
10
|
...options
|
|
11
11
|
};
|
|
12
12
|
if (isFunction(definitionObject)) {
|
|
@@ -22,9 +22,9 @@ export function buildGrammar(definitionObject, startProductionName, options) {
|
|
|
22
22
|
throw new Error(`Grammar definition contains a property '${key}', which is not a function. All object properties must be productions, declared as functions.`);
|
|
23
23
|
}
|
|
24
24
|
const productionContent = objectProperty.call(definitionObject);
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const newNonterminal = nonterminal(key,
|
|
25
|
+
const productionContentNode = grammarExpressionToNode(productionContent);
|
|
26
|
+
const isUnfoldedNonterminal = options.unfoldedNonterminalNames?.includes(key) === true;
|
|
27
|
+
const newNonterminal = nonterminal(key, productionContentNode, isUnfoldedNonterminal);
|
|
28
28
|
const newOptionalNonterminal = {
|
|
29
29
|
...newNonterminal,
|
|
30
30
|
optional: true,
|
|
@@ -40,7 +40,7 @@ export function buildGrammar(definitionObject, startProductionName, options) {
|
|
|
40
40
|
return newCacheId;
|
|
41
41
|
};
|
|
42
42
|
for (const [func, nonterminal] of nonterminalLookup) {
|
|
43
|
-
const preparedContent =
|
|
43
|
+
const preparedContent = prepareGrammarNode(nonterminal.content, nonterminalLookup, optionalNonterminalLookup, getNewCacheId);
|
|
44
44
|
nonterminal.content = preparedContent;
|
|
45
45
|
const optionalNonterminal = optionalNonterminalLookup.get(func);
|
|
46
46
|
// The optional wrapper should share the already-resolved content
|
|
@@ -62,57 +62,57 @@ export function buildGrammar(definitionObject, startProductionName, options) {
|
|
|
62
62
|
}
|
|
63
63
|
return new Grammar(nonterminals, startProductionName, cacheIdCounter);
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
function prepare(
|
|
67
|
-
const setCacheIdIfNeeded = (
|
|
68
|
-
if (
|
|
69
|
-
|
|
65
|
+
function prepareGrammarNode(rootNode, nonterminalLookup, optionalNonterminalLookup, getNewCacheId) {
|
|
66
|
+
function prepare(node) {
|
|
67
|
+
const setCacheIdIfNeeded = (node) => {
|
|
68
|
+
if (node.cached === true) {
|
|
69
|
+
node.cacheId = getNewCacheId();
|
|
70
70
|
}
|
|
71
|
-
return
|
|
71
|
+
return node;
|
|
72
72
|
};
|
|
73
|
-
switch (
|
|
73
|
+
switch (node.type) {
|
|
74
74
|
case 'StringTerminal':
|
|
75
75
|
case 'Nonterminal': {
|
|
76
76
|
return setCacheIdIfNeeded({
|
|
77
|
-
...
|
|
77
|
+
...node
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
case 'PatternTerminal': {
|
|
81
81
|
return setCacheIdIfNeeded({
|
|
82
|
-
...
|
|
82
|
+
...node,
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
case 'Repetition': {
|
|
86
86
|
return setCacheIdIfNeeded({
|
|
87
|
-
...
|
|
88
|
-
content: prepare(
|
|
87
|
+
...node,
|
|
88
|
+
content: prepare(node.content),
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
91
|
case 'Sequence':
|
|
92
92
|
case 'Choice': {
|
|
93
93
|
return setCacheIdIfNeeded({
|
|
94
|
-
...
|
|
95
|
-
members:
|
|
94
|
+
...node,
|
|
95
|
+
members: node.members.map(member => prepare(member)),
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
case 'NonterminalReference': {
|
|
99
|
-
const reference =
|
|
99
|
+
const reference = node.reference;
|
|
100
100
|
let nonterminal;
|
|
101
|
-
if (
|
|
101
|
+
if (node.optional) {
|
|
102
102
|
nonterminal = optionalNonterminalLookup.get(reference);
|
|
103
103
|
}
|
|
104
104
|
else {
|
|
105
105
|
nonterminal = nonterminalLookup.get(reference);
|
|
106
106
|
}
|
|
107
107
|
if (!nonterminal) {
|
|
108
|
-
throw new Error(`Couldn't resolve function reference in grammar
|
|
108
|
+
throw new Error(`Couldn't resolve function reference in grammar node: ${JSON.stringify(node)}`);
|
|
109
109
|
}
|
|
110
|
-
if (
|
|
110
|
+
if (node.cached === true) {
|
|
111
111
|
return {
|
|
112
112
|
...nonterminal,
|
|
113
113
|
cached: true,
|
|
114
114
|
cacheId: getNewCacheId(),
|
|
115
|
-
|
|
115
|
+
canonicalNonterminal: nonterminal.canonicalNonterminal ?? nonterminal
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
118
|
else {
|
|
@@ -121,7 +121,7 @@ function prepareGrammarElement(rootElement, nonterminalLookup, optionalNontermin
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
-
return prepare(
|
|
124
|
+
return prepare(rootNode);
|
|
125
125
|
}
|
|
126
126
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
127
127
|
// Internal AST builder methods
|
|
@@ -137,7 +137,7 @@ function stringTerminal(content) {
|
|
|
137
137
|
cached: false,
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
|
-
function nonterminal(name, content,
|
|
140
|
+
function nonterminal(name, content, unfolded) {
|
|
141
141
|
if (name.length < 1) {
|
|
142
142
|
throw new Error(`A nonterminal name must include at least 1 character.`);
|
|
143
143
|
}
|
|
@@ -147,7 +147,7 @@ function nonterminal(name, content, unwrapped) {
|
|
|
147
147
|
content,
|
|
148
148
|
optional: false,
|
|
149
149
|
cached: false,
|
|
150
|
-
|
|
150
|
+
unfolded,
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
function sequence(members) {
|
|
@@ -158,27 +158,27 @@ function sequence(members) {
|
|
|
158
158
|
cached: false,
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
|
-
function
|
|
161
|
+
function unresolvedNonterminalReference(nonterminalReferenceFunction) {
|
|
162
162
|
return {
|
|
163
163
|
type: 'NonterminalReference',
|
|
164
|
-
reference,
|
|
164
|
+
reference: nonterminalReferenceFunction,
|
|
165
165
|
optional: false,
|
|
166
166
|
cached: false,
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
|
-
export function
|
|
170
|
-
if (isString(
|
|
171
|
-
return stringTerminal(
|
|
169
|
+
export function grammarExpressionToNode(grammarExpression) {
|
|
170
|
+
if (isString(grammarExpression)) {
|
|
171
|
+
return stringTerminal(grammarExpression);
|
|
172
172
|
}
|
|
173
|
-
else if (isArray(
|
|
174
|
-
const
|
|
175
|
-
return sequence(
|
|
173
|
+
else if (isArray(grammarExpression)) {
|
|
174
|
+
const memberNodes = grammarExpression.map(member => grammarExpressionToNode(member));
|
|
175
|
+
return sequence(memberNodes);
|
|
176
176
|
}
|
|
177
|
-
else if (isFunction(
|
|
178
|
-
return
|
|
177
|
+
else if (isFunction(grammarExpression)) {
|
|
178
|
+
return unresolvedNonterminalReference(grammarExpression);
|
|
179
179
|
}
|
|
180
180
|
else {
|
|
181
|
-
return
|
|
181
|
+
return grammarExpression;
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
//# sourceMappingURL=Builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Builder.js","sourceRoot":"","sources":["../../src/parser/Builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AAEzE,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAA;AACnG,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"Builder.js","sourceRoot":"","sources":["../../src/parser/Builder.ts"],"names":[],"mappings":"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"}
|
package/dist/parser/Grammar.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PatternExpression } from 'regexp-composer';
|
|
2
2
|
export declare class Grammar<T> {
|
|
3
3
|
readonly productions: Record<keyof T, any>;
|
|
4
4
|
readonly startProductionName: keyof T;
|
|
5
5
|
readonly maxCacheId: number;
|
|
6
6
|
constructor(productions: Record<keyof T, any>, startProductionName: keyof T, maxCacheId: number);
|
|
7
7
|
parse(text: string): import("./Parser.js").ParseTreeNode[];
|
|
8
|
-
get
|
|
9
|
-
}
|
|
10
|
-
export declare function zeroOrMore(content:
|
|
11
|
-
export declare function oneOrMore(content:
|
|
12
|
-
export declare function anyOf(...members:
|
|
13
|
-
export declare function bestOf(...members:
|
|
14
|
-
export declare function possibly<T extends
|
|
15
|
-
export declare function pattern(
|
|
16
|
-
export declare function cached<T extends
|
|
17
|
-
export declare function uncached<T extends
|
|
18
|
-
export type
|
|
19
|
-
export type
|
|
20
|
-
interface
|
|
8
|
+
get rootNode(): Record<keyof T, any>[keyof T];
|
|
9
|
+
}
|
|
10
|
+
export declare function zeroOrMore(content: GrammarExpression): Repetition;
|
|
11
|
+
export declare function oneOrMore(content: GrammarExpression): Repetition;
|
|
12
|
+
export declare function anyOf(...members: GrammarExpression[]): Choice;
|
|
13
|
+
export declare function bestOf(...members: GrammarExpression[]): Choice;
|
|
14
|
+
export declare function possibly<T extends GrammarExpression>(content: GrammarExpression): T;
|
|
15
|
+
export declare function pattern(patternExpression: PatternExpression): PatternTerminal;
|
|
16
|
+
export declare function cached<T extends GrammarExpression>(content: GrammarExpression): T;
|
|
17
|
+
export declare function uncached<T extends GrammarExpression>(content: GrammarExpression): T;
|
|
18
|
+
export type GrammarExpression = string | GrammarNode | (() => GrammarExpression) | GrammarExpression[];
|
|
19
|
+
export type GrammarNode = StringTerminal | PatternTerminal | Nonterminal | Sequence | Repetition | Choice | NonterminalReference;
|
|
20
|
+
interface GrammarNodeBase {
|
|
21
21
|
type: string;
|
|
22
22
|
optional: boolean;
|
|
23
23
|
cached: boolean;
|
|
@@ -25,36 +25,36 @@ interface GrammarElementBase {
|
|
|
25
25
|
name?: string;
|
|
26
26
|
}
|
|
27
27
|
export type Terminal = StringTerminal | PatternTerminal;
|
|
28
|
-
export interface StringTerminal extends
|
|
28
|
+
export interface StringTerminal extends GrammarNodeBase {
|
|
29
29
|
type: 'StringTerminal';
|
|
30
30
|
content: string;
|
|
31
31
|
}
|
|
32
|
-
export interface PatternTerminal extends
|
|
32
|
+
export interface PatternTerminal extends GrammarNodeBase {
|
|
33
33
|
type: 'PatternTerminal';
|
|
34
|
-
pattern:
|
|
34
|
+
pattern: PatternExpression;
|
|
35
35
|
regExp: RegExp;
|
|
36
36
|
}
|
|
37
|
-
export interface Nonterminal extends
|
|
37
|
+
export interface Nonterminal extends GrammarNodeBase {
|
|
38
38
|
type: 'Nonterminal';
|
|
39
39
|
name: string;
|
|
40
|
-
content:
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
content: GrammarNode;
|
|
41
|
+
unfolded: boolean;
|
|
42
|
+
canonicalNonterminal?: Nonterminal;
|
|
43
43
|
}
|
|
44
|
-
export interface Sequence extends
|
|
44
|
+
export interface Sequence extends GrammarNodeBase {
|
|
45
45
|
type: 'Sequence';
|
|
46
|
-
members:
|
|
46
|
+
members: GrammarNode[];
|
|
47
47
|
}
|
|
48
|
-
export interface Repetition extends
|
|
48
|
+
export interface Repetition extends GrammarNodeBase {
|
|
49
49
|
type: 'Repetition';
|
|
50
|
-
content:
|
|
50
|
+
content: GrammarNode;
|
|
51
51
|
}
|
|
52
|
-
export interface Choice extends
|
|
52
|
+
export interface Choice extends GrammarNodeBase {
|
|
53
53
|
type: 'Choice';
|
|
54
|
-
members:
|
|
54
|
+
members: GrammarNode[];
|
|
55
55
|
exhaustive: boolean;
|
|
56
56
|
}
|
|
57
|
-
export interface NonterminalReference extends
|
|
57
|
+
export interface NonterminalReference extends GrammarNodeBase {
|
|
58
58
|
type: 'NonterminalReference';
|
|
59
59
|
reference: Function;
|
|
60
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Grammar.d.ts","sourceRoot":"","sources":["../../src/parser/Grammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Grammar.d.ts","sourceRoot":"","sources":["../../src/parser/Grammar.ts"],"names":[],"mappings":"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"}
|
package/dist/parser/Grammar.js
CHANGED
|
@@ -2,7 +2,7 @@ import { buildRegExp, inputStart, isPatternOptional } from 'regexp-composer';
|
|
|
2
2
|
import { isArray } from '../utilities/Utilities.js';
|
|
3
3
|
import { parse } from './Parser.js';
|
|
4
4
|
import { validatePatternCaptureGroups } from './StaticAnalysis.js';
|
|
5
|
-
import {
|
|
5
|
+
import { grammarExpressionToNode } from './Builder.js';
|
|
6
6
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
7
7
|
// Grammar class
|
|
8
8
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
@@ -18,7 +18,7 @@ export class Grammar {
|
|
|
18
18
|
parse(text) {
|
|
19
19
|
return parse(text, this);
|
|
20
20
|
}
|
|
21
|
-
get
|
|
21
|
+
get rootNode() {
|
|
22
22
|
return this.productions[this.startProductionName];
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -28,7 +28,7 @@ export class Grammar {
|
|
|
28
28
|
export function zeroOrMore(content) {
|
|
29
29
|
return {
|
|
30
30
|
type: 'Repetition',
|
|
31
|
-
content:
|
|
31
|
+
content: grammarExpressionToNode(content),
|
|
32
32
|
optional: true,
|
|
33
33
|
cached: false,
|
|
34
34
|
};
|
|
@@ -36,7 +36,7 @@ export function zeroOrMore(content) {
|
|
|
36
36
|
export function oneOrMore(content) {
|
|
37
37
|
return {
|
|
38
38
|
type: 'Repetition',
|
|
39
|
-
content:
|
|
39
|
+
content: grammarExpressionToNode(content),
|
|
40
40
|
optional: false,
|
|
41
41
|
cached: false,
|
|
42
42
|
};
|
|
@@ -45,10 +45,10 @@ export function anyOf(...members) {
|
|
|
45
45
|
if (members.length === 0) {
|
|
46
46
|
throw new Error(`'anyOf' requires at least one member.`);
|
|
47
47
|
}
|
|
48
|
-
const
|
|
48
|
+
const memberNodes = members.map(member => grammarExpressionToNode(member));
|
|
49
49
|
return {
|
|
50
50
|
type: 'Choice',
|
|
51
|
-
members:
|
|
51
|
+
members: memberNodes,
|
|
52
52
|
optional: false,
|
|
53
53
|
exhaustive: false,
|
|
54
54
|
cached: false,
|
|
@@ -58,40 +58,40 @@ export function bestOf(...members) {
|
|
|
58
58
|
if (members.length === 0) {
|
|
59
59
|
throw new Error(`'bestOf' requires at least one member.`);
|
|
60
60
|
}
|
|
61
|
-
const
|
|
61
|
+
const memberNodes = members.map(member => grammarExpressionToNode(member));
|
|
62
62
|
return {
|
|
63
63
|
type: 'Choice',
|
|
64
|
-
members:
|
|
64
|
+
members: memberNodes,
|
|
65
65
|
optional: false,
|
|
66
66
|
exhaustive: true,
|
|
67
67
|
cached: false,
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
export function possibly(content) {
|
|
71
|
-
return { ...
|
|
71
|
+
return { ...grammarExpressionToNode(content), optional: true };
|
|
72
72
|
}
|
|
73
|
-
export function pattern(
|
|
74
|
-
if (isArray(
|
|
75
|
-
|
|
73
|
+
export function pattern(patternExpression) {
|
|
74
|
+
if (isArray(patternExpression)) {
|
|
75
|
+
patternExpression = [inputStart, ...patternExpression];
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
78
|
-
|
|
78
|
+
patternExpression = [inputStart, patternExpression];
|
|
79
79
|
}
|
|
80
|
-
validatePatternCaptureGroups(
|
|
81
|
-
const regExp = buildRegExp(
|
|
82
|
-
const optional = isPatternOptional(
|
|
80
|
+
validatePatternCaptureGroups(patternExpression);
|
|
81
|
+
const regExp = buildRegExp(patternExpression);
|
|
82
|
+
const optional = isPatternOptional(patternExpression);
|
|
83
83
|
return {
|
|
84
84
|
type: 'PatternTerminal',
|
|
85
|
-
pattern,
|
|
85
|
+
pattern: patternExpression,
|
|
86
86
|
regExp,
|
|
87
87
|
optional,
|
|
88
88
|
cached: false,
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
export function cached(content) {
|
|
92
|
-
return { ...
|
|
92
|
+
return { ...grammarExpressionToNode(content), cached: true };
|
|
93
93
|
}
|
|
94
94
|
export function uncached(content) {
|
|
95
|
-
return { ...
|
|
95
|
+
return { ...grammarExpressionToNode(content), cached: false };
|
|
96
96
|
}
|
|
97
97
|
//# sourceMappingURL=Grammar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Grammar.js","sourceRoot":"","sources":["../../src/parser/Grammar.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Grammar.js","sourceRoot":"","sources":["../../src/parser/Grammar.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildCaretSpacing, expandTabs, getLineAndColumn } from '../utilities/LineAndColumn.js';
|
|
2
|
-
import { escapeChar,
|
|
2
|
+
import { escapeChar, TerminalFormatter } from './TerminalFormatter.js';
|
|
3
3
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
4
4
|
// Parse error class
|
|
5
5
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
@@ -108,9 +108,9 @@ function isRedundantCandidate(candidate, candidates) {
|
|
|
108
108
|
}
|
|
109
109
|
// Compares nonterminals by their canonical grammar reference, because the same
|
|
110
110
|
// production can be represented by multiple cloned instances during a parse.
|
|
111
|
-
function stackIndexOf(productionStack,
|
|
112
|
-
const
|
|
113
|
-
return productionStack.findIndex(nonterminal => (nonterminal.
|
|
111
|
+
function stackIndexOf(productionStack, nonterminal) {
|
|
112
|
+
const canonicalNonterminal = nonterminal.canonicalNonterminal ?? nonterminal;
|
|
113
|
+
return productionStack.findIndex(nonterminal => (nonterminal.canonicalNonterminal ?? nonterminal) === canonicalNonterminal);
|
|
114
114
|
}
|
|
115
115
|
function areTerminalsEqual(a, b) {
|
|
116
116
|
if (a === b) {
|
|
@@ -145,7 +145,7 @@ function stringifyFailedTerminal(failedMatch) {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
const stringifiedLengthLimit = 100;
|
|
148
|
-
const terminalToText = new
|
|
148
|
+
const terminalToText = new TerminalFormatter(stringifiedLengthLimit);
|
|
149
149
|
return terminalToText.stringifyTerminal(terminal);
|
|
150
150
|
}
|
|
151
151
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
@@ -177,7 +177,7 @@ function findCommonProductionPrefix(productionStacks) {
|
|
|
177
177
|
return commonPrefix;
|
|
178
178
|
}
|
|
179
179
|
function areSameNonterminal(a, b) {
|
|
180
|
-
return (a.
|
|
180
|
+
return (a.canonicalNonterminal ?? a) === (b.canonicalNonterminal ?? b);
|
|
181
181
|
}
|
|
182
182
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
183
183
|
// Parse error helpers
|