Hello again,
I am using a modified version of the calculator.jison sample to build a
simple expression evaluator for javascript. This task is simple enough I
don't want to build out and evaluate an AST, so, like the calculator
example, all the work is being done inline in the grammar. However, I'm
stumped on thing. Given that the generated parser is a static variable,
I'm presuming that it is threadsafe. In my expression language
definition, I want to give users of the language the ability to supply
variable values. I'm doing that like this in my expression definitions
(assuming expr.jison results in a module named "expr" and is therefore a
global variable to the parser)
| IDENTIFIER
{{
$$ = expr.resolveIdentifierValue(yyname)
}}
Of course that is greatly simplified, but the point is that when setting
up a user of this language could do this:
expr.resolveIdentifierValue = function(identifierName) {
return "Well hello there";
}
However, this is NOT threadsafe. Maybe thread safety in JS isn't a real
concern? I guess in Node.js everything is evented, and I'm not sure how
the browsers are threaded. But in previous expression languages I've
written, this would be dangerous, so I'd rather do something like this:
| IDENTIFIER
{{
$$ = context.resolveIdentifierValue(yyname)
}}
Where context comes from something like this, using a closure to wrap
some local data that can be used to resolve identifiers:
my_data = {identifier:"hi", other_identifier:"ho"}
context = {resolveIdentifierValue : function(name){ return
my_data[name];}}
expr.parse("identifier == other_identifier", context);
Is there any way to achieve this, or something similar, without
modifying the generated parser javascript?
Thank you very much for your time,
Nathan Stults
On Tue, Nov 9, 2010 at 3:48 PM, Nathan Stults <Nathan_Stults@hsihealth.com>wrote: > Hello again, > > > > I am using a modified version of the calculator.jison sample to build a > simple expression evaluator for javascript. This task is simple enough I > don’t want to build out and evaluate an AST, so, like the calculator > example, all the work is being done inline in the grammar. However, I’m > stumped on thing. Given that the generated parser is a static variable, I’m > presuming that it is threadsafe. In my expression language definition, I > want to give users of the language the ability to supply variable values. > I’m doing that like this in my expression definitions (assuming expr.jison > results in a module named “expr” and is therefore a global variable to the > parser) > > > > | ID ENTIFIER > > {{ > > $$ = expr.resolveIdentifierValue(yyname) > > }} > > > > Of course that is greatly simplified, but the point is that when setting up > a user of this language could do this: > > > > expr.resolveIdentifierValue = function(identifierName) { > > return “Well hello there”; > > } > > > > However, this is NOT threadsafe. Maybe thread safety in JS isn’t a real > concern? I guess in Node.js everything is evented, and I’m not sure how the > browsers are threaded. But in previous expression languages I’ve written, > this would be dangerous, so I’d rather do something like this: > > > > | IDENTIFIER > > {{ > > $$ = context.resolveIdentifierValue(yyname) > > }} > > > > Where context comes from something like this, using a closure to wrap some > local data that can be used to resolve identifiers: > > my_data = {identifier:”hi”, other_identifier:”ho”} > > context = {resolveIdentifierValue : function(name){ return my_data[name];}} > > expr.parse(“identifier == other_identifier”, c ontext); > > > > Is there any way to achieve this, or something similar, without modifying > the generated parser javascript? > > > > Thank you very much for your time, > > > > Nathan Stults > The context variable you seek is the yy variable. (You can find a bit of explanation here: http://zaach.github.com/jison/docs/#sharing-scope) Taking your example, it would be used like this: my_data = {identifier:”hi”, other_identifier:”ho”}; context = {resolveIdentifierValue : function(name){ return my_data[name];}}; expr.yy = context; expr.parse(“identifier == other_identifier”); And in your grammar: | IDENTIFIER {{ $$ = yy.resolveIdentifierValue(yyname) }} -- Zach Carter
Thank you very much, that will do the trick.
From: jison@librelist.com [mailto:jison@librelist.com] On Behalf Of Zachary Carter
Sent: Tuesday, November 09, 2010 4:53 PM
To: jison@librelist.com
Subject: Re: [jison] Scoping for 'parse' method on generated parser
On Tue, Nov 9, 2010 at 3:48 PM, Nathan Stults <Nathan_Stults@hsihealth.com> wrote:
Hello again,
I am using a modified version of the calculator.jison sample to build a
simple expression evaluator for javascript. This task is simple enough I
don’t want to build out and evaluate an AST, so, like the calculator
example, all the work is being done inline in the grammar. However, I’m
stumped on thing. Given that the generated parser is a static variable,
I’m presuming that it is threadsafe. In my expression language definition,
I want to give users of the language the ability to supply variable
values. I’m doing that like this in my expression definitions (assuming
expr.jison results in a module named “expr” and is therefore a global
variable to the parser)
| ID ENTIFIER
{{
$$ = expr.resolveIdentifierValue(yyname)
}}
Of course that is greatly simplified, but the point is that when setting
up a user of this language could do this:
expr.resolveIdentifierValue = function(identifierName) {
return “Well hello there”;
}
However, this is NOT threadsafe. Maybe thread safety in JS isn’t a real
concern? I guess in Node.js everything is evented, and I’m not sure how
the browsers are threaded. But in previous expression languages I’ve
written, this would be dangerous, so I’d rather do something like this:
| IDENTIFIER
{{
$$ = context.resolveIdentifierValue(yyname)
}}
Where context comes from something like this, using a closure to wrap some
local data that can be used to resolve identifiers:
my_data = {identifier:”hi”, other_identifier:”ho”}
context = {resolveIdentifierValue : function(name){ return my_data[name];}}
expr.parse(“identifier == other_identifier”, c ontext);
Is there any way to achieve this, or something similar, without modifying
the generated parser javascript?
Thank you very much for your time,
Nathan Stults
The context variable you seek is the yy variable. (You can find a bit of
explanation here: http://zaach.github.com/jison/docs/#sharing-scope)
Taking your example, it would be used like this:
my_data = {identifier:”hi”, other_identifier:”ho”};
context = {resolveIdentifierValue : function(name){ return my_data[name];}};
expr.yy = context;
expr.parse(“identifier == other_identifier”);
And in your grammar:
| IDENTIFIER
{{
$$ = yy.resolveIdentifierValue(yyname)
}}
--
Zach Carter