parser-lr 0.8.0 → 0.8.2

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 (50) hide show
  1. package/bin/parser-lr.js +629 -218
  2. package/bin/parser-lr.js.map +1 -1
  3. package/dist/lib/diagnostics/format-diagnostic.d.ts +31 -0
  4. package/dist/lib/diagnostics/format-diagnostic.d.ts.map +1 -0
  5. package/dist/lib/diagnostics/format-diagnostic.js +36 -0
  6. package/dist/lib/diagnostics/format-diagnostic.js.map +1 -0
  7. package/dist/lib/diagnostics/index.d.ts +5 -0
  8. package/dist/lib/diagnostics/index.d.ts.map +1 -0
  9. package/dist/lib/diagnostics/index.js +3 -0
  10. package/dist/lib/diagnostics/index.js.map +1 -0
  11. package/dist/lib/diagnostics/source-position.d.ts +24 -0
  12. package/dist/lib/diagnostics/source-position.d.ts.map +1 -0
  13. package/dist/lib/diagnostics/source-position.js +39 -0
  14. package/dist/lib/diagnostics/source-position.js.map +1 -0
  15. package/dist/lib/grammar/ast-type.d.ts +2 -0
  16. package/dist/lib/grammar/ast-type.d.ts.map +1 -1
  17. package/dist/lib/grammar/grammar-from-cst.js +8 -5
  18. package/dist/lib/grammar/grammar-from-cst.js.map +1 -1
  19. package/dist/lib/grammar/grammar.json +330 -164
  20. package/dist/lib/grammar/index.d.ts +1 -1
  21. package/dist/lib/grammar/index.d.ts.map +1 -1
  22. package/dist/lib/grammar/production.d.ts +2 -0
  23. package/dist/lib/grammar/production.d.ts.map +1 -1
  24. package/dist/lib/grammar/table-validator.d.ts +12 -2
  25. package/dist/lib/grammar/table-validator.d.ts.map +1 -1
  26. package/dist/lib/grammar/table-validator.js +49 -24
  27. package/dist/lib/grammar/table-validator.js.map +1 -1
  28. package/dist/lib/grammar/transform-rule.d.ts +3 -0
  29. package/dist/lib/grammar/transform-rule.d.ts.map +1 -1
  30. package/dist/lib/grammar-entry.d.ts +1 -1
  31. package/dist/lib/grammar-entry.d.ts.map +1 -1
  32. package/dist/lib/grammar-entry.js.map +1 -1
  33. package/dist/lib/index.d.ts +3 -0
  34. package/dist/lib/index.d.ts.map +1 -1
  35. package/dist/lib/index.js +1 -0
  36. package/dist/lib/index.js.map +1 -1
  37. package/dist/lib/parse-context.d.ts +7 -0
  38. package/dist/lib/parse-context.d.ts.map +1 -1
  39. package/dist/lib/parse-context.js +9 -0
  40. package/dist/lib/parse-context.js.map +1 -1
  41. package/dist/lib/parse-table/table/lr-parse-table.d.ts.map +1 -1
  42. package/dist/lib/parse-table/table/lr-parse-table.js +10 -3
  43. package/dist/lib/parse-table/table/lr-parse-table.js.map +1 -1
  44. package/dist/lib/parser-lr.d.ts +15 -0
  45. package/dist/lib/parser-lr.d.ts.map +1 -1
  46. package/dist/lib/parser-lr.js +38 -9
  47. package/dist/lib/parser-lr.js.map +1 -1
  48. package/docs/grammar.md +29 -0
  49. package/grammars/grammar.grammar +2 -1
  50. 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.8.0";
3784
+ var version$1 = "0.8.2";
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 `state ${String(conflict.state)}: shift/reduce conflict on ${tokenLabel} resolved as shift`;
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 `state ${String(conflict.state)}: reduce/reduce conflict on ${tokenLabel} `
5993
- + `resolved using rule ${String(keptProduction)}`;
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
- const cst = this.parseCst(tokens);
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.
@@ -8263,10 +8382,12 @@ function parseLabeledAlternative(node) {
8263
8382
  const label = labelNode === null || findChild(node, 'hash') === null
8264
8383
  ? null
8265
8384
  : identifierText(labelNode);
8266
- const sequence = requireChild(node, 'sequence');
8385
+ const sequence = findChild(node, 'sequence');
8267
8386
  return {
8268
8387
  label,
8269
- expression: parseSequence(sequence),
8388
+ expression: sequence === null
8389
+ ? { kind: 'sequence', elements: [] }
8390
+ : parseSequence(sequence),
8270
8391
  };
8271
8392
  }
8272
8393
  /**
@@ -9262,7 +9383,8 @@ var productions = [
9262
9383
  id: 61,
9263
9384
  name: "labeled_alternative",
9264
9385
  rhs: [
9265
- "sequence"
9386
+ "hash",
9387
+ "identifier"
9266
9388
  ],
9267
9389
  variant: null,
9268
9390
  origin: "labeled_alternative"
@@ -9280,6 +9402,15 @@ var productions = [
9280
9402
  },
9281
9403
  {
9282
9404
  id: 63,
9405
+ name: "labeled_alternative",
9406
+ rhs: [
9407
+ "sequence"
9408
+ ],
9409
+ variant: null,
9410
+ origin: "labeled_alternative"
9411
+ },
9412
+ {
9413
+ id: 64,
9283
9414
  name: "sequence$repeat_10",
9284
9415
  rhs: [
9285
9416
  "factor",
@@ -9289,7 +9420,7 @@ var productions = [
9289
9420
  origin: "sequence$repeat_10"
9290
9421
  },
9291
9422
  {
9292
- id: 64,
9423
+ id: 65,
9293
9424
  name: "sequence$repeat_10",
9294
9425
  rhs: [
9295
9426
  ],
@@ -9297,7 +9428,7 @@ var productions = [
9297
9428
  origin: "sequence$repeat_10"
9298
9429
  },
9299
9430
  {
9300
- id: 65,
9431
+ id: 66,
9301
9432
  name: "sequence",
9302
9433
  rhs: [
9303
9434
  "factor",
@@ -9307,7 +9438,7 @@ var productions = [
9307
9438
  origin: "sequence"
9308
9439
  },
9309
9440
  {
9310
- id: 66,
9441
+ id: 67,
9311
9442
  name: "factor",
9312
9443
  rhs: [
9313
9444
  "bracketed"
@@ -9316,7 +9447,7 @@ var productions = [
9316
9447
  origin: "factor"
9317
9448
  },
9318
9449
  {
9319
- id: 67,
9450
+ id: 68,
9320
9451
  name: "factor",
9321
9452
  rhs: [
9322
9453
  "repeat"
@@ -9325,7 +9456,7 @@ var productions = [
9325
9456
  origin: "factor"
9326
9457
  },
9327
9458
  {
9328
- id: 68,
9459
+ id: 69,
9329
9460
  name: "factor",
9330
9461
  rhs: [
9331
9462
  "group"
@@ -9334,7 +9465,7 @@ var productions = [
9334
9465
  origin: "factor"
9335
9466
  },
9336
9467
  {
9337
- id: 69,
9468
+ id: 70,
9338
9469
  name: "factor",
9339
9470
  rhs: [
9340
9471
  "primary"
@@ -9343,7 +9474,7 @@ var productions = [
9343
9474
  origin: "factor"
9344
9475
  },
9345
9476
  {
9346
- id: 70,
9477
+ id: 71,
9347
9478
  name: "bracketed",
9348
9479
  rhs: [
9349
9480
  "lbracket",
@@ -9354,7 +9485,7 @@ var productions = [
9354
9485
  origin: "bracketed"
9355
9486
  },
9356
9487
  {
9357
- id: 71,
9488
+ id: 72,
9358
9489
  name: "bracketed",
9359
9490
  rhs: [
9360
9491
  "lbracket",
@@ -9367,7 +9498,7 @@ var productions = [
9367
9498
  origin: "bracketed"
9368
9499
  },
9369
9500
  {
9370
- id: 72,
9501
+ id: 73,
9371
9502
  name: "repeat",
9372
9503
  rhs: [
9373
9504
  "lbrace",
@@ -9378,7 +9509,7 @@ var productions = [
9378
9509
  origin: "repeat"
9379
9510
  },
9380
9511
  {
9381
- id: 73,
9512
+ id: 74,
9382
9513
  name: "group",
9383
9514
  rhs: [
9384
9515
  "lpar",
@@ -9389,7 +9520,7 @@ var productions = [
9389
9520
  origin: "group"
9390
9521
  },
9391
9522
  {
9392
- id: 74,
9523
+ id: 75,
9393
9524
  name: "primary",
9394
9525
  rhs: [
9395
9526
  "string_literal"
@@ -9398,7 +9529,7 @@ var productions = [
9398
9529
  origin: "primary"
9399
9530
  },
9400
9531
  {
9401
- id: 75,
9532
+ id: 76,
9402
9533
  name: "primary",
9403
9534
  rhs: [
9404
9535
  "identifier"
@@ -9407,7 +9538,7 @@ var productions = [
9407
9538
  origin: "primary"
9408
9539
  },
9409
9540
  {
9410
- id: 76,
9541
+ id: 77,
9411
9542
  name: "$accept",
9412
9543
  rhs: [
9413
9544
  "grammar_file"
@@ -10866,67 +10997,67 @@ var actions = [
10866
10997
  state: 110,
10867
10998
  symbol: "$eof",
10868
10999
  kind: "reduce",
10869
- productionId: 66
11000
+ productionId: 67
10870
11001
  },
10871
11002
  {
10872
11003
  state: 110,
10873
11004
  symbol: "bar",
10874
11005
  kind: "reduce",
10875
- productionId: 66
11006
+ productionId: 67
10876
11007
  },
10877
11008
  {
10878
11009
  state: 110,
10879
11010
  symbol: "identifier",
10880
11011
  kind: "reduce",
10881
- productionId: 66
11012
+ productionId: 67
10882
11013
  },
10883
11014
  {
10884
11015
  state: 110,
10885
11016
  symbol: "lbrace",
10886
11017
  kind: "reduce",
10887
- productionId: 66
11018
+ productionId: 67
10888
11019
  },
10889
11020
  {
10890
11021
  state: 110,
10891
11022
  symbol: "lbracket",
10892
11023
  kind: "reduce",
10893
- productionId: 66
11024
+ productionId: 67
10894
11025
  },
10895
11026
  {
10896
11027
  state: 110,
10897
11028
  symbol: "lpar",
10898
11029
  kind: "reduce",
10899
- productionId: 66
11030
+ productionId: 67
10900
11031
  },
10901
11032
  {
10902
11033
  state: 110,
10903
11034
  symbol: "rbrace",
10904
11035
  kind: "reduce",
10905
- productionId: 66
11036
+ productionId: 67
10906
11037
  },
10907
11038
  {
10908
11039
  state: 110,
10909
11040
  symbol: "rbracket",
10910
11041
  kind: "reduce",
10911
- productionId: 66
11042
+ productionId: 67
10912
11043
  },
10913
11044
  {
10914
11045
  state: 110,
10915
11046
  symbol: "rpar",
10916
11047
  kind: "reduce",
10917
- productionId: 66
11048
+ productionId: 67
10918
11049
  },
10919
11050
  {
10920
11051
  state: 110,
10921
11052
  symbol: "semicolon",
10922
11053
  kind: "reduce",
10923
- productionId: 66
11054
+ productionId: 67
10924
11055
  },
10925
11056
  {
10926
11057
  state: 110,
10927
11058
  symbol: "string_literal",
10928
11059
  kind: "reduce",
10929
- productionId: 66
11060
+ productionId: 67
10930
11061
  },
10931
11062
  {
10932
11063
  state: 111,
@@ -10962,13 +11093,13 @@ var actions = [
10962
11093
  state: 113,
10963
11094
  symbol: "$eof",
10964
11095
  kind: "reduce",
10965
- productionId: 64
11096
+ productionId: 65
10966
11097
  },
10967
11098
  {
10968
11099
  state: 113,
10969
11100
  symbol: "bar",
10970
11101
  kind: "reduce",
10971
- productionId: 64
11102
+ productionId: 65
10972
11103
  },
10973
11104
  {
10974
11105
  state: 113,
@@ -10998,25 +11129,25 @@ var actions = [
10998
11129
  state: 113,
10999
11130
  symbol: "rbrace",
11000
11131
  kind: "reduce",
11001
- productionId: 64
11132
+ productionId: 65
11002
11133
  },
11003
11134
  {
11004
11135
  state: 113,
11005
11136
  symbol: "rbracket",
11006
11137
  kind: "reduce",
11007
- productionId: 64
11138
+ productionId: 65
11008
11139
  },
11009
11140
  {
11010
11141
  state: 113,
11011
11142
  symbol: "rpar",
11012
11143
  kind: "reduce",
11013
- productionId: 64
11144
+ productionId: 65
11014
11145
  },
11015
11146
  {
11016
11147
  state: 113,
11017
11148
  symbol: "semicolon",
11018
11149
  kind: "reduce",
11019
- productionId: 64
11150
+ productionId: 65
11020
11151
  },
11021
11152
  {
11022
11153
  state: 113,
@@ -11028,67 +11159,67 @@ var actions = [
11028
11159
  state: 114,
11029
11160
  symbol: "$eof",
11030
11161
  kind: "reduce",
11031
- productionId: 68
11162
+ productionId: 69
11032
11163
  },
11033
11164
  {
11034
11165
  state: 114,
11035
11166
  symbol: "bar",
11036
11167
  kind: "reduce",
11037
- productionId: 68
11168
+ productionId: 69
11038
11169
  },
11039
11170
  {
11040
11171
  state: 114,
11041
11172
  symbol: "identifier",
11042
11173
  kind: "reduce",
11043
- productionId: 68
11174
+ productionId: 69
11044
11175
  },
11045
11176
  {
11046
11177
  state: 114,
11047
11178
  symbol: "lbrace",
11048
11179
  kind: "reduce",
11049
- productionId: 68
11180
+ productionId: 69
11050
11181
  },
11051
11182
  {
11052
11183
  state: 114,
11053
11184
  symbol: "lbracket",
11054
11185
  kind: "reduce",
11055
- productionId: 68
11186
+ productionId: 69
11056
11187
  },
11057
11188
  {
11058
11189
  state: 114,
11059
11190
  symbol: "lpar",
11060
11191
  kind: "reduce",
11061
- productionId: 68
11192
+ productionId: 69
11062
11193
  },
11063
11194
  {
11064
11195
  state: 114,
11065
11196
  symbol: "rbrace",
11066
11197
  kind: "reduce",
11067
- productionId: 68
11198
+ productionId: 69
11068
11199
  },
11069
11200
  {
11070
11201
  state: 114,
11071
11202
  symbol: "rbracket",
11072
11203
  kind: "reduce",
11073
- productionId: 68
11204
+ productionId: 69
11074
11205
  },
11075
11206
  {
11076
11207
  state: 114,
11077
11208
  symbol: "rpar",
11078
11209
  kind: "reduce",
11079
- productionId: 68
11210
+ productionId: 69
11080
11211
  },
11081
11212
  {
11082
11213
  state: 114,
11083
11214
  symbol: "semicolon",
11084
11215
  kind: "reduce",
11085
- productionId: 68
11216
+ productionId: 69
11086
11217
  },
11087
11218
  {
11088
11219
  state: 114,
11089
11220
  symbol: "string_literal",
11090
11221
  kind: "reduce",
11091
- productionId: 68
11222
+ productionId: 69
11092
11223
  },
11093
11224
  {
11094
11225
  state: 115,
@@ -11100,67 +11231,67 @@ var actions = [
11100
11231
  state: 116,
11101
11232
  symbol: "$eof",
11102
11233
  kind: "reduce",
11103
- productionId: 75
11234
+ productionId: 76
11104
11235
  },
11105
11236
  {
11106
11237
  state: 116,
11107
11238
  symbol: "bar",
11108
11239
  kind: "reduce",
11109
- productionId: 75
11240
+ productionId: 76
11110
11241
  },
11111
11242
  {
11112
11243
  state: 116,
11113
11244
  symbol: "identifier",
11114
11245
  kind: "reduce",
11115
- productionId: 75
11246
+ productionId: 76
11116
11247
  },
11117
11248
  {
11118
11249
  state: 116,
11119
11250
  symbol: "lbrace",
11120
11251
  kind: "reduce",
11121
- productionId: 75
11252
+ productionId: 76
11122
11253
  },
11123
11254
  {
11124
11255
  state: 116,
11125
11256
  symbol: "lbracket",
11126
11257
  kind: "reduce",
11127
- productionId: 75
11258
+ productionId: 76
11128
11259
  },
11129
11260
  {
11130
11261
  state: 116,
11131
11262
  symbol: "lpar",
11132
11263
  kind: "reduce",
11133
- productionId: 75
11264
+ productionId: 76
11134
11265
  },
11135
11266
  {
11136
11267
  state: 116,
11137
11268
  symbol: "rbrace",
11138
11269
  kind: "reduce",
11139
- productionId: 75
11270
+ productionId: 76
11140
11271
  },
11141
11272
  {
11142
11273
  state: 116,
11143
11274
  symbol: "rbracket",
11144
11275
  kind: "reduce",
11145
- productionId: 75
11276
+ productionId: 76
11146
11277
  },
11147
11278
  {
11148
11279
  state: 116,
11149
11280
  symbol: "rpar",
11150
11281
  kind: "reduce",
11151
- productionId: 75
11282
+ productionId: 76
11152
11283
  },
11153
11284
  {
11154
11285
  state: 116,
11155
11286
  symbol: "semicolon",
11156
11287
  kind: "reduce",
11157
- productionId: 75
11288
+ productionId: 76
11158
11289
  },
11159
11290
  {
11160
11291
  state: 116,
11161
11292
  symbol: "string_literal",
11162
11293
  kind: "reduce",
11163
- productionId: 75
11294
+ productionId: 76
11164
11295
  },
11165
11296
  {
11166
11297
  state: 117,
@@ -11310,235 +11441,235 @@ var actions = [
11310
11441
  state: 121,
11311
11442
  symbol: "$eof",
11312
11443
  kind: "reduce",
11313
- productionId: 69
11444
+ productionId: 70
11314
11445
  },
11315
11446
  {
11316
11447
  state: 121,
11317
11448
  symbol: "bar",
11318
11449
  kind: "reduce",
11319
- productionId: 69
11450
+ productionId: 70
11320
11451
  },
11321
11452
  {
11322
11453
  state: 121,
11323
11454
  symbol: "identifier",
11324
11455
  kind: "reduce",
11325
- productionId: 69
11456
+ productionId: 70
11326
11457
  },
11327
11458
  {
11328
11459
  state: 121,
11329
11460
  symbol: "lbrace",
11330
11461
  kind: "reduce",
11331
- productionId: 69
11462
+ productionId: 70
11332
11463
  },
11333
11464
  {
11334
11465
  state: 121,
11335
11466
  symbol: "lbracket",
11336
11467
  kind: "reduce",
11337
- productionId: 69
11468
+ productionId: 70
11338
11469
  },
11339
11470
  {
11340
11471
  state: 121,
11341
11472
  symbol: "lpar",
11342
11473
  kind: "reduce",
11343
- productionId: 69
11474
+ productionId: 70
11344
11475
  },
11345
11476
  {
11346
11477
  state: 121,
11347
11478
  symbol: "rbrace",
11348
11479
  kind: "reduce",
11349
- productionId: 69
11480
+ productionId: 70
11350
11481
  },
11351
11482
  {
11352
11483
  state: 121,
11353
11484
  symbol: "rbracket",
11354
11485
  kind: "reduce",
11355
- productionId: 69
11486
+ productionId: 70
11356
11487
  },
11357
11488
  {
11358
11489
  state: 121,
11359
11490
  symbol: "rpar",
11360
11491
  kind: "reduce",
11361
- productionId: 69
11492
+ productionId: 70
11362
11493
  },
11363
11494
  {
11364
11495
  state: 121,
11365
11496
  symbol: "semicolon",
11366
11497
  kind: "reduce",
11367
- productionId: 69
11498
+ productionId: 70
11368
11499
  },
11369
11500
  {
11370
11501
  state: 121,
11371
11502
  symbol: "string_literal",
11372
11503
  kind: "reduce",
11373
- productionId: 69
11504
+ productionId: 70
11374
11505
  },
11375
11506
  {
11376
11507
  state: 122,
11377
11508
  symbol: "$eof",
11378
11509
  kind: "reduce",
11379
- productionId: 67
11510
+ productionId: 68
11380
11511
  },
11381
11512
  {
11382
11513
  state: 122,
11383
11514
  symbol: "bar",
11384
11515
  kind: "reduce",
11385
- productionId: 67
11516
+ productionId: 68
11386
11517
  },
11387
11518
  {
11388
11519
  state: 122,
11389
11520
  symbol: "identifier",
11390
11521
  kind: "reduce",
11391
- productionId: 67
11522
+ productionId: 68
11392
11523
  },
11393
11524
  {
11394
11525
  state: 122,
11395
11526
  symbol: "lbrace",
11396
11527
  kind: "reduce",
11397
- productionId: 67
11528
+ productionId: 68
11398
11529
  },
11399
11530
  {
11400
11531
  state: 122,
11401
11532
  symbol: "lbracket",
11402
11533
  kind: "reduce",
11403
- productionId: 67
11534
+ productionId: 68
11404
11535
  },
11405
11536
  {
11406
11537
  state: 122,
11407
11538
  symbol: "lpar",
11408
11539
  kind: "reduce",
11409
- productionId: 67
11540
+ productionId: 68
11410
11541
  },
11411
11542
  {
11412
11543
  state: 122,
11413
11544
  symbol: "rbrace",
11414
11545
  kind: "reduce",
11415
- productionId: 67
11546
+ productionId: 68
11416
11547
  },
11417
11548
  {
11418
11549
  state: 122,
11419
11550
  symbol: "rbracket",
11420
11551
  kind: "reduce",
11421
- productionId: 67
11552
+ productionId: 68
11422
11553
  },
11423
11554
  {
11424
11555
  state: 122,
11425
11556
  symbol: "rpar",
11426
11557
  kind: "reduce",
11427
- productionId: 67
11558
+ productionId: 68
11428
11559
  },
11429
11560
  {
11430
11561
  state: 122,
11431
11562
  symbol: "semicolon",
11432
11563
  kind: "reduce",
11433
- productionId: 67
11564
+ productionId: 68
11434
11565
  },
11435
11566
  {
11436
11567
  state: 122,
11437
11568
  symbol: "string_literal",
11438
11569
  kind: "reduce",
11439
- productionId: 67
11570
+ productionId: 68
11440
11571
  },
11441
11572
  {
11442
11573
  state: 123,
11443
11574
  symbol: "$eof",
11444
11575
  kind: "reduce",
11445
- productionId: 61
11576
+ productionId: 63
11446
11577
  },
11447
11578
  {
11448
11579
  state: 123,
11449
11580
  symbol: "bar",
11450
11581
  kind: "reduce",
11451
- productionId: 61
11582
+ productionId: 63
11452
11583
  },
11453
11584
  {
11454
11585
  state: 123,
11455
11586
  symbol: "rbrace",
11456
11587
  kind: "reduce",
11457
- productionId: 61
11588
+ productionId: 63
11458
11589
  },
11459
11590
  {
11460
11591
  state: 123,
11461
11592
  symbol: "rbracket",
11462
11593
  kind: "reduce",
11463
- productionId: 61
11594
+ productionId: 63
11464
11595
  },
11465
11596
  {
11466
11597
  state: 123,
11467
11598
  symbol: "rpar",
11468
11599
  kind: "reduce",
11469
- productionId: 61
11600
+ productionId: 63
11470
11601
  },
11471
11602
  {
11472
11603
  state: 123,
11473
11604
  symbol: "semicolon",
11474
11605
  kind: "reduce",
11475
- productionId: 61
11606
+ productionId: 63
11476
11607
  },
11477
11608
  {
11478
11609
  state: 124,
11479
11610
  symbol: "$eof",
11480
11611
  kind: "reduce",
11481
- productionId: 74
11612
+ productionId: 75
11482
11613
  },
11483
11614
  {
11484
11615
  state: 124,
11485
11616
  symbol: "bar",
11486
11617
  kind: "reduce",
11487
- productionId: 74
11618
+ productionId: 75
11488
11619
  },
11489
11620
  {
11490
11621
  state: 124,
11491
11622
  symbol: "identifier",
11492
11623
  kind: "reduce",
11493
- productionId: 74
11624
+ productionId: 75
11494
11625
  },
11495
11626
  {
11496
11627
  state: 124,
11497
11628
  symbol: "lbrace",
11498
11629
  kind: "reduce",
11499
- productionId: 74
11630
+ productionId: 75
11500
11631
  },
11501
11632
  {
11502
11633
  state: 124,
11503
11634
  symbol: "lbracket",
11504
11635
  kind: "reduce",
11505
- productionId: 74
11636
+ productionId: 75
11506
11637
  },
11507
11638
  {
11508
11639
  state: 124,
11509
11640
  symbol: "lpar",
11510
11641
  kind: "reduce",
11511
- productionId: 74
11642
+ productionId: 75
11512
11643
  },
11513
11644
  {
11514
11645
  state: 124,
11515
11646
  symbol: "rbrace",
11516
11647
  kind: "reduce",
11517
- productionId: 74
11648
+ productionId: 75
11518
11649
  },
11519
11650
  {
11520
11651
  state: 124,
11521
11652
  symbol: "rbracket",
11522
11653
  kind: "reduce",
11523
- productionId: 74
11654
+ productionId: 75
11524
11655
  },
11525
11656
  {
11526
11657
  state: 124,
11527
11658
  symbol: "rpar",
11528
11659
  kind: "reduce",
11529
- productionId: 74
11660
+ productionId: 75
11530
11661
  },
11531
11662
  {
11532
11663
  state: 124,
11533
11664
  symbol: "semicolon",
11534
11665
  kind: "reduce",
11535
- productionId: 74
11666
+ productionId: 75
11536
11667
  },
11537
11668
  {
11538
11669
  state: 124,
11539
11670
  symbol: "string_literal",
11540
11671
  kind: "reduce",
11541
- productionId: 74
11672
+ productionId: 75
11542
11673
  },
11543
11674
  {
11544
11675
  state: 125,
@@ -11550,67 +11681,67 @@ var actions = [
11550
11681
  state: 126,
11551
11682
  symbol: "$eof",
11552
11683
  kind: "reduce",
11553
- productionId: 73
11684
+ productionId: 74
11554
11685
  },
11555
11686
  {
11556
11687
  state: 126,
11557
11688
  symbol: "bar",
11558
11689
  kind: "reduce",
11559
- productionId: 73
11690
+ productionId: 74
11560
11691
  },
11561
11692
  {
11562
11693
  state: 126,
11563
11694
  symbol: "identifier",
11564
11695
  kind: "reduce",
11565
- productionId: 73
11696
+ productionId: 74
11566
11697
  },
11567
11698
  {
11568
11699
  state: 126,
11569
11700
  symbol: "lbrace",
11570
11701
  kind: "reduce",
11571
- productionId: 73
11702
+ productionId: 74
11572
11703
  },
11573
11704
  {
11574
11705
  state: 126,
11575
11706
  symbol: "lbracket",
11576
11707
  kind: "reduce",
11577
- productionId: 73
11708
+ productionId: 74
11578
11709
  },
11579
11710
  {
11580
11711
  state: 126,
11581
11712
  symbol: "lpar",
11582
11713
  kind: "reduce",
11583
- productionId: 73
11714
+ productionId: 74
11584
11715
  },
11585
11716
  {
11586
11717
  state: 126,
11587
11718
  symbol: "rbrace",
11588
11719
  kind: "reduce",
11589
- productionId: 73
11720
+ productionId: 74
11590
11721
  },
11591
11722
  {
11592
11723
  state: 126,
11593
11724
  symbol: "rbracket",
11594
11725
  kind: "reduce",
11595
- productionId: 73
11726
+ productionId: 74
11596
11727
  },
11597
11728
  {
11598
11729
  state: 126,
11599
11730
  symbol: "rpar",
11600
11731
  kind: "reduce",
11601
- productionId: 73
11732
+ productionId: 74
11602
11733
  },
11603
11734
  {
11604
11735
  state: 126,
11605
11736
  symbol: "semicolon",
11606
11737
  kind: "reduce",
11607
- productionId: 73
11738
+ productionId: 74
11608
11739
  },
11609
11740
  {
11610
11741
  state: 126,
11611
11742
  symbol: "string_literal",
11612
11743
  kind: "reduce",
11613
- productionId: 73
11744
+ productionId: 74
11614
11745
  },
11615
11746
  {
11616
11747
  state: 127,
@@ -11622,13 +11753,13 @@ var actions = [
11622
11753
  state: 128,
11623
11754
  symbol: "$eof",
11624
11755
  kind: "reduce",
11625
- productionId: 70
11756
+ productionId: 71
11626
11757
  },
11627
11758
  {
11628
11759
  state: 128,
11629
11760
  symbol: "bar",
11630
11761
  kind: "reduce",
11631
- productionId: 70
11762
+ productionId: 71
11632
11763
  },
11633
11764
  {
11634
11765
  state: 128,
@@ -11640,55 +11771,55 @@ var actions = [
11640
11771
  state: 128,
11641
11772
  symbol: "identifier",
11642
11773
  kind: "reduce",
11643
- productionId: 70
11774
+ productionId: 71
11644
11775
  },
11645
11776
  {
11646
11777
  state: 128,
11647
11778
  symbol: "lbrace",
11648
11779
  kind: "reduce",
11649
- productionId: 70
11780
+ productionId: 71
11650
11781
  },
11651
11782
  {
11652
11783
  state: 128,
11653
11784
  symbol: "lbracket",
11654
11785
  kind: "reduce",
11655
- productionId: 70
11786
+ productionId: 71
11656
11787
  },
11657
11788
  {
11658
11789
  state: 128,
11659
11790
  symbol: "lpar",
11660
11791
  kind: "reduce",
11661
- productionId: 70
11792
+ productionId: 71
11662
11793
  },
11663
11794
  {
11664
11795
  state: 128,
11665
11796
  symbol: "rbrace",
11666
11797
  kind: "reduce",
11667
- productionId: 70
11798
+ productionId: 71
11668
11799
  },
11669
11800
  {
11670
11801
  state: 128,
11671
11802
  symbol: "rbracket",
11672
11803
  kind: "reduce",
11673
- productionId: 70
11804
+ productionId: 71
11674
11805
  },
11675
11806
  {
11676
11807
  state: 128,
11677
11808
  symbol: "rpar",
11678
11809
  kind: "reduce",
11679
- productionId: 70
11810
+ productionId: 71
11680
11811
  },
11681
11812
  {
11682
11813
  state: 128,
11683
11814
  symbol: "semicolon",
11684
11815
  kind: "reduce",
11685
- productionId: 70
11816
+ productionId: 71
11686
11817
  },
11687
11818
  {
11688
11819
  state: 128,
11689
11820
  symbol: "string_literal",
11690
11821
  kind: "reduce",
11691
- productionId: 70
11822
+ productionId: 71
11692
11823
  },
11693
11824
  {
11694
11825
  state: 129,
@@ -11700,67 +11831,67 @@ var actions = [
11700
11831
  state: 130,
11701
11832
  symbol: "$eof",
11702
11833
  kind: "reduce",
11703
- productionId: 71
11834
+ productionId: 72
11704
11835
  },
11705
11836
  {
11706
11837
  state: 130,
11707
11838
  symbol: "bar",
11708
11839
  kind: "reduce",
11709
- productionId: 71
11840
+ productionId: 72
11710
11841
  },
11711
11842
  {
11712
11843
  state: 130,
11713
11844
  symbol: "identifier",
11714
11845
  kind: "reduce",
11715
- productionId: 71
11846
+ productionId: 72
11716
11847
  },
11717
11848
  {
11718
11849
  state: 130,
11719
11850
  symbol: "lbrace",
11720
11851
  kind: "reduce",
11721
- productionId: 71
11852
+ productionId: 72
11722
11853
  },
11723
11854
  {
11724
11855
  state: 130,
11725
11856
  symbol: "lbracket",
11726
11857
  kind: "reduce",
11727
- productionId: 71
11858
+ productionId: 72
11728
11859
  },
11729
11860
  {
11730
11861
  state: 130,
11731
11862
  symbol: "lpar",
11732
11863
  kind: "reduce",
11733
- productionId: 71
11864
+ productionId: 72
11734
11865
  },
11735
11866
  {
11736
11867
  state: 130,
11737
11868
  symbol: "rbrace",
11738
11869
  kind: "reduce",
11739
- productionId: 71
11870
+ productionId: 72
11740
11871
  },
11741
11872
  {
11742
11873
  state: 130,
11743
11874
  symbol: "rbracket",
11744
11875
  kind: "reduce",
11745
- productionId: 71
11876
+ productionId: 72
11746
11877
  },
11747
11878
  {
11748
11879
  state: 130,
11749
11880
  symbol: "rpar",
11750
11881
  kind: "reduce",
11751
- productionId: 71
11882
+ productionId: 72
11752
11883
  },
11753
11884
  {
11754
11885
  state: 130,
11755
11886
  symbol: "semicolon",
11756
11887
  kind: "reduce",
11757
- productionId: 71
11888
+ productionId: 72
11758
11889
  },
11759
11890
  {
11760
11891
  state: 130,
11761
11892
  symbol: "string_literal",
11762
11893
  kind: "reduce",
11763
- productionId: 71
11894
+ productionId: 72
11764
11895
  },
11765
11896
  {
11766
11897
  state: 131,
@@ -11772,67 +11903,79 @@ var actions = [
11772
11903
  state: 132,
11773
11904
  symbol: "$eof",
11774
11905
  kind: "reduce",
11775
- productionId: 72
11906
+ productionId: 73
11776
11907
  },
11777
11908
  {
11778
11909
  state: 132,
11779
11910
  symbol: "bar",
11780
11911
  kind: "reduce",
11781
- productionId: 72
11912
+ productionId: 73
11782
11913
  },
11783
11914
  {
11784
11915
  state: 132,
11785
11916
  symbol: "identifier",
11786
11917
  kind: "reduce",
11787
- productionId: 72
11918
+ productionId: 73
11788
11919
  },
11789
11920
  {
11790
11921
  state: 132,
11791
11922
  symbol: "lbrace",
11792
11923
  kind: "reduce",
11793
- productionId: 72
11924
+ productionId: 73
11794
11925
  },
11795
11926
  {
11796
11927
  state: 132,
11797
11928
  symbol: "lbracket",
11798
11929
  kind: "reduce",
11799
- productionId: 72
11930
+ productionId: 73
11800
11931
  },
11801
11932
  {
11802
11933
  state: 132,
11803
11934
  symbol: "lpar",
11804
11935
  kind: "reduce",
11805
- productionId: 72
11936
+ productionId: 73
11806
11937
  },
11807
11938
  {
11808
11939
  state: 132,
11809
11940
  symbol: "rbrace",
11810
11941
  kind: "reduce",
11811
- productionId: 72
11942
+ productionId: 73
11812
11943
  },
11813
11944
  {
11814
11945
  state: 132,
11815
11946
  symbol: "rbracket",
11816
11947
  kind: "reduce",
11817
- productionId: 72
11948
+ productionId: 73
11818
11949
  },
11819
11950
  {
11820
11951
  state: 132,
11821
11952
  symbol: "rpar",
11822
11953
  kind: "reduce",
11823
- productionId: 72
11954
+ productionId: 73
11824
11955
  },
11825
11956
  {
11826
11957
  state: 132,
11827
11958
  symbol: "semicolon",
11828
11959
  kind: "reduce",
11829
- productionId: 72
11960
+ productionId: 73
11830
11961
  },
11831
11962
  {
11832
11963
  state: 132,
11833
11964
  symbol: "string_literal",
11834
11965
  kind: "reduce",
11835
- productionId: 72
11966
+ productionId: 73
11967
+ },
11968
+ {
11969
+ state: 133,
11970
+ symbol: "$eof",
11971
+ kind: "reduce",
11972
+ productionId: 61
11973
+ },
11974
+ {
11975
+ state: 133,
11976
+ symbol: "bar",
11977
+ kind: "reduce",
11978
+ productionId: 61
11836
11979
  },
11837
11980
  {
11838
11981
  state: 133,
@@ -11858,6 +12001,30 @@ var actions = [
11858
12001
  kind: "shift",
11859
12002
  target: 120
11860
12003
  },
12004
+ {
12005
+ state: 133,
12006
+ symbol: "rbrace",
12007
+ kind: "reduce",
12008
+ productionId: 61
12009
+ },
12010
+ {
12011
+ state: 133,
12012
+ symbol: "rbracket",
12013
+ kind: "reduce",
12014
+ productionId: 61
12015
+ },
12016
+ {
12017
+ state: 133,
12018
+ symbol: "rpar",
12019
+ kind: "reduce",
12020
+ productionId: 61
12021
+ },
12022
+ {
12023
+ state: 133,
12024
+ symbol: "semicolon",
12025
+ kind: "reduce",
12026
+ productionId: 61
12027
+ },
11861
12028
  {
11862
12029
  state: 133,
11863
12030
  symbol: "string_literal",
@@ -11904,13 +12071,13 @@ var actions = [
11904
12071
  state: 135,
11905
12072
  symbol: "$eof",
11906
12073
  kind: "reduce",
11907
- productionId: 64
12074
+ productionId: 65
11908
12075
  },
11909
12076
  {
11910
12077
  state: 135,
11911
12078
  symbol: "bar",
11912
12079
  kind: "reduce",
11913
- productionId: 64
12080
+ productionId: 65
11914
12081
  },
11915
12082
  {
11916
12083
  state: 135,
@@ -11940,25 +12107,25 @@ var actions = [
11940
12107
  state: 135,
11941
12108
  symbol: "rbrace",
11942
12109
  kind: "reduce",
11943
- productionId: 64
12110
+ productionId: 65
11944
12111
  },
11945
12112
  {
11946
12113
  state: 135,
11947
12114
  symbol: "rbracket",
11948
12115
  kind: "reduce",
11949
- productionId: 64
12116
+ productionId: 65
11950
12117
  },
11951
12118
  {
11952
12119
  state: 135,
11953
12120
  symbol: "rpar",
11954
12121
  kind: "reduce",
11955
- productionId: 64
12122
+ productionId: 65
11956
12123
  },
11957
12124
  {
11958
12125
  state: 135,
11959
12126
  symbol: "semicolon",
11960
12127
  kind: "reduce",
11961
- productionId: 64
12128
+ productionId: 65
11962
12129
  },
11963
12130
  {
11964
12131
  state: 135,
@@ -11970,73 +12137,73 @@ var actions = [
11970
12137
  state: 136,
11971
12138
  symbol: "$eof",
11972
12139
  kind: "reduce",
11973
- productionId: 65
12140
+ productionId: 66
11974
12141
  },
11975
12142
  {
11976
12143
  state: 136,
11977
12144
  symbol: "bar",
11978
12145
  kind: "reduce",
11979
- productionId: 65
12146
+ productionId: 66
11980
12147
  },
11981
12148
  {
11982
12149
  state: 136,
11983
12150
  symbol: "rbrace",
11984
12151
  kind: "reduce",
11985
- productionId: 65
12152
+ productionId: 66
11986
12153
  },
11987
12154
  {
11988
12155
  state: 136,
11989
12156
  symbol: "rbracket",
11990
12157
  kind: "reduce",
11991
- productionId: 65
12158
+ productionId: 66
11992
12159
  },
11993
12160
  {
11994
12161
  state: 136,
11995
12162
  symbol: "rpar",
11996
12163
  kind: "reduce",
11997
- productionId: 65
12164
+ productionId: 66
11998
12165
  },
11999
12166
  {
12000
12167
  state: 136,
12001
12168
  symbol: "semicolon",
12002
12169
  kind: "reduce",
12003
- productionId: 65
12170
+ productionId: 66
12004
12171
  },
12005
12172
  {
12006
12173
  state: 137,
12007
12174
  symbol: "$eof",
12008
12175
  kind: "reduce",
12009
- productionId: 63
12176
+ productionId: 64
12010
12177
  },
12011
12178
  {
12012
12179
  state: 137,
12013
12180
  symbol: "bar",
12014
12181
  kind: "reduce",
12015
- productionId: 63
12182
+ productionId: 64
12016
12183
  },
12017
12184
  {
12018
12185
  state: 137,
12019
12186
  symbol: "rbrace",
12020
12187
  kind: "reduce",
12021
- productionId: 63
12188
+ productionId: 64
12022
12189
  },
12023
12190
  {
12024
12191
  state: 137,
12025
12192
  symbol: "rbracket",
12026
12193
  kind: "reduce",
12027
- productionId: 63
12194
+ productionId: 64
12028
12195
  },
12029
12196
  {
12030
12197
  state: 137,
12031
12198
  symbol: "rpar",
12032
12199
  kind: "reduce",
12033
- productionId: 63
12200
+ productionId: 64
12034
12201
  },
12035
12202
  {
12036
12203
  state: 137,
12037
12204
  symbol: "semicolon",
12038
12205
  kind: "reduce",
12039
- productionId: 63
12206
+ productionId: 64
12040
12207
  },
12041
12208
  {
12042
12209
  state: 138,
@@ -13143,6 +13310,10 @@ var ast = [
13143
13310
  }
13144
13311
  }
13145
13312
  ]
13313
+ },
13314
+ location: {
13315
+ offset: 4736,
13316
+ length: 50
13146
13317
  }
13147
13318
  },
13148
13319
  {
@@ -13161,6 +13332,10 @@ var ast = [
13161
13332
  }
13162
13333
  }
13163
13334
  ]
13335
+ },
13336
+ location: {
13337
+ offset: 4792,
13338
+ length: 56
13164
13339
  }
13165
13340
  },
13166
13341
  {
@@ -13179,6 +13354,10 @@ var ast = [
13179
13354
  }
13180
13355
  }
13181
13356
  ]
13357
+ },
13358
+ location: {
13359
+ offset: 4854,
13360
+ length: 55
13182
13361
  }
13183
13362
  },
13184
13363
  {
@@ -13197,6 +13376,10 @@ var ast = [
13197
13376
  }
13198
13377
  }
13199
13378
  ]
13379
+ },
13380
+ location: {
13381
+ offset: 4915,
13382
+ length: 59
13200
13383
  }
13201
13384
  },
13202
13385
  {
@@ -13215,6 +13398,10 @@ var ast = [
13215
13398
  }
13216
13399
  }
13217
13400
  ]
13401
+ },
13402
+ location: {
13403
+ offset: 4980,
13404
+ length: 47
13218
13405
  }
13219
13406
  },
13220
13407
  {
@@ -13233,6 +13420,10 @@ var ast = [
13233
13420
  }
13234
13421
  }
13235
13422
  ]
13423
+ },
13424
+ location: {
13425
+ offset: 5033,
13426
+ length: 59
13236
13427
  }
13237
13428
  },
13238
13429
  {
@@ -13251,6 +13442,10 @@ var ast = [
13251
13442
  }
13252
13443
  }
13253
13444
  ]
13445
+ },
13446
+ location: {
13447
+ offset: 5098,
13448
+ length: 66
13254
13449
  }
13255
13450
  },
13256
13451
  {
@@ -13269,6 +13464,10 @@ var ast = [
13269
13464
  }
13270
13465
  }
13271
13466
  ]
13467
+ },
13468
+ location: {
13469
+ offset: 5170,
13470
+ length: 56
13272
13471
  }
13273
13472
  },
13274
13473
  {
@@ -13287,6 +13486,10 @@ var ast = [
13287
13486
  }
13288
13487
  }
13289
13488
  ]
13489
+ },
13490
+ location: {
13491
+ offset: 5232,
13492
+ length: 52
13290
13493
  }
13291
13494
  },
13292
13495
  {
@@ -13305,6 +13508,10 @@ var ast = [
13305
13508
  }
13306
13509
  }
13307
13510
  ]
13511
+ },
13512
+ location: {
13513
+ offset: 5290,
13514
+ length: 44
13308
13515
  }
13309
13516
  }
13310
13517
  ];
@@ -13320,9 +13527,17 @@ var transform = [
13320
13527
  variant: "sections",
13321
13528
  head: "section",
13322
13529
  tail: "grammar_file$repeat_0"
13530
+ },
13531
+ location: {
13532
+ offset: 5383,
13533
+ length: 69
13323
13534
  }
13324
13535
  }
13325
- ]
13536
+ ],
13537
+ location: {
13538
+ offset: 5350,
13539
+ length: 104
13540
+ }
13326
13541
  },
13327
13542
  {
13328
13543
  production: "token_section",
@@ -13335,9 +13550,17 @@ var transform = [
13335
13550
  variant: "definitions",
13336
13551
  head: "token_def",
13337
13552
  tail: "token_section$repeat_1"
13553
+ },
13554
+ location: {
13555
+ offset: 5485,
13556
+ length: 76
13338
13557
  }
13339
13558
  }
13340
- ]
13559
+ ],
13560
+ location: {
13561
+ offset: 5460,
13562
+ length: 103
13563
+ }
13341
13564
  },
13342
13565
  {
13343
13566
  production: "skip_section",
@@ -13350,9 +13573,17 @@ var transform = [
13350
13573
  variant: "definitions",
13351
13574
  head: "token_def",
13352
13575
  tail: "skip_section$repeat_2"
13576
+ },
13577
+ location: {
13578
+ offset: 5593,
13579
+ length: 74
13353
13580
  }
13354
13581
  }
13355
- ]
13582
+ ],
13583
+ location: {
13584
+ offset: 5569,
13585
+ length: 100
13586
+ }
13356
13587
  },
13357
13588
  {
13358
13589
  production: "grammar_section",
@@ -13365,9 +13596,17 @@ var transform = [
13365
13596
  variant: "productions",
13366
13597
  head: "production",
13367
13598
  tail: "grammar_section$repeat_4"
13599
+ },
13600
+ location: {
13601
+ offset: 5702,
13602
+ length: 81
13368
13603
  }
13369
13604
  }
13370
- ]
13605
+ ],
13606
+ location: {
13607
+ offset: 5675,
13608
+ length: 110
13609
+ }
13371
13610
  },
13372
13611
  {
13373
13612
  production: "ast_section",
@@ -13380,9 +13619,17 @@ var transform = [
13380
13619
  variant: "types",
13381
13620
  head: "ast_type",
13382
13621
  tail: "ast_section$repeat_5"
13622
+ },
13623
+ location: {
13624
+ offset: 5814,
13625
+ length: 65
13383
13626
  }
13384
13627
  }
13385
- ]
13628
+ ],
13629
+ location: {
13630
+ offset: 5791,
13631
+ length: 90
13632
+ }
13386
13633
  },
13387
13634
  {
13388
13635
  production: "transform_section",
@@ -13395,9 +13642,17 @@ var transform = [
13395
13642
  variant: "rules",
13396
13643
  head: "transform_rule",
13397
13644
  tail: "transform_section$repeat_6"
13645
+ },
13646
+ location: {
13647
+ offset: 5916,
13648
+ length: 83
13398
13649
  }
13399
13650
  }
13400
- ]
13651
+ ],
13652
+ location: {
13653
+ offset: 5887,
13654
+ length: 114
13655
+ }
13401
13656
  },
13402
13657
  {
13403
13658
  production: "transform_rule",
@@ -13410,9 +13665,17 @@ var transform = [
13410
13665
  variant: "alternatives",
13411
13666
  head: "labeled_transform",
13412
13667
  tail: "transform_rule$repeat_7"
13668
+ },
13669
+ location: {
13670
+ offset: 6033,
13671
+ length: 87
13413
13672
  }
13414
13673
  }
13415
- ]
13674
+ ],
13675
+ location: {
13676
+ offset: 6007,
13677
+ length: 115
13678
+ }
13416
13679
  },
13417
13680
  {
13418
13681
  production: "reference_list",
@@ -13425,9 +13688,17 @@ var transform = [
13425
13688
  variant: "references",
13426
13689
  head: "reference",
13427
13690
  tail: "reference_list$repeat_8"
13691
+ },
13692
+ location: {
13693
+ offset: 6154,
13694
+ length: 77
13428
13695
  }
13429
13696
  }
13430
- ]
13697
+ ],
13698
+ location: {
13699
+ offset: 6128,
13700
+ length: 105
13701
+ }
13431
13702
  },
13432
13703
  {
13433
13704
  production: "choice",
@@ -13440,9 +13711,17 @@ var transform = [
13440
13711
  variant: "alternatives",
13441
13712
  head: "alternative",
13442
13713
  tail: "choice$repeat_9"
13714
+ },
13715
+ location: {
13716
+ offset: 6257,
13717
+ length: 65
13443
13718
  }
13444
13719
  }
13445
- ]
13720
+ ],
13721
+ location: {
13722
+ offset: 6239,
13723
+ length: 85
13724
+ }
13446
13725
  },
13447
13726
  {
13448
13727
  production: "sequence",
@@ -13455,9 +13734,17 @@ var transform = [
13455
13734
  variant: "factors",
13456
13735
  head: "factor",
13457
13736
  tail: "sequence$repeat_10"
13737
+ },
13738
+ location: {
13739
+ offset: 6350,
13740
+ length: 60
13458
13741
  }
13459
13742
  }
13460
- ]
13743
+ ],
13744
+ location: {
13745
+ offset: 6330,
13746
+ length: 82
13747
+ }
13461
13748
  }
13462
13749
  ];
13463
13750
  var grammarTableJson = {
@@ -13539,8 +13826,8 @@ function validateGrammarTable(grammar) {
13539
13826
  for (const rule of grammar.transformSchema.rules) {
13540
13827
  validateTransformProductionExists(rule, bnfProductionNames, issues);
13541
13828
  for (const alternative of rule.alternatives) {
13542
- validateTransformExpression(grammar, alternative.expression, issues);
13543
- collectPassCollapseWarnings(grammar, rule, alternative.expression, bnf.productions, issues);
13829
+ validateTransformExpression(grammar, alternative, issues);
13830
+ collectPassCollapseWarnings(grammar, rule, alternative, bnf.productions, issues);
13544
13831
  }
13545
13832
  }
13546
13833
  }
@@ -13559,37 +13846,47 @@ function validateGrammarTable(grammar) {
13559
13846
  */
13560
13847
  function collectDuplicateDefinitionWarnings(grammar, issues) {
13561
13848
  // Flag repeated production names in the grammar section.
13562
- reportDuplicateNames(grammar.productions.map((production) => production.name), 'grammar', 'production', issues);
13849
+ reportDuplicateDefinitions(grammar.productions.map((production) => ({
13850
+ name: production.name,
13851
+ location: production.location ?? null,
13852
+ })), 'grammar', 'production', issues);
13563
13853
  // Flag repeated ast type names.
13564
13854
  if (grammar.astSchema !== null) {
13565
- reportDuplicateNames(grammar.astSchema.types.map((type) => type.name), 'ast', 'type', issues);
13855
+ reportDuplicateDefinitions(grammar.astSchema.types.map((type) => ({
13856
+ name: type.name,
13857
+ location: type.location ?? null,
13858
+ })), 'ast', 'type', issues);
13566
13859
  }
13567
13860
  // Flag repeated transform rules for the same production.
13568
13861
  if (grammar.transformSchema !== null) {
13569
- reportDuplicateNames(grammar.transformSchema.rules.map((rule) => rule.production), 'transform', 'rule', issues);
13862
+ reportDuplicateDefinitions(grammar.transformSchema.rules.map((rule) => ({
13863
+ name: rule.production,
13864
+ location: rule.location ?? null,
13865
+ })), 'transform', 'rule', issues);
13570
13866
  }
13571
13867
  }
13572
13868
  /**
13573
13869
  * Records a warning for each name that appears more than once.
13574
13870
  *
13575
- * @param names - Declared names in source order.
13871
+ * @param definitions - Declared names and locations in source order.
13576
13872
  * @param section - Grammar section name for the message.
13577
13873
  * @param kind - Declaration kind for the message.
13578
13874
  * @param issues - Issue list to append to.
13579
13875
  */
13580
- function reportDuplicateNames(names, section, kind, issues) {
13876
+ function reportDuplicateDefinitions(definitions, section, kind, issues) {
13581
13877
  const seen = new Set();
13582
13878
  const reported = new Set();
13583
- for (const name of names) {
13584
- if (seen.has(name) && !reported.has(name)) {
13879
+ for (const definition of definitions) {
13880
+ if (seen.has(definition.name) && !reported.has(definition.name)) {
13585
13881
  issues.push({
13586
13882
  severity: 'warning',
13587
- message: `duplicate ${section} ${kind} ${JSON.stringify(name)}; `
13883
+ message: `duplicate ${section} ${kind} ${JSON.stringify(definition.name)}; `
13588
13884
  + `the later definition overrides the earlier one`,
13885
+ location: definition.location,
13589
13886
  });
13590
- reported.add(name);
13887
+ reported.add(definition.name);
13591
13888
  }
13592
- seen.add(name);
13889
+ seen.add(definition.name);
13593
13890
  }
13594
13891
  }
13595
13892
  /**
@@ -13612,6 +13909,7 @@ function validateTransformProductionExists(rule, bnfProductionNames, issues) {
13612
13909
  issues.push({
13613
13910
  severity: 'error',
13614
13911
  message: `transform rule for unknown production ${JSON.stringify(rule.production)}`,
13912
+ location: rule.location ?? null,
13615
13913
  });
13616
13914
  }
13617
13915
  }
@@ -13629,18 +13927,20 @@ function syntheticRepeatPrefix(name) {
13629
13927
  * Validates one transform expression against the grammar AST schema.
13630
13928
  *
13631
13929
  * @param grammar - Parsed grammar model.
13632
- * @param expression - Transform expression to validate.
13930
+ * @param alternative - Transform alternative owning the expression.
13633
13931
  * @param issues - Issue list to append to.
13634
13932
  */
13635
- function validateTransformExpression(grammar, expression, issues) {
13933
+ function validateTransformExpression(grammar, alternative, issues) {
13934
+ const expression = alternative.expression;
13935
+ const location = alternative.location ?? null;
13636
13936
  switch (expression.kind) {
13637
13937
  case 'build':
13638
- validateAstTarget(grammar, expression.typeName, expression.variant, issues);
13938
+ validateAstTarget(grammar, expression.typeName, expression.variant, location, issues);
13639
13939
  break;
13640
13940
  case 'foldLeft':
13641
13941
  case 'foldRight':
13642
13942
  case 'flatten':
13643
- validateAstTarget(grammar, expression.typeName, expression.variant, issues);
13943
+ validateAstTarget(grammar, expression.typeName, expression.variant, location, issues);
13644
13944
  break;
13645
13945
  }
13646
13946
  }
@@ -13650,13 +13950,15 @@ function validateTransformExpression(grammar, expression, issues) {
13650
13950
  * @param grammar - Parsed grammar model.
13651
13951
  * @param typeName - AST type name from a transform expression.
13652
13952
  * @param variant - AST variant label from a transform expression.
13953
+ * @param location - Source span of the transform alternative.
13653
13954
  * @param issues - Issue list to append to.
13654
13955
  */
13655
- function validateAstTarget(grammar, typeName, variant, issues) {
13956
+ function validateAstTarget(grammar, typeName, variant, location, issues) {
13656
13957
  if (grammar.astSchema === null) {
13657
13958
  issues.push({
13658
13959
  severity: 'error',
13659
13960
  message: `transform references ${typeName}.${variant} but the grammar has no ast section`,
13961
+ location,
13660
13962
  });
13661
13963
  return;
13662
13964
  }
@@ -13665,6 +13967,7 @@ function validateAstTarget(grammar, typeName, variant, issues) {
13665
13967
  issues.push({
13666
13968
  severity: 'error',
13667
13969
  message: `transform references undefined ast type ${JSON.stringify(typeName)}`,
13970
+ location,
13668
13971
  });
13669
13972
  return;
13670
13973
  }
@@ -13673,6 +13976,7 @@ function validateAstTarget(grammar, typeName, variant, issues) {
13673
13976
  issues.push({
13674
13977
  severity: 'error',
13675
13978
  message: `transform references ${typeName}.${variant} which is not declared in ast`,
13979
+ location,
13676
13980
  });
13677
13981
  }
13678
13982
  }
@@ -13703,11 +14007,12 @@ function collectAstVariants(expression) {
13703
14007
  *
13704
14008
  * @param grammar - Parsed grammar model.
13705
14009
  * @param rule - Parent production transform rule.
13706
- * @param expression - Transform expression for one alternative.
14010
+ * @param alternative - Transform alternative containing the pass expression.
13707
14011
  * @param bnfProductions - Desugared BNF productions.
13708
14012
  * @param issues - Issue list to append to.
13709
14013
  */
13710
- function collectPassCollapseWarnings(grammar, rule, expression, bnfProductions, issues) {
14014
+ function collectPassCollapseWarnings(grammar, rule, alternative, bnfProductions, issues) {
14015
+ const expression = alternative.expression;
13711
14016
  if (expression.kind !== 'pass') {
13712
14017
  return;
13713
14018
  }
@@ -13730,6 +14035,7 @@ function collectPassCollapseWarnings(grammar, rule, expression, bnfProductions,
13730
14035
  message: `pass(${expression.reference}) on ${rule.production} binds ${boundSymbol} `
13731
14036
  + `which has no transform rule and can match a single terminal; `
13732
14037
  + `add a transform for ${boundSymbol} or use build`,
14038
+ location: alternative.location ?? null,
13733
14039
  });
13734
14040
  }
13735
14041
  /**
@@ -13786,14 +14092,19 @@ function isTerminalSymbol(symbol) {
13786
14092
  return symbol?.kind === 'terminal' || symbol?.kind === 'token';
13787
14093
  }
13788
14094
  /**
13789
- * Formats validation issues as stderr warning or error lines.
14095
+ * Formats validation issues as stderr diagnostic lines.
13790
14096
  *
13791
14097
  * @param issues - Validation issues to format.
14098
+ * @param options - Optional grammar path and source text for line numbers.
13792
14099
  */
13793
- function formatTableValidationIssues(issues) {
13794
- return issues.map((issue) => issue.severity === 'error'
13795
- ? `error: ${issue.message}`
13796
- : `warning: ${issue.message}`);
14100
+ function formatTableValidationIssues(issues, options = {}) {
14101
+ return issues.map((issue) => formatDiagnostic({
14102
+ severity: issue.severity,
14103
+ message: issue.message,
14104
+ path: options.path,
14105
+ source: options.source,
14106
+ location: issue.location,
14107
+ }));
13797
14108
  }
13798
14109
 
13799
14110
  /**
@@ -13829,6 +14140,58 @@ function parseContextFromSources(options) {
13829
14140
  throw new ParseContextError('required: grammar source or table JSON');
13830
14141
  }
13831
14142
 
14143
+ /**
14144
+ * Rewrites a thrown source error into a positioned CLI diagnostic error.
14145
+ *
14146
+ * @param error - Thrown value from grammar or input reading.
14147
+ * @param path - Source file path.
14148
+ * @param source - Full source text used for line/column mapping.
14149
+ * @returns Positioned ParserLrError when the failure has an offset; otherwise the original value.
14150
+ */
14151
+ function locateSourceError(error, path, source) {
14152
+ const offset = sourceErrorOffset(error);
14153
+ if (offset === null) {
14154
+ return error;
14155
+ }
14156
+ return new ParserLrError(formatDiagnostic({
14157
+ severity: 'error',
14158
+ message: stripEmbeddedOffset(errorMessage(error)),
14159
+ path,
14160
+ source,
14161
+ offset,
14162
+ }));
14163
+ }
14164
+ /**
14165
+ * Returns a source offset from a known offset-bearing error.
14166
+ *
14167
+ * @param error - Thrown value to inspect.
14168
+ */
14169
+ function sourceErrorOffset(error) {
14170
+ if (error instanceof ReadGrammarError || error instanceof LexerError) {
14171
+ return error.offset;
14172
+ }
14173
+ return null;
14174
+ }
14175
+ /**
14176
+ * Returns a human-readable message from a thrown value.
14177
+ *
14178
+ * @param error - Thrown value.
14179
+ */
14180
+ function errorMessage(error) {
14181
+ if (error instanceof Error) {
14182
+ return error.message;
14183
+ }
14184
+ return String(error);
14185
+ }
14186
+ /**
14187
+ * Removes an embedded `at offset N` suffix so the diagnostic formatter owns the position.
14188
+ *
14189
+ * @param message - Original error message.
14190
+ */
14191
+ function stripEmbeddedOffset(message) {
14192
+ return message.replace(/\s+at offset \d+\s*$/, '');
14193
+ }
14194
+
13832
14195
  /**
13833
14196
  * Reads a UTF-8 text file from disk.
13834
14197
  *
@@ -13892,11 +14255,21 @@ function registerParseCommand(program) {
13892
14255
  }
13893
14256
  const context = await loadContextFromPaths(options);
13894
14257
  logProgress(`lexing ${options.input}`);
13895
- const tokens = await context.lexChunkStreamAsync(readTextChunks(options.input));
14258
+ const tokens = await lexInputFile(context, options.input);
13896
14259
  logProgress('parsing');
13897
- const tree = context.parse(tokens);
14260
+ const result = context.parseResult(tokens);
14261
+ if (result.tree === null) {
14262
+ const source = await readTextFile(options.input);
14263
+ throw new ParserLrError(formatDiagnostic({
14264
+ severity: 'error',
14265
+ message: result.errorMessage ?? 'Parse failed',
14266
+ path: options.input,
14267
+ source,
14268
+ offset: result.errorOffset,
14269
+ }));
14270
+ }
13898
14271
  logProgress(`formatting output (${options.format})`);
13899
- const output = formatParseOutput(tree, options.format);
14272
+ const output = formatParseOutput(result.tree, options.format);
13900
14273
  // Write output to disk or stdout.
13901
14274
  if (options.output !== undefined) {
13902
14275
  logProgress(`writing ${options.output}`);
@@ -13908,6 +14281,21 @@ function registerParseCommand(program) {
13908
14281
  }
13909
14282
  });
13910
14283
  }
14284
+ /**
14285
+ * Lexes an input file and rewrites offset-bearing lexer failures with line numbers.
14286
+ *
14287
+ * @param context - Loaded parse context.
14288
+ * @param path - Input file path.
14289
+ */
14290
+ async function lexInputFile(context, path) {
14291
+ try {
14292
+ return await context.lexChunkStreamAsync(readTextChunks(path));
14293
+ }
14294
+ catch (error) {
14295
+ const source = await readTextFile(path);
14296
+ throw locateSourceError(error, path, source);
14297
+ }
14298
+ }
13911
14299
  /**
13912
14300
  * Reads grammar or table files and builds a parse context.
13913
14301
  *
@@ -13918,8 +14306,13 @@ async function loadContextFromPaths(options) {
13918
14306
  if (options.grammar !== undefined) {
13919
14307
  logProgress(`reading grammar ${options.grammar}`);
13920
14308
  const grammarSource = await readTextFile(options.grammar);
13921
- logProgress('building parse table');
13922
- return parseContextFromGrammar(grammarSource);
14309
+ try {
14310
+ logProgress('building parse table');
14311
+ return parseContextFromGrammar(grammarSource);
14312
+ }
14313
+ catch (error) {
14314
+ throw locateSourceError(error, options.grammar, grammarSource);
14315
+ }
13923
14316
  }
13924
14317
  logProgress(`reading table ${options.table}`);
13925
14318
  const tableJson = await readTextFile(options.table);
@@ -13945,9 +14338,9 @@ function registerTableCommands(program) {
13945
14338
  .action(async (options) => {
13946
14339
  logProgress(`reading grammar ${options.grammar}`);
13947
14340
  const grammarSource = await readTextFile(options.grammar);
14341
+ const grammar = readGrammarAtPath(options.grammar, grammarSource);
13948
14342
  logProgress(`building ${options.algorithm} parse table`);
13949
- const grammar = readGrammar(grammarSource);
13950
- writeGrammarValidationMessages(grammar, false);
14343
+ writeGrammarValidationMessages(grammar, options.grammar, grammarSource, false);
13951
14344
  const context = parseContextFromSources({
13952
14345
  grammarSource,
13953
14346
  algorithm: options.algorithm,
@@ -13976,27 +14369,45 @@ function registerTableCommands(program) {
13976
14369
  .action(async (options) => {
13977
14370
  logProgress(`reading grammar ${options.grammar}`);
13978
14371
  const grammarSource = await readTextFile(options.grammar);
13979
- const grammar = readGrammar(grammarSource);
13980
- const exitCode = writeGrammarValidationMessages(grammar, options.strict === true);
14372
+ const grammar = readGrammarAtPath(options.grammar, grammarSource);
14373
+ const exitCode = writeGrammarValidationMessages(grammar, options.grammar, grammarSource, options.strict === true);
13981
14374
  process.exitCode = exitCode;
13982
14375
  });
13983
14376
  }
14377
+ /**
14378
+ * Parses a grammar file and rewrites offset-bearing failures with line numbers.
14379
+ *
14380
+ * @param path - Grammar file path.
14381
+ * @param source - Grammar file text.
14382
+ */
14383
+ function readGrammarAtPath(path, source) {
14384
+ try {
14385
+ return readGrammar(source);
14386
+ }
14387
+ catch (error) {
14388
+ throw locateSourceError(error, path, source);
14389
+ }
14390
+ }
13984
14391
  /**
13985
14392
  * Writes grammar validation messages to stderr and returns a process exit code.
13986
14393
  *
13987
14394
  * @param grammar - Parsed grammar model.
14395
+ * @param path - Grammar file path for diagnostics.
14396
+ * @param source - Grammar file text for line/column mapping.
13988
14397
  * @param strict - Whether warnings should fail validation.
13989
14398
  */
13990
- function writeGrammarValidationMessages(grammar, strict) {
14399
+ function writeGrammarValidationMessages(grammar, path, source, strict) {
13991
14400
  const issues = validateGrammarTable(grammar);
13992
14401
  let hasError = false;
13993
14402
  let hasWarning = false;
13994
- for (const line of formatTableValidationIssues(issues)) {
14403
+ for (const line of formatTableValidationIssues(issues, { path, source })) {
13995
14404
  process.stderr.write(`${line}\n`);
13996
- if (line.startsWith('error:')) {
14405
+ }
14406
+ for (const issue of issues) {
14407
+ if (issue.severity === 'error') {
13997
14408
  hasError = true;
13998
14409
  }
13999
- if (line.startsWith('warning:')) {
14410
+ if (issue.severity === 'warning') {
14000
14411
  hasWarning = true;
14001
14412
  }
14002
14413
  }