ohm-js 17.4.0 → 17.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ohm-extras.cjs +32 -27
- package/dist/ohm-extras.js +32 -27
- package/dist/ohm.cjs +23 -10
- package/dist/ohm.cjs.map +1 -1
- package/dist/ohm.js +24 -11
- package/dist/ohm.min.js +1 -1
- package/extras/recoverSourceOrder.js +5 -34
- package/index.mjs +10 -1
- package/package.json +9 -6
- package/src/Builder.js +6 -1
- package/src/buildGrammar.js +2 -2
- package/src/groupIterSiblings.js +26 -0
- package/src/main.js +14 -6
- package/src/v18.js +335 -0
- package/src/version.js +1 -1
package/dist/ohm-extras.cjs
CHANGED
|
@@ -5215,9 +5215,10 @@ class GrammarDecl {
|
|
|
5215
5215
|
// --------------------------------------------------------------------
|
|
5216
5216
|
|
|
5217
5217
|
class Builder {
|
|
5218
|
-
constructor() {
|
|
5218
|
+
constructor(options) {
|
|
5219
5219
|
this.currentDecl = null;
|
|
5220
5220
|
this.currentRuleName = null;
|
|
5221
|
+
this.options = options || {};
|
|
5221
5222
|
}
|
|
5222
5223
|
|
|
5223
5224
|
newGrammar(name) {
|
|
@@ -5337,6 +5338,10 @@ class Builder {
|
|
|
5337
5338
|
if (!(expr instanceof PExpr)) {
|
|
5338
5339
|
expr = this.fromRecipe(expr);
|
|
5339
5340
|
}
|
|
5341
|
+
// For v18 compatibility, where we don't want a binding for lookahead.
|
|
5342
|
+
if (this.options.eliminateLookaheads) {
|
|
5343
|
+
return new Not(new Not(expr));
|
|
5344
|
+
}
|
|
5340
5345
|
return new Lookahead(expr);
|
|
5341
5346
|
}
|
|
5342
5347
|
|
|
@@ -5416,8 +5421,8 @@ function namespaceHas(ns, name) {
|
|
|
5416
5421
|
// `tree`, which is the concrete syntax tree of a user-written grammar.
|
|
5417
5422
|
// The grammar will be assigned into `namespace` under the name of the grammar
|
|
5418
5423
|
// as specified in the source.
|
|
5419
|
-
function buildGrammar(match, namespace, optOhmGrammarForTesting) {
|
|
5420
|
-
const builder = new Builder();
|
|
5424
|
+
function buildGrammar(match, namespace, optOhmGrammarForTesting, options) {
|
|
5425
|
+
const builder = new Builder(options);
|
|
5421
5426
|
let decl;
|
|
5422
5427
|
let currentRuleName;
|
|
5423
5428
|
let currentRuleFormals;
|
|
@@ -5871,15 +5876,15 @@ const isBuffer = obj =>
|
|
|
5871
5876
|
typeof obj.constructor.isBuffer === 'function' &&
|
|
5872
5877
|
obj.constructor.isBuffer(obj);
|
|
5873
5878
|
|
|
5874
|
-
function compileAndLoad(source, namespace) {
|
|
5879
|
+
function compileAndLoad(source, namespace, buildOptions) {
|
|
5875
5880
|
const m = ohmGrammar.match(source, 'Grammars');
|
|
5876
5881
|
if (m.failed()) {
|
|
5877
5882
|
throw grammarSyntaxError(m);
|
|
5878
5883
|
}
|
|
5879
|
-
return buildGrammar(m, namespace);
|
|
5884
|
+
return buildGrammar(m, namespace, undefined, buildOptions);
|
|
5880
5885
|
}
|
|
5881
5886
|
|
|
5882
|
-
function
|
|
5887
|
+
function _grammars(source, optNamespace, buildOptions) {
|
|
5883
5888
|
const ns = Object.create(optNamespace || {});
|
|
5884
5889
|
if (typeof source !== 'string') {
|
|
5885
5890
|
// For convenience, detect Node.js Buffer objects and automatically call toString().
|
|
@@ -5891,10 +5896,14 @@ function grammars$1(source, optNamespace) {
|
|
|
5891
5896
|
);
|
|
5892
5897
|
}
|
|
5893
5898
|
}
|
|
5894
|
-
compileAndLoad(source, ns);
|
|
5899
|
+
compileAndLoad(source, ns, buildOptions);
|
|
5895
5900
|
return ns;
|
|
5896
5901
|
}
|
|
5897
5902
|
|
|
5903
|
+
function grammars$1(source, optNamespace) {
|
|
5904
|
+
return _grammars(source, optNamespace);
|
|
5905
|
+
}
|
|
5906
|
+
|
|
5898
5907
|
const grammarsSource = String.raw`
|
|
5899
5908
|
/*
|
|
5900
5909
|
Superset of the Ohm grammar that allows examples to be embedded in comments.
|
|
@@ -6043,20 +6052,6 @@ function extractExamples(grammarsDef) {
|
|
|
6043
6052
|
return semantics(matchResult).examples();
|
|
6044
6053
|
}
|
|
6045
6054
|
|
|
6046
|
-
/*
|
|
6047
|
-
To find iter nodes that are derived from the same repetition expression, we
|
|
6048
|
-
look for adjacent iter nodes that have the same source interval and the same
|
|
6049
|
-
number of children.
|
|
6050
|
-
|
|
6051
|
-
A few things to note:
|
|
6052
|
-
- The children of `*` and `+` nodes can't be nullable, so the associated iter
|
|
6053
|
-
nodes always consume some input, and therefore consecutive nodes that have
|
|
6054
|
-
the same interval must come from the same repetition expression.
|
|
6055
|
-
- We *could* mistake `a? b?` for (a b)?`, if neither of them comsume any input.
|
|
6056
|
-
However, for the purposes of this module, those two cases are equivalent
|
|
6057
|
-
anyways, since we only care about finding the correct order of the non-iter
|
|
6058
|
-
nodes, and both interpretations yield the same order.
|
|
6059
|
-
*/
|
|
6060
6055
|
const isIterSibling = (refNode, n) => {
|
|
6061
6056
|
return (
|
|
6062
6057
|
n.isIteration() &&
|
|
@@ -6066,22 +6061,32 @@ const isIterSibling = (refNode, n) => {
|
|
|
6066
6061
|
);
|
|
6067
6062
|
};
|
|
6068
6063
|
|
|
6069
|
-
function
|
|
6070
|
-
const
|
|
6064
|
+
function groupIterSiblings(nodes) {
|
|
6065
|
+
const groups = [];
|
|
6071
6066
|
for (let i = 0; i < nodes.length; i++) {
|
|
6072
6067
|
const n = nodes[i];
|
|
6073
6068
|
if (!n.isIteration()) {
|
|
6074
|
-
|
|
6069
|
+
groups.push({kind: 'node', node: n});
|
|
6075
6070
|
continue;
|
|
6076
6071
|
}
|
|
6077
|
-
|
|
6078
|
-
// We found an iter node, now find its siblings.
|
|
6079
6072
|
const siblings = [n];
|
|
6080
|
-
// Find the first node that's *not* part of the current list.
|
|
6081
6073
|
for (let j = i + 1; j < nodes.length && isIterSibling(n, nodes[j]); j++) {
|
|
6082
6074
|
siblings.push(nodes[j]);
|
|
6083
6075
|
i = j;
|
|
6084
6076
|
}
|
|
6077
|
+
groups.push({kind: 'iter', siblings});
|
|
6078
|
+
}
|
|
6079
|
+
return groups;
|
|
6080
|
+
}
|
|
6081
|
+
|
|
6082
|
+
function recoverSourceOrder(nodes, depth = 0) {
|
|
6083
|
+
const ans = [];
|
|
6084
|
+
for (const group of groupIterSiblings(nodes)) {
|
|
6085
|
+
if (group.kind === 'node') {
|
|
6086
|
+
ans.push(group.node);
|
|
6087
|
+
continue;
|
|
6088
|
+
}
|
|
6089
|
+
const {siblings} = group;
|
|
6085
6090
|
const cousins = [];
|
|
6086
6091
|
const numRows = siblings[0].children.length;
|
|
6087
6092
|
for (let row = 0; row < numRows; row++) {
|
package/dist/ohm-extras.js
CHANGED
|
@@ -5217,9 +5217,10 @@
|
|
|
5217
5217
|
// --------------------------------------------------------------------
|
|
5218
5218
|
|
|
5219
5219
|
class Builder {
|
|
5220
|
-
constructor() {
|
|
5220
|
+
constructor(options) {
|
|
5221
5221
|
this.currentDecl = null;
|
|
5222
5222
|
this.currentRuleName = null;
|
|
5223
|
+
this.options = options || {};
|
|
5223
5224
|
}
|
|
5224
5225
|
|
|
5225
5226
|
newGrammar(name) {
|
|
@@ -5339,6 +5340,10 @@
|
|
|
5339
5340
|
if (!(expr instanceof PExpr)) {
|
|
5340
5341
|
expr = this.fromRecipe(expr);
|
|
5341
5342
|
}
|
|
5343
|
+
// For v18 compatibility, where we don't want a binding for lookahead.
|
|
5344
|
+
if (this.options.eliminateLookaheads) {
|
|
5345
|
+
return new Not(new Not(expr));
|
|
5346
|
+
}
|
|
5342
5347
|
return new Lookahead(expr);
|
|
5343
5348
|
}
|
|
5344
5349
|
|
|
@@ -5418,8 +5423,8 @@
|
|
|
5418
5423
|
// `tree`, which is the concrete syntax tree of a user-written grammar.
|
|
5419
5424
|
// The grammar will be assigned into `namespace` under the name of the grammar
|
|
5420
5425
|
// as specified in the source.
|
|
5421
|
-
function buildGrammar(match, namespace, optOhmGrammarForTesting) {
|
|
5422
|
-
const builder = new Builder();
|
|
5426
|
+
function buildGrammar(match, namespace, optOhmGrammarForTesting, options) {
|
|
5427
|
+
const builder = new Builder(options);
|
|
5423
5428
|
let decl;
|
|
5424
5429
|
let currentRuleName;
|
|
5425
5430
|
let currentRuleFormals;
|
|
@@ -5873,15 +5878,15 @@
|
|
|
5873
5878
|
typeof obj.constructor.isBuffer === 'function' &&
|
|
5874
5879
|
obj.constructor.isBuffer(obj);
|
|
5875
5880
|
|
|
5876
|
-
function compileAndLoad(source, namespace) {
|
|
5881
|
+
function compileAndLoad(source, namespace, buildOptions) {
|
|
5877
5882
|
const m = ohmGrammar.match(source, 'Grammars');
|
|
5878
5883
|
if (m.failed()) {
|
|
5879
5884
|
throw grammarSyntaxError(m);
|
|
5880
5885
|
}
|
|
5881
|
-
return buildGrammar(m, namespace);
|
|
5886
|
+
return buildGrammar(m, namespace, undefined, buildOptions);
|
|
5882
5887
|
}
|
|
5883
5888
|
|
|
5884
|
-
function
|
|
5889
|
+
function _grammars(source, optNamespace, buildOptions) {
|
|
5885
5890
|
const ns = Object.create(optNamespace || {});
|
|
5886
5891
|
if (typeof source !== 'string') {
|
|
5887
5892
|
// For convenience, detect Node.js Buffer objects and automatically call toString().
|
|
@@ -5893,10 +5898,14 @@
|
|
|
5893
5898
|
);
|
|
5894
5899
|
}
|
|
5895
5900
|
}
|
|
5896
|
-
compileAndLoad(source, ns);
|
|
5901
|
+
compileAndLoad(source, ns, buildOptions);
|
|
5897
5902
|
return ns;
|
|
5898
5903
|
}
|
|
5899
5904
|
|
|
5905
|
+
function grammars$1(source, optNamespace) {
|
|
5906
|
+
return _grammars(source, optNamespace);
|
|
5907
|
+
}
|
|
5908
|
+
|
|
5900
5909
|
const grammarsSource = String.raw`
|
|
5901
5910
|
/*
|
|
5902
5911
|
Superset of the Ohm grammar that allows examples to be embedded in comments.
|
|
@@ -6045,20 +6054,6 @@
|
|
|
6045
6054
|
return semantics(matchResult).examples();
|
|
6046
6055
|
}
|
|
6047
6056
|
|
|
6048
|
-
/*
|
|
6049
|
-
To find iter nodes that are derived from the same repetition expression, we
|
|
6050
|
-
look for adjacent iter nodes that have the same source interval and the same
|
|
6051
|
-
number of children.
|
|
6052
|
-
|
|
6053
|
-
A few things to note:
|
|
6054
|
-
- The children of `*` and `+` nodes can't be nullable, so the associated iter
|
|
6055
|
-
nodes always consume some input, and therefore consecutive nodes that have
|
|
6056
|
-
the same interval must come from the same repetition expression.
|
|
6057
|
-
- We *could* mistake `a? b?` for (a b)?`, if neither of them comsume any input.
|
|
6058
|
-
However, for the purposes of this module, those two cases are equivalent
|
|
6059
|
-
anyways, since we only care about finding the correct order of the non-iter
|
|
6060
|
-
nodes, and both interpretations yield the same order.
|
|
6061
|
-
*/
|
|
6062
6057
|
const isIterSibling = (refNode, n) => {
|
|
6063
6058
|
return (
|
|
6064
6059
|
n.isIteration() &&
|
|
@@ -6068,22 +6063,32 @@
|
|
|
6068
6063
|
);
|
|
6069
6064
|
};
|
|
6070
6065
|
|
|
6071
|
-
function
|
|
6072
|
-
const
|
|
6066
|
+
function groupIterSiblings(nodes) {
|
|
6067
|
+
const groups = [];
|
|
6073
6068
|
for (let i = 0; i < nodes.length; i++) {
|
|
6074
6069
|
const n = nodes[i];
|
|
6075
6070
|
if (!n.isIteration()) {
|
|
6076
|
-
|
|
6071
|
+
groups.push({kind: 'node', node: n});
|
|
6077
6072
|
continue;
|
|
6078
6073
|
}
|
|
6079
|
-
|
|
6080
|
-
// We found an iter node, now find its siblings.
|
|
6081
6074
|
const siblings = [n];
|
|
6082
|
-
// Find the first node that's *not* part of the current list.
|
|
6083
6075
|
for (let j = i + 1; j < nodes.length && isIterSibling(n, nodes[j]); j++) {
|
|
6084
6076
|
siblings.push(nodes[j]);
|
|
6085
6077
|
i = j;
|
|
6086
6078
|
}
|
|
6079
|
+
groups.push({kind: 'iter', siblings});
|
|
6080
|
+
}
|
|
6081
|
+
return groups;
|
|
6082
|
+
}
|
|
6083
|
+
|
|
6084
|
+
function recoverSourceOrder(nodes, depth = 0) {
|
|
6085
|
+
const ans = [];
|
|
6086
|
+
for (const group of groupIterSiblings(nodes)) {
|
|
6087
|
+
if (group.kind === 'node') {
|
|
6088
|
+
ans.push(group.node);
|
|
6089
|
+
continue;
|
|
6090
|
+
}
|
|
6091
|
+
const {siblings} = group;
|
|
6087
6092
|
const cousins = [];
|
|
6088
6093
|
const numRows = siblings[0].children.length;
|
|
6089
6094
|
for (let row = 0; row < numRows; row++) {
|
package/dist/ohm.cjs
CHANGED
|
@@ -4950,9 +4950,10 @@ class GrammarDecl {
|
|
|
4950
4950
|
// --------------------------------------------------------------------
|
|
4951
4951
|
|
|
4952
4952
|
class Builder {
|
|
4953
|
-
constructor() {
|
|
4953
|
+
constructor(options) {
|
|
4954
4954
|
this.currentDecl = null;
|
|
4955
4955
|
this.currentRuleName = null;
|
|
4956
|
+
this.options = options || {};
|
|
4956
4957
|
}
|
|
4957
4958
|
|
|
4958
4959
|
newGrammar(name) {
|
|
@@ -5072,6 +5073,10 @@ class Builder {
|
|
|
5072
5073
|
if (!(expr instanceof PExpr)) {
|
|
5073
5074
|
expr = this.fromRecipe(expr);
|
|
5074
5075
|
}
|
|
5076
|
+
// For v18 compatibility, where we don't want a binding for lookahead.
|
|
5077
|
+
if (this.options.eliminateLookaheads) {
|
|
5078
|
+
return new Not(new Not(expr));
|
|
5079
|
+
}
|
|
5075
5080
|
return new Lookahead(expr);
|
|
5076
5081
|
}
|
|
5077
5082
|
|
|
@@ -5151,8 +5156,8 @@ function namespaceHas(ns, name) {
|
|
|
5151
5156
|
// `tree`, which is the concrete syntax tree of a user-written grammar.
|
|
5152
5157
|
// The grammar will be assigned into `namespace` under the name of the grammar
|
|
5153
5158
|
// as specified in the source.
|
|
5154
|
-
function buildGrammar(match, namespace, optOhmGrammarForTesting) {
|
|
5155
|
-
const builder = new Builder();
|
|
5159
|
+
function buildGrammar(match, namespace, optOhmGrammarForTesting, options) {
|
|
5160
|
+
const builder = new Builder(options);
|
|
5156
5161
|
let decl;
|
|
5157
5162
|
let currentRuleName;
|
|
5158
5163
|
let currentRuleFormals;
|
|
@@ -5600,7 +5605,7 @@ Object.assign(IndentationSensitive, {
|
|
|
5600
5605
|
});
|
|
5601
5606
|
|
|
5602
5607
|
// Generated by scripts/prebuild.js
|
|
5603
|
-
const version = '17.
|
|
5608
|
+
const version = '17.5.0';
|
|
5604
5609
|
|
|
5605
5610
|
Grammar.initApplicationParser(ohmGrammar, buildGrammar);
|
|
5606
5611
|
|
|
@@ -5609,16 +5614,16 @@ const isBuffer = obj =>
|
|
|
5609
5614
|
typeof obj.constructor.isBuffer === 'function' &&
|
|
5610
5615
|
obj.constructor.isBuffer(obj);
|
|
5611
5616
|
|
|
5612
|
-
function compileAndLoad(source, namespace) {
|
|
5617
|
+
function compileAndLoad(source, namespace, buildOptions) {
|
|
5613
5618
|
const m = ohmGrammar.match(source, 'Grammars');
|
|
5614
5619
|
if (m.failed()) {
|
|
5615
5620
|
throw grammarSyntaxError(m);
|
|
5616
5621
|
}
|
|
5617
|
-
return buildGrammar(m, namespace);
|
|
5622
|
+
return buildGrammar(m, namespace, undefined, buildOptions);
|
|
5618
5623
|
}
|
|
5619
5624
|
|
|
5620
|
-
function
|
|
5621
|
-
const ns =
|
|
5625
|
+
function _grammar(source, optNamespace, buildOptions) {
|
|
5626
|
+
const ns = _grammars(source, optNamespace, buildOptions);
|
|
5622
5627
|
|
|
5623
5628
|
// Ensure that the source contained no more than one grammar definition.
|
|
5624
5629
|
const grammarNames = Object.keys(ns);
|
|
@@ -5635,7 +5640,7 @@ function grammar(source, optNamespace) {
|
|
|
5635
5640
|
return ns[grammarNames[0]]; // Return the one and only grammar.
|
|
5636
5641
|
}
|
|
5637
5642
|
|
|
5638
|
-
function
|
|
5643
|
+
function _grammars(source, optNamespace, buildOptions) {
|
|
5639
5644
|
const ns = Object.create(optNamespace || {});
|
|
5640
5645
|
if (typeof source !== 'string') {
|
|
5641
5646
|
// For convenience, detect Node.js Buffer objects and automatically call toString().
|
|
@@ -5647,10 +5652,18 @@ function grammars(source, optNamespace) {
|
|
|
5647
5652
|
);
|
|
5648
5653
|
}
|
|
5649
5654
|
}
|
|
5650
|
-
compileAndLoad(source, ns);
|
|
5655
|
+
compileAndLoad(source, ns, buildOptions);
|
|
5651
5656
|
return ns;
|
|
5652
5657
|
}
|
|
5653
5658
|
|
|
5659
|
+
function grammar(source, optNamespace) {
|
|
5660
|
+
return _grammar(source, optNamespace);
|
|
5661
|
+
}
|
|
5662
|
+
|
|
5663
|
+
function grammars(source, optNamespace) {
|
|
5664
|
+
return _grammars(source, optNamespace);
|
|
5665
|
+
}
|
|
5666
|
+
|
|
5654
5667
|
exports.ExperimentalIndentationSensitive = IndentationSensitive;
|
|
5655
5668
|
exports._buildGrammar = buildGrammar;
|
|
5656
5669
|
exports.grammar = grammar;
|