ohmjs / ohm

A library and language for building parsers, interpreters, compilers, etc.
MIT License
5.01k stars 217 forks source link

_terminal() not specified results in undefined #389

Closed guitarvydas closed 2 years ago

guitarvydas commented 2 years ago

I am generating Ohm-JS code and failed to generate a "_terminal" rule.

The failing code returned "undefined" instead of a more graceful failure.

The debugger shows me:

class ... 
...
checkActionDict(u)
{
    u._checkTopDownActionDict(this.typeName, this.name, this.actionDict)
}
execute(u, t)
{
    try {
        const {ctorName: u} = t._node;
        let e = this.actionDict[u];
    return e ? ...

u is "_terminal" e is undefined
return undefined

The bug is clearly my problem, but debugging could have been faster had I seen something more interesting than the generic undefined.

Should this throw instead? / error message ~~ "_terminal not defined".

pdubroy commented 2 years ago

Can you share a screenshot of the stack trace, and/or share the generated code so I can reproduce the error? I'm not able to reproduce it using v16.3.4. Here's what I tried:

const ohm = require('ohm-js');

const g = ohm.grammar(`G { x = "x" }`);
const s1 = g.createSemantics().addOperation('showBug', {});
s1(g.match('x')).showBug(); // Throws

const s2 = g.createSemantics().addOperation('showBug', {
  _terminal: undefined
});
s2(g.match('x')).showBug(); // This throws too
guitarvydas commented 2 years ago

I agree that throws are generated and appropriate.

The above examples helped me clarify the problem. It turns out that my code was converting one of the throws to an undefined result.