parser-lr 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/parser-lr.js +404 -874
- package/bin/parser-lr.js.map +1 -1
- package/dist/lib/diagnostics/format-diagnostic.d.ts +31 -0
- package/dist/lib/diagnostics/format-diagnostic.d.ts.map +1 -0
- package/dist/lib/diagnostics/format-diagnostic.js +36 -0
- package/dist/lib/diagnostics/format-diagnostic.js.map +1 -0
- package/dist/lib/diagnostics/index.d.ts +5 -0
- package/dist/lib/diagnostics/index.d.ts.map +1 -0
- package/dist/lib/diagnostics/index.js +3 -0
- package/dist/lib/diagnostics/index.js.map +1 -0
- package/dist/lib/diagnostics/source-position.d.ts +24 -0
- package/dist/lib/diagnostics/source-position.d.ts.map +1 -0
- package/dist/lib/diagnostics/source-position.js +39 -0
- package/dist/lib/diagnostics/source-position.js.map +1 -0
- package/dist/lib/grammar/ast-type.d.ts +2 -0
- package/dist/lib/grammar/ast-type.d.ts.map +1 -1
- package/dist/lib/grammar/grammar-from-cst.js +8 -4
- package/dist/lib/grammar/grammar-from-cst.js.map +1 -1
- package/dist/lib/grammar/grammar.json +86 -820
- package/dist/lib/grammar/index.d.ts +1 -1
- package/dist/lib/grammar/index.d.ts.map +1 -1
- package/dist/lib/grammar/production.d.ts +2 -0
- package/dist/lib/grammar/production.d.ts.map +1 -1
- package/dist/lib/grammar/table-validator.d.ts +12 -2
- package/dist/lib/grammar/table-validator.d.ts.map +1 -1
- package/dist/lib/grammar/table-validator.js +68 -25
- package/dist/lib/grammar/table-validator.js.map +1 -1
- package/dist/lib/grammar/transform-rule.d.ts +3 -0
- package/dist/lib/grammar/transform-rule.d.ts.map +1 -1
- package/dist/lib/grammar-entry.d.ts +1 -1
- package/dist/lib/grammar-entry.d.ts.map +1 -1
- package/dist/lib/grammar-entry.js.map +1 -1
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/parse-context.d.ts +7 -0
- package/dist/lib/parse-context.d.ts.map +1 -1
- package/dist/lib/parse-context.js +9 -0
- package/dist/lib/parse-context.js.map +1 -1
- package/dist/lib/parse-table/table/lr-parse-table.d.ts.map +1 -1
- package/dist/lib/parse-table/table/lr-parse-table.js +10 -3
- package/dist/lib/parse-table/table/lr-parse-table.js.map +1 -1
- package/dist/lib/parser-lr.d.ts +15 -0
- package/dist/lib/parser-lr.d.ts.map +1 -1
- package/dist/lib/parser-lr.js +38 -9
- package/dist/lib/parser-lr.js.map +1 -1
- package/docs/The Ferrite Programming Language.md +568 -0
- package/docs/grammar.md +55 -3
- package/grammars/6502.grammar +2 -2
- package/grammars/ferrite.grammar +107 -97
- package/grammars/grammar.grammar +19 -140
- package/grammars/lisp.grammar +3 -2
- package/package.json +1 -1
package/bin/parser-lr.js
CHANGED
|
@@ -3781,7 +3781,7 @@ const {
|
|
|
3781
3781
|
Help,
|
|
3782
3782
|
} = commander;
|
|
3783
3783
|
|
|
3784
|
-
var version$1 = "0.
|
|
3784
|
+
var version$1 = "0.8.1";
|
|
3785
3785
|
var packageDefinition = {
|
|
3786
3786
|
version: version$1};
|
|
3787
3787
|
|
|
@@ -5920,6 +5920,80 @@ function buildLalrGotoTargets(grammar, analysis, lr1Collection, lr1ToLalr) {
|
|
|
5920
5920
|
Lr1ItemSetBuilder.buildLr1ToLalrMap = buildLr1ToLalrMap;
|
|
5921
5921
|
})(Lr1ItemSetBuilder || (Lr1ItemSetBuilder = {}));
|
|
5922
5922
|
|
|
5923
|
+
/**
|
|
5924
|
+
* Converts a source offset into a 1-based line and column.
|
|
5925
|
+
*
|
|
5926
|
+
* @param source - Full source text.
|
|
5927
|
+
* @param offset - Zero-based UTF-16 code unit offset.
|
|
5928
|
+
* @returns Line and column for the offset, clamped to the source bounds.
|
|
5929
|
+
*/
|
|
5930
|
+
function offsetToPosition(source, offset) {
|
|
5931
|
+
// Clamp out-of-range offsets to the nearest valid index.
|
|
5932
|
+
const clamped = Math.max(0, Math.min(offset, source.length));
|
|
5933
|
+
let line = 1;
|
|
5934
|
+
let column = 1;
|
|
5935
|
+
// Scan characters before the offset, advancing line on each newline.
|
|
5936
|
+
for (let index = 0; index < clamped; index += 1) {
|
|
5937
|
+
if (source[index] === '\n') {
|
|
5938
|
+
line += 1;
|
|
5939
|
+
column = 1;
|
|
5940
|
+
continue;
|
|
5941
|
+
}
|
|
5942
|
+
column += 1;
|
|
5943
|
+
}
|
|
5944
|
+
return { line, column };
|
|
5945
|
+
}
|
|
5946
|
+
/**
|
|
5947
|
+
* Returns the start offset from a location or raw offset value.
|
|
5948
|
+
*
|
|
5949
|
+
* @param location - Optional source span.
|
|
5950
|
+
* @param offset - Optional raw offset when no span is available.
|
|
5951
|
+
*/
|
|
5952
|
+
function resolveDiagnosticOffset(location, offset) {
|
|
5953
|
+
if (location !== null && location !== undefined) {
|
|
5954
|
+
return location.offset;
|
|
5955
|
+
}
|
|
5956
|
+
if (offset === null || offset === undefined) {
|
|
5957
|
+
return null;
|
|
5958
|
+
}
|
|
5959
|
+
return offset;
|
|
5960
|
+
}
|
|
5961
|
+
|
|
5962
|
+
/**
|
|
5963
|
+
* Formats a diagnostic as `path:line:column: severity: message` when possible.
|
|
5964
|
+
*
|
|
5965
|
+
* @param options - Severity, message, and optional source position inputs.
|
|
5966
|
+
* @returns One diagnostic line without a trailing newline.
|
|
5967
|
+
*/
|
|
5968
|
+
function formatDiagnostic(options) {
|
|
5969
|
+
const prefix = formatDiagnosticLocationPrefix(options);
|
|
5970
|
+
const body = `${options.severity}: ${options.message}`;
|
|
5971
|
+
if (prefix === null) {
|
|
5972
|
+
return body;
|
|
5973
|
+
}
|
|
5974
|
+
return `${prefix}: ${body}`;
|
|
5975
|
+
}
|
|
5976
|
+
/**
|
|
5977
|
+
* Builds the `path:line:column` or `path` prefix for a diagnostic.
|
|
5978
|
+
*
|
|
5979
|
+
* @param options - Path and optional source position inputs.
|
|
5980
|
+
* @returns Location prefix, or null when no path is available.
|
|
5981
|
+
*/
|
|
5982
|
+
function formatDiagnosticLocationPrefix(options) {
|
|
5983
|
+
const path = options.path ?? null;
|
|
5984
|
+
if (path === null || path.length === 0) {
|
|
5985
|
+
return null;
|
|
5986
|
+
}
|
|
5987
|
+
const offset = resolveDiagnosticOffset(options.location, options.offset);
|
|
5988
|
+
const source = options.source ?? null;
|
|
5989
|
+
// Prefer path:line:column when both source text and an offset are known.
|
|
5990
|
+
if (source !== null && offset !== null) {
|
|
5991
|
+
const position = offsetToPosition(source, offset);
|
|
5992
|
+
return `${path}:${String(position.line)}:${String(position.column)}`;
|
|
5993
|
+
}
|
|
5994
|
+
return path;
|
|
5995
|
+
}
|
|
5996
|
+
|
|
5923
5997
|
/**
|
|
5924
5998
|
* LR parse table with ACTION and GOTO entries plus any detected conflicts.
|
|
5925
5999
|
*/
|
|
@@ -5984,13 +6058,19 @@ class LrParseTable {
|
|
|
5984
6058
|
function formatParseConflictWarning(conflict) {
|
|
5985
6059
|
const tokenLabel = formatConflictTokenLabel(conflict.symbol);
|
|
5986
6060
|
if (conflict.kind === 'shift-reduce') {
|
|
5987
|
-
return
|
|
6061
|
+
return formatDiagnostic({
|
|
6062
|
+
severity: 'warning',
|
|
6063
|
+
message: `state ${String(conflict.state)}: shift/reduce conflict on ${tokenLabel} resolved as shift`,
|
|
6064
|
+
});
|
|
5988
6065
|
}
|
|
5989
6066
|
const keptProduction = conflict.existing.kind === 'reduce'
|
|
5990
6067
|
? conflict.existing.productionId
|
|
5991
6068
|
: conflict.incoming.productionId;
|
|
5992
|
-
return
|
|
5993
|
-
|
|
6069
|
+
return formatDiagnostic({
|
|
6070
|
+
severity: 'warning',
|
|
6071
|
+
message: `state ${String(conflict.state)}: reduce/reduce conflict on ${tokenLabel} `
|
|
6072
|
+
+ `resolved using rule ${String(keptProduction)}`,
|
|
6073
|
+
});
|
|
5994
6074
|
}
|
|
5995
6075
|
/**
|
|
5996
6076
|
* Returns a readable terminal label for conflict warning text.
|
|
@@ -7535,6 +7615,42 @@ class ParserLr {
|
|
|
7535
7615
|
}
|
|
7536
7616
|
return parseWithTable(this.table, tokens);
|
|
7537
7617
|
}
|
|
7618
|
+
/**
|
|
7619
|
+
* Parses a token stream and retains syntax-error offset details.
|
|
7620
|
+
*
|
|
7621
|
+
* @param tokens - Token stream ending with `$eof`.
|
|
7622
|
+
* @returns Tree and optional syntax-error details.
|
|
7623
|
+
*/
|
|
7624
|
+
parseResult(tokens) {
|
|
7625
|
+
if (this.table === null) {
|
|
7626
|
+
return {
|
|
7627
|
+
tree: null,
|
|
7628
|
+
errorOffset: 0,
|
|
7629
|
+
errorMessage: 'Parse table has no parser entries',
|
|
7630
|
+
};
|
|
7631
|
+
}
|
|
7632
|
+
const result = parseWithTableResult(this.table, tokens);
|
|
7633
|
+
if (result.cst === null) {
|
|
7634
|
+
return {
|
|
7635
|
+
tree: null,
|
|
7636
|
+
errorOffset: result.errorOffset,
|
|
7637
|
+
errorMessage: result.errorMessage,
|
|
7638
|
+
};
|
|
7639
|
+
}
|
|
7640
|
+
if (this.grammar.transformSchema === null) {
|
|
7641
|
+
return {
|
|
7642
|
+
tree: result.cst,
|
|
7643
|
+
errorOffset: null,
|
|
7644
|
+
errorMessage: null,
|
|
7645
|
+
};
|
|
7646
|
+
}
|
|
7647
|
+
const tree = transformCst(result.cst, this.grammar.transformSchema, this.table);
|
|
7648
|
+
return {
|
|
7649
|
+
tree,
|
|
7650
|
+
errorOffset: tree === null ? result.errorOffset : null,
|
|
7651
|
+
errorMessage: tree === null ? 'AST transform failed' : null,
|
|
7652
|
+
};
|
|
7653
|
+
}
|
|
7538
7654
|
/**
|
|
7539
7655
|
* Parses a token stream into an AST when transform rules are declared.
|
|
7540
7656
|
*
|
|
@@ -7542,14 +7658,7 @@ class ParserLr {
|
|
|
7542
7658
|
* @returns Transformed AST, CST when no transform section exists, or null on failure.
|
|
7543
7659
|
*/
|
|
7544
7660
|
parseAst(tokens) {
|
|
7545
|
-
|
|
7546
|
-
if (cst === null) {
|
|
7547
|
-
return null;
|
|
7548
|
-
}
|
|
7549
|
-
if (this.grammar.transformSchema === null || this.table === null) {
|
|
7550
|
-
return cst;
|
|
7551
|
-
}
|
|
7552
|
-
return transformCst(cst, this.grammar.transformSchema, this.table);
|
|
7661
|
+
return this.parseResult(tokens).tree;
|
|
7553
7662
|
}
|
|
7554
7663
|
/**
|
|
7555
7664
|
* Parses a token stream, applying CST-to-AST transforms when configured.
|
|
@@ -7680,6 +7789,15 @@ class ParseContext {
|
|
|
7680
7789
|
parse(tokens) {
|
|
7681
7790
|
return this.parser.parse(tokens);
|
|
7682
7791
|
}
|
|
7792
|
+
/**
|
|
7793
|
+
* Parses a token stream and retains syntax-error offset details.
|
|
7794
|
+
*
|
|
7795
|
+
* @param tokens - Token stream ending with `$eof`.
|
|
7796
|
+
* @returns Tree and optional syntax-error details.
|
|
7797
|
+
*/
|
|
7798
|
+
parseResult(tokens) {
|
|
7799
|
+
return this.parser.parseResult(tokens);
|
|
7800
|
+
}
|
|
7683
7801
|
/**
|
|
7684
7802
|
* Lexes and parses source text into an AST, applying transforms when present.
|
|
7685
7803
|
*
|
|
@@ -8031,7 +8149,7 @@ function parseOptionalTransformSection(node) {
|
|
|
8031
8149
|
function parseProduction(node) {
|
|
8032
8150
|
const name = identifierText(requireChild(node, 'identifier'));
|
|
8033
8151
|
const expression = parseExpressionNode(findExpressionChild(node));
|
|
8034
|
-
return { name, expression };
|
|
8152
|
+
return { name, expression, location: node.location };
|
|
8035
8153
|
}
|
|
8036
8154
|
/**
|
|
8037
8155
|
* Parses one AST type (`identifier = expression ;`).
|
|
@@ -8041,7 +8159,7 @@ function parseProduction(node) {
|
|
|
8041
8159
|
function parseAstType(node) {
|
|
8042
8160
|
const name = identifierText(requireChild(node, 'identifier'));
|
|
8043
8161
|
const expression = parseExpressionNode(findExpressionChild(node));
|
|
8044
|
-
return { name, expression };
|
|
8162
|
+
return { name, expression, location: node.location };
|
|
8045
8163
|
}
|
|
8046
8164
|
/**
|
|
8047
8165
|
* Parses one transform rule.
|
|
@@ -8053,6 +8171,7 @@ function parseTransformRule(node) {
|
|
|
8053
8171
|
return {
|
|
8054
8172
|
production,
|
|
8055
8173
|
alternatives: collectRepeated(node, 'labeled_transform').map(parseLabeledTransform),
|
|
8174
|
+
location: node.location,
|
|
8056
8175
|
};
|
|
8057
8176
|
}
|
|
8058
8177
|
/**
|
|
@@ -8063,7 +8182,7 @@ function parseTransformRule(node) {
|
|
|
8063
8182
|
function parseLabeledTransform(node) {
|
|
8064
8183
|
const label = identifierText(requireChild(node, 'identifier'));
|
|
8065
8184
|
const expression = parseTransformExpr(requireChild(node, 'transform_expr'));
|
|
8066
|
-
return { label, expression };
|
|
8185
|
+
return { label, expression, location: node.location };
|
|
8067
8186
|
}
|
|
8068
8187
|
/**
|
|
8069
8188
|
* Parses a transform expression.
|
|
@@ -8241,8 +8360,11 @@ function parseExpressionNode(node) {
|
|
|
8241
8360
|
* @param node - `choice` CST node.
|
|
8242
8361
|
*/
|
|
8243
8362
|
function parseChoice(node) {
|
|
8363
|
+
// Parse each labeled or unlabeled alternative.
|
|
8244
8364
|
const alternatives = collectAlternatives(node).map(parseLabeledAlternative);
|
|
8245
|
-
|
|
8365
|
+
// Collapse a sole unlabeled alternative; keep labeled singles as a choice
|
|
8366
|
+
// so AST / transform variants remain visible to validation and consumers.
|
|
8367
|
+
if (alternatives.length === 1 && alternatives[0].label === null) {
|
|
8246
8368
|
return alternatives[0].expression;
|
|
8247
8369
|
}
|
|
8248
8370
|
return {
|
|
@@ -13126,134 +13248,35 @@ var gotos = [
|
|
|
13126
13248
|
var ast = [
|
|
13127
13249
|
{
|
|
13128
13250
|
name: "grammar_file",
|
|
13129
|
-
expression: {
|
|
13130
|
-
kind: "sequence",
|
|
13131
|
-
elements: [
|
|
13132
|
-
{
|
|
13133
|
-
kind: "reference",
|
|
13134
|
-
name: "name_decl"
|
|
13135
|
-
},
|
|
13136
|
-
{
|
|
13137
|
-
kind: "repeat",
|
|
13138
|
-
element: {
|
|
13139
|
-
kind: "reference",
|
|
13140
|
-
name: "section"
|
|
13141
|
-
}
|
|
13142
|
-
},
|
|
13143
|
-
{
|
|
13144
|
-
kind: "reference",
|
|
13145
|
-
name: "start_decl"
|
|
13146
|
-
},
|
|
13147
|
-
{
|
|
13148
|
-
kind: "reference",
|
|
13149
|
-
name: "grammar_section"
|
|
13150
|
-
},
|
|
13151
|
-
{
|
|
13152
|
-
kind: "optional",
|
|
13153
|
-
element: {
|
|
13154
|
-
kind: "reference",
|
|
13155
|
-
name: "ast_section"
|
|
13156
|
-
}
|
|
13157
|
-
},
|
|
13158
|
-
{
|
|
13159
|
-
kind: "optional",
|
|
13160
|
-
element: {
|
|
13161
|
-
kind: "reference",
|
|
13162
|
-
name: "transform_section"
|
|
13163
|
-
}
|
|
13164
|
-
}
|
|
13165
|
-
]
|
|
13166
|
-
}
|
|
13167
|
-
},
|
|
13168
|
-
{
|
|
13169
|
-
name: "name_decl",
|
|
13170
|
-
expression: {
|
|
13171
|
-
kind: "sequence",
|
|
13172
|
-
elements: [
|
|
13173
|
-
{
|
|
13174
|
-
kind: "reference",
|
|
13175
|
-
name: "name_kw"
|
|
13176
|
-
},
|
|
13177
|
-
{
|
|
13178
|
-
kind: "reference",
|
|
13179
|
-
name: "grammar_name"
|
|
13180
|
-
},
|
|
13181
|
-
{
|
|
13182
|
-
kind: "reference",
|
|
13183
|
-
name: "semicolon"
|
|
13184
|
-
}
|
|
13185
|
-
]
|
|
13186
|
-
}
|
|
13187
|
-
},
|
|
13188
|
-
{
|
|
13189
|
-
name: "grammar_name",
|
|
13190
13251
|
expression: {
|
|
13191
13252
|
kind: "choice",
|
|
13192
13253
|
alternatives: [
|
|
13193
13254
|
{
|
|
13194
|
-
label:
|
|
13195
|
-
expression: {
|
|
13196
|
-
kind: "reference",
|
|
13197
|
-
name: "identifier"
|
|
13198
|
-
}
|
|
13199
|
-
},
|
|
13200
|
-
{
|
|
13201
|
-
label: null,
|
|
13255
|
+
label: "sections",
|
|
13202
13256
|
expression: {
|
|
13203
|
-
kind: "
|
|
13204
|
-
|
|
13257
|
+
kind: "repeat",
|
|
13258
|
+
element: {
|
|
13259
|
+
kind: "reference",
|
|
13260
|
+
name: "section"
|
|
13261
|
+
}
|
|
13205
13262
|
}
|
|
13206
13263
|
}
|
|
13207
13264
|
]
|
|
13208
13265
|
}
|
|
13209
13266
|
},
|
|
13210
13267
|
{
|
|
13211
|
-
name: "
|
|
13268
|
+
name: "token_section",
|
|
13212
13269
|
expression: {
|
|
13213
13270
|
kind: "choice",
|
|
13214
13271
|
alternatives: [
|
|
13215
13272
|
{
|
|
13216
|
-
label:
|
|
13217
|
-
expression: {
|
|
13218
|
-
kind: "reference",
|
|
13219
|
-
name: "token_section"
|
|
13220
|
-
}
|
|
13221
|
-
},
|
|
13222
|
-
{
|
|
13223
|
-
label: null,
|
|
13273
|
+
label: "definitions",
|
|
13224
13274
|
expression: {
|
|
13225
|
-
kind: "
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
label: null,
|
|
13231
|
-
expression: {
|
|
13232
|
-
kind: "reference",
|
|
13233
|
-
name: "states_section"
|
|
13234
|
-
}
|
|
13235
|
-
}
|
|
13236
|
-
]
|
|
13237
|
-
}
|
|
13238
|
-
},
|
|
13239
|
-
{
|
|
13240
|
-
name: "token_section",
|
|
13241
|
-
expression: {
|
|
13242
|
-
kind: "sequence",
|
|
13243
|
-
elements: [
|
|
13244
|
-
{
|
|
13245
|
-
kind: "reference",
|
|
13246
|
-
name: "tokens_kw"
|
|
13247
|
-
},
|
|
13248
|
-
{
|
|
13249
|
-
kind: "reference",
|
|
13250
|
-
name: "token_def"
|
|
13251
|
-
},
|
|
13252
|
-
{
|
|
13253
|
-
kind: "repeat",
|
|
13254
|
-
element: {
|
|
13255
|
-
kind: "reference",
|
|
13256
|
-
name: "token_def"
|
|
13275
|
+
kind: "repeat",
|
|
13276
|
+
element: {
|
|
13277
|
+
kind: "reference",
|
|
13278
|
+
name: "token_def"
|
|
13279
|
+
}
|
|
13257
13280
|
}
|
|
13258
13281
|
}
|
|
13259
13282
|
]
|
|
@@ -13262,109 +13285,17 @@ var ast = [
|
|
|
13262
13285
|
{
|
|
13263
13286
|
name: "skip_section",
|
|
13264
13287
|
expression: {
|
|
13265
|
-
kind: "
|
|
13266
|
-
|
|
13267
|
-
{
|
|
13268
|
-
kind: "reference",
|
|
13269
|
-
name: "skip_kw"
|
|
13270
|
-
},
|
|
13271
|
-
{
|
|
13272
|
-
kind: "reference",
|
|
13273
|
-
name: "token_def"
|
|
13274
|
-
},
|
|
13275
|
-
{
|
|
13276
|
-
kind: "repeat",
|
|
13277
|
-
element: {
|
|
13278
|
-
kind: "reference",
|
|
13279
|
-
name: "token_def"
|
|
13280
|
-
}
|
|
13281
|
-
}
|
|
13282
|
-
]
|
|
13283
|
-
}
|
|
13284
|
-
},
|
|
13285
|
-
{
|
|
13286
|
-
name: "states_section",
|
|
13287
|
-
expression: {
|
|
13288
|
-
kind: "sequence",
|
|
13289
|
-
elements: [
|
|
13290
|
-
{
|
|
13291
|
-
kind: "reference",
|
|
13292
|
-
name: "states_kw"
|
|
13293
|
-
},
|
|
13294
|
-
{
|
|
13295
|
-
kind: "reference",
|
|
13296
|
-
name: "state_name"
|
|
13297
|
-
},
|
|
13288
|
+
kind: "choice",
|
|
13289
|
+
alternatives: [
|
|
13298
13290
|
{
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
kind: "
|
|
13302
|
-
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
|
|
13306
|
-
},
|
|
13307
|
-
{
|
|
13308
|
-
kind: "reference",
|
|
13309
|
-
name: "state_name"
|
|
13310
|
-
}
|
|
13311
|
-
]
|
|
13291
|
+
label: "definitions",
|
|
13292
|
+
expression: {
|
|
13293
|
+
kind: "repeat",
|
|
13294
|
+
element: {
|
|
13295
|
+
kind: "reference",
|
|
13296
|
+
name: "token_def"
|
|
13297
|
+
}
|
|
13312
13298
|
}
|
|
13313
|
-
},
|
|
13314
|
-
{
|
|
13315
|
-
kind: "reference",
|
|
13316
|
-
name: "semicolon"
|
|
13317
|
-
}
|
|
13318
|
-
]
|
|
13319
|
-
}
|
|
13320
|
-
},
|
|
13321
|
-
{
|
|
13322
|
-
name: "token_def",
|
|
13323
|
-
expression: {
|
|
13324
|
-
kind: "sequence",
|
|
13325
|
-
elements: [
|
|
13326
|
-
{
|
|
13327
|
-
kind: "reference",
|
|
13328
|
-
name: "identifier"
|
|
13329
|
-
},
|
|
13330
|
-
{
|
|
13331
|
-
kind: "reference",
|
|
13332
|
-
name: "equal"
|
|
13333
|
-
},
|
|
13334
|
-
{
|
|
13335
|
-
kind: "reference",
|
|
13336
|
-
name: "regex_literal"
|
|
13337
|
-
},
|
|
13338
|
-
{
|
|
13339
|
-
kind: "reference",
|
|
13340
|
-
name: "semicolon"
|
|
13341
|
-
}
|
|
13342
|
-
]
|
|
13343
|
-
}
|
|
13344
|
-
},
|
|
13345
|
-
{
|
|
13346
|
-
name: "state_name",
|
|
13347
|
-
expression: {
|
|
13348
|
-
kind: "reference",
|
|
13349
|
-
name: "identifier"
|
|
13350
|
-
}
|
|
13351
|
-
},
|
|
13352
|
-
{
|
|
13353
|
-
name: "start_decl",
|
|
13354
|
-
expression: {
|
|
13355
|
-
kind: "sequence",
|
|
13356
|
-
elements: [
|
|
13357
|
-
{
|
|
13358
|
-
kind: "reference",
|
|
13359
|
-
name: "start_kw"
|
|
13360
|
-
},
|
|
13361
|
-
{
|
|
13362
|
-
kind: "reference",
|
|
13363
|
-
name: "identifier"
|
|
13364
|
-
},
|
|
13365
|
-
{
|
|
13366
|
-
kind: "reference",
|
|
13367
|
-
name: "semicolon"
|
|
13368
13299
|
}
|
|
13369
13300
|
]
|
|
13370
13301
|
}
|
|
@@ -13372,21 +13303,16 @@ var ast = [
|
|
|
13372
13303
|
{
|
|
13373
13304
|
name: "grammar_section",
|
|
13374
13305
|
expression: {
|
|
13375
|
-
kind: "
|
|
13376
|
-
|
|
13377
|
-
{
|
|
13378
|
-
kind: "reference",
|
|
13379
|
-
name: "grammar_kw"
|
|
13380
|
-
},
|
|
13381
|
-
{
|
|
13382
|
-
kind: "reference",
|
|
13383
|
-
name: "production"
|
|
13384
|
-
},
|
|
13306
|
+
kind: "choice",
|
|
13307
|
+
alternatives: [
|
|
13385
13308
|
{
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
kind: "
|
|
13389
|
-
|
|
13309
|
+
label: "productions",
|
|
13310
|
+
expression: {
|
|
13311
|
+
kind: "repeat",
|
|
13312
|
+
element: {
|
|
13313
|
+
kind: "reference",
|
|
13314
|
+
name: "production"
|
|
13315
|
+
}
|
|
13390
13316
|
}
|
|
13391
13317
|
}
|
|
13392
13318
|
]
|
|
@@ -13395,21 +13321,16 @@ var ast = [
|
|
|
13395
13321
|
{
|
|
13396
13322
|
name: "ast_section",
|
|
13397
13323
|
expression: {
|
|
13398
|
-
kind: "
|
|
13399
|
-
|
|
13400
|
-
{
|
|
13401
|
-
kind: "reference",
|
|
13402
|
-
name: "ast_kw"
|
|
13403
|
-
},
|
|
13404
|
-
{
|
|
13405
|
-
kind: "reference",
|
|
13406
|
-
name: "ast_type"
|
|
13407
|
-
},
|
|
13324
|
+
kind: "choice",
|
|
13325
|
+
alternatives: [
|
|
13408
13326
|
{
|
|
13409
|
-
|
|
13410
|
-
|
|
13411
|
-
kind: "
|
|
13412
|
-
|
|
13327
|
+
label: "types",
|
|
13328
|
+
expression: {
|
|
13329
|
+
kind: "repeat",
|
|
13330
|
+
element: {
|
|
13331
|
+
kind: "reference",
|
|
13332
|
+
name: "ast_type"
|
|
13333
|
+
}
|
|
13413
13334
|
}
|
|
13414
13335
|
}
|
|
13415
13336
|
]
|
|
@@ -13418,621 +13339,88 @@ var ast = [
|
|
|
13418
13339
|
{
|
|
13419
13340
|
name: "transform_section",
|
|
13420
13341
|
expression: {
|
|
13421
|
-
kind: "
|
|
13422
|
-
|
|
13423
|
-
{
|
|
13424
|
-
kind: "reference",
|
|
13425
|
-
name: "transform_kw"
|
|
13426
|
-
},
|
|
13427
|
-
{
|
|
13428
|
-
kind: "reference",
|
|
13429
|
-
name: "transform_rule"
|
|
13430
|
-
},
|
|
13342
|
+
kind: "choice",
|
|
13343
|
+
alternatives: [
|
|
13431
13344
|
{
|
|
13432
|
-
|
|
13433
|
-
|
|
13434
|
-
kind: "
|
|
13435
|
-
|
|
13345
|
+
label: "rules",
|
|
13346
|
+
expression: {
|
|
13347
|
+
kind: "repeat",
|
|
13348
|
+
element: {
|
|
13349
|
+
kind: "reference",
|
|
13350
|
+
name: "transform_rule"
|
|
13351
|
+
}
|
|
13436
13352
|
}
|
|
13437
13353
|
}
|
|
13438
13354
|
]
|
|
13439
13355
|
}
|
|
13440
13356
|
},
|
|
13441
|
-
{
|
|
13442
|
-
name: "production",
|
|
13443
|
-
expression: {
|
|
13444
|
-
kind: "sequence",
|
|
13445
|
-
elements: [
|
|
13446
|
-
{
|
|
13447
|
-
kind: "reference",
|
|
13448
|
-
name: "identifier"
|
|
13449
|
-
},
|
|
13450
|
-
{
|
|
13451
|
-
kind: "reference",
|
|
13452
|
-
name: "equal"
|
|
13453
|
-
},
|
|
13454
|
-
{
|
|
13455
|
-
kind: "reference",
|
|
13456
|
-
name: "expression"
|
|
13457
|
-
},
|
|
13458
|
-
{
|
|
13459
|
-
kind: "reference",
|
|
13460
|
-
name: "semicolon"
|
|
13461
|
-
}
|
|
13462
|
-
]
|
|
13463
|
-
}
|
|
13464
|
-
},
|
|
13465
|
-
{
|
|
13466
|
-
name: "ast_type",
|
|
13467
|
-
expression: {
|
|
13468
|
-
kind: "sequence",
|
|
13469
|
-
elements: [
|
|
13470
|
-
{
|
|
13471
|
-
kind: "reference",
|
|
13472
|
-
name: "identifier"
|
|
13473
|
-
},
|
|
13474
|
-
{
|
|
13475
|
-
kind: "reference",
|
|
13476
|
-
name: "equal"
|
|
13477
|
-
},
|
|
13478
|
-
{
|
|
13479
|
-
kind: "reference",
|
|
13480
|
-
name: "expression"
|
|
13481
|
-
},
|
|
13482
|
-
{
|
|
13483
|
-
kind: "reference",
|
|
13484
|
-
name: "semicolon"
|
|
13485
|
-
}
|
|
13486
|
-
]
|
|
13487
|
-
}
|
|
13488
|
-
},
|
|
13489
13357
|
{
|
|
13490
13358
|
name: "transform_rule",
|
|
13491
|
-
expression: {
|
|
13492
|
-
kind: "sequence",
|
|
13493
|
-
elements: [
|
|
13494
|
-
{
|
|
13495
|
-
kind: "reference",
|
|
13496
|
-
name: "identifier"
|
|
13497
|
-
},
|
|
13498
|
-
{
|
|
13499
|
-
kind: "reference",
|
|
13500
|
-
name: "arrow"
|
|
13501
|
-
},
|
|
13502
|
-
{
|
|
13503
|
-
kind: "reference",
|
|
13504
|
-
name: "labeled_transform"
|
|
13505
|
-
},
|
|
13506
|
-
{
|
|
13507
|
-
kind: "repeat",
|
|
13508
|
-
element: {
|
|
13509
|
-
kind: "sequence",
|
|
13510
|
-
elements: [
|
|
13511
|
-
{
|
|
13512
|
-
kind: "reference",
|
|
13513
|
-
name: "bar"
|
|
13514
|
-
},
|
|
13515
|
-
{
|
|
13516
|
-
kind: "reference",
|
|
13517
|
-
name: "labeled_transform"
|
|
13518
|
-
}
|
|
13519
|
-
]
|
|
13520
|
-
}
|
|
13521
|
-
},
|
|
13522
|
-
{
|
|
13523
|
-
kind: "reference",
|
|
13524
|
-
name: "semicolon"
|
|
13525
|
-
}
|
|
13526
|
-
]
|
|
13527
|
-
}
|
|
13528
|
-
},
|
|
13529
|
-
{
|
|
13530
|
-
name: "labeled_transform",
|
|
13531
|
-
expression: {
|
|
13532
|
-
kind: "sequence",
|
|
13533
|
-
elements: [
|
|
13534
|
-
{
|
|
13535
|
-
kind: "reference",
|
|
13536
|
-
name: "hash"
|
|
13537
|
-
},
|
|
13538
|
-
{
|
|
13539
|
-
kind: "reference",
|
|
13540
|
-
name: "identifier"
|
|
13541
|
-
},
|
|
13542
|
-
{
|
|
13543
|
-
kind: "reference",
|
|
13544
|
-
name: "transform_expr"
|
|
13545
|
-
}
|
|
13546
|
-
]
|
|
13547
|
-
}
|
|
13548
|
-
},
|
|
13549
|
-
{
|
|
13550
|
-
name: "transform_expr",
|
|
13551
13359
|
expression: {
|
|
13552
13360
|
kind: "choice",
|
|
13553
13361
|
alternatives: [
|
|
13554
13362
|
{
|
|
13555
|
-
label:
|
|
13556
|
-
expression: {
|
|
13557
|
-
kind: "reference",
|
|
13558
|
-
name: "drop_kw"
|
|
13559
|
-
}
|
|
13560
|
-
},
|
|
13561
|
-
{
|
|
13562
|
-
label: null,
|
|
13563
|
-
expression: {
|
|
13564
|
-
kind: "reference",
|
|
13565
|
-
name: "pass_expr"
|
|
13566
|
-
}
|
|
13567
|
-
},
|
|
13568
|
-
{
|
|
13569
|
-
label: null,
|
|
13570
|
-
expression: {
|
|
13571
|
-
kind: "reference",
|
|
13572
|
-
name: "fold_left_expr"
|
|
13573
|
-
}
|
|
13574
|
-
},
|
|
13575
|
-
{
|
|
13576
|
-
label: null,
|
|
13577
|
-
expression: {
|
|
13578
|
-
kind: "reference",
|
|
13579
|
-
name: "fold_right_expr"
|
|
13580
|
-
}
|
|
13581
|
-
},
|
|
13582
|
-
{
|
|
13583
|
-
label: null,
|
|
13584
|
-
expression: {
|
|
13585
|
-
kind: "reference",
|
|
13586
|
-
name: "flatten_expr"
|
|
13587
|
-
}
|
|
13588
|
-
},
|
|
13589
|
-
{
|
|
13590
|
-
label: null,
|
|
13363
|
+
label: "alternatives",
|
|
13591
13364
|
expression: {
|
|
13592
|
-
kind: "
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13596
|
-
|
|
13597
|
-
}
|
|
13598
|
-
},
|
|
13599
|
-
{
|
|
13600
|
-
name: "pass_expr",
|
|
13601
|
-
expression: {
|
|
13602
|
-
kind: "sequence",
|
|
13603
|
-
elements: [
|
|
13604
|
-
{
|
|
13605
|
-
kind: "reference",
|
|
13606
|
-
name: "pass_kw"
|
|
13607
|
-
},
|
|
13608
|
-
{
|
|
13609
|
-
kind: "reference",
|
|
13610
|
-
name: "lpar"
|
|
13611
|
-
},
|
|
13612
|
-
{
|
|
13613
|
-
kind: "reference",
|
|
13614
|
-
name: "reference"
|
|
13615
|
-
},
|
|
13616
|
-
{
|
|
13617
|
-
kind: "reference",
|
|
13618
|
-
name: "rpar"
|
|
13619
|
-
}
|
|
13620
|
-
]
|
|
13621
|
-
}
|
|
13622
|
-
},
|
|
13623
|
-
{
|
|
13624
|
-
name: "fold_left_expr",
|
|
13625
|
-
expression: {
|
|
13626
|
-
kind: "sequence",
|
|
13627
|
-
elements: [
|
|
13628
|
-
{
|
|
13629
|
-
kind: "reference",
|
|
13630
|
-
name: "fold_left_kw"
|
|
13631
|
-
},
|
|
13632
|
-
{
|
|
13633
|
-
kind: "reference",
|
|
13634
|
-
name: "lpar"
|
|
13635
|
-
},
|
|
13636
|
-
{
|
|
13637
|
-
kind: "reference",
|
|
13638
|
-
name: "build_target"
|
|
13639
|
-
},
|
|
13640
|
-
{
|
|
13641
|
-
kind: "reference",
|
|
13642
|
-
name: "comma"
|
|
13643
|
-
},
|
|
13644
|
-
{
|
|
13645
|
-
kind: "reference",
|
|
13646
|
-
name: "reference_list"
|
|
13647
|
-
},
|
|
13648
|
-
{
|
|
13649
|
-
kind: "reference",
|
|
13650
|
-
name: "rpar"
|
|
13651
|
-
}
|
|
13652
|
-
]
|
|
13653
|
-
}
|
|
13654
|
-
},
|
|
13655
|
-
{
|
|
13656
|
-
name: "fold_right_expr",
|
|
13657
|
-
expression: {
|
|
13658
|
-
kind: "sequence",
|
|
13659
|
-
elements: [
|
|
13660
|
-
{
|
|
13661
|
-
kind: "reference",
|
|
13662
|
-
name: "fold_right_kw"
|
|
13663
|
-
},
|
|
13664
|
-
{
|
|
13665
|
-
kind: "reference",
|
|
13666
|
-
name: "lpar"
|
|
13667
|
-
},
|
|
13668
|
-
{
|
|
13669
|
-
kind: "reference",
|
|
13670
|
-
name: "build_target"
|
|
13671
|
-
},
|
|
13672
|
-
{
|
|
13673
|
-
kind: "reference",
|
|
13674
|
-
name: "comma"
|
|
13675
|
-
},
|
|
13676
|
-
{
|
|
13677
|
-
kind: "reference",
|
|
13678
|
-
name: "reference_list"
|
|
13679
|
-
},
|
|
13680
|
-
{
|
|
13681
|
-
kind: "reference",
|
|
13682
|
-
name: "rpar"
|
|
13683
|
-
}
|
|
13684
|
-
]
|
|
13685
|
-
}
|
|
13686
|
-
},
|
|
13687
|
-
{
|
|
13688
|
-
name: "flatten_expr",
|
|
13689
|
-
expression: {
|
|
13690
|
-
kind: "sequence",
|
|
13691
|
-
elements: [
|
|
13692
|
-
{
|
|
13693
|
-
kind: "reference",
|
|
13694
|
-
name: "flatten_kw"
|
|
13695
|
-
},
|
|
13696
|
-
{
|
|
13697
|
-
kind: "reference",
|
|
13698
|
-
name: "lpar"
|
|
13699
|
-
},
|
|
13700
|
-
{
|
|
13701
|
-
kind: "reference",
|
|
13702
|
-
name: "build_target"
|
|
13703
|
-
},
|
|
13704
|
-
{
|
|
13705
|
-
kind: "reference",
|
|
13706
|
-
name: "comma"
|
|
13707
|
-
},
|
|
13708
|
-
{
|
|
13709
|
-
kind: "reference",
|
|
13710
|
-
name: "reference"
|
|
13711
|
-
},
|
|
13712
|
-
{
|
|
13713
|
-
kind: "reference",
|
|
13714
|
-
name: "comma"
|
|
13715
|
-
},
|
|
13716
|
-
{
|
|
13717
|
-
kind: "reference",
|
|
13718
|
-
name: "reference"
|
|
13719
|
-
},
|
|
13720
|
-
{
|
|
13721
|
-
kind: "reference",
|
|
13722
|
-
name: "rpar"
|
|
13723
|
-
}
|
|
13724
|
-
]
|
|
13725
|
-
}
|
|
13726
|
-
},
|
|
13727
|
-
{
|
|
13728
|
-
name: "build_expr",
|
|
13729
|
-
expression: {
|
|
13730
|
-
kind: "sequence",
|
|
13731
|
-
elements: [
|
|
13732
|
-
{
|
|
13733
|
-
kind: "reference",
|
|
13734
|
-
name: "build_target"
|
|
13735
|
-
},
|
|
13736
|
-
{
|
|
13737
|
-
kind: "optional",
|
|
13738
|
-
element: {
|
|
13739
|
-
kind: "sequence",
|
|
13740
|
-
elements: [
|
|
13741
|
-
{
|
|
13742
|
-
kind: "reference",
|
|
13743
|
-
name: "lpar"
|
|
13744
|
-
},
|
|
13745
|
-
{
|
|
13746
|
-
kind: "reference",
|
|
13747
|
-
name: "reference_list"
|
|
13748
|
-
},
|
|
13749
|
-
{
|
|
13750
|
-
kind: "reference",
|
|
13751
|
-
name: "rpar"
|
|
13752
|
-
}
|
|
13753
|
-
]
|
|
13365
|
+
kind: "repeat",
|
|
13366
|
+
element: {
|
|
13367
|
+
kind: "reference",
|
|
13368
|
+
name: "labeled_transform"
|
|
13369
|
+
}
|
|
13754
13370
|
}
|
|
13755
13371
|
}
|
|
13756
13372
|
]
|
|
13757
13373
|
}
|
|
13758
13374
|
},
|
|
13759
|
-
{
|
|
13760
|
-
name: "build_target",
|
|
13761
|
-
expression: {
|
|
13762
|
-
kind: "sequence",
|
|
13763
|
-
elements: [
|
|
13764
|
-
{
|
|
13765
|
-
kind: "reference",
|
|
13766
|
-
name: "identifier"
|
|
13767
|
-
},
|
|
13768
|
-
{
|
|
13769
|
-
kind: "reference",
|
|
13770
|
-
name: "dot"
|
|
13771
|
-
},
|
|
13772
|
-
{
|
|
13773
|
-
kind: "reference",
|
|
13774
|
-
name: "hash"
|
|
13775
|
-
},
|
|
13776
|
-
{
|
|
13777
|
-
kind: "reference",
|
|
13778
|
-
name: "identifier"
|
|
13779
|
-
}
|
|
13780
|
-
]
|
|
13781
|
-
}
|
|
13782
|
-
},
|
|
13783
13375
|
{
|
|
13784
13376
|
name: "reference_list",
|
|
13785
13377
|
expression: {
|
|
13786
|
-
kind: "
|
|
13787
|
-
|
|
13788
|
-
{
|
|
13789
|
-
kind: "reference",
|
|
13790
|
-
name: "reference"
|
|
13791
|
-
},
|
|
13378
|
+
kind: "choice",
|
|
13379
|
+
alternatives: [
|
|
13792
13380
|
{
|
|
13793
|
-
|
|
13794
|
-
|
|
13795
|
-
kind: "
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
|
|
13800
|
-
},
|
|
13801
|
-
{
|
|
13802
|
-
kind: "reference",
|
|
13803
|
-
name: "reference"
|
|
13804
|
-
}
|
|
13805
|
-
]
|
|
13381
|
+
label: "references",
|
|
13382
|
+
expression: {
|
|
13383
|
+
kind: "repeat",
|
|
13384
|
+
element: {
|
|
13385
|
+
kind: "reference",
|
|
13386
|
+
name: "reference"
|
|
13387
|
+
}
|
|
13806
13388
|
}
|
|
13807
13389
|
}
|
|
13808
13390
|
]
|
|
13809
13391
|
}
|
|
13810
13392
|
},
|
|
13811
|
-
{
|
|
13812
|
-
name: "reference",
|
|
13813
|
-
expression: {
|
|
13814
|
-
kind: "reference",
|
|
13815
|
-
name: "identifier"
|
|
13816
|
-
}
|
|
13817
|
-
},
|
|
13818
|
-
{
|
|
13819
|
-
name: "expression",
|
|
13820
|
-
expression: {
|
|
13821
|
-
kind: "reference",
|
|
13822
|
-
name: "choice"
|
|
13823
|
-
}
|
|
13824
|
-
},
|
|
13825
13393
|
{
|
|
13826
13394
|
name: "choice",
|
|
13827
|
-
expression: {
|
|
13828
|
-
kind: "sequence",
|
|
13829
|
-
elements: [
|
|
13830
|
-
{
|
|
13831
|
-
kind: "reference",
|
|
13832
|
-
name: "alternative"
|
|
13833
|
-
},
|
|
13834
|
-
{
|
|
13835
|
-
kind: "repeat",
|
|
13836
|
-
element: {
|
|
13837
|
-
kind: "sequence",
|
|
13838
|
-
elements: [
|
|
13839
|
-
{
|
|
13840
|
-
kind: "reference",
|
|
13841
|
-
name: "bar"
|
|
13842
|
-
},
|
|
13843
|
-
{
|
|
13844
|
-
kind: "reference",
|
|
13845
|
-
name: "alternative"
|
|
13846
|
-
}
|
|
13847
|
-
]
|
|
13848
|
-
}
|
|
13849
|
-
}
|
|
13850
|
-
]
|
|
13851
|
-
}
|
|
13852
|
-
},
|
|
13853
|
-
{
|
|
13854
|
-
name: "alternative",
|
|
13855
|
-
expression: {
|
|
13856
|
-
kind: "reference",
|
|
13857
|
-
name: "labeled_alternative"
|
|
13858
|
-
}
|
|
13859
|
-
},
|
|
13860
|
-
{
|
|
13861
|
-
name: "labeled_alternative",
|
|
13862
|
-
expression: {
|
|
13863
|
-
kind: "sequence",
|
|
13864
|
-
elements: [
|
|
13865
|
-
{
|
|
13866
|
-
kind: "optional",
|
|
13867
|
-
element: {
|
|
13868
|
-
kind: "sequence",
|
|
13869
|
-
elements: [
|
|
13870
|
-
{
|
|
13871
|
-
kind: "reference",
|
|
13872
|
-
name: "hash"
|
|
13873
|
-
},
|
|
13874
|
-
{
|
|
13875
|
-
kind: "reference",
|
|
13876
|
-
name: "identifier"
|
|
13877
|
-
}
|
|
13878
|
-
]
|
|
13879
|
-
}
|
|
13880
|
-
},
|
|
13881
|
-
{
|
|
13882
|
-
kind: "reference",
|
|
13883
|
-
name: "sequence"
|
|
13884
|
-
}
|
|
13885
|
-
]
|
|
13886
|
-
}
|
|
13887
|
-
},
|
|
13888
|
-
{
|
|
13889
|
-
name: "sequence",
|
|
13890
|
-
expression: {
|
|
13891
|
-
kind: "sequence",
|
|
13892
|
-
elements: [
|
|
13893
|
-
{
|
|
13894
|
-
kind: "reference",
|
|
13895
|
-
name: "factor"
|
|
13896
|
-
},
|
|
13897
|
-
{
|
|
13898
|
-
kind: "repeat",
|
|
13899
|
-
element: {
|
|
13900
|
-
kind: "reference",
|
|
13901
|
-
name: "factor"
|
|
13902
|
-
}
|
|
13903
|
-
}
|
|
13904
|
-
]
|
|
13905
|
-
}
|
|
13906
|
-
},
|
|
13907
|
-
{
|
|
13908
|
-
name: "factor",
|
|
13909
13395
|
expression: {
|
|
13910
13396
|
kind: "choice",
|
|
13911
13397
|
alternatives: [
|
|
13912
13398
|
{
|
|
13913
|
-
label:
|
|
13914
|
-
expression: {
|
|
13915
|
-
kind: "reference",
|
|
13916
|
-
name: "bracketed"
|
|
13917
|
-
}
|
|
13918
|
-
},
|
|
13919
|
-
{
|
|
13920
|
-
label: null,
|
|
13399
|
+
label: "alternatives",
|
|
13921
13400
|
expression: {
|
|
13922
|
-
kind: "
|
|
13923
|
-
|
|
13924
|
-
|
|
13925
|
-
|
|
13926
|
-
|
|
13927
|
-
label: null,
|
|
13928
|
-
expression: {
|
|
13929
|
-
kind: "reference",
|
|
13930
|
-
name: "group"
|
|
13931
|
-
}
|
|
13932
|
-
},
|
|
13933
|
-
{
|
|
13934
|
-
label: null,
|
|
13935
|
-
expression: {
|
|
13936
|
-
kind: "reference",
|
|
13937
|
-
name: "primary"
|
|
13938
|
-
}
|
|
13939
|
-
}
|
|
13940
|
-
]
|
|
13941
|
-
}
|
|
13942
|
-
},
|
|
13943
|
-
{
|
|
13944
|
-
name: "bracketed",
|
|
13945
|
-
expression: {
|
|
13946
|
-
kind: "sequence",
|
|
13947
|
-
elements: [
|
|
13948
|
-
{
|
|
13949
|
-
kind: "reference",
|
|
13950
|
-
name: "lbracket"
|
|
13951
|
-
},
|
|
13952
|
-
{
|
|
13953
|
-
kind: "reference",
|
|
13954
|
-
name: "expression"
|
|
13955
|
-
},
|
|
13956
|
-
{
|
|
13957
|
-
kind: "reference",
|
|
13958
|
-
name: "rbracket"
|
|
13959
|
-
},
|
|
13960
|
-
{
|
|
13961
|
-
kind: "optional",
|
|
13962
|
-
element: {
|
|
13963
|
-
kind: "sequence",
|
|
13964
|
-
elements: [
|
|
13965
|
-
{
|
|
13966
|
-
kind: "reference",
|
|
13967
|
-
name: "colon"
|
|
13968
|
-
},
|
|
13969
|
-
{
|
|
13970
|
-
kind: "reference",
|
|
13971
|
-
name: "identifier"
|
|
13972
|
-
}
|
|
13973
|
-
]
|
|
13401
|
+
kind: "repeat",
|
|
13402
|
+
element: {
|
|
13403
|
+
kind: "reference",
|
|
13404
|
+
name: "alternative"
|
|
13405
|
+
}
|
|
13974
13406
|
}
|
|
13975
13407
|
}
|
|
13976
13408
|
]
|
|
13977
13409
|
}
|
|
13978
13410
|
},
|
|
13979
13411
|
{
|
|
13980
|
-
name: "
|
|
13981
|
-
expression: {
|
|
13982
|
-
kind: "sequence",
|
|
13983
|
-
elements: [
|
|
13984
|
-
{
|
|
13985
|
-
kind: "reference",
|
|
13986
|
-
name: "lbrace"
|
|
13987
|
-
},
|
|
13988
|
-
{
|
|
13989
|
-
kind: "reference",
|
|
13990
|
-
name: "expression"
|
|
13991
|
-
},
|
|
13992
|
-
{
|
|
13993
|
-
kind: "reference",
|
|
13994
|
-
name: "rbrace"
|
|
13995
|
-
}
|
|
13996
|
-
]
|
|
13997
|
-
}
|
|
13998
|
-
},
|
|
13999
|
-
{
|
|
14000
|
-
name: "group",
|
|
14001
|
-
expression: {
|
|
14002
|
-
kind: "sequence",
|
|
14003
|
-
elements: [
|
|
14004
|
-
{
|
|
14005
|
-
kind: "reference",
|
|
14006
|
-
name: "lpar"
|
|
14007
|
-
},
|
|
14008
|
-
{
|
|
14009
|
-
kind: "reference",
|
|
14010
|
-
name: "expression"
|
|
14011
|
-
},
|
|
14012
|
-
{
|
|
14013
|
-
kind: "reference",
|
|
14014
|
-
name: "rpar"
|
|
14015
|
-
}
|
|
14016
|
-
]
|
|
14017
|
-
}
|
|
14018
|
-
},
|
|
14019
|
-
{
|
|
14020
|
-
name: "primary",
|
|
13412
|
+
name: "sequence",
|
|
14021
13413
|
expression: {
|
|
14022
13414
|
kind: "choice",
|
|
14023
13415
|
alternatives: [
|
|
14024
13416
|
{
|
|
14025
|
-
label:
|
|
14026
|
-
expression: {
|
|
14027
|
-
kind: "reference",
|
|
14028
|
-
name: "string_literal"
|
|
14029
|
-
}
|
|
14030
|
-
},
|
|
14031
|
-
{
|
|
14032
|
-
label: null,
|
|
13417
|
+
label: "factors",
|
|
14033
13418
|
expression: {
|
|
14034
|
-
kind: "
|
|
14035
|
-
|
|
13419
|
+
kind: "repeat",
|
|
13420
|
+
element: {
|
|
13421
|
+
kind: "reference",
|
|
13422
|
+
name: "factor"
|
|
13423
|
+
}
|
|
14036
13424
|
}
|
|
14037
13425
|
}
|
|
14038
13426
|
]
|
|
@@ -14056,7 +13444,7 @@ var transform = [
|
|
|
14056
13444
|
]
|
|
14057
13445
|
},
|
|
14058
13446
|
{
|
|
14059
|
-
production: "token_section
|
|
13447
|
+
production: "token_section",
|
|
14060
13448
|
alternatives: [
|
|
14061
13449
|
{
|
|
14062
13450
|
label: "main",
|
|
@@ -14071,7 +13459,7 @@ var transform = [
|
|
|
14071
13459
|
]
|
|
14072
13460
|
},
|
|
14073
13461
|
{
|
|
14074
|
-
production: "skip_section
|
|
13462
|
+
production: "skip_section",
|
|
14075
13463
|
alternatives: [
|
|
14076
13464
|
{
|
|
14077
13465
|
label: "main",
|
|
@@ -14086,7 +13474,7 @@ var transform = [
|
|
|
14086
13474
|
]
|
|
14087
13475
|
},
|
|
14088
13476
|
{
|
|
14089
|
-
production: "grammar_section
|
|
13477
|
+
production: "grammar_section",
|
|
14090
13478
|
alternatives: [
|
|
14091
13479
|
{
|
|
14092
13480
|
label: "main",
|
|
@@ -14101,7 +13489,7 @@ var transform = [
|
|
|
14101
13489
|
]
|
|
14102
13490
|
},
|
|
14103
13491
|
{
|
|
14104
|
-
production: "ast_section
|
|
13492
|
+
production: "ast_section",
|
|
14105
13493
|
alternatives: [
|
|
14106
13494
|
{
|
|
14107
13495
|
label: "main",
|
|
@@ -14116,7 +13504,7 @@ var transform = [
|
|
|
14116
13504
|
]
|
|
14117
13505
|
},
|
|
14118
13506
|
{
|
|
14119
|
-
production: "transform_section
|
|
13507
|
+
production: "transform_section",
|
|
14120
13508
|
alternatives: [
|
|
14121
13509
|
{
|
|
14122
13510
|
label: "main",
|
|
@@ -14131,7 +13519,7 @@ var transform = [
|
|
|
14131
13519
|
]
|
|
14132
13520
|
},
|
|
14133
13521
|
{
|
|
14134
|
-
production: "transform_rule
|
|
13522
|
+
production: "transform_rule",
|
|
14135
13523
|
alternatives: [
|
|
14136
13524
|
{
|
|
14137
13525
|
label: "main",
|
|
@@ -14146,7 +13534,7 @@ var transform = [
|
|
|
14146
13534
|
]
|
|
14147
13535
|
},
|
|
14148
13536
|
{
|
|
14149
|
-
production: "reference_list
|
|
13537
|
+
production: "reference_list",
|
|
14150
13538
|
alternatives: [
|
|
14151
13539
|
{
|
|
14152
13540
|
label: "main",
|
|
@@ -14161,7 +13549,7 @@ var transform = [
|
|
|
14161
13549
|
]
|
|
14162
13550
|
},
|
|
14163
13551
|
{
|
|
14164
|
-
production: "choice
|
|
13552
|
+
production: "choice",
|
|
14165
13553
|
alternatives: [
|
|
14166
13554
|
{
|
|
14167
13555
|
label: "main",
|
|
@@ -14176,7 +13564,7 @@ var transform = [
|
|
|
14176
13564
|
]
|
|
14177
13565
|
},
|
|
14178
13566
|
{
|
|
14179
|
-
production: "sequence
|
|
13567
|
+
production: "sequence",
|
|
14180
13568
|
alternatives: [
|
|
14181
13569
|
{
|
|
14182
13570
|
label: "main",
|
|
@@ -14270,8 +13658,8 @@ function validateGrammarTable(grammar) {
|
|
|
14270
13658
|
for (const rule of grammar.transformSchema.rules) {
|
|
14271
13659
|
validateTransformProductionExists(rule, bnfProductionNames, issues);
|
|
14272
13660
|
for (const alternative of rule.alternatives) {
|
|
14273
|
-
validateTransformExpression(grammar, alternative
|
|
14274
|
-
collectPassCollapseWarnings(grammar, rule, alternative
|
|
13661
|
+
validateTransformExpression(grammar, alternative, issues);
|
|
13662
|
+
collectPassCollapseWarnings(grammar, rule, alternative, bnf.productions, issues);
|
|
14275
13663
|
}
|
|
14276
13664
|
}
|
|
14277
13665
|
}
|
|
@@ -14290,37 +13678,47 @@ function validateGrammarTable(grammar) {
|
|
|
14290
13678
|
*/
|
|
14291
13679
|
function collectDuplicateDefinitionWarnings(grammar, issues) {
|
|
14292
13680
|
// Flag repeated production names in the grammar section.
|
|
14293
|
-
|
|
13681
|
+
reportDuplicateDefinitions(grammar.productions.map((production) => ({
|
|
13682
|
+
name: production.name,
|
|
13683
|
+
location: production.location ?? null,
|
|
13684
|
+
})), 'grammar', 'production', issues);
|
|
14294
13685
|
// Flag repeated ast type names.
|
|
14295
13686
|
if (grammar.astSchema !== null) {
|
|
14296
|
-
|
|
13687
|
+
reportDuplicateDefinitions(grammar.astSchema.types.map((type) => ({
|
|
13688
|
+
name: type.name,
|
|
13689
|
+
location: type.location ?? null,
|
|
13690
|
+
})), 'ast', 'type', issues);
|
|
14297
13691
|
}
|
|
14298
13692
|
// Flag repeated transform rules for the same production.
|
|
14299
13693
|
if (grammar.transformSchema !== null) {
|
|
14300
|
-
|
|
13694
|
+
reportDuplicateDefinitions(grammar.transformSchema.rules.map((rule) => ({
|
|
13695
|
+
name: rule.production,
|
|
13696
|
+
location: rule.location ?? null,
|
|
13697
|
+
})), 'transform', 'rule', issues);
|
|
14301
13698
|
}
|
|
14302
13699
|
}
|
|
14303
13700
|
/**
|
|
14304
13701
|
* Records a warning for each name that appears more than once.
|
|
14305
13702
|
*
|
|
14306
|
-
* @param
|
|
13703
|
+
* @param definitions - Declared names and locations in source order.
|
|
14307
13704
|
* @param section - Grammar section name for the message.
|
|
14308
13705
|
* @param kind - Declaration kind for the message.
|
|
14309
13706
|
* @param issues - Issue list to append to.
|
|
14310
13707
|
*/
|
|
14311
|
-
function
|
|
13708
|
+
function reportDuplicateDefinitions(definitions, section, kind, issues) {
|
|
14312
13709
|
const seen = new Set();
|
|
14313
13710
|
const reported = new Set();
|
|
14314
|
-
for (const
|
|
14315
|
-
if (seen.has(name) && !reported.has(name)) {
|
|
13711
|
+
for (const definition of definitions) {
|
|
13712
|
+
if (seen.has(definition.name) && !reported.has(definition.name)) {
|
|
14316
13713
|
issues.push({
|
|
14317
13714
|
severity: 'warning',
|
|
14318
|
-
message: `duplicate ${section} ${kind} ${JSON.stringify(name)}; `
|
|
13715
|
+
message: `duplicate ${section} ${kind} ${JSON.stringify(definition.name)}; `
|
|
14319
13716
|
+ `the later definition overrides the earlier one`,
|
|
13717
|
+
location: definition.location,
|
|
14320
13718
|
});
|
|
14321
|
-
reported.add(name);
|
|
13719
|
+
reported.add(definition.name);
|
|
14322
13720
|
}
|
|
14323
|
-
seen.add(name);
|
|
13721
|
+
seen.add(definition.name);
|
|
14324
13722
|
}
|
|
14325
13723
|
}
|
|
14326
13724
|
/**
|
|
@@ -14331,29 +13729,50 @@ function reportDuplicateNames(names, section, kind, issues) {
|
|
|
14331
13729
|
* @param issues - Issue list to append to.
|
|
14332
13730
|
*/
|
|
14333
13731
|
function validateTransformProductionExists(rule, bnfProductionNames, issues) {
|
|
14334
|
-
|
|
13732
|
+
// Accept direct production names.
|
|
13733
|
+
if (bnfProductionNames.has(rule.production)) {
|
|
13734
|
+
return;
|
|
13735
|
+
}
|
|
13736
|
+
// Match authored `$repeat_0` aliases to globally numbered repeats.
|
|
13737
|
+
const repeatPrefix = syntheticRepeatPrefix(rule.production);
|
|
13738
|
+
const matchesRepeat = repeatPrefix !== null
|
|
13739
|
+
&& [...bnfProductionNames].some((productionName) => syntheticRepeatPrefix(productionName) === repeatPrefix);
|
|
13740
|
+
if (!matchesRepeat) {
|
|
14335
13741
|
issues.push({
|
|
14336
13742
|
severity: 'error',
|
|
14337
13743
|
message: `transform rule for unknown production ${JSON.stringify(rule.production)}`,
|
|
13744
|
+
location: rule.location ?? null,
|
|
14338
13745
|
});
|
|
14339
13746
|
}
|
|
14340
13747
|
}
|
|
13748
|
+
/**
|
|
13749
|
+
* Returns the stable prefix of a numbered synthetic repeat production.
|
|
13750
|
+
*
|
|
13751
|
+
* @param name - Production or transform-rule name.
|
|
13752
|
+
* @returns Prefix ending in `$repeat`, or null for a regular production.
|
|
13753
|
+
*/
|
|
13754
|
+
function syntheticRepeatPrefix(name) {
|
|
13755
|
+
const match = /^(.+\$repeat)_\d+$/.exec(name);
|
|
13756
|
+
return match?.[1] ?? null;
|
|
13757
|
+
}
|
|
14341
13758
|
/**
|
|
14342
13759
|
* Validates one transform expression against the grammar AST schema.
|
|
14343
13760
|
*
|
|
14344
13761
|
* @param grammar - Parsed grammar model.
|
|
14345
|
-
* @param
|
|
13762
|
+
* @param alternative - Transform alternative owning the expression.
|
|
14346
13763
|
* @param issues - Issue list to append to.
|
|
14347
13764
|
*/
|
|
14348
|
-
function validateTransformExpression(grammar,
|
|
13765
|
+
function validateTransformExpression(grammar, alternative, issues) {
|
|
13766
|
+
const expression = alternative.expression;
|
|
13767
|
+
const location = alternative.location ?? null;
|
|
14349
13768
|
switch (expression.kind) {
|
|
14350
13769
|
case 'build':
|
|
14351
|
-
validateAstTarget(grammar, expression.typeName, expression.variant, issues);
|
|
13770
|
+
validateAstTarget(grammar, expression.typeName, expression.variant, location, issues);
|
|
14352
13771
|
break;
|
|
14353
13772
|
case 'foldLeft':
|
|
14354
13773
|
case 'foldRight':
|
|
14355
13774
|
case 'flatten':
|
|
14356
|
-
validateAstTarget(grammar, expression.typeName, expression.variant, issues);
|
|
13775
|
+
validateAstTarget(grammar, expression.typeName, expression.variant, location, issues);
|
|
14357
13776
|
break;
|
|
14358
13777
|
}
|
|
14359
13778
|
}
|
|
@@ -14363,13 +13782,15 @@ function validateTransformExpression(grammar, expression, issues) {
|
|
|
14363
13782
|
* @param grammar - Parsed grammar model.
|
|
14364
13783
|
* @param typeName - AST type name from a transform expression.
|
|
14365
13784
|
* @param variant - AST variant label from a transform expression.
|
|
13785
|
+
* @param location - Source span of the transform alternative.
|
|
14366
13786
|
* @param issues - Issue list to append to.
|
|
14367
13787
|
*/
|
|
14368
|
-
function validateAstTarget(grammar, typeName, variant, issues) {
|
|
13788
|
+
function validateAstTarget(grammar, typeName, variant, location, issues) {
|
|
14369
13789
|
if (grammar.astSchema === null) {
|
|
14370
13790
|
issues.push({
|
|
14371
13791
|
severity: 'error',
|
|
14372
13792
|
message: `transform references ${typeName}.${variant} but the grammar has no ast section`,
|
|
13793
|
+
location,
|
|
14373
13794
|
});
|
|
14374
13795
|
return;
|
|
14375
13796
|
}
|
|
@@ -14378,6 +13799,7 @@ function validateAstTarget(grammar, typeName, variant, issues) {
|
|
|
14378
13799
|
issues.push({
|
|
14379
13800
|
severity: 'error',
|
|
14380
13801
|
message: `transform references undefined ast type ${JSON.stringify(typeName)}`,
|
|
13802
|
+
location,
|
|
14381
13803
|
});
|
|
14382
13804
|
return;
|
|
14383
13805
|
}
|
|
@@ -14386,6 +13808,7 @@ function validateAstTarget(grammar, typeName, variant, issues) {
|
|
|
14386
13808
|
issues.push({
|
|
14387
13809
|
severity: 'error',
|
|
14388
13810
|
message: `transform references ${typeName}.${variant} which is not declared in ast`,
|
|
13811
|
+
location,
|
|
14389
13812
|
});
|
|
14390
13813
|
}
|
|
14391
13814
|
}
|
|
@@ -14416,11 +13839,12 @@ function collectAstVariants(expression) {
|
|
|
14416
13839
|
*
|
|
14417
13840
|
* @param grammar - Parsed grammar model.
|
|
14418
13841
|
* @param rule - Parent production transform rule.
|
|
14419
|
-
* @param
|
|
13842
|
+
* @param alternative - Transform alternative containing the pass expression.
|
|
14420
13843
|
* @param bnfProductions - Desugared BNF productions.
|
|
14421
13844
|
* @param issues - Issue list to append to.
|
|
14422
13845
|
*/
|
|
14423
|
-
function collectPassCollapseWarnings(grammar, rule,
|
|
13846
|
+
function collectPassCollapseWarnings(grammar, rule, alternative, bnfProductions, issues) {
|
|
13847
|
+
const expression = alternative.expression;
|
|
14424
13848
|
if (expression.kind !== 'pass') {
|
|
14425
13849
|
return;
|
|
14426
13850
|
}
|
|
@@ -14443,6 +13867,7 @@ function collectPassCollapseWarnings(grammar, rule, expression, bnfProductions,
|
|
|
14443
13867
|
message: `pass(${expression.reference}) on ${rule.production} binds ${boundSymbol} `
|
|
14444
13868
|
+ `which has no transform rule and can match a single terminal; `
|
|
14445
13869
|
+ `add a transform for ${boundSymbol} or use build`,
|
|
13870
|
+
location: alternative.location ?? null,
|
|
14446
13871
|
});
|
|
14447
13872
|
}
|
|
14448
13873
|
/**
|
|
@@ -14499,14 +13924,19 @@ function isTerminalSymbol(symbol) {
|
|
|
14499
13924
|
return symbol?.kind === 'terminal' || symbol?.kind === 'token';
|
|
14500
13925
|
}
|
|
14501
13926
|
/**
|
|
14502
|
-
* Formats validation issues as stderr
|
|
13927
|
+
* Formats validation issues as stderr diagnostic lines.
|
|
14503
13928
|
*
|
|
14504
13929
|
* @param issues - Validation issues to format.
|
|
13930
|
+
* @param options - Optional grammar path and source text for line numbers.
|
|
14505
13931
|
*/
|
|
14506
|
-
function formatTableValidationIssues(issues) {
|
|
14507
|
-
return issues.map((issue) =>
|
|
14508
|
-
|
|
14509
|
-
:
|
|
13932
|
+
function formatTableValidationIssues(issues, options = {}) {
|
|
13933
|
+
return issues.map((issue) => formatDiagnostic({
|
|
13934
|
+
severity: issue.severity,
|
|
13935
|
+
message: issue.message,
|
|
13936
|
+
path: options.path,
|
|
13937
|
+
source: options.source,
|
|
13938
|
+
location: issue.location,
|
|
13939
|
+
}));
|
|
14510
13940
|
}
|
|
14511
13941
|
|
|
14512
13942
|
/**
|
|
@@ -14542,6 +13972,58 @@ function parseContextFromSources(options) {
|
|
|
14542
13972
|
throw new ParseContextError('required: grammar source or table JSON');
|
|
14543
13973
|
}
|
|
14544
13974
|
|
|
13975
|
+
/**
|
|
13976
|
+
* Rewrites a thrown source error into a positioned CLI diagnostic error.
|
|
13977
|
+
*
|
|
13978
|
+
* @param error - Thrown value from grammar or input reading.
|
|
13979
|
+
* @param path - Source file path.
|
|
13980
|
+
* @param source - Full source text used for line/column mapping.
|
|
13981
|
+
* @returns Positioned ParserLrError when the failure has an offset; otherwise the original value.
|
|
13982
|
+
*/
|
|
13983
|
+
function locateSourceError(error, path, source) {
|
|
13984
|
+
const offset = sourceErrorOffset(error);
|
|
13985
|
+
if (offset === null) {
|
|
13986
|
+
return error;
|
|
13987
|
+
}
|
|
13988
|
+
return new ParserLrError(formatDiagnostic({
|
|
13989
|
+
severity: 'error',
|
|
13990
|
+
message: stripEmbeddedOffset(errorMessage(error)),
|
|
13991
|
+
path,
|
|
13992
|
+
source,
|
|
13993
|
+
offset,
|
|
13994
|
+
}));
|
|
13995
|
+
}
|
|
13996
|
+
/**
|
|
13997
|
+
* Returns a source offset from a known offset-bearing error.
|
|
13998
|
+
*
|
|
13999
|
+
* @param error - Thrown value to inspect.
|
|
14000
|
+
*/
|
|
14001
|
+
function sourceErrorOffset(error) {
|
|
14002
|
+
if (error instanceof ReadGrammarError || error instanceof LexerError) {
|
|
14003
|
+
return error.offset;
|
|
14004
|
+
}
|
|
14005
|
+
return null;
|
|
14006
|
+
}
|
|
14007
|
+
/**
|
|
14008
|
+
* Returns a human-readable message from a thrown value.
|
|
14009
|
+
*
|
|
14010
|
+
* @param error - Thrown value.
|
|
14011
|
+
*/
|
|
14012
|
+
function errorMessage(error) {
|
|
14013
|
+
if (error instanceof Error) {
|
|
14014
|
+
return error.message;
|
|
14015
|
+
}
|
|
14016
|
+
return String(error);
|
|
14017
|
+
}
|
|
14018
|
+
/**
|
|
14019
|
+
* Removes an embedded `at offset N` suffix so the diagnostic formatter owns the position.
|
|
14020
|
+
*
|
|
14021
|
+
* @param message - Original error message.
|
|
14022
|
+
*/
|
|
14023
|
+
function stripEmbeddedOffset(message) {
|
|
14024
|
+
return message.replace(/\s+at offset \d+\s*$/, '');
|
|
14025
|
+
}
|
|
14026
|
+
|
|
14545
14027
|
/**
|
|
14546
14028
|
* Reads a UTF-8 text file from disk.
|
|
14547
14029
|
*
|
|
@@ -14605,11 +14087,21 @@ function registerParseCommand(program) {
|
|
|
14605
14087
|
}
|
|
14606
14088
|
const context = await loadContextFromPaths(options);
|
|
14607
14089
|
logProgress(`lexing ${options.input}`);
|
|
14608
|
-
const tokens = await context
|
|
14090
|
+
const tokens = await lexInputFile(context, options.input);
|
|
14609
14091
|
logProgress('parsing');
|
|
14610
|
-
const
|
|
14092
|
+
const result = context.parseResult(tokens);
|
|
14093
|
+
if (result.tree === null) {
|
|
14094
|
+
const source = await readTextFile(options.input);
|
|
14095
|
+
throw new ParserLrError(formatDiagnostic({
|
|
14096
|
+
severity: 'error',
|
|
14097
|
+
message: result.errorMessage ?? 'Parse failed',
|
|
14098
|
+
path: options.input,
|
|
14099
|
+
source,
|
|
14100
|
+
offset: result.errorOffset,
|
|
14101
|
+
}));
|
|
14102
|
+
}
|
|
14611
14103
|
logProgress(`formatting output (${options.format})`);
|
|
14612
|
-
const output = formatParseOutput(tree, options.format);
|
|
14104
|
+
const output = formatParseOutput(result.tree, options.format);
|
|
14613
14105
|
// Write output to disk or stdout.
|
|
14614
14106
|
if (options.output !== undefined) {
|
|
14615
14107
|
logProgress(`writing ${options.output}`);
|
|
@@ -14621,6 +14113,21 @@ function registerParseCommand(program) {
|
|
|
14621
14113
|
}
|
|
14622
14114
|
});
|
|
14623
14115
|
}
|
|
14116
|
+
/**
|
|
14117
|
+
* Lexes an input file and rewrites offset-bearing lexer failures with line numbers.
|
|
14118
|
+
*
|
|
14119
|
+
* @param context - Loaded parse context.
|
|
14120
|
+
* @param path - Input file path.
|
|
14121
|
+
*/
|
|
14122
|
+
async function lexInputFile(context, path) {
|
|
14123
|
+
try {
|
|
14124
|
+
return await context.lexChunkStreamAsync(readTextChunks(path));
|
|
14125
|
+
}
|
|
14126
|
+
catch (error) {
|
|
14127
|
+
const source = await readTextFile(path);
|
|
14128
|
+
throw locateSourceError(error, path, source);
|
|
14129
|
+
}
|
|
14130
|
+
}
|
|
14624
14131
|
/**
|
|
14625
14132
|
* Reads grammar or table files and builds a parse context.
|
|
14626
14133
|
*
|
|
@@ -14631,8 +14138,13 @@ async function loadContextFromPaths(options) {
|
|
|
14631
14138
|
if (options.grammar !== undefined) {
|
|
14632
14139
|
logProgress(`reading grammar ${options.grammar}`);
|
|
14633
14140
|
const grammarSource = await readTextFile(options.grammar);
|
|
14634
|
-
|
|
14635
|
-
|
|
14141
|
+
try {
|
|
14142
|
+
logProgress('building parse table');
|
|
14143
|
+
return parseContextFromGrammar(grammarSource);
|
|
14144
|
+
}
|
|
14145
|
+
catch (error) {
|
|
14146
|
+
throw locateSourceError(error, options.grammar, grammarSource);
|
|
14147
|
+
}
|
|
14636
14148
|
}
|
|
14637
14149
|
logProgress(`reading table ${options.table}`);
|
|
14638
14150
|
const tableJson = await readTextFile(options.table);
|
|
@@ -14658,9 +14170,9 @@ function registerTableCommands(program) {
|
|
|
14658
14170
|
.action(async (options) => {
|
|
14659
14171
|
logProgress(`reading grammar ${options.grammar}`);
|
|
14660
14172
|
const grammarSource = await readTextFile(options.grammar);
|
|
14173
|
+
const grammar = readGrammarAtPath(options.grammar, grammarSource);
|
|
14661
14174
|
logProgress(`building ${options.algorithm} parse table`);
|
|
14662
|
-
|
|
14663
|
-
writeGrammarValidationMessages(grammar, false);
|
|
14175
|
+
writeGrammarValidationMessages(grammar, options.grammar, grammarSource, false);
|
|
14664
14176
|
const context = parseContextFromSources({
|
|
14665
14177
|
grammarSource,
|
|
14666
14178
|
algorithm: options.algorithm,
|
|
@@ -14689,27 +14201,45 @@ function registerTableCommands(program) {
|
|
|
14689
14201
|
.action(async (options) => {
|
|
14690
14202
|
logProgress(`reading grammar ${options.grammar}`);
|
|
14691
14203
|
const grammarSource = await readTextFile(options.grammar);
|
|
14692
|
-
const grammar =
|
|
14693
|
-
const exitCode = writeGrammarValidationMessages(grammar, options.strict === true);
|
|
14204
|
+
const grammar = readGrammarAtPath(options.grammar, grammarSource);
|
|
14205
|
+
const exitCode = writeGrammarValidationMessages(grammar, options.grammar, grammarSource, options.strict === true);
|
|
14694
14206
|
process.exitCode = exitCode;
|
|
14695
14207
|
});
|
|
14696
14208
|
}
|
|
14209
|
+
/**
|
|
14210
|
+
* Parses a grammar file and rewrites offset-bearing failures with line numbers.
|
|
14211
|
+
*
|
|
14212
|
+
* @param path - Grammar file path.
|
|
14213
|
+
* @param source - Grammar file text.
|
|
14214
|
+
*/
|
|
14215
|
+
function readGrammarAtPath(path, source) {
|
|
14216
|
+
try {
|
|
14217
|
+
return readGrammar(source);
|
|
14218
|
+
}
|
|
14219
|
+
catch (error) {
|
|
14220
|
+
throw locateSourceError(error, path, source);
|
|
14221
|
+
}
|
|
14222
|
+
}
|
|
14697
14223
|
/**
|
|
14698
14224
|
* Writes grammar validation messages to stderr and returns a process exit code.
|
|
14699
14225
|
*
|
|
14700
14226
|
* @param grammar - Parsed grammar model.
|
|
14227
|
+
* @param path - Grammar file path for diagnostics.
|
|
14228
|
+
* @param source - Grammar file text for line/column mapping.
|
|
14701
14229
|
* @param strict - Whether warnings should fail validation.
|
|
14702
14230
|
*/
|
|
14703
|
-
function writeGrammarValidationMessages(grammar, strict) {
|
|
14231
|
+
function writeGrammarValidationMessages(grammar, path, source, strict) {
|
|
14704
14232
|
const issues = validateGrammarTable(grammar);
|
|
14705
14233
|
let hasError = false;
|
|
14706
14234
|
let hasWarning = false;
|
|
14707
|
-
for (const line of formatTableValidationIssues(issues)) {
|
|
14235
|
+
for (const line of formatTableValidationIssues(issues, { path, source })) {
|
|
14708
14236
|
process.stderr.write(`${line}\n`);
|
|
14709
|
-
|
|
14237
|
+
}
|
|
14238
|
+
for (const issue of issues) {
|
|
14239
|
+
if (issue.severity === 'error') {
|
|
14710
14240
|
hasError = true;
|
|
14711
14241
|
}
|
|
14712
|
-
if (
|
|
14242
|
+
if (issue.severity === 'warning') {
|
|
14713
14243
|
hasWarning = true;
|
|
14714
14244
|
}
|
|
14715
14245
|
}
|