grammar-well 1.1.2 → 1.1.3
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/compiler/compiler.d.ts +49 -49
- package/build/compiler/compiler.js +227 -227
- package/build/compiler/generator.d.ts +23 -23
- package/build/compiler/generator.js +213 -212
- package/build/compiler/generator.js.map +1 -1
- package/build/compiler/import-resolver.d.ts +15 -15
- package/build/compiler/import-resolver.js +36 -36
- package/build/compiler/outputs/javascript.d.ts +3 -3
- package/build/compiler/outputs/javascript.js +14 -14
- package/build/compiler/outputs/json.d.ts +2 -2
- package/build/compiler/outputs/json.js +7 -7
- package/build/compiler/outputs/typescript.d.ts +2 -2
- package/build/compiler/outputs/typescript.js +9 -8
- package/build/compiler/outputs/typescript.js.map +1 -1
- package/build/grammars/gwell.d.ts +1023 -997
- package/build/grammars/gwell.js +540 -536
- package/build/grammars/gwell.js.map +1 -1
- package/build/grammars/json.d.ts +151 -151
- package/build/grammars/json.js +111 -111
- package/build/grammars/number.d.ts +239 -239
- package/build/grammars/number.js +114 -114
- package/build/grammars/number.json +1 -1
- package/build/grammars/string.d.ts +116 -116
- package/build/grammars/string.js +49 -49
- package/build/grammars/string.json +1 -1
- package/build/grammars/whitespace.d.ts +51 -51
- package/build/grammars/whitespace.js +29 -29
- package/build/grammars/whitespace.json +1 -1
- package/build/index.d.ts +4 -4
- package/build/index.js +20 -20
- package/build/lexers/character-lexer.d.ts +27 -27
- package/build/lexers/character-lexer.js +70 -70
- package/build/lexers/stateful-lexer.d.ts +48 -48
- package/build/lexers/stateful-lexer.js +308 -308
- package/build/lexers/token-buffer.d.ts +32 -32
- package/build/lexers/token-buffer.js +91 -91
- package/build/parser/algorithms/cyk.d.ts +16 -16
- package/build/parser/algorithms/cyk.js +57 -57
- package/build/parser/algorithms/earley.d.ts +48 -48
- package/build/parser/algorithms/earley.js +157 -157
- package/build/parser/algorithms/lr.d.ts +10 -10
- package/build/parser/algorithms/lr.js +33 -33
- package/build/parser/parser.d.ts +26 -26
- package/build/parser/parser.js +73 -73
- package/build/typings.d.ts +199 -198
- package/build/typings.js +2 -2
- package/build/utility/general.d.ts +55 -55
- package/build/utility/general.js +165 -165
- package/build/utility/lint.d.ts +2 -2
- package/build/utility/lint.js +27 -27
- package/build/utility/lr.d.ts +52 -52
- package/build/utility/lr.js +129 -129
- package/build/utility/text-format.d.ts +11 -11
- package/build/utility/text-format.js +83 -83
- package/package.json +1 -1
- package/src/compiler/generator.ts +1 -0
- package/src/compiler/outputs/typescript.ts +2 -1
- package/src/grammars/gwell.gwell +15 -13
- package/src/grammars/gwell.js +17 -13
- package/src/grammars/gwell.json +1 -1
- package/src/typings.ts +1 -0
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { CompileOptions, GrammarBuilderContext, TemplateFormat, LanguageDirective } from "../typings";
|
|
2
|
-
import { ESMOutput, JavascriptOutput } from "./outputs/javascript";
|
|
3
|
-
import { TypescriptFormat } from "./outputs/typescript";
|
|
4
|
-
import { JSONFormatter } from "./outputs/json";
|
|
5
|
-
import { Generator } from "./generator";
|
|
6
|
-
declare const TemplateFormats: {
|
|
7
|
-
_default: typeof JavascriptOutput;
|
|
8
|
-
object: (grammar: any, exportName: any) => {
|
|
9
|
-
grammar: any;
|
|
10
|
-
exportName: any;
|
|
11
|
-
};
|
|
12
|
-
json: typeof JSONFormatter;
|
|
13
|
-
js: typeof JavascriptOutput;
|
|
14
|
-
javascript: typeof JavascriptOutput;
|
|
15
|
-
module: typeof ESMOutput;
|
|
16
|
-
esmodule: typeof ESMOutput;
|
|
17
|
-
esm: typeof ESMOutput;
|
|
18
|
-
ts: typeof TypescriptFormat;
|
|
19
|
-
typescript: typeof TypescriptFormat;
|
|
20
|
-
};
|
|
21
|
-
export declare function Compile(rules: string | LanguageDirective | (LanguageDirective[]), config?: CompileOptions): Promise<string | {
|
|
22
|
-
grammar: any;
|
|
23
|
-
exportName: any;
|
|
24
|
-
}>;
|
|
25
|
-
export declare class GrammarBuilder {
|
|
26
|
-
private config;
|
|
27
|
-
private parser;
|
|
28
|
-
private context;
|
|
29
|
-
generator: Generator;
|
|
30
|
-
constructor(config?: CompileOptions, context?: GrammarBuilderContext);
|
|
31
|
-
export<T extends TemplateFormat = '_default'>(format: T, name?: string): ReturnType<typeof TemplateFormats[T]>;
|
|
32
|
-
import(source: string): Promise<void>;
|
|
33
|
-
import(directive: LanguageDirective): Promise<void>;
|
|
34
|
-
import(directives: LanguageDirective[]): Promise<void>;
|
|
35
|
-
private processImportDirective;
|
|
36
|
-
private processConfigDirective;
|
|
37
|
-
private processGrammarDirective;
|
|
38
|
-
private processLexerDirective;
|
|
39
|
-
private importBuiltIn;
|
|
40
|
-
private importGrammar;
|
|
41
|
-
private mergeLanguageDefinitionString;
|
|
42
|
-
private buildRules;
|
|
43
|
-
private buildRule;
|
|
44
|
-
private buildSymbol;
|
|
45
|
-
private buildCharacterRules;
|
|
46
|
-
private buildSubExpressionRules;
|
|
47
|
-
private buildRepeatRules;
|
|
48
|
-
}
|
|
49
|
-
export {};
|
|
1
|
+
import { CompileOptions, GrammarBuilderContext, TemplateFormat, LanguageDirective } from "../typings";
|
|
2
|
+
import { ESMOutput, JavascriptOutput } from "./outputs/javascript";
|
|
3
|
+
import { TypescriptFormat } from "./outputs/typescript";
|
|
4
|
+
import { JSONFormatter } from "./outputs/json";
|
|
5
|
+
import { Generator } from "./generator";
|
|
6
|
+
declare const TemplateFormats: {
|
|
7
|
+
_default: typeof JavascriptOutput;
|
|
8
|
+
object: (grammar: any, exportName: any) => {
|
|
9
|
+
grammar: any;
|
|
10
|
+
exportName: any;
|
|
11
|
+
};
|
|
12
|
+
json: typeof JSONFormatter;
|
|
13
|
+
js: typeof JavascriptOutput;
|
|
14
|
+
javascript: typeof JavascriptOutput;
|
|
15
|
+
module: typeof ESMOutput;
|
|
16
|
+
esmodule: typeof ESMOutput;
|
|
17
|
+
esm: typeof ESMOutput;
|
|
18
|
+
ts: typeof TypescriptFormat;
|
|
19
|
+
typescript: typeof TypescriptFormat;
|
|
20
|
+
};
|
|
21
|
+
export declare function Compile(rules: string | LanguageDirective | (LanguageDirective[]), config?: CompileOptions): Promise<string | {
|
|
22
|
+
grammar: any;
|
|
23
|
+
exportName: any;
|
|
24
|
+
}>;
|
|
25
|
+
export declare class GrammarBuilder {
|
|
26
|
+
private config;
|
|
27
|
+
private parser;
|
|
28
|
+
private context;
|
|
29
|
+
generator: Generator;
|
|
30
|
+
constructor(config?: CompileOptions, context?: GrammarBuilderContext);
|
|
31
|
+
export<T extends TemplateFormat = '_default'>(format: T, name?: string): ReturnType<typeof TemplateFormats[T]>;
|
|
32
|
+
import(source: string): Promise<void>;
|
|
33
|
+
import(directive: LanguageDirective): Promise<void>;
|
|
34
|
+
import(directives: LanguageDirective[]): Promise<void>;
|
|
35
|
+
private processImportDirective;
|
|
36
|
+
private processConfigDirective;
|
|
37
|
+
private processGrammarDirective;
|
|
38
|
+
private processLexerDirective;
|
|
39
|
+
private importBuiltIn;
|
|
40
|
+
private importGrammar;
|
|
41
|
+
private mergeLanguageDefinitionString;
|
|
42
|
+
private buildRules;
|
|
43
|
+
private buildRule;
|
|
44
|
+
private buildSymbol;
|
|
45
|
+
private buildCharacterRules;
|
|
46
|
+
private buildSubExpressionRules;
|
|
47
|
+
private buildRepeatRules;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
@@ -1,228 +1,228 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GrammarBuilder = exports.Compile = void 0;
|
|
4
|
-
const parser_1 = require("../parser/parser");
|
|
5
|
-
const import_resolver_1 = require("./import-resolver");
|
|
6
|
-
const gwell_1 = require("../grammars/gwell");
|
|
7
|
-
const javascript_1 = require("./outputs/javascript");
|
|
8
|
-
const typescript_1 = require("./outputs/typescript");
|
|
9
|
-
const json_1 = require("./outputs/json");
|
|
10
|
-
const number = require("../grammars/number.json");
|
|
11
|
-
const string = require("../grammars/string.json");
|
|
12
|
-
const whitespace = require("../grammars/whitespace.json");
|
|
13
|
-
const generator_1 = require("./generator");
|
|
14
|
-
const BuiltInRegistry = {
|
|
15
|
-
number,
|
|
16
|
-
string,
|
|
17
|
-
whitespace,
|
|
18
|
-
};
|
|
19
|
-
const TemplateFormats = {
|
|
20
|
-
_default: javascript_1.JavascriptOutput,
|
|
21
|
-
object: (grammar, exportName) => ({ grammar, exportName }),
|
|
22
|
-
json: json_1.JSONFormatter,
|
|
23
|
-
js: javascript_1.JavascriptOutput,
|
|
24
|
-
javascript: javascript_1.JavascriptOutput,
|
|
25
|
-
module: javascript_1.ESMOutput,
|
|
26
|
-
esmodule: javascript_1.ESMOutput,
|
|
27
|
-
esm: javascript_1.ESMOutput,
|
|
28
|
-
ts: typescript_1.TypescriptFormat,
|
|
29
|
-
typescript: typescript_1.TypescriptFormat
|
|
30
|
-
};
|
|
31
|
-
async function Compile(rules, config = {}) {
|
|
32
|
-
const builder = new GrammarBuilder(config);
|
|
33
|
-
await builder.import(rules);
|
|
34
|
-
return builder.export(config.template);
|
|
35
|
-
}
|
|
36
|
-
exports.Compile = Compile;
|
|
37
|
-
class GrammarBuilder {
|
|
38
|
-
config;
|
|
39
|
-
parser = new parser_1.Parser((0, gwell_1.default)());
|
|
40
|
-
context;
|
|
41
|
-
generator = new generator_1.Generator();
|
|
42
|
-
constructor(config = {}, context) {
|
|
43
|
-
this.config = config;
|
|
44
|
-
this.context = context || {
|
|
45
|
-
alreadyCompiled: new Set(),
|
|
46
|
-
resolver: config.resolverInstance ? config.resolverInstance : config.resolver ? new config.resolver(config.basedir) : new import_resolver_1.FileSystemResolver(config.basedir),
|
|
47
|
-
uuids: {}
|
|
48
|
-
};
|
|
49
|
-
this.generator.state.grammar.uuids = this.context.uuids;
|
|
50
|
-
}
|
|
51
|
-
export(format, name = 'GWLanguage') {
|
|
52
|
-
const grammar = this.generator.state;
|
|
53
|
-
const output = format || grammar.config.preprocessor || '_default';
|
|
54
|
-
if (TemplateFormats[output]) {
|
|
55
|
-
return TemplateFormats[output](this.generator, name);
|
|
56
|
-
}
|
|
57
|
-
throw new Error("No such preprocessor: " + output);
|
|
58
|
-
}
|
|
59
|
-
async import(directives) {
|
|
60
|
-
if (typeof directives == 'string') {
|
|
61
|
-
await this.mergeLanguageDefinitionString(directives);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
directives = Array.isArray(directives) ? directives : [directives];
|
|
65
|
-
for (const directive of directives) {
|
|
66
|
-
if ("head" in directive) {
|
|
67
|
-
this.generator.state.head.push(directive.head.js);
|
|
68
|
-
}
|
|
69
|
-
else if ("body" in directive) {
|
|
70
|
-
this.generator.state.body.push(directive.body.js);
|
|
71
|
-
}
|
|
72
|
-
else if ("import" in directive) {
|
|
73
|
-
await this.processImportDirective(directive);
|
|
74
|
-
}
|
|
75
|
-
else if ("config" in directive) {
|
|
76
|
-
this.processConfigDirective(directive);
|
|
77
|
-
}
|
|
78
|
-
else if ("grammar" in directive) {
|
|
79
|
-
this.processGrammarDirective(directive);
|
|
80
|
-
}
|
|
81
|
-
else if ("lexer" in directive) {
|
|
82
|
-
this.processLexerDirective(directive);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
async processImportDirective(directive) {
|
|
87
|
-
if (directive.path) {
|
|
88
|
-
await this.importGrammar(directive.import);
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
this.importBuiltIn(directive.import);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
processConfigDirective(directive) {
|
|
95
|
-
Object.assign(this.generator.state.config, directive.config);
|
|
96
|
-
}
|
|
97
|
-
processGrammarDirective(directive) {
|
|
98
|
-
if (directive.grammar.config) {
|
|
99
|
-
this.generator.state.grammar.start = directive.grammar.config.start || this.generator.state.grammar.start;
|
|
100
|
-
}
|
|
101
|
-
for (const rule of directive.grammar.rules) {
|
|
102
|
-
this.buildRules(rule.name, rule.expressions, rule);
|
|
103
|
-
this.generator.state.grammar.start = this.generator.state.grammar.start || rule.name;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
processLexerDirective(directive) {
|
|
107
|
-
if (!this.generator.state.lexer) {
|
|
108
|
-
this.generator.state.lexer = {
|
|
109
|
-
start: '',
|
|
110
|
-
states: {}
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
this.generator.state.lexer.start = directive.lexer.start || this.generator.state.lexer.start || (directive.lexer.states.length ? directive.lexer.states[0].name : '');
|
|
114
|
-
for (const state of directive.lexer.states) {
|
|
115
|
-
this.generator.addLexerState(state);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
importBuiltIn(name) {
|
|
119
|
-
name = name.toLowerCase();
|
|
120
|
-
if (!this.context.alreadyCompiled.has(name)) {
|
|
121
|
-
this.context.alreadyCompiled.add(name);
|
|
122
|
-
if (!BuiltInRegistry[name])
|
|
123
|
-
return;
|
|
124
|
-
this.generator.merge(BuiltInRegistry[name].state);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
async importGrammar(name) {
|
|
128
|
-
const resolver = this.context.resolver;
|
|
129
|
-
const path = resolver.path(name);
|
|
130
|
-
if (!this.context.alreadyCompiled.has(path)) {
|
|
131
|
-
this.context.alreadyCompiled.add(path);
|
|
132
|
-
await this.mergeLanguageDefinitionString(await resolver.body(path));
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
async mergeLanguageDefinitionString(body) {
|
|
136
|
-
const builder = new GrammarBuilder(this.config, this.context);
|
|
137
|
-
await builder.import(this.parser.run(body).results[0]);
|
|
138
|
-
this.generator.merge(builder.generator.state);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
buildRules(name, expressions, rule) {
|
|
142
|
-
for (const expression of expressions) {
|
|
143
|
-
this.generator.addGrammarRule(this.buildRule(name, expression, rule));
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
buildRule(name, expression, rule) {
|
|
147
|
-
const symbols = [];
|
|
148
|
-
for (let i = 0; i < expression.symbols.length; i++) {
|
|
149
|
-
const symbol = this.buildSymbol(name, expression.symbols[i]);
|
|
150
|
-
if (symbol)
|
|
151
|
-
symbols.push(symbol);
|
|
152
|
-
}
|
|
153
|
-
return { name, symbols, postprocess: expression.postprocess || rule?.postprocess };
|
|
154
|
-
}
|
|
155
|
-
buildSymbol(name, symbol) {
|
|
156
|
-
if ('repeat' in symbol) {
|
|
157
|
-
return this.buildRepeatRules(name, symbol);
|
|
158
|
-
}
|
|
159
|
-
if ('rule' in symbol) {
|
|
160
|
-
return symbol;
|
|
161
|
-
}
|
|
162
|
-
if ('regex' in symbol) {
|
|
163
|
-
return symbol;
|
|
164
|
-
}
|
|
165
|
-
if ('token' in symbol) {
|
|
166
|
-
return symbol;
|
|
167
|
-
}
|
|
168
|
-
if ('literal' in symbol) {
|
|
169
|
-
if (!symbol.literal.length) {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
if (symbol.literal.length === 1 || this.generator.state.lexer) {
|
|
173
|
-
return symbol;
|
|
174
|
-
}
|
|
175
|
-
return this.buildCharacterRules(name, symbol);
|
|
176
|
-
}
|
|
177
|
-
if ('subexpression' in symbol) {
|
|
178
|
-
return this.buildSubExpressionRules(name, symbol);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
buildCharacterRules(name, symbol) {
|
|
182
|
-
const id = this.generator.grammarUUID(name + "$STR");
|
|
183
|
-
this.buildRules(id, [
|
|
184
|
-
{
|
|
185
|
-
symbols: symbol.literal
|
|
186
|
-
.split("")
|
|
187
|
-
.map((literal) => {
|
|
188
|
-
if (symbol.insensitive && literal.toLowerCase() != literal.toUpperCase())
|
|
189
|
-
return { regex: literal, flags: 'i' };
|
|
190
|
-
return { literal };
|
|
191
|
-
}),
|
|
192
|
-
postprocess: { builtin: "join" }
|
|
193
|
-
}
|
|
194
|
-
]);
|
|
195
|
-
return { rule: id };
|
|
196
|
-
}
|
|
197
|
-
buildSubExpressionRules(name, symbol) {
|
|
198
|
-
const id = this.generator.grammarUUID(name + "$SUB");
|
|
199
|
-
this.buildRules(id, symbol.subexpression);
|
|
200
|
-
return { rule: id };
|
|
201
|
-
}
|
|
202
|
-
buildRepeatRules(name, symbol) {
|
|
203
|
-
let id;
|
|
204
|
-
const expr1 = { symbols: [] };
|
|
205
|
-
const expr2 = { symbols: [] };
|
|
206
|
-
if (symbol.repeat == '+') {
|
|
207
|
-
id = this.generator.grammarUUID(name + "$RPT1N");
|
|
208
|
-
expr1.symbols = [symbol.expression];
|
|
209
|
-
expr2.symbols = [{ rule: id }, symbol.expression];
|
|
210
|
-
expr2.postprocess = { builtin: "concat" };
|
|
211
|
-
}
|
|
212
|
-
else if (symbol.repeat == '*') {
|
|
213
|
-
id = this.generator.grammarUUID(name + "$RPT0N");
|
|
214
|
-
expr2.symbols = [{ rule: id }, symbol.expression];
|
|
215
|
-
expr2.postprocess = { builtin: "concat" };
|
|
216
|
-
}
|
|
217
|
-
else if (symbol.repeat == '?') {
|
|
218
|
-
id = this.generator.grammarUUID(name + "$RPT01");
|
|
219
|
-
expr1.symbols = [symbol.expression];
|
|
220
|
-
expr1.postprocess = { builtin: "first" };
|
|
221
|
-
expr2.postprocess = { builtin: "null" };
|
|
222
|
-
}
|
|
223
|
-
this.buildRules(id, [expr1, expr2]);
|
|
224
|
-
return { rule: id };
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
exports.GrammarBuilder = GrammarBuilder;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GrammarBuilder = exports.Compile = void 0;
|
|
4
|
+
const parser_1 = require("../parser/parser");
|
|
5
|
+
const import_resolver_1 = require("./import-resolver");
|
|
6
|
+
const gwell_1 = require("../grammars/gwell");
|
|
7
|
+
const javascript_1 = require("./outputs/javascript");
|
|
8
|
+
const typescript_1 = require("./outputs/typescript");
|
|
9
|
+
const json_1 = require("./outputs/json");
|
|
10
|
+
const number = require("../grammars/number.json");
|
|
11
|
+
const string = require("../grammars/string.json");
|
|
12
|
+
const whitespace = require("../grammars/whitespace.json");
|
|
13
|
+
const generator_1 = require("./generator");
|
|
14
|
+
const BuiltInRegistry = {
|
|
15
|
+
number,
|
|
16
|
+
string,
|
|
17
|
+
whitespace,
|
|
18
|
+
};
|
|
19
|
+
const TemplateFormats = {
|
|
20
|
+
_default: javascript_1.JavascriptOutput,
|
|
21
|
+
object: (grammar, exportName) => ({ grammar, exportName }),
|
|
22
|
+
json: json_1.JSONFormatter,
|
|
23
|
+
js: javascript_1.JavascriptOutput,
|
|
24
|
+
javascript: javascript_1.JavascriptOutput,
|
|
25
|
+
module: javascript_1.ESMOutput,
|
|
26
|
+
esmodule: javascript_1.ESMOutput,
|
|
27
|
+
esm: javascript_1.ESMOutput,
|
|
28
|
+
ts: typescript_1.TypescriptFormat,
|
|
29
|
+
typescript: typescript_1.TypescriptFormat
|
|
30
|
+
};
|
|
31
|
+
async function Compile(rules, config = {}) {
|
|
32
|
+
const builder = new GrammarBuilder(config);
|
|
33
|
+
await builder.import(rules);
|
|
34
|
+
return builder.export(config.template);
|
|
35
|
+
}
|
|
36
|
+
exports.Compile = Compile;
|
|
37
|
+
class GrammarBuilder {
|
|
38
|
+
config;
|
|
39
|
+
parser = new parser_1.Parser((0, gwell_1.default)());
|
|
40
|
+
context;
|
|
41
|
+
generator = new generator_1.Generator();
|
|
42
|
+
constructor(config = {}, context) {
|
|
43
|
+
this.config = config;
|
|
44
|
+
this.context = context || {
|
|
45
|
+
alreadyCompiled: new Set(),
|
|
46
|
+
resolver: config.resolverInstance ? config.resolverInstance : config.resolver ? new config.resolver(config.basedir) : new import_resolver_1.FileSystemResolver(config.basedir),
|
|
47
|
+
uuids: {}
|
|
48
|
+
};
|
|
49
|
+
this.generator.state.grammar.uuids = this.context.uuids;
|
|
50
|
+
}
|
|
51
|
+
export(format, name = 'GWLanguage') {
|
|
52
|
+
const grammar = this.generator.state;
|
|
53
|
+
const output = format || grammar.config.preprocessor || '_default';
|
|
54
|
+
if (TemplateFormats[output]) {
|
|
55
|
+
return TemplateFormats[output](this.generator, name);
|
|
56
|
+
}
|
|
57
|
+
throw new Error("No such preprocessor: " + output);
|
|
58
|
+
}
|
|
59
|
+
async import(directives) {
|
|
60
|
+
if (typeof directives == 'string') {
|
|
61
|
+
await this.mergeLanguageDefinitionString(directives);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
directives = Array.isArray(directives) ? directives : [directives];
|
|
65
|
+
for (const directive of directives) {
|
|
66
|
+
if ("head" in directive) {
|
|
67
|
+
this.generator.state.head.push(directive.head.js);
|
|
68
|
+
}
|
|
69
|
+
else if ("body" in directive) {
|
|
70
|
+
this.generator.state.body.push(directive.body.js);
|
|
71
|
+
}
|
|
72
|
+
else if ("import" in directive) {
|
|
73
|
+
await this.processImportDirective(directive);
|
|
74
|
+
}
|
|
75
|
+
else if ("config" in directive) {
|
|
76
|
+
this.processConfigDirective(directive);
|
|
77
|
+
}
|
|
78
|
+
else if ("grammar" in directive) {
|
|
79
|
+
this.processGrammarDirective(directive);
|
|
80
|
+
}
|
|
81
|
+
else if ("lexer" in directive) {
|
|
82
|
+
this.processLexerDirective(directive);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async processImportDirective(directive) {
|
|
87
|
+
if (directive.path) {
|
|
88
|
+
await this.importGrammar(directive.import);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.importBuiltIn(directive.import);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
processConfigDirective(directive) {
|
|
95
|
+
Object.assign(this.generator.state.config, directive.config);
|
|
96
|
+
}
|
|
97
|
+
processGrammarDirective(directive) {
|
|
98
|
+
if (directive.grammar.config) {
|
|
99
|
+
this.generator.state.grammar.start = directive.grammar.config.start || this.generator.state.grammar.start;
|
|
100
|
+
}
|
|
101
|
+
for (const rule of directive.grammar.rules) {
|
|
102
|
+
this.buildRules(rule.name, rule.expressions, rule);
|
|
103
|
+
this.generator.state.grammar.start = this.generator.state.grammar.start || rule.name;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
processLexerDirective(directive) {
|
|
107
|
+
if (!this.generator.state.lexer) {
|
|
108
|
+
this.generator.state.lexer = {
|
|
109
|
+
start: '',
|
|
110
|
+
states: {}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
this.generator.state.lexer.start = directive.lexer.start || this.generator.state.lexer.start || (directive.lexer.states.length ? directive.lexer.states[0].name : '');
|
|
114
|
+
for (const state of directive.lexer.states) {
|
|
115
|
+
this.generator.addLexerState(state);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
importBuiltIn(name) {
|
|
119
|
+
name = name.toLowerCase();
|
|
120
|
+
if (!this.context.alreadyCompiled.has(name)) {
|
|
121
|
+
this.context.alreadyCompiled.add(name);
|
|
122
|
+
if (!BuiltInRegistry[name])
|
|
123
|
+
return;
|
|
124
|
+
this.generator.merge(BuiltInRegistry[name].state);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async importGrammar(name) {
|
|
128
|
+
const resolver = this.context.resolver;
|
|
129
|
+
const path = resolver.path(name);
|
|
130
|
+
if (!this.context.alreadyCompiled.has(path)) {
|
|
131
|
+
this.context.alreadyCompiled.add(path);
|
|
132
|
+
await this.mergeLanguageDefinitionString(await resolver.body(path));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async mergeLanguageDefinitionString(body) {
|
|
136
|
+
const builder = new GrammarBuilder(this.config, this.context);
|
|
137
|
+
await builder.import(this.parser.run(body).results[0]);
|
|
138
|
+
this.generator.merge(builder.generator.state);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
buildRules(name, expressions, rule) {
|
|
142
|
+
for (const expression of expressions) {
|
|
143
|
+
this.generator.addGrammarRule(this.buildRule(name, expression, rule));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
buildRule(name, expression, rule) {
|
|
147
|
+
const symbols = [];
|
|
148
|
+
for (let i = 0; i < expression.symbols.length; i++) {
|
|
149
|
+
const symbol = this.buildSymbol(name, expression.symbols[i]);
|
|
150
|
+
if (symbol)
|
|
151
|
+
symbols.push(symbol);
|
|
152
|
+
}
|
|
153
|
+
return { name, symbols, postprocess: expression.postprocess || rule?.postprocess };
|
|
154
|
+
}
|
|
155
|
+
buildSymbol(name, symbol) {
|
|
156
|
+
if ('repeat' in symbol) {
|
|
157
|
+
return this.buildRepeatRules(name, symbol);
|
|
158
|
+
}
|
|
159
|
+
if ('rule' in symbol) {
|
|
160
|
+
return symbol;
|
|
161
|
+
}
|
|
162
|
+
if ('regex' in symbol) {
|
|
163
|
+
return symbol;
|
|
164
|
+
}
|
|
165
|
+
if ('token' in symbol) {
|
|
166
|
+
return symbol;
|
|
167
|
+
}
|
|
168
|
+
if ('literal' in symbol) {
|
|
169
|
+
if (!symbol.literal.length) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
if (symbol.literal.length === 1 || this.generator.state.lexer) {
|
|
173
|
+
return symbol;
|
|
174
|
+
}
|
|
175
|
+
return this.buildCharacterRules(name, symbol);
|
|
176
|
+
}
|
|
177
|
+
if ('subexpression' in symbol) {
|
|
178
|
+
return this.buildSubExpressionRules(name, symbol);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
buildCharacterRules(name, symbol) {
|
|
182
|
+
const id = this.generator.grammarUUID(name + "$STR");
|
|
183
|
+
this.buildRules(id, [
|
|
184
|
+
{
|
|
185
|
+
symbols: symbol.literal
|
|
186
|
+
.split("")
|
|
187
|
+
.map((literal) => {
|
|
188
|
+
if (symbol.insensitive && literal.toLowerCase() != literal.toUpperCase())
|
|
189
|
+
return { regex: literal, flags: 'i' };
|
|
190
|
+
return { literal };
|
|
191
|
+
}),
|
|
192
|
+
postprocess: { builtin: "join" }
|
|
193
|
+
}
|
|
194
|
+
]);
|
|
195
|
+
return { rule: id };
|
|
196
|
+
}
|
|
197
|
+
buildSubExpressionRules(name, symbol) {
|
|
198
|
+
const id = this.generator.grammarUUID(name + "$SUB");
|
|
199
|
+
this.buildRules(id, symbol.subexpression);
|
|
200
|
+
return { rule: id };
|
|
201
|
+
}
|
|
202
|
+
buildRepeatRules(name, symbol) {
|
|
203
|
+
let id;
|
|
204
|
+
const expr1 = { symbols: [] };
|
|
205
|
+
const expr2 = { symbols: [] };
|
|
206
|
+
if (symbol.repeat == '+') {
|
|
207
|
+
id = this.generator.grammarUUID(name + "$RPT1N");
|
|
208
|
+
expr1.symbols = [symbol.expression];
|
|
209
|
+
expr2.symbols = [{ rule: id }, symbol.expression];
|
|
210
|
+
expr2.postprocess = { builtin: "concat" };
|
|
211
|
+
}
|
|
212
|
+
else if (symbol.repeat == '*') {
|
|
213
|
+
id = this.generator.grammarUUID(name + "$RPT0N");
|
|
214
|
+
expr2.symbols = [{ rule: id }, symbol.expression];
|
|
215
|
+
expr2.postprocess = { builtin: "concat" };
|
|
216
|
+
}
|
|
217
|
+
else if (symbol.repeat == '?') {
|
|
218
|
+
id = this.generator.grammarUUID(name + "$RPT01");
|
|
219
|
+
expr1.symbols = [symbol.expression];
|
|
220
|
+
expr1.postprocess = { builtin: "first" };
|
|
221
|
+
expr2.postprocess = { builtin: "null" };
|
|
222
|
+
}
|
|
223
|
+
this.buildRules(id, [expr1, expr2]);
|
|
224
|
+
return { rule: id };
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
exports.GrammarBuilder = GrammarBuilder;
|
|
228
228
|
//# sourceMappingURL=compiler.js.map
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { GeneratorState, GeneratorGrammarRule, LexerStateDefinition } from "../typings";
|
|
2
|
-
export declare class Generator {
|
|
3
|
-
state: GeneratorState;
|
|
4
|
-
serializeHead(): string;
|
|
5
|
-
serializeBody(): string;
|
|
6
|
-
serializeLanguage(depth?: number): string;
|
|
7
|
-
merge(state: GeneratorState): void;
|
|
8
|
-
grammarUUID(name: string): string;
|
|
9
|
-
addGrammarRule(rule: GeneratorGrammarRule): void;
|
|
10
|
-
addLexerState(state: LexerStateDefinition): void;
|
|
11
|
-
private serializeGrammar;
|
|
12
|
-
private serializeGrammarRules;
|
|
13
|
-
private serializeSymbol;
|
|
14
|
-
private serializeGrammarRule;
|
|
15
|
-
private serializePostProcess;
|
|
16
|
-
private templatePostProcess;
|
|
17
|
-
private serializeLexerConfig;
|
|
18
|
-
private serializeLexerConfigStates;
|
|
19
|
-
private serializeLexerConfigStateRules;
|
|
20
|
-
private newLine;
|
|
21
|
-
private pretty;
|
|
22
|
-
private isVal;
|
|
23
|
-
}
|
|
1
|
+
import { GeneratorState, GeneratorGrammarRule, LexerStateDefinition } from "../typings";
|
|
2
|
+
export declare class Generator {
|
|
3
|
+
state: GeneratorState;
|
|
4
|
+
serializeHead(): string;
|
|
5
|
+
serializeBody(): string;
|
|
6
|
+
serializeLanguage(depth?: number): string;
|
|
7
|
+
merge(state: GeneratorState): void;
|
|
8
|
+
grammarUUID(name: string): string;
|
|
9
|
+
addGrammarRule(rule: GeneratorGrammarRule): void;
|
|
10
|
+
addLexerState(state: LexerStateDefinition): void;
|
|
11
|
+
private serializeGrammar;
|
|
12
|
+
private serializeGrammarRules;
|
|
13
|
+
private serializeSymbol;
|
|
14
|
+
private serializeGrammarRule;
|
|
15
|
+
private serializePostProcess;
|
|
16
|
+
private templatePostProcess;
|
|
17
|
+
private serializeLexerConfig;
|
|
18
|
+
private serializeLexerConfigStates;
|
|
19
|
+
private serializeLexerConfigStateRules;
|
|
20
|
+
private newLine;
|
|
21
|
+
private pretty;
|
|
22
|
+
private isVal;
|
|
23
|
+
}
|