_inheritsFrom seems to fail.
See original GitHub issueHi!
I has playing with Ohm… when I stumbled upon:
intGrammar.extendSemantics(natSemantics)
⇒ Error: Cannot extend a semantics for grammar 'NatGrammar' for use with grammar
'IntGrammar' (not a sub-grammar)
when it, /a piori/, should not have raised the error.
A reason may be that g === grammar
is too restrictive in _inheritsFrom
:
g
and grammar
may be ≠ objects according to ===
but still represent the same grammar.
Full story below.
nat_grammar.ohm
:
NatGrammar { □ }
nat_semantics.js
:
const natGrammar = require('./nat_grammar.js').grammar;
module.exports = {
semantics: natGrammar.createSemantics().addOperation('eval', { □ }
})
};
int_grammar.ohm
:
IntGrammar <: NatGrammar { □ }
int_semantics.js
const natSemantics = require('./nat_semantics.js').semantics;
const intGrammar = require('./int_grammar.js').grammar;
debugger;
const semantics = intGrammar.extendSemantics(natSemantics).□
…when this happened:
intGrammar.extendSemantics(natSemantics)
⇒ Error: Cannot extend a semantics for grammar 'NatGrammar' for use with grammar
'IntGrammar' (not a sub-grammar)
So, I stepped into the code until:
break in node_modules/ohm-js/src/Grammar.js:136
134 _inheritsFrom: function(grammar) {
135 var g = this.superGrammar;
>136 while (g) {
137 if (g === grammar) {
138 return true;
and g === grammar
is false… but inspection shows that properties wise, it
should have been true: they represent the same grammar.
It boils down to defining an equality between grammars when the js
implementation of ===
between objects is not sufficient I guess…
to reproduce the error (see attached files: test.zip):
$ node int_semantics_test.js
Issue Analytics
- State:
- Created 7 years ago
- Comments:6 (4 by maintainers)
Top GitHub Comments
Also, thank you very much for the super detailed bug report 😃
The gist of it:
Do you think it worth implementing:
Here are the “ingredients” to build a Grammar: “□” means that I did not find how it is built and that it is not a primitive type.
Here are the logical steps that defines equality between grammars from
Grammar.prototype.equals
:□
means that equality is not defined or implicit☑
means that equality is explicitly defined (that is: a named functiona a → true | false
)∨
means “or” (it looks a lot like a v…)EqFormal
functionEqBody
functionEqRule
functionBecause equality is so fundamental, I think it would be nice to have explicit equality functions for these objects (Body, Formal, Rule) instead of implicit ones.
It would avoid multiple implicit equality definitions that would inevitably lead to inconsistencies since it would lead to situations like: a =1 b ∧ b =2 c but a ≠ c because =1 ≠ =2 where a = b ∧ b = c ⇒ a = c would have been expected.
Here is the implementation in Grammar.js:
Maybe make sure that there is no circular definition of a new Grammar object?
this.superGrammar = superGrammar
It is possible at runtime to build a circular grammar w/o error:Do you think it worth implementing: