jison icon indicating copy to clipboard operation
jison copied to clipboard

variables in yy seems to be reset back to initial value, is it expected behavior?

Open nnabuuu opened this issue 9 years ago • 2 comments

Here is a very simple example to re-produce this issue:

/* description: Reproduce the issue. */

/* lexical grammar */
%lex
%{
    yy.someArray3 = [];
    yy.someValue2 = 'someValue';
%}
%%

"a"+                   return 'A'
"b"+                   return 'B'
\s+                   /* skip whitespace */
<<EOF>>               return 'EOF'

/lex

/* operator associations and precedence */

%start ab 

%% /* language grammar */

ab
    : c d EOF
    {return $1 + $2;}
    ;

c
    : A
        {

            yy.someValue = $1;
            yy.someValue2 = $1;
            yy.someArray = [$1];
            yy.someArray2 = [];
            yy.someArray2.push($1);
            yy.someArray3.push($1);
            console.log(yy);
            $$ = $1;
        }
    ;

d
    : B
        { 
            console.log(yy);
            $$ = $1;
        }
    ;

When using this to parse "aaaaaaabb", the response is:

{ lexer:
   { yy: [Circular],
     _input: 'bb',
     done: false,
     _backtrack: false,
     _more: false,
     yyleng: 7,
     yylineno: 0,
     match: 'aaaaaaa',
     matched: 'aaaaaaa',
     yytext: 'aaaaaaa',
     conditionStack: [ 'INITIAL' ],
     yylloc: { first_line: 1, last_line: 1, first_column: 0, last_column: 7 },
     offset: 0,
     matches: [ 'aaaaaaa', index: 0, input: 'aaaaaaabb' ] },
  parser: { yy: {}, parseError: [Function: parseError] },
  someArray3: [ 'aaaaaaa' ],
  someValue2: 'aaaaaaa',
  someValue: 'aaaaaaa',
  someArray: [ 'aaaaaaa' ],
  someArray2: [ 'aaaaaaa' ] }
{ lexer:
   { yy: [Circular],
     _input: '',
     done: false,
     _backtrack: false,
     _more: false,
     yyleng: 2,
     yylineno: 0,
     match: 'bb',
     matched: 'aaaaaaabb',
     yytext: 'bb',
     conditionStack: [ 'INITIAL' ],
     yylloc: { first_line: 1, last_line: 1, first_column: 7, last_column: 9 },
     offset: 0,
     matches: [ 'bb', index: 0, input: 'bb' ] },
  parser: { yy: {}, parseError: [Function: parseError] },
  someArray3: [],
  someValue2: 'someValue',
  someValue: 'aaaaaaa',
  someArray: [ 'aaaaaaa' ],
  someArray2: [ 'aaaaaaa' ] }

Here you see, yy.someArray3 and yy.someValue2 is set back to the defined values.

Is this the expected behavior?

nnabuuu avatar Apr 14 '16 07:04 nnabuuu

Yes.

The %{...%} block where you set up those values is invoked every time at the start of a rule reduction. In other words: think of that code chunk as being prefixed before every rule action code block.

As other rules will be 'reduced' (~ their action code chunks will be executed) after rule c: A gets reduced and before the parse finishes, you will effectively execute that %{...%} code chunk at the top a few more times, producing exactly the result you are seeing in your example.

GerHobbelt avatar Sep 18 '16 23:09 GerHobbelt

Thanks for the explanation.

nnabuuu avatar Sep 20 '16 03:09 nnabuuu