grammar-well 1.3.3 → 2.0.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.
Files changed (246) hide show
  1. package/README.md +76 -560
  2. package/build/generator/artifacts/basic.d.ts +7 -0
  3. package/build/generator/artifacts/basic.js +24 -0
  4. package/build/generator/artifacts/basic.js.map +1 -0
  5. package/build/generator/artifacts/lexer.d.ts +13 -0
  6. package/build/generator/artifacts/lexer.js +204 -0
  7. package/build/generator/artifacts/lexer.js.map +1 -0
  8. package/build/{compiler/generator → generator}/artifacts/lr.d.ts +14 -14
  9. package/build/{compiler/generator → generator}/artifacts/lr.js +18 -22
  10. package/build/generator/artifacts/lr.js.map +1 -0
  11. package/build/generator/builtin/registry.json +1 -0
  12. package/build/generator/generator.d.ts +38 -0
  13. package/build/generator/generator.js +368 -0
  14. package/build/generator/generator.js.map +1 -0
  15. package/build/generator/grammars/index.d.ts +2 -0
  16. package/build/generator/grammars/index.js +3 -0
  17. package/build/generator/grammars/index.js.map +1 -0
  18. package/build/generator/grammars/v1.d.ts +1190 -0
  19. package/build/generator/grammars/v1.js +614 -0
  20. package/build/generator/grammars/v1.js.map +1 -0
  21. package/build/generator/grammars/v2.d.ts +1367 -0
  22. package/build/generator/grammars/v2.js +695 -0
  23. package/build/generator/grammars/v2.js.map +1 -0
  24. package/build/generator/import-resolvers/auto.d.ts +2 -0
  25. package/build/generator/import-resolvers/auto.js +11 -0
  26. package/build/generator/import-resolvers/auto.js.map +1 -0
  27. package/build/generator/import-resolvers/browser.d.ts +7 -0
  28. package/build/generator/import-resolvers/browser.js +13 -0
  29. package/build/generator/import-resolvers/browser.js.map +1 -0
  30. package/build/generator/import-resolvers/filesystem.d.ts +7 -0
  31. package/build/generator/import-resolvers/filesystem.js +15 -0
  32. package/build/generator/import-resolvers/filesystem.js.map +1 -0
  33. package/build/generator/index.d.ts +3 -0
  34. package/build/generator/index.js +4 -0
  35. package/build/generator/index.js.map +1 -0
  36. package/build/generator/state.d.ts +28 -0
  37. package/build/generator/state.js +73 -0
  38. package/build/generator/state.js.map +1 -0
  39. package/build/generator/stringify/common.d.ts +22 -0
  40. package/build/generator/stringify/common.js +83 -0
  41. package/build/generator/stringify/common.js.map +1 -0
  42. package/build/generator/stringify/exports/javascript.d.ts +3 -0
  43. package/build/generator/stringify/exports/javascript.js +26 -0
  44. package/build/generator/stringify/exports/javascript.js.map +1 -0
  45. package/build/generator/stringify/exports/json.d.ts +2 -0
  46. package/build/generator/stringify/exports/json.js +4 -0
  47. package/build/generator/stringify/exports/json.js.map +1 -0
  48. package/build/generator/stringify/exports/registry.d.ts +20 -0
  49. package/build/generator/stringify/exports/registry.js +17 -0
  50. package/build/generator/stringify/exports/registry.js.map +1 -0
  51. package/build/generator/stringify/exports/typescript.d.ts +2 -0
  52. package/build/generator/stringify/exports/typescript.js +16 -0
  53. package/build/generator/stringify/exports/typescript.js.map +1 -0
  54. package/build/generator/stringify/grammar/v2.d.ts +20 -0
  55. package/build/generator/stringify/grammar/v2.js +211 -0
  56. package/build/generator/stringify/grammar/v2.js.map +1 -0
  57. package/build/generator/stringify/javascript.d.ts +13 -0
  58. package/build/generator/stringify/javascript.js +83 -0
  59. package/build/generator/stringify/javascript.js.map +1 -0
  60. package/build/index.d.ts +7 -6
  61. package/build/index.js +7 -24
  62. package/build/index.js.map +1 -1
  63. package/build/lexers/character-lexer.d.ts +2 -2
  64. package/build/lexers/character-lexer.js +1 -5
  65. package/build/lexers/character-lexer.js.map +1 -1
  66. package/build/lexers/stateful-lexer.d.ts +12 -17
  67. package/build/lexers/stateful-lexer.js +38 -186
  68. package/build/lexers/stateful-lexer.js.map +1 -1
  69. package/build/lexers/token-buffer.d.ts +8 -8
  70. package/build/lexers/token-buffer.js +1 -5
  71. package/build/lexers/token-buffer.js.map +1 -1
  72. package/build/parser/algorithms/cyk.d.ts +6 -6
  73. package/build/parser/algorithms/cyk.js +10 -13
  74. package/build/parser/algorithms/cyk.js.map +1 -1
  75. package/build/parser/algorithms/earley.d.ts +7 -7
  76. package/build/parser/algorithms/earley.js +7 -11
  77. package/build/parser/algorithms/earley.js.map +1 -1
  78. package/build/parser/algorithms/lrk/algorithm.d.ts +3 -3
  79. package/build/parser/algorithms/lrk/algorithm.js +10 -13
  80. package/build/parser/algorithms/lrk/algorithm.js.map +1 -1
  81. package/build/parser/algorithms/lrk/bimap.js +1 -5
  82. package/build/parser/algorithms/lrk/bimap.js.map +1 -1
  83. package/build/parser/algorithms/lrk/canonical-collection.d.ts +7 -7
  84. package/build/parser/algorithms/lrk/canonical-collection.js +11 -15
  85. package/build/parser/algorithms/lrk/canonical-collection.js.map +1 -1
  86. package/build/parser/algorithms/lrk/closure.d.ts +3 -3
  87. package/build/parser/algorithms/lrk/closure.js +3 -7
  88. package/build/parser/algorithms/lrk/closure.js.map +1 -1
  89. package/build/parser/algorithms/lrk/stack.d.ts +6 -6
  90. package/build/parser/algorithms/lrk/stack.js +1 -5
  91. package/build/parser/algorithms/lrk/stack.js.map +1 -1
  92. package/build/parser/algorithms/lrk/state.d.ts +5 -5
  93. package/build/parser/algorithms/lrk/state.js +1 -2
  94. package/build/parser/parse.d.ts +10 -0
  95. package/build/parser/parse.js +34 -0
  96. package/build/parser/parse.js.map +1 -0
  97. package/build/tsconfig.tsbuildinfo +1 -0
  98. package/build/typings/ast.d.ts +134 -0
  99. package/build/typings/ast.js +3 -0
  100. package/build/typings/ast.js.map +1 -0
  101. package/build/typings/common.d.ts +4 -0
  102. package/build/typings/common.js +2 -0
  103. package/build/typings/common.js.map +1 -0
  104. package/build/typings/generator.d.ts +58 -0
  105. package/build/typings/generator.js +3 -0
  106. package/build/typings/generator.js.map +1 -0
  107. package/build/typings/index.d.ts +43 -0
  108. package/build/typings/index.js +5 -0
  109. package/build/typings/index.js.map +1 -0
  110. package/build/typings/runtime.d.ts +70 -0
  111. package/build/typings/runtime.js +2 -0
  112. package/build/typings/runtime.js.map +1 -0
  113. package/build/utility/format.d.ts +1 -0
  114. package/build/utility/format.js +12 -0
  115. package/build/utility/format.js.map +1 -0
  116. package/build/utility/general.d.ts +1 -1
  117. package/build/utility/general.js +5 -13
  118. package/build/utility/general.js.map +1 -1
  119. package/build/utility/index.d.ts +4 -1
  120. package/build/utility/index.js +4 -17
  121. package/build/utility/index.js.map +1 -1
  122. package/build/utility/lint.d.ts +2 -2
  123. package/build/utility/lint.js +2 -6
  124. package/build/utility/lint.js.map +1 -1
  125. package/build/utility/monarch.d.ts +2 -2
  126. package/build/utility/monarch.js +33 -38
  127. package/build/utility/monarch.js.map +1 -1
  128. package/build/utility/parsing.d.ts +6 -0
  129. package/build/utility/parsing.js +26 -0
  130. package/build/utility/parsing.js.map +1 -0
  131. package/build/utility/text-format.d.ts +6 -6
  132. package/build/utility/text-format.js +2 -6
  133. package/build/utility/text-format.js.map +1 -1
  134. package/package.json +17 -24
  135. package/src/generator/artifacts/basic.ts +26 -0
  136. package/src/generator/artifacts/lexer.ts +228 -0
  137. package/src/{compiler/generator → generator}/artifacts/lr.ts +25 -24
  138. package/src/generator/builtin/character.well +7 -0
  139. package/src/generator/builtin/json.well +85 -0
  140. package/src/generator/builtin/number.well +21 -0
  141. package/src/generator/builtin/registry.json +1 -0
  142. package/src/generator/builtin/string.well +54 -0
  143. package/src/generator/builtin/whitespace.well +16 -0
  144. package/src/generator/generator.ts +401 -0
  145. package/src/generator/grammars/index.ts +2 -0
  146. package/src/generator/grammars/v1.ts +620 -0
  147. package/src/generator/grammars/v1.well +422 -0
  148. package/src/generator/grammars/v2.ts +701 -0
  149. package/src/generator/grammars/v2.well +413 -0
  150. package/src/generator/import-resolvers/auto.ts +12 -0
  151. package/src/generator/import-resolvers/browser.ts +13 -0
  152. package/src/generator/import-resolvers/filesystem.ts +18 -0
  153. package/src/generator/index.ts +3 -0
  154. package/src/generator/state.ts +89 -0
  155. package/src/generator/stringify/common.ts +90 -0
  156. package/src/generator/stringify/exports/javascript.ts +29 -0
  157. package/src/generator/stringify/exports/json.ts +5 -0
  158. package/src/generator/stringify/exports/registry.ts +20 -0
  159. package/src/generator/stringify/exports/typescript.ts +17 -0
  160. package/src/generator/stringify/grammar/v2.ts +223 -0
  161. package/src/generator/stringify/javascript.ts +94 -0
  162. package/src/index.ts +7 -6
  163. package/src/lexers/character-lexer.ts +2 -2
  164. package/src/lexers/stateful-lexer.ts +46 -203
  165. package/src/lexers/token-buffer.ts +3 -3
  166. package/src/parser/algorithms/cyk.ts +13 -12
  167. package/src/parser/algorithms/earley.ts +10 -10
  168. package/src/parser/algorithms/lrk/algorithm.ts +8 -7
  169. package/src/parser/algorithms/lrk/canonical-collection.ts +14 -14
  170. package/src/parser/algorithms/lrk/closure.ts +6 -6
  171. package/src/parser/algorithms/lrk/stack.ts +6 -6
  172. package/src/parser/algorithms/lrk/state.ts +5 -5
  173. package/src/parser/parse.ts +45 -0
  174. package/src/typings/ast.ts +148 -0
  175. package/src/typings/common.ts +2 -0
  176. package/src/typings/generator.ts +62 -0
  177. package/src/typings/index.ts +38 -0
  178. package/src/typings/runtime.ts +82 -0
  179. package/src/utility/format.ts +12 -0
  180. package/src/utility/general.ts +1 -2
  181. package/src/utility/index.ts +4 -1
  182. package/src/utility/lint.ts +5 -5
  183. package/src/utility/monarch.ts +34 -34
  184. package/src/utility/parsing.ts +30 -0
  185. package/src/utility/text-format.ts +7 -7
  186. package/.eslintrc.cjs +0 -14
  187. package/bootstrap.ts +0 -45
  188. package/build/compiler/builtin.json +0 -1
  189. package/build/compiler/compiler.d.ts +0 -50
  190. package/build/compiler/compiler.js +0 -249
  191. package/build/compiler/compiler.js.map +0 -1
  192. package/build/compiler/generator/artifacts/lr.js.map +0 -1
  193. package/build/compiler/generator/artifacts/standard.d.ts +0 -7
  194. package/build/compiler/generator/artifacts/standard.js +0 -28
  195. package/build/compiler/generator/artifacts/standard.js.map +0 -1
  196. package/build/compiler/generator/generator.d.ts +0 -24
  197. package/build/compiler/generator/generator.js +0 -217
  198. package/build/compiler/generator/generator.js.map +0 -1
  199. package/build/compiler/gwell.d.ts +0 -1112
  200. package/build/compiler/gwell.js +0 -576
  201. package/build/compiler/gwell.js.map +0 -1
  202. package/build/compiler/import-resolver.d.ts +0 -15
  203. package/build/compiler/import-resolver.js +0 -37
  204. package/build/compiler/import-resolver.js.map +0 -1
  205. package/build/compiler/index.d.ts +0 -2
  206. package/build/compiler/index.js +0 -19
  207. package/build/compiler/index.js.map +0 -1
  208. package/build/compiler/outputs/javascript.d.ts +0 -3
  209. package/build/compiler/outputs/javascript.js +0 -29
  210. package/build/compiler/outputs/javascript.js.map +0 -1
  211. package/build/compiler/outputs/json.d.ts +0 -2
  212. package/build/compiler/outputs/json.js +0 -8
  213. package/build/compiler/outputs/json.js.map +0 -1
  214. package/build/compiler/outputs/typescript.d.ts +0 -2
  215. package/build/compiler/outputs/typescript.js +0 -21
  216. package/build/compiler/outputs/typescript.js.map +0 -1
  217. package/build/parser/algorithms/lr.d.ts +0 -7
  218. package/build/parser/algorithms/lr.js +0 -108
  219. package/build/parser/algorithms/lr.js.map +0 -5
  220. package/build/parser/algorithms/lr0.d.ts +0 -7
  221. package/build/parser/algorithms/lr0.js +0 -156
  222. package/build/parser/algorithms/lr0.js.map +0 -1
  223. package/build/parser/parser.d.ts +0 -26
  224. package/build/parser/parser.js +0 -74
  225. package/build/parser/parser.js.map +0 -1
  226. package/build/typings.d.ts +0 -226
  227. package/build/typings.js +0 -3
  228. package/build/typings.js.map +0 -1
  229. package/src/compiler/builtin/json.gwell +0 -74
  230. package/src/compiler/builtin/number.gwell +0 -20
  231. package/src/compiler/builtin/string.gwell +0 -48
  232. package/src/compiler/builtin/whitespace.gwell +0 -10
  233. package/src/compiler/builtin.json +0 -1
  234. package/src/compiler/compiler.ts +0 -265
  235. package/src/compiler/generator/artifacts/standard.ts +0 -26
  236. package/src/compiler/generator/generator.ts +0 -237
  237. package/src/compiler/gwell.gwell +0 -294
  238. package/src/compiler/gwell.js +0 -578
  239. package/src/compiler/import-resolver.ts +0 -36
  240. package/src/compiler/index.ts +0 -2
  241. package/src/compiler/outputs/javascript.ts +0 -27
  242. package/src/compiler/outputs/json.ts +0 -5
  243. package/src/compiler/outputs/typescript.ts +0 -18
  244. package/src/parser/parser.ts +0 -77
  245. package/src/typings.ts +0 -248
  246. package/testing.ts +0 -18
@@ -1,265 +0,0 @@
1
- import { CompileOptions, GrammarBuilderContext, TemplateFormat, LanguageDirective, ConfigDirective, GrammarBuilderSymbolRepeat, GrammarBuilderExpression, GeneratorGrammarRule, GrammarDirective, ImportDirective, LexerDirective, GrammarBuilderSymbolSubexpression, GrammarTypeLiteral, GeneratorGrammarSymbol, GrammarBuilderSymbol, GrammarBuilderRule } from "../typings";
2
-
3
- import { Parser } from "../parser/parser";
4
- import { FileSystemResolver } from "./import-resolver";
5
- import Language from './gwell';
6
-
7
- import { ESMOutput, JavascriptOutput } from "./outputs/javascript";
8
- import { TypescriptFormat } from "./outputs/typescript";
9
- import { JSONFormatter } from "./outputs/json";
10
-
11
- import { Generator } from "./generator/generator";
12
- import * as BuiltInRegistry from "./builtin.json"
13
-
14
- const TemplateFormats = {
15
- _default: JavascriptOutput,
16
- object: (grammar, exportName) => ({ grammar, exportName }),
17
- json: JSONFormatter,
18
- js: JavascriptOutput,
19
- javascript: JavascriptOutput,
20
- module: ESMOutput,
21
- esmodule: ESMOutput,
22
- esm: ESMOutput,
23
- ts: TypescriptFormat,
24
- typescript: TypescriptFormat
25
- }
26
-
27
- export async function Compile(rules: string | LanguageDirective | (LanguageDirective[]), config: CompileOptions = {}) {
28
- const builder = new GrammarBuilder(config);
29
- await builder.import(rules as any);
30
- Object.assign(builder.generator.state.config, config.overrides);
31
- return builder.export(config.template);
32
- }
33
-
34
- export class GrammarBuilder {
35
- private parser = new Parser(Language() as any);
36
- private context: GrammarBuilderContext;
37
-
38
- generator = new Generator();
39
-
40
- constructor(private config: CompileOptions = {}, context?: GrammarBuilderContext, private alias: string = '') {
41
- this.context = context || {
42
- alreadyCompiled: new Set(),
43
- resolver: config.resolverInstance ? config.resolverInstance : config.resolver ? new config.resolver(config.basedir) : new FileSystemResolver(config.basedir),
44
- uuids: {}
45
- }
46
- this.generator.state.grammar.uuids = this.context.uuids;
47
- }
48
-
49
- export<T extends TemplateFormat = '_default'>(format: T, name: string = 'GWLanguage'): ReturnType<typeof TemplateFormats[T]> {
50
- const grammar = this.generator.state;
51
- const output = format || grammar.config.preprocessor || '_default';
52
- if (TemplateFormats[output]) {
53
- return TemplateFormats[output](this.generator, name);
54
- }
55
- throw new Error("No such preprocessor: " + output)
56
- }
57
-
58
- async import(source: string): Promise<void>
59
- async import(directive: LanguageDirective): Promise<void>
60
- async import(directives: LanguageDirective[]): Promise<void>
61
- async import(directives: string | LanguageDirective | (LanguageDirective[])): Promise<void> {
62
- if (typeof directives == 'string') {
63
- await this.mergeLanguageDefinitionString(directives);
64
- return;
65
- }
66
- directives = Array.isArray(directives) ? directives : [directives];
67
- for (const directive of directives) {
68
- if ("head" in directive) {
69
- this.generator.state.head.push(directive.head.js);
70
- } else if ("body" in directive) {
71
- this.generator.state.body.push(directive.body.js);
72
- } else if ("import" in directive) {
73
- await this.processImportDirective(directive);
74
- } else if ("config" in directive) {
75
- this.processConfigDirective(directive);
76
- } else if ("grammar" in directive) {
77
- this.processGrammarDirective(directive);
78
- } else if ("lexer" in directive) {
79
- this.processLexerDirective(directive);
80
- }
81
- }
82
- }
83
-
84
- private async processImportDirective(directive: ImportDirective) {
85
- if (directive.path) {
86
- await this.importGrammar(directive.import, this.alias + (directive.alias || ''));
87
- } else {
88
- await this.importBuiltIn(directive.import, this.alias + (directive.alias || ''));
89
- }
90
- }
91
-
92
- private processConfigDirective(directive: ConfigDirective) {
93
- Object.assign(this.generator.state.config, directive.config);
94
- }
95
-
96
- private processGrammarDirective(directive: GrammarDirective) {
97
- if (directive.grammar.config) {
98
- if (directive.grammar.config.start) {
99
- this.generator.state.grammar.start = this.alias + directive.grammar.config.start;
100
- }
101
-
102
- Object.assign(this.generator.state.grammar.config, directive.grammar.config);
103
- // this.generator.state.grammar.postprocessDefault = directive.grammar.config.postprocessDefault || this.generator.state.grammar.postprocessDefault;
104
- // this.generator.state.grammar.postprocessOverride = directive.grammar.config.postprocessOverride || this.generator.state.grammar.postprocessOverride;
105
- }
106
-
107
- if (!this.generator.state.grammar.start && directive.grammar.rules.length) {
108
- this.generator.state.grammar.start = this.alias + directive.grammar.rules[0].name;
109
- }
110
-
111
- for (const rule of directive.grammar.rules) {
112
- rule.name = this.alias + rule.name;
113
- this.buildRules(rule.name, rule.expressions, rule);
114
- }
115
- }
116
-
117
- private processLexerDirective(directive: LexerDirective) {
118
- if (!this.generator.state.lexer) {
119
- this.generator.state.lexer = {
120
- start: '',
121
- states: {}
122
- };
123
- }
124
- if (directive.lexer.start) {
125
- this.generator.state.lexer.start = this.alias + directive.lexer.start;
126
- }
127
-
128
- if (!this.generator.state.lexer.start && directive.lexer.states.length) {
129
- this.generator.state.lexer.start = this.alias + directive.lexer.states[0].name
130
- }
131
-
132
- for (const state of directive.lexer.states) {
133
- state.name = this.alias + state.name;
134
- if (this.alias) {
135
- state.rules.forEach(v => {
136
- if ('import' in v) {
137
- v.import = v.import.map(v2 => this.alias + v2);
138
- }
139
- if ('set' in v) {
140
- v.set = this.alias + v.set;
141
- }
142
- if ('goto' in v) {
143
- v.goto = this.alias + v.goto;
144
- }
145
- })
146
- }
147
- this.generator.addLexerState(state);
148
- }
149
- }
150
-
151
- private async importBuiltIn(name: string, alias?: string) {
152
- name = name.toLowerCase();
153
- if (!this.context.alreadyCompiled.has(name)) {
154
- this.context.alreadyCompiled.add(name);
155
- if (!BuiltInRegistry[name])
156
- return;
157
- await this.mergeLanguageDefinitionString(BuiltInRegistry[name], alias);
158
- }
159
- }
160
-
161
- private async importGrammar(path: string, alias?: string) {
162
- const resolver = this.context.resolver;
163
- const fullPath = resolver.path(path);
164
- if (!this.context.alreadyCompiled.has(fullPath)) {
165
- this.context.alreadyCompiled.add(fullPath);
166
- await this.mergeLanguageDefinitionString(await resolver.body(fullPath), alias);
167
- }
168
- }
169
-
170
- private async mergeLanguageDefinitionString(body: string, alias: string = '') {
171
- const builder = new GrammarBuilder(this.config, this.context, alias);
172
- await builder.import(this.parser.run(body).results[0]);
173
- this.generator.merge(builder.generator.state);
174
- return;
175
- }
176
-
177
- private buildRules(name: string, expressions: GrammarBuilderExpression[], rule?: GrammarBuilderRule) {
178
- for (const expression of expressions) {
179
- this.generator.addGrammarRule(this.buildRule(name, expression, rule));
180
- }
181
- }
182
-
183
- private buildRule(name: string, expression: GrammarBuilderExpression, rule?: GrammarBuilderRule): GeneratorGrammarRule {
184
- const symbols: GeneratorGrammarSymbol[] = [];
185
- for (let i = 0; i < expression.symbols.length; i++) {
186
- const symbol = this.buildSymbol(name, expression.symbols[i]);
187
- if (symbol)
188
- symbols.push(symbol);
189
- }
190
- return { name, symbols, postprocess: expression.postprocess || rule?.postprocess };
191
- }
192
-
193
- private buildSymbol(name: string, symbol: GrammarBuilderSymbol): GeneratorGrammarSymbol {
194
- if ('repeat' in symbol) {
195
- return this.buildRepeatRules(name, symbol);
196
- }
197
- if ('rule' in symbol) {
198
- return { ...symbol, rule: this.alias + symbol.rule };
199
- }
200
- if ('regex' in symbol) {
201
- return symbol;
202
- }
203
- if ('token' in symbol) {
204
- return symbol;
205
- }
206
- if ('literal' in symbol) {
207
- if (!symbol.literal.length) {
208
- return null;
209
- }
210
- if (symbol.literal.length === 1 || this.generator.state.lexer) {
211
- return symbol;
212
- }
213
- return this.buildCharacterRules(name, symbol);
214
- }
215
- if ('subexpression' in symbol) {
216
- return this.buildSubExpressionRules(name, symbol);
217
- }
218
- }
219
-
220
- private buildCharacterRules(name: string, symbol: GrammarTypeLiteral) {
221
- const id = this.generator.grammarUUID(name + "$STR");
222
- this.buildRules(id, [
223
- {
224
- symbols: symbol.literal
225
- .split("")
226
- .map((literal) => {
227
- if (symbol.insensitive && literal.toLowerCase() != literal.toUpperCase())
228
- return { regex: literal, flags: 'i' }
229
- return { literal }
230
- }),
231
- postprocess: { builtin: "join" }
232
- }
233
- ]);
234
- return { rule: id };
235
- }
236
-
237
- private buildSubExpressionRules(name: string, symbol: GrammarBuilderSymbolSubexpression) {
238
- const id = this.generator.grammarUUID(name + "$SUB");
239
- this.buildRules(id, symbol.subexpression);
240
- return { rule: id };
241
- }
242
-
243
- private buildRepeatRules(name: string, symbol: GrammarBuilderSymbolRepeat) {
244
- let id: string;
245
- const expr1: GrammarBuilderExpression = { symbols: [] };
246
- const expr2: GrammarBuilderExpression = { symbols: [] };
247
- if (symbol.repeat == '+') {
248
- id = this.generator.grammarUUID(name + "$RPT1N");
249
- expr1.symbols = [symbol.expression];
250
- expr2.symbols = [{ rule: id }, symbol.expression];
251
- expr2.postprocess = { builtin: "concat" };
252
- } else if (symbol.repeat == '*') {
253
- id = this.generator.grammarUUID(name + "$RPT0N");
254
- expr2.symbols = [{ rule: id }, symbol.expression];
255
- expr2.postprocess = { builtin: "concat" };
256
- } else if (symbol.repeat == '?') {
257
- id = this.generator.grammarUUID(name + "$RPT01");
258
- expr1.symbols = [symbol.expression];
259
- expr1.postprocess = { builtin: "first" };
260
- expr2.postprocess = { builtin: "null" };
261
- }
262
- this.buildRules(id, [expr1, expr2]);
263
- return { rule: id };
264
- }
265
- }
@@ -1,26 +0,0 @@
1
- import { GeneratorGrammarRule, } from "../../../typings";
2
- import { Generator } from "../generator";
3
-
4
- export class StandardGrammar {
5
-
6
- constructor(private generator: Generator) { }
7
-
8
- serialize(depth: number = 0) {
9
- if (!this.generator.state.grammar) {
10
- return null;
11
- }
12
- return Generator.Pretty({
13
- start: JSON.stringify(this.generator.state.grammar.start),
14
- rules: this.serializeGrammarRules(depth + 1)
15
- }, depth);
16
- }
17
-
18
- private serializeGrammarRules(depth: number = 0) {
19
- const map = {};
20
- for (const rule in this.generator.state.grammar.rules) {
21
- map[rule] = this.generator.state.grammar.rules[rule].map(v => this.generator.serializeGrammarRule(v))
22
- }
23
- return Generator.Pretty(map, depth);
24
- }
25
-
26
- }
@@ -1,237 +0,0 @@
1
- import { Dictionary, GeneratorState, GeneratorGrammarRule, GeneratorGrammarSymbol, LexerConfig, LexerStateDefinition } from "../../typings";
2
- import { LRParseTableBuilder } from "./artifacts/lr";
3
- import { StandardGrammar } from "./artifacts/standard";
4
-
5
- const PostProcessors = {
6
- "join": "({data}) => data.join('')",
7
- "concat": "({data}) => data[0].concat([data[1]])",
8
- "null": "() => null",
9
- "first": "({data}) => data[0]"
10
- };
11
-
12
- export class Generator {
13
-
14
- state: GeneratorState = {
15
- grammar: {
16
- start: '',
17
- config: {},
18
- rules: {},
19
- uuids: {},
20
- },
21
- lexer: null,
22
- head: [],
23
- body: [],
24
- config: {},
25
- version: 'unknown',
26
- }
27
-
28
- serializeHead() {
29
- if (this.state.config.noscript)
30
- return '';
31
- return this.state.head.join('\n');
32
- }
33
-
34
- serializeBody() {
35
- if (this.state.config.noscript)
36
- return '';
37
- return this.state.body.join('\n');
38
- }
39
-
40
- serializeLanguage(depth: number = 0) {
41
- const serialier = new StandardGrammar(this);
42
- let lr = null;
43
-
44
- if ('lr' in this.state.config) {
45
- const table = new LRParseTableBuilder(this);
46
- lr = Generator.Pretty({
47
- k: "0",
48
- table: table.serialize(depth + 2)
49
- }, depth + 1);
50
- }
51
-
52
- return Generator.Pretty({
53
- grammar: serialier.serialize(depth + 1),
54
- lexer: this.serializeLexerConfig(depth + 1),
55
- lr
56
- }, depth);
57
- }
58
-
59
- merge(state: GeneratorState) {
60
- // TODO: Resolve Conflicting Rules and UUIDS
61
- Object.assign(this.state.grammar.rules, state.grammar.rules);
62
- this.state.grammar.start = state.grammar.start || this.state.grammar.start;
63
- this.state.grammar.config.postprocessorDefault = state.grammar.config.postprocessorDefault || this.state.grammar.config.postprocessorDefault;
64
- this.state.grammar.config.postprocessorOverride = state.grammar.config.postprocessorOverride || this.state.grammar.config.postprocessorOverride;
65
-
66
- if (state.lexer) {
67
- if (this.state.lexer) {
68
- Object.assign(this.state.lexer.states, state.lexer.states);
69
- } else {
70
- this.state.lexer = state.lexer;
71
- }
72
- this.state.lexer.start = state.lexer.start || this.state.lexer.start;
73
- }
74
- this.state.head.push(...state.head);
75
- this.state.body.push(...state.body);
76
- Object.assign(this.state.config, state.config);
77
- }
78
-
79
- grammarUUID(name: string) {
80
- this.state.grammar.uuids[name] = (this.state.grammar.uuids[name] || 0) + 1;
81
- return name + 'x' + this.state.grammar.uuids[name];
82
- }
83
-
84
- addGrammarRule(rule: GeneratorGrammarRule) {
85
- this.state.grammar.rules[rule.name] = this.state.grammar.rules[rule.name] || [];
86
- this.state.grammar.rules[rule.name].push(rule);
87
- }
88
-
89
- addLexerState(state: LexerStateDefinition) {
90
- this.state.lexer.states[state.name] = this.state.lexer.states[state.name] || { name: state.name, rules: [] }
91
- const target = this.state.lexer.states[state.name];
92
- target.default = typeof state.default == 'string' ? state.default : target.default;
93
- target.unmatched = typeof state.unmatched == 'string' ? state.unmatched : target.unmatched;
94
- target.rules.push(...state.rules);
95
- }
96
-
97
- serializePostProcess(postprocess: GeneratorGrammarRule['postprocess'], alias: Dictionary<number>) {
98
- postprocess = this.state.grammar.config.postprocessorOverride || postprocess || this.state.grammar.config.postprocessorDefault;
99
- if (!postprocess)
100
- return null;
101
- if ('builtin' in postprocess)
102
- return PostProcessors[postprocess.builtin];
103
- if (this.state.config.noscript)
104
- return;
105
- if (typeof postprocess == 'string')
106
- return postprocess;
107
- if ('js' in postprocess)
108
- return postprocess.js;
109
- if ('template' in postprocess)
110
- return this.templatePostProcess(postprocess.template, alias);
111
- }
112
-
113
- private templatePostProcess(templateBody: string, alias: { [key: string]: number }) {
114
- for (const key in alias) {
115
- templateBody = templateBody.replace(new RegExp('(?:\\$)' + key + '(?![a-zA-Z\\d\\$_])'), `data[${alias[key]}]`);
116
- }
117
- return "({data}) => { return " + templateBody.replace(/\$(\d+)/g, "data[$1]") + "; }";
118
- }
119
-
120
- private serializeLexerConfig(depth: number = 0) {
121
- if (!this.state.lexer)
122
- return null;
123
-
124
- if (typeof this.state.lexer === 'string')
125
- return this.state.lexer;
126
-
127
- return Generator.Pretty({
128
- start: JSON.stringify(this.state.lexer.start),
129
- states: this.serializeLexerConfigStates(depth + 1)
130
- }, depth);
131
- }
132
-
133
- private serializeLexerConfigStates(depth: number) {
134
- const map = {};
135
- for (const key in this.state.lexer.states) {
136
- const state = this.state.lexer.states[key];
137
- map[state.name] = Generator.Pretty({
138
- name: JSON.stringify(state.name),
139
- default: state.default ? JSON.stringify(state.default) : null,
140
- unmatched: state.unmatched ? JSON.stringify(state.unmatched) : null,
141
- rules: this.serializeLexerConfigStateRules(state.rules, depth + 2)
142
- }, depth + 1);
143
- }
144
- return Generator.Pretty(map, depth);
145
- }
146
-
147
- private serializeLexerConfigStateRules(rules: LexerConfig['states'][0]['rules'], depth: number) {
148
- const ary = rules.map(rule => {
149
- if ('import' in rule)
150
- return Generator.Pretty({ import: JSON.stringify(rule.import) }, -1)
151
- return Generator.Pretty({
152
- when: Generator.SerializeSymbol(rule.when as any),
153
- type: JSON.stringify(rule.type),
154
- tag: JSON.stringify(rule.tag),
155
- pop: JSON.stringify(rule.pop),
156
- before: JSON.stringify(rule.before),
157
- open: JSON.stringify(rule.open),
158
- close: JSON.stringify(rule.close),
159
- highlight: JSON.stringify(rule.highlight),
160
- set: JSON.stringify(rule.set),
161
- inset: JSON.stringify(rule.inset),
162
- goto: JSON.stringify(rule.goto),
163
- }, -1);
164
- });
165
- return Generator.Pretty(ary, depth);
166
- }
167
-
168
- serializeGrammarRule(rule: GeneratorGrammarRule) {
169
- const symbols = [];
170
- const alias = {};
171
- for (let i = 0; i < rule.symbols.length; i++) {
172
- symbols.push(Generator.SerializeSymbol(rule.symbols[i]));
173
- if (rule.symbols[i].alias) {
174
- alias[rule.symbols[i].alias] = i;
175
- }
176
- }
177
-
178
- return Generator.Pretty({
179
- name: JSON.stringify(rule.name),
180
- symbols: Generator.Pretty(symbols, -1),
181
- postprocess: this.serializePostProcess(rule.postprocess, alias)
182
- }, -1);
183
- }
184
-
185
- static NewLine(depth: number) {
186
- return '\n' + ' '.repeat(depth * 4);
187
- }
188
-
189
- static Pretty(obj: string[] | { [key: string]: string | (string[]) }, depth = 0) {
190
- if (Array.isArray(obj)) {
191
- let r = `[`;
192
- for (let i = 0; i < obj.length; i++) {
193
- const value = obj[i];
194
- r += `${depth >= 0 ? Generator.NewLine(depth + 1) : ' '}${value}${(Generator.IsVal(obj[i + 1]) ? ',' : '')}`;
195
- }
196
- r += `${depth >= 0 ? Generator.NewLine(depth) : ' '}]`;
197
- return r;
198
- }
199
-
200
- let r = `{`;
201
- const keys = Object.keys(obj).filter(v => Generator.IsVal(obj[v]));
202
- const prefix = depth >= 0 ? Generator.NewLine(depth + 1) : ' ';
203
- for (let i = 0; i < keys.length; i++) {
204
- const key = /[a-z_][a-z\d_$]*/i.test(keys[i]) ? keys[i] : JSON.stringify(keys[i]);
205
- const value = Array.isArray(obj[keys[i]]) ? Generator.Pretty(obj[keys[i]] as string[], depth >= 0 ? depth + 1 : -1) : obj[keys[i]];
206
- const suffix = (Generator.IsVal(obj[keys[i + 1]]) ? ',' : '');
207
- r += `${prefix}${key}: ${value}${suffix}`;
208
- }
209
- r += `${depth >= 0 ? Generator.NewLine(depth) : ' '}}`;
210
- return r;
211
- }
212
-
213
- static IsVal(value) {
214
- return typeof value !== 'undefined' && value !== null;
215
- }
216
-
217
- static SerializeSymbol(s: GeneratorGrammarSymbol) {
218
- if (typeof s === 'string') {
219
- return JSON.stringify(s);
220
- } else if ('rule' in s) {
221
- return JSON.stringify(s.rule);
222
- } else if ('regex' in s) {
223
- return `/${s.regex}/${s.flags || ''}`;
224
- } else if ('token' in s) {
225
- return `{ token: ${JSON.stringify(s.token)} }`;
226
- } else if ('literal' in s) {
227
- return `{ literal: ${JSON.stringify(s.literal)} }`;
228
- } else {
229
- return JSON.stringify(s);
230
- }
231
- }
232
-
233
- static SymbolIsTerminal(s: GeneratorGrammarSymbol) {
234
- return !(typeof s === 'string' || 'rule' in s);
235
- }
236
-
237
- }