parser-lr 0.6.1 → 0.8.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.
Files changed (185) hide show
  1. package/README.md +14 -30
  2. package/bin/parser-lr.js +12759 -13493
  3. package/bin/parser-lr.js.map +1 -1
  4. package/dist/lib/grammar/grammar-from-cst.js +4 -1
  5. package/dist/lib/grammar/grammar-from-cst.js.map +1 -1
  6. package/dist/lib/grammar/grammar.json +86 -820
  7. package/dist/lib/grammar/index.d.ts +1 -1
  8. package/dist/lib/grammar/index.d.ts.map +1 -1
  9. package/dist/lib/grammar/index.js +1 -1
  10. package/dist/lib/grammar/index.js.map +1 -1
  11. package/dist/lib/grammar/meta-grammar-table.d.ts +0 -12
  12. package/dist/lib/grammar/meta-grammar-table.d.ts.map +1 -1
  13. package/dist/lib/grammar/meta-grammar-table.js +5 -22
  14. package/dist/lib/grammar/meta-grammar-table.js.map +1 -1
  15. package/dist/lib/grammar/table-validator.d.ts.map +1 -1
  16. package/dist/lib/grammar/table-validator.js +19 -1
  17. package/dist/lib/grammar/table-validator.js.map +1 -1
  18. package/dist/lib/grammar-entry.d.ts +42 -0
  19. package/dist/lib/grammar-entry.d.ts.map +1 -0
  20. package/dist/lib/grammar-entry.js +45 -0
  21. package/dist/lib/grammar-entry.js.map +1 -0
  22. package/dist/lib/index.d.ts +7 -5
  23. package/dist/lib/index.d.ts.map +1 -1
  24. package/dist/lib/index.js +0 -3
  25. package/dist/lib/index.js.map +1 -1
  26. package/dist/lib/parse-context.d.ts +4 -15
  27. package/dist/lib/parse-context.d.ts.map +1 -1
  28. package/dist/lib/parse-context.js +4 -23
  29. package/dist/lib/parse-context.js.map +1 -1
  30. package/dist/lib/transform/grammar-fixture.js +3 -3
  31. package/dist/lib/transform/grammar-fixture.js.map +1 -1
  32. package/docs/The Ferrite Programming Language.md +568 -0
  33. package/docs/grammar.md +55 -3
  34. package/docs/parser-lr-browser-lib-split.md +174 -0
  35. package/grammars/6502.grammar +2 -2
  36. package/grammars/ferrite.grammar +107 -97
  37. package/grammars/grammar.grammar +19 -140
  38. package/grammars/lisp.grammar +3 -2
  39. package/package.json +7 -2
  40. package/dist/lib/grammar/grammar-json-path.d.ts +0 -2
  41. package/dist/lib/grammar/grammar-json-path.d.ts.map +0 -1
  42. package/dist/lib/grammar/grammar-json-path.esm.d.ts +0 -5
  43. package/dist/lib/grammar/grammar-json-path.esm.d.ts.map +0 -1
  44. package/dist/lib/grammar/grammar-json-path.esm.js +0 -9
  45. package/dist/lib/grammar/grammar-json-path.esm.js.map +0 -1
  46. package/dist/lib/grammar/grammar-json-path.js +0 -2
  47. package/dist/lib/grammar/grammar-json-path.js.map +0 -1
  48. package/dist/lib-cjs/ast/ast-node.js +0 -70
  49. package/dist/lib-cjs/ast/ast-node.js.map +0 -1
  50. package/dist/lib-cjs/errors/index.js +0 -9
  51. package/dist/lib-cjs/errors/index.js.map +0 -1
  52. package/dist/lib-cjs/errors/parser-lr-error.js +0 -52
  53. package/dist/lib-cjs/errors/parser-lr-error.js.map +0 -1
  54. package/dist/lib-cjs/grammar/ast-schema.js +0 -43
  55. package/dist/lib-cjs/grammar/ast-schema.js.map +0 -1
  56. package/dist/lib-cjs/grammar/ast-type.js +0 -3
  57. package/dist/lib-cjs/grammar/ast-type.js.map +0 -1
  58. package/dist/lib-cjs/grammar/expression.js +0 -3
  59. package/dist/lib-cjs/grammar/expression.js.map +0 -1
  60. package/dist/lib-cjs/grammar/grammar-from-cst.js +0 -641
  61. package/dist/lib-cjs/grammar/grammar-from-cst.js.map +0 -1
  62. package/dist/lib-cjs/grammar/grammar-json-path.js +0 -13
  63. package/dist/lib-cjs/grammar/grammar-json-path.js.map +0 -1
  64. package/dist/lib-cjs/grammar/grammar-literals.js +0 -71
  65. package/dist/lib-cjs/grammar/grammar-literals.js.map +0 -1
  66. package/dist/lib-cjs/grammar/grammar.js +0 -64
  67. package/dist/lib-cjs/grammar/grammar.js.map +0 -1
  68. package/dist/lib-cjs/grammar/grammar.json +0 -5760
  69. package/dist/lib-cjs/grammar/index.js +0 -21
  70. package/dist/lib-cjs/grammar/index.js.map +0 -1
  71. package/dist/lib-cjs/grammar/meta-grammar-table.js +0 -68
  72. package/dist/lib-cjs/grammar/meta-grammar-table.js.map +0 -1
  73. package/dist/lib-cjs/grammar/production.js +0 -3
  74. package/dist/lib-cjs/grammar/production.js.map +0 -1
  75. package/dist/lib-cjs/grammar/read-grammar-error.js +0 -22
  76. package/dist/lib-cjs/grammar/read-grammar-error.js.map +0 -1
  77. package/dist/lib-cjs/grammar/read-grammar.js +0 -24
  78. package/dist/lib-cjs/grammar/read-grammar.js.map +0 -1
  79. package/dist/lib-cjs/grammar/table-validator.js +0 -262
  80. package/dist/lib-cjs/grammar/table-validator.js.map +0 -1
  81. package/dist/lib-cjs/grammar/token-rule.js +0 -3
  82. package/dist/lib-cjs/grammar/token-rule.js.map +0 -1
  83. package/dist/lib-cjs/grammar/transform-expression.js +0 -3
  84. package/dist/lib-cjs/grammar/transform-expression.js.map +0 -1
  85. package/dist/lib-cjs/grammar/transform-rule.js +0 -3
  86. package/dist/lib-cjs/grammar/transform-rule.js.map +0 -1
  87. package/dist/lib-cjs/grammar/transform-schema.js +0 -43
  88. package/dist/lib-cjs/grammar/transform-schema.js.map +0 -1
  89. package/dist/lib-cjs/index.js +0 -66
  90. package/dist/lib-cjs/index.js.map +0 -1
  91. package/dist/lib-cjs/lexer/index.js +0 -32
  92. package/dist/lib-cjs/lexer/index.js.map +0 -1
  93. package/dist/lib-cjs/lexer/lexer-compile-error.js +0 -22
  94. package/dist/lib-cjs/lexer/lexer-compile-error.js.map +0 -1
  95. package/dist/lib-cjs/lexer/lexer-compile.js +0 -201
  96. package/dist/lib-cjs/lexer/lexer-compile.js.map +0 -1
  97. package/dist/lib-cjs/lexer/lexer-error.js +0 -22
  98. package/dist/lib-cjs/lexer/lexer-error.js.map +0 -1
  99. package/dist/lib-cjs/lexer/lexer-input-error.js +0 -17
  100. package/dist/lib-cjs/lexer/lexer-input-error.js.map +0 -1
  101. package/dist/lib-cjs/lexer/lexer-state-error.js +0 -19
  102. package/dist/lib-cjs/lexer/lexer-state-error.js.map +0 -1
  103. package/dist/lib-cjs/lexer/lexer.js +0 -278
  104. package/dist/lib-cjs/lexer/lexer.js.map +0 -1
  105. package/dist/lib-cjs/lexer/token.js +0 -44
  106. package/dist/lib-cjs/lexer/token.js.map +0 -1
  107. package/dist/lib-cjs/package.json +0 -3
  108. package/dist/lib-cjs/parse-context-error.js +0 -19
  109. package/dist/lib-cjs/parse-context-error.js.map +0 -1
  110. package/dist/lib-cjs/parse-context.js +0 -137
  111. package/dist/lib-cjs/parse-context.js.map +0 -1
  112. package/dist/lib-cjs/parse-output-error.js +0 -19
  113. package/dist/lib-cjs/parse-output-error.js.map +0 -1
  114. package/dist/lib-cjs/parse-output.js +0 -18
  115. package/dist/lib-cjs/parse-output.js.map +0 -1
  116. package/dist/lib-cjs/parse-table/analysis/first-follow.js +0 -294
  117. package/dist/lib-cjs/parse-table/analysis/first-follow.js.map +0 -1
  118. package/dist/lib-cjs/parse-table/analysis/index.js +0 -9
  119. package/dist/lib-cjs/parse-table/analysis/index.js.map +0 -1
  120. package/dist/lib-cjs/parse-table/bnf/bnf-grammar.js +0 -140
  121. package/dist/lib-cjs/parse-table/bnf/bnf-grammar.js.map +0 -1
  122. package/dist/lib-cjs/parse-table/bnf/bnf-production.js +0 -3
  123. package/dist/lib-cjs/parse-table/bnf/bnf-production.js.map +0 -1
  124. package/dist/lib-cjs/parse-table/bnf/bnf-symbol.js +0 -39
  125. package/dist/lib-cjs/parse-table/bnf/bnf-symbol.js.map +0 -1
  126. package/dist/lib-cjs/parse-table/bnf/desugar-ebnf.js +0 -224
  127. package/dist/lib-cjs/parse-table/bnf/desugar-ebnf.js.map +0 -1
  128. package/dist/lib-cjs/parse-table/bnf/index.js +0 -13
  129. package/dist/lib-cjs/parse-table/bnf/index.js.map +0 -1
  130. package/dist/lib-cjs/parse-table/build-lr-table.js +0 -171
  131. package/dist/lib-cjs/parse-table/build-lr-table.js.map +0 -1
  132. package/dist/lib-cjs/parse-table/index.js +0 -49
  133. package/dist/lib-cjs/parse-table/index.js.map +0 -1
  134. package/dist/lib-cjs/parse-table/lr-algorithm-error.js +0 -19
  135. package/dist/lib-cjs/parse-table/lr-algorithm-error.js.map +0 -1
  136. package/dist/lib-cjs/parse-table/lr-algorithm.js +0 -31
  137. package/dist/lib-cjs/parse-table/lr-algorithm.js.map +0 -1
  138. package/dist/lib-cjs/parse-table/lr0/index.js +0 -14
  139. package/dist/lib-cjs/parse-table/lr0/index.js.map +0 -1
  140. package/dist/lib-cjs/parse-table/lr0/lr0-item-set.js +0 -286
  141. package/dist/lib-cjs/parse-table/lr0/lr0-item-set.js.map +0 -1
  142. package/dist/lib-cjs/parse-table/lr1/index.js +0 -18
  143. package/dist/lib-cjs/parse-table/lr1/index.js.map +0 -1
  144. package/dist/lib-cjs/parse-table/lr1/lr1-item-set.js +0 -432
  145. package/dist/lib-cjs/parse-table/lr1/lr1-item-set.js.map +0 -1
  146. package/dist/lib-cjs/parse-table/parse-table-build-error.js +0 -24
  147. package/dist/lib-cjs/parse-table/parse-table-build-error.js.map +0 -1
  148. package/dist/lib-cjs/parse-table/parse-table-error.js +0 -19
  149. package/dist/lib-cjs/parse-table/parse-table-error.js.map +0 -1
  150. package/dist/lib-cjs/parse-table/parse-table-json.js +0 -12
  151. package/dist/lib-cjs/parse-table/parse-table-json.js.map +0 -1
  152. package/dist/lib-cjs/parse-table/parse-table.js +0 -345
  153. package/dist/lib-cjs/parse-table/parse-table.js.map +0 -1
  154. package/dist/lib-cjs/parse-table/slr/index.js +0 -13
  155. package/dist/lib-cjs/parse-table/slr/index.js.map +0 -1
  156. package/dist/lib-cjs/parse-table/slr/parse-action.js +0 -8
  157. package/dist/lib-cjs/parse-table/slr/parse-action.js.map +0 -1
  158. package/dist/lib-cjs/parse-table/slr/slr-table.js +0 -18
  159. package/dist/lib-cjs/parse-table/slr/slr-table.js.map +0 -1
  160. package/dist/lib-cjs/parse-table/table/index.js +0 -21
  161. package/dist/lib-cjs/parse-table/table/index.js.map +0 -1
  162. package/dist/lib-cjs/parse-table/table/lr-parse-table.js +0 -192
  163. package/dist/lib-cjs/parse-table/table/lr-parse-table.js.map +0 -1
  164. package/dist/lib-cjs/parse-table/table/parse-action.js +0 -54
  165. package/dist/lib-cjs/parse-table/table/parse-action.js.map +0 -1
  166. package/dist/lib-cjs/parse-table/table/table-builder-base.js +0 -153
  167. package/dist/lib-cjs/parse-table/table/table-builder-base.js.map +0 -1
  168. package/dist/lib-cjs/parse-table/token-inventory.js +0 -18
  169. package/dist/lib-cjs/parse-table/token-inventory.js.map +0 -1
  170. package/dist/lib-cjs/parser-lr.js +0 -143
  171. package/dist/lib-cjs/parser-lr.js.map +0 -1
  172. package/dist/lib-cjs/shift-reduce/index.js +0 -11
  173. package/dist/lib-cjs/shift-reduce/index.js.map +0 -1
  174. package/dist/lib-cjs/shift-reduce/shift-reduce-engine.js +0 -224
  175. package/dist/lib-cjs/shift-reduce/shift-reduce-engine.js.map +0 -1
  176. package/dist/lib-cjs/transform/binding-map.js +0 -82
  177. package/dist/lib-cjs/transform/binding-map.js.map +0 -1
  178. package/dist/lib-cjs/transform/cst-transformer.js +0 -480
  179. package/dist/lib-cjs/transform/cst-transformer.js.map +0 -1
  180. package/dist/lib-cjs/transform/grammar-fixture.js +0 -109
  181. package/dist/lib-cjs/transform/grammar-fixture.js.map +0 -1
  182. package/dist/lib-cjs/transform/index.js +0 -12
  183. package/dist/lib-cjs/transform/index.js.map +0 -1
  184. package/docs/parser-lr-enhancement-proposals.md +0 -337
  185. package/grammars/fixtures/table-only-import/table-only-smoke.cjs +0 -38
@@ -1,109 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fixtureGrammarPath = fixtureGrammarPath;
4
- exports.findChildrenBySymbol = findChildrenBySymbol;
5
- exports.findChildBySymbol = findChildBySymbol;
6
- exports.parseFixture = parseFixture;
7
- exports.discoverFixtures = discoverFixtures;
8
- exports.runFixtureCase = runFixtureCase;
9
- const node_fs_1 = require("node:fs");
10
- const node_path_1 = require("node:path");
11
- const parse_context_js_1 = require("../parse-context.js");
12
- /**
13
- * Returns the `.grammar` file for one fixture directory.
14
- *
15
- * Fixture grammars are named after their directory (for example
16
- * `bare-terminal/bare-terminal.grammar`). The meta-grammar keeps the reserved
17
- * name `grammar.grammar` at the repo root only.
18
- *
19
- * @param fixtureDir - Directory containing a fixture grammar and input files.
20
- */
21
- function fixtureGrammarPath(fixtureDir) {
22
- const grammarPath = (0, node_path_1.join)(fixtureDir, `${(0, node_path_1.basename)(fixtureDir)}.grammar`);
23
- return (0, node_fs_1.existsSync)(grammarPath) ? grammarPath : null;
24
- }
25
- /**
26
- * Returns child AST nodes matching a symbol name.
27
- *
28
- * @param node - Parent AST node.
29
- * @param symbol - Child symbol to find.
30
- */
31
- function findChildrenBySymbol(node, symbol) {
32
- return node.children.filter((child) => child.symbol === symbol);
33
- }
34
- /**
35
- * Returns the first child AST node matching a symbol name.
36
- *
37
- * @param node - Parent AST node.
38
- * @param symbol - Child symbol to find.
39
- */
40
- function findChildBySymbol(node, symbol) {
41
- return node.children.find((child) => child.symbol === symbol) ?? null;
42
- }
43
- /**
44
- * Parses one fixture grammar and input file into an AST.
45
- *
46
- * @param fixtureDir - Directory containing a named fixture grammar and an input file.
47
- * @param inputFileName - Input file name within the fixture directory.
48
- */
49
- function parseFixture(fixtureDir, inputFileName = 'input.txt') {
50
- const grammarPath = fixtureGrammarPath(fixtureDir);
51
- if (grammarPath === null) {
52
- throw new Error(`fixture grammar not found in ${fixtureDir}`);
53
- }
54
- const grammarSource = (0, node_fs_1.readFileSync)(grammarPath, 'utf8');
55
- const input = (0, node_fs_1.readFileSync)((0, node_path_1.join)(fixtureDir, inputFileName), 'utf8').trimEnd();
56
- const context = parse_context_js_1.ParseContext.fromGrammar(grammarSource, 'lr1');
57
- return context.parseSource(input);
58
- }
59
- /**
60
- * Discovers fixture directories containing a named `.grammar` file under a root path.
61
- *
62
- * @param rootDir - Root directory to scan recursively.
63
- */
64
- function discoverFixtures(rootDir) {
65
- const fixtures = [];
66
- const visit = (directory) => {
67
- const grammarPath = fixtureGrammarPath(directory);
68
- if (grammarPath !== null) {
69
- const inputFiles = (0, node_fs_1.readdirSync)(directory)
70
- .filter((name) => name.startsWith('input') && name.endsWith('.txt'))
71
- .sort();
72
- for (const inputFile of inputFiles) {
73
- const baseName = inputFile.replace(/^input/, '').replace(/\.txt$/, '');
74
- const expectedName = baseName === '' ? 'expected.json' : `expected${baseName}.json`;
75
- const expectedPath = (0, node_path_1.join)(directory, expectedName);
76
- fixtures.push({
77
- name: `${directory.split('/').slice(-2).join('/')}/${inputFile}`,
78
- grammarPath,
79
- inputPath: (0, node_path_1.join)(directory, inputFile),
80
- expectedPath: (0, node_fs_1.existsSync)(expectedPath) ? expectedPath : null,
81
- });
82
- }
83
- }
84
- for (const entry of (0, node_fs_1.readdirSync)(directory, { withFileTypes: true })) {
85
- if (entry.isDirectory()) {
86
- visit((0, node_path_1.join)(directory, entry.name));
87
- }
88
- }
89
- };
90
- visit(rootDir);
91
- return fixtures;
92
- }
93
- /**
94
- * Parses a fixture case and compares to expected JSON when present.
95
- *
96
- * @param fixture - Fixture metadata.
97
- */
98
- function runFixtureCase(fixture, expectFn) {
99
- const grammarSource = (0, node_fs_1.readFileSync)(fixture.grammarPath, 'utf8');
100
- const input = (0, node_fs_1.readFileSync)(fixture.inputPath, 'utf8').trimEnd();
101
- const context = parse_context_js_1.ParseContext.fromGrammar(grammarSource, 'lr1');
102
- const ast = context.parseSource(input);
103
- if (fixture.expectedPath !== null) {
104
- const expected = JSON.parse((0, node_fs_1.readFileSync)(fixture.expectedPath, 'utf8'));
105
- expectFn(ast).toEqual(expected);
106
- }
107
- return ast;
108
- }
109
- //# sourceMappingURL=grammar-fixture.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"grammar-fixture.js","sourceRoot":"","sources":["../../../src/lib/transform/grammar-fixture.ts"],"names":[],"mappings":";;AA0BA,gDAKC;AAQD,oDAGC;AAQD,8CAGC;AAQD,oCAiBC;AAOD,4CAyCC;AAOD,wCAkBC;AAvJD,qCAAgE;AAChE,yCAA2C;AAG3C,0DAAmD;AAanD;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAC,UAAkB;IAEjD,MAAM,WAAW,GAAG,IAAA,gBAAI,EAAC,UAAU,EAAE,GAAG,IAAA,oBAAQ,EAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAExE,OAAO,IAAA,oBAAU,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,IAAa,EAAE,MAAc;IAE9D,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,IAAa,EAAE,MAAc;IAE3D,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC;AAC1E,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CACxB,UAAkB,EAClB,aAAa,GAAG,WAAW;IAG3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAEnD,IAAI,WAAW,KAAK,IAAI,EACxB,CAAC;QACG,MAAM,IAAI,KAAK,CAAC,gCAAgC,UAAU,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,aAAa,GAAG,IAAA,sBAAY,EAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAA,sBAAY,EAAC,IAAA,gBAAI,EAAC,UAAU,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9E,MAAM,OAAO,GAAG,+BAAY,CAAC,WAAW,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAE/D,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,OAAe;IAE5C,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAE1C,MAAM,KAAK,GAAG,CAAC,SAAiB,EAAQ,EAAE;QAEtC,MAAM,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAElD,IAAI,WAAW,KAAK,IAAI,EACxB,CAAC;YACG,MAAM,UAAU,GAAG,IAAA,qBAAW,EAAC,SAAS,CAAC;iBACpC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;iBACnE,IAAI,EAAE,CAAC;YAEZ,KAAK,MAAM,SAAS,IAAI,UAAU,EAClC,CAAC;gBACG,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACvE,MAAM,YAAY,GAAG,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,QAAQ,OAAO,CAAC;gBACpF,MAAM,YAAY,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;gBAEnD,QAAQ,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,EAAE;oBAChE,WAAW;oBACX,SAAS,EAAE,IAAA,gBAAI,EAAC,SAAS,EAAE,SAAS,CAAC;oBACrC,YAAY,EAAE,IAAA,oBAAU,EAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI;iBAC/D,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAA,qBAAW,EAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EACnE,CAAC;YACG,IAAI,KAAK,CAAC,WAAW,EAAE,EACvB,CAAC;gBACG,KAAK,CAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACvC,CAAC;QACL,CAAC;IACL,CAAC,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,CAAC;IAEf,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAC1B,OAA2B,EAC3B,QAAqE;IAGrE,MAAM,aAAa,GAAG,IAAA,sBAAY,EAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,IAAA,sBAAY,EAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;IAChE,MAAM,OAAO,GAAG,+BAAY,CAAC,WAAW,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAEvC,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,EACjC,CAAC;QACG,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;QAExE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformCst = exports.describeProductionSlots = exports.CstTransformer = exports.referenceSlotIndex = exports.productionSlots = exports.parseRhsSymbolKey = void 0;
4
- var binding_map_js_1 = require("./binding-map.js");
5
- Object.defineProperty(exports, "parseRhsSymbolKey", { enumerable: true, get: function () { return binding_map_js_1.parseRhsSymbolKey; } });
6
- Object.defineProperty(exports, "productionSlots", { enumerable: true, get: function () { return binding_map_js_1.productionSlots; } });
7
- Object.defineProperty(exports, "referenceSlotIndex", { enumerable: true, get: function () { return binding_map_js_1.referenceSlotIndex; } });
8
- var cst_transformer_js_1 = require("./cst-transformer.js");
9
- Object.defineProperty(exports, "CstTransformer", { enumerable: true, get: function () { return cst_transformer_js_1.CstTransformer; } });
10
- Object.defineProperty(exports, "describeProductionSlots", { enumerable: true, get: function () { return cst_transformer_js_1.describeProductionSlots; } });
11
- Object.defineProperty(exports, "transformCst", { enumerable: true, get: function () { return cst_transformer_js_1.transformCst; } });
12
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/transform/index.ts"],"names":[],"mappings":";;;AAAA,mDAA0F;AAAjF,mHAAA,iBAAiB,OAAA;AAAE,iHAAA,eAAe,OAAA;AAAE,oHAAA,kBAAkB,OAAA;AAE/D,2DAA6F;AAApF,oHAAA,cAAc,OAAA;AAAE,6HAAA,uBAAuB,OAAA;AAAE,kHAAA,YAAY,OAAA"}
@@ -1,337 +0,0 @@
1
- # parser-lr open requests (EduBASIC)
2
-
3
- Audience: agents working on [parser-lr](https://github.com/adamrmoss/parser-lr).
4
-
5
- Consumer: **edu-basic** (`parser-lr` **0.5.0** in [`package.json`](../package.json)). Reference grammar: [`src/lang/parsing/grammars/edu-basic.grammar`](../src/lang/parsing/grammars/edu-basic.grammar).
6
-
7
- This document lists **only what parser-lr still needs to change**. Items resolved in 0.5.0 are noted so they are not re-opened.
8
-
9
- ---
10
-
11
- ## Resolved in 0.5.0 (no further work)
12
-
13
- | Item | Notes |
14
- |------|--------|
15
- | **`pass()` preserves production symbol** | Bare `CLS` → `cls_stmt`, not `kw_cls`. Same for `PRINT`, `END`, `ELSE`, `WEND`, `DO`, `LOOP`, etc. |
16
- | **`table validate` command** | Documented in README; implementation exists but is blocked by packaging bug below. |
17
- | **CJS `require` export** | `package.json` `exports.require` → `dist/lib-cjs/index.js`. |
18
-
19
- After upgrading to a build that includes the pass fix, EduBASIC can delete [`keyword-fallbacks.ts`](../src/lang/parsing/ast-bridge/statements/keyword-fallbacks.ts) (kept temporarily for older tables / edge cases).
20
-
21
- ---
22
-
23
- ## 1. CLI cannot find `grammar.json` (blocker)
24
-
25
- ### Symptom
26
-
27
- ```bash
28
- npm run parser:table
29
- # ENOENT: .../node_modules/parser-lr/bin/grammar.json
30
- ```
31
-
32
- Same failure for:
33
-
34
- ```bash
35
- npx parser-lr table validate -g src/lang/parsing/grammars/edu-basic.grammar
36
- ```
37
-
38
- ### Actual layout in published 0.5.0
39
-
40
- | Path | Present? |
41
- |------|----------|
42
- | `dist/lib/grammar/grammar.json` | Yes |
43
- | `dist/lib-cjs/grammar/grammar.json` | Yes |
44
- | `bin/grammar.json` | **No** |
45
-
46
- CLI bundle resolves meta-grammar relative to `bin/`, not `dist/lib/grammar/`.
47
-
48
- ### Required fix
49
-
50
- Bundle CLI against the same `grammarJsonDirectory()` helper the library uses, or copy `grammar.json` beside `bin/parser-lr.js` in `prepack`.
51
-
52
- ### Acceptance test (parser-lr repo)
53
-
54
- ```bash
55
- npm pack
56
- tmpdir=$(mktemp -d)
57
- tar -xzf parser-lr-*.tgz -C "$tmpdir"
58
- cd "$tmpdir/package"
59
- node bin/parser-lr.js table validate -g grammars/calc.grammar
60
- node bin/parser-lr.js table generate -g grammars/calc.grammar -o /tmp/calc.json -a lalr
61
- ```
62
-
63
- Both commands must exit 0 on a clean install from the tarball.
64
-
65
- ---
66
-
67
- ## 2. Table-only import must not load meta-grammar (blocker for Jest)
68
-
69
- ### Symptom
70
-
71
- EduBASIC tests import `ParseContext` / `AstNode` from `parser-lr` only to parse a pre-built table. Jest fails:
72
-
73
- ```
74
- SyntaxError: Cannot use 'import.meta' outside a module
75
- at grammar-json-path.esm.js
76
- ```
77
-
78
- Import chain today:
79
-
80
- ```
81
- dist/lib/index.js
82
- → grammar/index.js
83
- → read-grammar.js
84
- → meta-grammar-table.js (readFileSync grammar.json at module load)
85
- → grammar-json-path.esm.js (uses import.meta.url)
86
- ```
87
-
88
- `readGrammar()` is not called; meta-grammar still loads because it sits on the public barrel.
89
-
90
- ### Required fix (pick one)
91
-
92
- **Option A (preferred):** Lazy-load meta-grammar inside `readGrammar()` / `metaGrammarTable()` only. Do not import `meta-grammar-table.js` from `grammar/index.js` at top level. Split exports:
93
-
94
- - `parser-lr` — parse runtime (`ParseContext`, `AstNode`, lexer, shift-reduce, transform)
95
- - `parser-lr/grammar` or `parser-lr/read-grammar` — grammar file parsing (`readGrammar`, `validateGrammarTable`)
96
-
97
- **Option B:** Ensure `dist/lib-cjs/` is safe under Jest without `import.meta`, and document that table-only consumers must `require('parser-lr')` (CJS). EduBASIC can point Jest at CJS, but the ESM entry should still not pull meta-grammar for consumers that only call `ParseContext.fromTableJson`.
98
-
99
- ### Acceptance test (parser-lr repo)
100
-
101
- ```javascript
102
- // table-only-smoke.cjs — must not throw under plain node
103
- const { ParseContext } = require('parser-lr');
104
- const table = require('./grammars/calc.table.json'); // or generate inline
105
- const ctx = ParseContext.fromTableJson(JSON.stringify(table));
106
- console.log(ctx.parseSource('1 + 2')?.symbol);
107
- ```
108
-
109
- ```javascript
110
- // table-only-smoke.mjs — same for ESM default entry
111
- import { ParseContext } from 'parser-lr';
112
- ```
113
-
114
- Neither import may read `grammar.json` or evaluate `import.meta`.
115
-
116
- ---
117
-
118
- ## 3. Preserve intermediate production nodes (high)
119
-
120
- ### Problem
121
-
122
- `pass()` fix covers **bound slots** on statement dispatch (`[stmt]:cls_stmt`). Nested productions used inside statements still **flatten** when they have no `transform` rule, even when the grammar names them explicitly.
123
-
124
- EduBASIC bridge code must scan for raw tokens or alternate shapes.
125
-
126
- ### 3a. `comparison_op` inside `case_selector`
127
-
128
- **Grammar (already in edu-basic):**
129
-
130
- ```ebnf
131
- case_selector =
132
- #relational kw_is comparison_op expr
133
- ;
134
-
135
- comparison_op =
136
- #less less
137
- | #greater_equal greater_equal
138
- | … ;
139
- ```
140
-
141
- `comparison_op` **has** expression-level transforms:
142
-
143
- ```ebnf
144
- comparison_op ->
145
- #less pass(tok)
146
- | #greaterEqual pass(tok)
147
- | … ;
148
- ```
149
-
150
- **Input:** `CASE IS < 0`
151
-
152
- **Actual `case_selector` children (variant `relational`):** `kw_is`, `less`, `expr`
153
-
154
- **Required:** `kw_is`, `comparison_op` (variant `less`, child `less`), `expr`
155
-
156
- Without this, consumers match lexer token names (`less`, `greater_equal`) instead of the grammar non-terminal `comparison_op`.
157
-
158
- ### 3b. `let_target` inside `let_stmt`
159
-
160
- **Grammar:**
161
-
162
- ```ebnf
163
- let_stmt = kw_let let_target compound_op expr ;
164
- let_target = identifier assn_path_suffix ;
165
- ```
166
-
167
- **Input:** `LET x% = 1`
168
-
169
- **Actual:** flat `identifier`, `equal`, `expr` under `let_stmt` (no `let_target` wrapper).
170
-
171
- **Required:** `let_stmt` children include `let_target` wrapping `identifier` (and optional `assn_path_suffix`).
172
-
173
- EduBASIC workaround: [`assignment-helpers.ts`](../src/lang/parsing/ast-bridge/assignment-helpers.ts) `buildLetAssignmentTarget` accepts bare `identifier` at statement root.
174
-
175
- ### 3c. `print_list` / `print_segment`
176
-
177
- **Grammar:**
178
-
179
- ```ebnf
180
- print_stmt = kw_print [ print_list ] ;
181
- print_list = print_segment { print_segment } ;
182
- print_segment = #bare expr | #trailingComma expr comma | … ;
183
- ```
184
-
185
- Bridge must accept: `print_list` wrapper, `print_list$repeat_*` tails, bare `print_segment`, or trailing `postfix_expr` siblings interchangeably ([`io.ts`](../src/lang/parsing/ast-bridge/statements/io.ts) `buildPrintSegmentsFromStatement`).
186
-
187
- **Required:** stable list shape matching expression `flatten` output (same as `expr_list`).
188
-
189
- ### Proposed semantics
190
-
191
- When a CST node is a **non-terminal production** `P` and `P` has **no** `transform` rule:
192
-
193
- 1. Emit AST node `{ symbol: P, variant: <alt label>, children: [ transformed children ] }`.
194
- 2. Do **not** hoist single-child terminals to replace `P`.
195
- 3. Apply existing `transform` rules when present (as with `comparison_op` in expression context).
196
-
197
- This generalizes the 0.5.0 `pass()` bound-slot fix to **all referenced non-terminals**.
198
-
199
- ### Minimal reproducer grammar (add to parser-lr fixtures)
200
-
201
- ```ebnf
202
- name "nested-production-repro" ;
203
-
204
- tokens
205
- kw_is = /IS/i ;
206
- kw_case = /CASE/i ;
207
- less = /</ ;
208
- ident = /[a-z]+/ ;
209
- integer = /[0-9]+/ ;
210
-
211
- start line ;
212
-
213
- grammar
214
- line = kw_case case_selector ;
215
- case_selector = #relational kw_is comparison_op integer ;
216
- comparison_op = #less less ;
217
-
218
- ast
219
- comparison_op =
220
- #less [tok]:less
221
- ;
222
-
223
- transform
224
- comparison_op ->
225
- #less comparison_op.#less(tok) ;
226
- ```
227
-
228
- **Input:** `CASE IS < 0`
229
-
230
- **Assert:** `case_selector` child at index 1 has `symbol === "comparison_op"`, not `less`.
231
-
232
- ---
233
-
234
- ## 4. `table validate` must work on edu-basic grammar (medium)
235
-
236
- Depends on **§1** (CLI packaging).
237
-
238
- Once the CLI runs, validate this consumer grammar:
239
-
240
- ```bash
241
- npx parser-lr table validate -g src/lang/parsing/grammars/edu-basic.grammar
242
- ```
243
-
244
- Useful warnings (already described in README) should include:
245
-
246
- - `pass(boundSlot)` where bound production has no `transform` and can match a single terminal (legacy warning; should disappear after §3).
247
- - `transform` references `type.#variant` not declared in `ast`.
248
- - Duplicate `grammar` / `ast` / `transform` sections (edu-basic currently duplicates statement blocks; validator should flag).
249
-
250
- `--strict` should be usable in CI.
251
-
252
- ---
253
-
254
- ## 5. Document transform contract (medium)
255
-
256
- Update [`docs/grammar.md`](https://github.com/adamrmoss/parser-lr/blob/main/docs/grammar.md) with explicit rules:
257
-
258
- | Transform | Behavior |
259
- |-----------|----------|
260
- | `pass(slot)` | Preserve bound production symbol; never collapse to sole terminal child. |
261
- | No rule for production `P` | Identity node `{ symbol: P, children }` (proposed §3). |
262
- | `build(type.#variant, …)` | Absent optional slots omitted from children, not shifted. |
263
- | `flatten(type.#list, head, tail)` | Repeat tails: no empty placeholder nodes; no dropped items. |
264
-
265
- Include before/after JSON for `CLS`, `CASE IS < 0`, and `LET x = 1`.
266
-
267
- ---
268
-
269
- ## 6. Regression fixtures to add in parser-lr (medium)
270
-
271
- | Fixture | Covers |
272
- |---------|--------|
273
- | `pass-preserves-production/` | Bare optional production (`cls_stmt = kw_cls [ … ]`) |
274
- | `nested-production-repro/` | §3 `comparison_op` inside parent without parent transform |
275
- | `let-target-repro/` | §3b `let_target` wrapper |
276
- | `flatten-repeat/` | `a,b,c` list with no spurious empty tails |
277
- | `build-optional-slots/` | Optional grammar slots absent in `build()` output |
278
- | `table-only-import/` | §2 smoke scripts |
279
-
280
- Each fixture: `.grammar`, input line(s), expected AST JSON golden file.
281
-
282
- ---
283
-
284
- ## EduBASIC verification (run after parser-lr release)
285
-
286
- Run these locally after bumping `parser-lr` and regenerating the table:
287
-
288
- ```bash
289
- npm install parser-lr@<version>
290
- npm run parser:table
291
- npm run parser:check
292
- npm test
293
- ```
294
-
295
- Spot checks:
296
-
297
- ```bash
298
- node -e "
299
- import { ParseContext } from 'parser-lr';
300
- import table from './src/lang/parsing/edu-basic.table.json' with { type: 'json' };
301
- const ctx = ParseContext.fromTableJson(JSON.stringify(table));
302
- for (const line of ['CLS', 'PRINT', 'CASE IS < 0', 'LET x% = 1', 'HELP PRINT']) {
303
- const ast = ctx.parseSource(line);
304
- console.log(line, '=>', ast?.symbol, JSON.stringify(ast?.children?.map(c => c.symbol)));
305
- }
306
- "
307
- ```
308
-
309
- Expected after all items above:
310
-
311
- | Line | Root symbol | Notable children |
312
- |------|-------------|------------------|
313
- | `CLS` | `cls_stmt` | `kw_cls` |
314
- | `PRINT` | `print_stmt` | `kw_print` |
315
- | `CASE IS < 0` | `case_stmt` | selector child includes `comparison_op` |
316
- | `LET x% = 1` | `let_stmt` | includes `let_target` |
317
- | `HELP PRINT` | `help_stmt` | `kw_help`, `help_topic` |
318
-
319
- Then remove from edu-basic:
320
-
321
- - [`keyword-fallbacks.ts`](../src/lang/parsing/ast-bridge/statements/keyword-fallbacks.ts)
322
- - Flat-tree fallback branches in [`io.ts`](../src/lang/parsing/ast-bridge/statements/io.ts) (`buildHelpStatement`, `buildPrintSegmentsFromStatement`)
323
- - `isComparisonOpSymbol` token-name matching in [`control-flow.ts`](../src/lang/parsing/ast-bridge/statements/control-flow.ts)
324
- - Bare `identifier` path in [`assignment-helpers.ts`](../src/lang/parsing/ast-bridge/assignment-helpers.ts)
325
-
326
- ---
327
-
328
- ## Priority summary
329
-
330
- | Priority | Item | Blocks edu-basic |
331
- |----------|------|------------------|
332
- | P0 | §1 CLI `grammar.json` path | `npm run parser:table`, `table validate` |
333
- | P0 | §2 Lazy meta-grammar / split entry | Jest and any `import { ParseContext } from 'parser-lr'` |
334
- | P1 | §3 Intermediate production nodes | Bridge simplification; `CASE IS`, `LET`, `PRINT` |
335
- | P2 | §4–§6 Validate, docs, fixtures | CI confidence, upstream maintenance |
336
-
337
- Target: **parser-lr 0.5.1** (or 0.6.0) with tarball acceptance tests for §1 and §2.
@@ -1,38 +0,0 @@
1
- const { readFileSync } = require('node:fs');
2
- const { join } = require('node:path');
3
-
4
- const fs = require('node:fs');
5
- const originalReadFileSync = fs.readFileSync;
6
- let readMetaGrammar = false;
7
-
8
- fs.readFileSync = function patchedReadFileSync(path, ...rest)
9
- {
10
- if (String(path).endsWith('grammar.json'))
11
- {
12
- readMetaGrammar = true;
13
- }
14
-
15
- return originalReadFileSync.call(this, path, ...rest);
16
- };
17
-
18
- const { ParseContext } = require('parser-lr');
19
-
20
- const tableJson = readFileSync(
21
- join(__dirname, 'calc.table.json'),
22
- 'utf8',
23
- );
24
-
25
- const context = ParseContext.fromTableJson(tableJson);
26
- const ast = context.parseSource('1 + 2');
27
-
28
- if (ast === null)
29
- {
30
- throw new Error('table-only smoke (cjs): expected a non-null AST');
31
- }
32
-
33
- if (readMetaGrammar)
34
- {
35
- throw new Error('table-only smoke (cjs): unexpected grammar.json read');
36
- }
37
-
38
- process.stdout.write(`cjs ${ast.symbol}\n`);