grammar-well 2.0.6 → 2.1.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/build/generator/generator.js +4 -1
- package/build/generator/generator.js.map +1 -1
- package/build/generator/grammars/v1.d.ts +1 -0
- package/build/generator/grammars/v1.js +1 -0
- package/build/generator/grammars/v1.js.map +1 -1
- package/build/generator/grammars/v2.d.ts +10 -2
- package/build/generator/grammars/v2.js +4 -1
- package/build/generator/grammars/v2.js.map +1 -1
- package/build/generator/state.d.ts +7 -5
- package/build/generator/state.js +5 -2
- package/build/generator/state.js.map +1 -1
- package/build/generator/stringify/exports/javascript.js +3 -2
- package/build/generator/stringify/exports/javascript.js.map +1 -1
- package/build/generator/stringify/exports/typescript.js +3 -2
- package/build/generator/stringify/exports/typescript.js.map +1 -1
- package/build/generator/stringify/grammar/v2.d.ts +4 -0
- package/build/generator/stringify/grammar/v2.js +14 -5
- package/build/generator/stringify/grammar/v2.js.map +1 -1
- package/build/generator/stringify/javascript.d.ts +1 -0
- package/build/generator/stringify/javascript.js +23 -2
- package/build/generator/stringify/javascript.js.map +1 -1
- package/build/lexers/character-lexer.d.ts +1 -0
- package/build/lexers/character-lexer.js +2 -1
- package/build/lexers/character-lexer.js.map +1 -1
- package/build/lexers/stateful-lexer.d.ts +1 -0
- package/build/lexers/stateful-lexer.js +2 -1
- package/build/lexers/stateful-lexer.js.map +1 -1
- package/build/lexers/token-buffer.d.ts +2 -1
- package/build/lexers/token-buffer.js +7 -2
- package/build/lexers/token-buffer.js.map +1 -1
- package/build/parser/algorithms/earley.js +14 -1
- package/build/parser/algorithms/earley.js.map +1 -1
- package/build/parser/parse.js +8 -7
- package/build/parser/parse.js.map +1 -1
- package/build/typings/ast.d.ts +1 -1
- package/build/typings/runtime.d.ts +4 -0
- package/build/version.json +1 -1
- package/package.json +1 -1
- package/src/generator/generator.ts +4 -1
- package/src/generator/grammars/v1.ts +2 -1
- package/src/generator/grammars/v2.ts +5 -2
- package/src/generator/grammars/v2.well +2 -0
- package/src/generator/state.ts +11 -5
- package/src/generator/stringify/exports/javascript.ts +3 -2
- package/src/generator/stringify/exports/typescript.ts +3 -2
- package/src/generator/stringify/grammar/v2.ts +17 -5
- package/src/generator/stringify/javascript.ts +24 -2
- package/src/lexers/character-lexer.ts +2 -1
- package/src/lexers/stateful-lexer.ts +2 -1
- package/src/lexers/token-buffer.ts +5 -2
- package/src/parser/algorithms/earley.ts +18 -3
- package/src/parser/parse.ts +8 -7
- package/src/typings/ast.ts +1 -1
- package/src/typings/generator.ts +1 -1
- package/src/typings/runtime.ts +3 -1
- package/src/version.json +1 -1
package/src/generator/state.ts
CHANGED
|
@@ -4,8 +4,9 @@ export class GeneratorState {
|
|
|
4
4
|
grammar?: GeneratorStateGrammar;
|
|
5
5
|
lexer?: GeneratorLexerConfig;
|
|
6
6
|
lifecycle: {
|
|
7
|
-
import?: string;
|
|
8
|
-
new?: string;
|
|
7
|
+
import?: string[];
|
|
8
|
+
new?: string[];
|
|
9
|
+
token?: string[];
|
|
9
10
|
} = {}
|
|
10
11
|
|
|
11
12
|
config = {};
|
|
@@ -72,9 +73,14 @@ export class GeneratorState {
|
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
addLifecycle(lifecycle: string, literal: string) {
|
|
76
|
-
this.lifecycle[lifecycle] = this.lifecycle[lifecycle] ||
|
|
77
|
-
|
|
76
|
+
addLifecycle(lifecycle: string, literal: string | string[]) {
|
|
77
|
+
this.lifecycle[lifecycle] = this.lifecycle[lifecycle] || [];
|
|
78
|
+
|
|
79
|
+
if (typeof literal == 'string')
|
|
80
|
+
this.lifecycle[lifecycle].push(literal);
|
|
81
|
+
|
|
82
|
+
if (Array.isArray(literal))
|
|
83
|
+
this.lifecycle[lifecycle].push(...literal);
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
export() {
|
|
@@ -20,10 +20,11 @@ function Generate(generator: JavaScriptGenerator) {
|
|
|
20
20
|
return `// Generated automatically by Grammar-Well, version ${generator.state.version}
|
|
21
21
|
// https://github.com/0x6563/grammar-well
|
|
22
22
|
|
|
23
|
-
${generator.lifecycle('import')}
|
|
23
|
+
${generator.lifecycle('import').join('')}
|
|
24
24
|
|
|
25
25
|
class ${exportName} {
|
|
26
|
+
state = {};
|
|
26
27
|
artifacts = ${generator.artifacts(1)}
|
|
27
|
-
constructor(){${generator.lifecycle('new')}}
|
|
28
|
+
constructor(){${generator.lifecycle('new').join('')}}
|
|
28
29
|
}`;
|
|
29
30
|
}
|
|
@@ -6,11 +6,12 @@ export function TypescriptFormat(generator: JavaScriptGenerator) {
|
|
|
6
6
|
// https://github.com/0x6563/grammar-well
|
|
7
7
|
// @ts-nocheck
|
|
8
8
|
|
|
9
|
-
${generator.lifecycle('import')}
|
|
9
|
+
${generator.lifecycle('import').join('')}
|
|
10
10
|
|
|
11
11
|
class ${exportName} {
|
|
12
|
+
state = {};
|
|
12
13
|
artifacts = ${generator.artifacts(1)}
|
|
13
|
-
constructor(){${generator.lifecycle('new')}}
|
|
14
|
+
constructor(){${generator.lifecycle('new').join('')}}
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
export default ${exportName};`;
|
|
@@ -6,7 +6,11 @@ export class V2GrammarString {
|
|
|
6
6
|
directives = Array.isArray(directives) ? directives : [directives];
|
|
7
7
|
for (const directive of directives) {
|
|
8
8
|
if ("lifecycle" in directive) {
|
|
9
|
-
|
|
9
|
+
if ('js' in directive.js)
|
|
10
|
+
this.appendSection("on:" + directive.lifecycle, directive.js.js.trim());
|
|
11
|
+
else if ('template' in directive.js)
|
|
12
|
+
this.appendSource("on:" + directive.lifecycle + this.formatTemplate(directive.js));
|
|
13
|
+
|
|
10
14
|
} else if ("import" in directive) {
|
|
11
15
|
this.appendImportDirective(directive);
|
|
12
16
|
} else if ("config" in directive) {
|
|
@@ -93,12 +97,16 @@ export class V2GrammarString {
|
|
|
93
97
|
return `=> \${ ${postProcess.js} }`;
|
|
94
98
|
}
|
|
95
99
|
if ('template' in postProcess) {
|
|
96
|
-
|
|
97
|
-
const suffix = postProcess.template.slice(-1);
|
|
98
|
-
return `=> ${prefix} ${postProcess.template.slice(1, -1).trim()} ${suffix}`;
|
|
100
|
+
return this.formatTemplate(postProcess)
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
|
|
104
|
+
formatTemplate(postProcess: { template: string }) {
|
|
105
|
+
const prefix = postProcess.template.slice(0, 1);
|
|
106
|
+
const suffix = postProcess.template.slice(-1);
|
|
107
|
+
return `=> ${prefix} ${postProcess.template.slice(1, -1).trim()} ${suffix}`;
|
|
108
|
+
}
|
|
109
|
+
|
|
102
110
|
appendLexerDirective(directive: ASTLexer) {
|
|
103
111
|
let body = '';
|
|
104
112
|
if (directive.lexer.start) {
|
|
@@ -211,10 +219,14 @@ export class V2GrammarString {
|
|
|
211
219
|
}
|
|
212
220
|
|
|
213
221
|
appendSection(label: string, body: string) {
|
|
222
|
+
this.appendSource(`${label} {\n${body}\n}\n`)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
appendSource(source) {
|
|
214
226
|
if (this.source) {
|
|
215
227
|
this.source += '\n';
|
|
216
228
|
}
|
|
217
|
-
this.source +=
|
|
229
|
+
this.source += source;
|
|
218
230
|
}
|
|
219
231
|
|
|
220
232
|
indent(depth: number = 0, content: string) {
|
|
@@ -22,8 +22,8 @@ export class JavaScriptGenerator {
|
|
|
22
22
|
|
|
23
23
|
lifecycle(lifecycle: string) {
|
|
24
24
|
if (this.options.noscript)
|
|
25
|
-
return
|
|
26
|
-
return this.state.lifecycle[lifecycle] ||
|
|
25
|
+
return [];
|
|
26
|
+
return this.state.lifecycle[lifecycle] || [];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
artifacts(depth: number = 0) {
|
|
@@ -48,9 +48,31 @@ export class JavaScriptGenerator {
|
|
|
48
48
|
output.grammar = basic.stringify(depth + 1);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
const onToken = this.lifecycle('token');
|
|
52
|
+
if (onToken.length) {
|
|
53
|
+
output.tokenProcessor = `() => {`
|
|
54
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 1)}return (token) => {`
|
|
55
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 2)}const processors = [`;
|
|
56
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 3)}${onToken.map(v => `({ token, state }) => ${v}`).join(',' + CommonGenerator.SmartIndent(depth + 3))}`
|
|
57
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 2)}];`
|
|
58
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 2)}for (const processor of processors) {`
|
|
59
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 3)}token = processor({ token, state: this.state })`
|
|
60
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 2)}}`
|
|
61
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 2)}return token;`
|
|
62
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth + 1)}}`
|
|
63
|
+
output.tokenProcessor += `${CommonGenerator.SmartIndent(depth)}}`;
|
|
64
|
+
}
|
|
51
65
|
return CommonGenerator.JSON(output, depth);
|
|
52
66
|
}
|
|
53
67
|
|
|
68
|
+
f(token) {
|
|
69
|
+
const processors = [({ token, state }) => token]
|
|
70
|
+
for (const processor of processors) {
|
|
71
|
+
token = processor({ token, state: this.state })
|
|
72
|
+
}
|
|
73
|
+
return token;
|
|
74
|
+
}
|
|
75
|
+
|
|
54
76
|
postProcess(postprocess: GeneratorGrammarProductionRule['postprocess'], alias: Dictionary<number>) {
|
|
55
77
|
postprocess = this.state.grammar.config.postprocessorOverride || postprocess || this.state.grammar.config.postprocessorDefault;
|
|
56
78
|
if (!postprocess)
|
|
@@ -15,7 +15,7 @@ export class TokenBuffer {
|
|
|
15
15
|
return { historyIndex: this.$historyIndex, offset: this.offset };
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
constructor(public lexer: RuntimeLexer) { }
|
|
18
|
+
constructor(public lexer: RuntimeLexer, private tokenProcessor?: (token: RuntimeLexerToken) => RuntimeLexerToken) { }
|
|
19
19
|
|
|
20
20
|
reset(buffer: string) {
|
|
21
21
|
this.lexer.feed(buffer);
|
|
@@ -77,8 +77,11 @@ export class TokenBuffer {
|
|
|
77
77
|
this.queued = '';
|
|
78
78
|
token = this.lexer.next();
|
|
79
79
|
}
|
|
80
|
-
if (token)
|
|
80
|
+
if (token) {
|
|
81
|
+
if (this.tokenProcessor)
|
|
82
|
+
token = this.tokenProcessor(token);
|
|
81
83
|
this.history.push(token);
|
|
84
|
+
}
|
|
82
85
|
return token;
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dictionary, RuntimeGrammarProductionRule, RuntimeParserClass } from "../../typings/index.js";
|
|
1
|
+
import { Dictionary, RuntimeGrammarProductionRule, RuntimeLexerToken, RuntimeParserClass } from "../../typings/index.js";
|
|
2
2
|
import { TokenBuffer } from "../../lexers/token-buffer.js";
|
|
3
3
|
import { TextFormatter } from "../../utility/text-format.js";
|
|
4
4
|
import { ParserUtility } from "../../utility/parsing.js";
|
|
@@ -58,9 +58,22 @@ export function Earley(language: RuntimeParserClass & { tokens: TokenBuffer }, o
|
|
|
58
58
|
results.push(data);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
const clone = results.length > 1;
|
|
62
|
+
for (let i = 0; i < results.length; i++) {
|
|
63
|
+
results[i] = PostProcess(results[i], clone);
|
|
64
|
+
}
|
|
61
65
|
return { results, info: { table } };
|
|
62
66
|
}
|
|
63
67
|
|
|
68
|
+
function PostProcess(ast: PreAST | RuntimeLexerToken, clone?: boolean) {
|
|
69
|
+
if (!Array.isArray(ast))
|
|
70
|
+
return clone ? { ...ast } : ast;
|
|
71
|
+
const data = [];
|
|
72
|
+
for (let i = 0; i < ast[1].length; i++) {
|
|
73
|
+
data[i] = PostProcess(ast[1][i], clone);
|
|
74
|
+
}
|
|
75
|
+
return ParserUtility.PostProcess(ast[0], data, ast[2]);
|
|
76
|
+
}
|
|
64
77
|
|
|
65
78
|
class Column {
|
|
66
79
|
data: any;
|
|
@@ -170,7 +183,7 @@ class State {
|
|
|
170
183
|
|
|
171
184
|
|
|
172
185
|
finish() {
|
|
173
|
-
this.data =
|
|
186
|
+
this.data = [this.rule, this.data, { reference: this.reference, dot: this.dot }];
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
protected build() {
|
|
@@ -190,4 +203,6 @@ interface StateToken {
|
|
|
190
203
|
token: any,
|
|
191
204
|
isToken: boolean,
|
|
192
205
|
reference: number
|
|
193
|
-
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
type PreAST = [RuntimeGrammarProductionRule, (RuntimeLexerToken | PreAST)[], { reference: number, dot: number }];
|
package/src/parser/parse.ts
CHANGED
|
@@ -29,13 +29,14 @@ export function Parse(
|
|
|
29
29
|
return results == 'full' ? result : result.results[0];
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function GetTokenizer(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
function GetTokenizer(artifacts: RuntimeParserClass['artifacts']) {
|
|
33
|
+
const tokenProcessor = artifacts?.tokenProcessor ? artifacts.tokenProcessor() : null;
|
|
34
|
+
if (!artifacts.lexer) {
|
|
35
|
+
return new TokenBuffer(new CharacterLexer(), tokenProcessor);
|
|
36
|
+
} else if ("feed" in artifacts.lexer && typeof artifacts.lexer.feed == 'function') {
|
|
37
|
+
return new TokenBuffer(artifacts.lexer, tokenProcessor);
|
|
38
|
+
} else if ('states' in artifacts.lexer) {
|
|
39
|
+
return new TokenBuffer(new StatefulLexer(artifacts.lexer), tokenProcessor);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
|
package/src/typings/ast.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type AST = ASTDirectives[];
|
|
|
5
5
|
export type ASTJavascriptLifecycleLiteral = {
|
|
6
6
|
lifecycle: string;
|
|
7
7
|
path?: boolean;
|
|
8
|
-
js: ASTJavaScriptLiteral;
|
|
8
|
+
js: ASTJavaScriptLiteral | ASTJavaScriptTemplate;
|
|
9
9
|
}
|
|
10
10
|
export type ASTJavaScriptLiteral = { js: string }
|
|
11
11
|
export type ASTJavaScriptTemplate = { template: string }
|
package/src/typings/generator.ts
CHANGED
package/src/typings/runtime.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LRState } from "./index.js";
|
|
2
|
-
import { ASTGrammarSymbolLiteral, ASTGrammarSymbolToken,
|
|
2
|
+
import { ASTGrammarSymbolLiteral, ASTGrammarSymbolToken, ASTLexerStateNonMatchRule } from "./ast.js";
|
|
3
3
|
import { Dictionary } from "./common.js";
|
|
4
4
|
|
|
5
5
|
export interface RuntimeParserClass {
|
|
@@ -13,6 +13,7 @@ export interface RuntimeParserClass {
|
|
|
13
13
|
k: number;
|
|
14
14
|
table: Dictionary<LRState>;
|
|
15
15
|
}
|
|
16
|
+
tokenProcessor: () => ((token: RuntimeLexerToken) => RuntimeLexerToken) | undefined
|
|
16
17
|
}
|
|
17
18
|
new();
|
|
18
19
|
}
|
|
@@ -60,6 +61,7 @@ export interface RuntimeLexerToken {
|
|
|
60
61
|
offset: number;
|
|
61
62
|
line: number;
|
|
62
63
|
column: number;
|
|
64
|
+
custom?: { [key: string]: any }
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
|
package/src/version.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"2.0
|
|
1
|
+
{"version":"2.1.0"}
|