question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

_inheritsFrom seems to fail.

See original GitHub issue

Hi!

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:closed
  • Created 7 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
pdubroycommented, Sep 12, 2016

Also, thank you very much for the super detailed bug report 😃

0reactions
phfrohringcommented, Sep 12, 2016

The gist of it:

  • equality is a fundamental concept that is worth explicit definitions (to me at least).
  • some equalities are not explicitly defined for (Body, Formal, Rule)
  • runtime circular definitions may worth a check.

Do you think it worth implementing:

  1. Formal and Formal equality explicitly?
  2. Rule and Rule equality explicitly?
  3. Body and Body equality explicitly?
  4. A check at runtime for circular definitions?

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.

  - Grammar ≔
      - name : String
      - optDefaultStartRule : String | null | undefined
      - superGrammar : Grammar
      - rules : [Rule]
          - Rule :
              - description : String | undefined | null
              - formals : [Formal]
                  - Formal : □
              - body : □
  • What is the definition of “Formal” ?
  • What is the definition of “Body” ?

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 function a a → true | false)
  • means “or” (it looks a lot like a v…)
- g1 = g2 ⇔
    - ∨ ☑ g1 === g2
    - ∨:
        - ☑ name1 === name2
        - ☑ optDefaultStartRule1 === optDefaultStartRule2
        - □ superGrammar1 = superGrammar2
        - □ rules1 = rules2:
            - ☑ rules1.length === rules2.length
            - □ ∀ i:  rules1[i] = rules2[i]:
                - ☑ description1 === description2
                - □ formals1 = formals2:
                    - □ ∀ i:  formals1[i] = formals2[i]:
                        - □
                - □ body1 = body2:
                    - □
  • Equality between Formal objects is implicit: there is no EqFormal function
  • Equality between Body objects is implicit: there is no EqBody function
  • Equality between Rule objects is implicit: there is no EqRule function

Because 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:

function Grammar(
    name,
    superGrammar,
    rules,
    optDefaultStartRule) {
    this.name = name;
    this.superGrammar = superGrammar;
    this.rules = rules;
    if (optDefaultStartRule) {
        if (!(optDefaultStartRule in rules)) {
            throw new Error("Invalid start rule: '" + optDefaultStartRule +
                            "' is not a rule in grammar '" + name + "'");
        }
        this.defaultStartRule = optDefaultStartRule;
    }
}

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:

  • a ← b ← c ← d
  • a ≔ d
  • ⇒ d ← b ← c ← d

Do you think it worth implementing:

  1. Formal and Formal equality explicitly?
  2. Rule and Rule equality explicitly?
  3. Body and Body equality explicitly?
  4. A check at runtime for circular definitions?
Read more comments on GitHub >

github_iconTop Results From Across the Web

Json.net fails when trying to deserialize a class that inherits ...
I have a class SearchError that inherits from Exception , and when ever I try to deserialize it ...
Read more >
Error On Any Inheritance · Issue #1060 · ionic-team/stencil
The change in 0.12 to introduce a compiler error when a Stencil component inherits from any class is causing us a lot of...
Read more >
Mock.NonPublic.Arrange with inherited non-overridden ...
Arrange with inherited non-overridden members doesn't seem to work. 1 Answer 69 Views ... I have a class that inherits from another class....
Read more >
Oo Has Failed - C2 wiki
In Java, you can simply inherit from an Applet-class to make your new applet. That's reuse. The new Swing JApplet class inherits from...
Read more >
Custom errors, extending Error - The Modern JavaScript Tutorial
Create a class FormatError that inherits from the built-in SyntaxError class. It should support message , name and stack properties. Usage ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found