zaach / jison

Bison in JavaScript.
http://jison.org
4.36k stars 450 forks source link

Question - how to provide a context? #371

Open ca0v opened 6 years ago

ca0v commented 6 years ago

Presently, the parse function only accepts a single input parameter:

parse: function parse(input) {
  // outside dependencies must be global
}

I'm looking for a way to pass in a parsing context to contain outside dependencies:

parse: function parse(input, context) {
  // can now reference outside dependencies via context
}

So that I could do this:

parse("POINT(1 2)", {PointArray: PointArray});

And reference "context" in my grammar:

coordinate
    : DOUBLE_TOK DOUBLE_TOK
        { $$ = new context.PointArray([ Number($1), Number($2) ]); }

I'm not seeing a way to do this and I've noticed projects which use a grunt script to swap the jison output into a code template. Is that the desired/expected use case?

GerHobbelt commented 6 years ago

You can extend the parse() interface using the %parse-param arg1, arg2, arg3... option in your jison grammar top section.

arg1... is a list of 1..n arguments which are added to the function call interface as second, third, etc. parameter, producing something like this:

parser.parse = function yyparse(input, arg1, arg2, arg3) {...}

in the generated parser code. These extra args are available as-is in your production rule action code blocks, so you can reference them easily, e.g.

rule: termA termB termC {
  // sample action code
  $$ = sum(arg1 /* ref to %parse-params arg1 */, $termA, $termB, $termC);
};

This is a simile (not exactly a copy, but same intent; bison's is C/C++-specific) of the bison %parse-param feature.

XRefs:

hugozap commented 4 years ago

I was having issues accessing the arguments and had to use yy.argumentName from inside the rule action (I'm using @GerHobbelt fork, not sure if that's relevant)