librelist archives

« back to archive

Scoping for 'parse' method on generated parser

Scoping for 'parse' method on generated parser

From:
Nathan Stults
Date:
2010-11-09 @ 20:48
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

Re: [jison] Scoping for 'parse' method on generated parser

From:
Zachary Carter
Date:
2010-11-10 @ 00:53
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

Re: [jison] Scoping for 'parse' method on generated parser

From:
Nathan Stults
Date:
2010-11-10 @ 00:58
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