tjvr/nearley-reverse

How to use string literals?

Closed this issue · 3 comments

The postprocessor of a string literal is not a factory function:

Foo -> "foo"
{"name": "Foo$string$1", "symbols": [{"literal":"f"}, {"literal":"o"}, {"literal":"o"}], "postprocess": function joiner(d) {return d.join('');}}

// as compared to a factory-function:
{"name": "Statement", "symbols": ["Statement$string$1"], "postprocess": factory(..)}

As such, there is no encode function for string literals, and this causes various errors.

It can be confirmed is an issue by adding a debug-log to the encode function:

        if (!Array.isArray(result)) { result = [result] }
        return result
+     } else {
+       console.error('no encode function for ' + rule.name)
      }
no encode function for Statement$string$1

(When no encode function exists on the rule.postprocess value, encode returns undefined. The caller of encode, expand, then skips ahead (array = encode(rule, value); if (!array) continue), which leads to best never being modified from undefined, which leads to sequence being undefined, which finally causes a crash in flatten (from for (let item of obj.sequence) {..}). Stack tracebacks in human language for the win!)

I'm obviously missing something! (Unfortunately looking at tosh2 didn't lead me anywhere.) So - how are string literals meant to be used with nearley-reverse..?

tjvr commented

They're not! tosh2 uses a lexer, and so avoids this problem. :-)

Oh, that's cool.

I suppose I'll look at this, then?

edit: and maybe tosh2's usage of it, of course.

tjvr commented

Yup! :)