Jison global variables
Asked Answered
C

2

10

In previous versions of Jison, it was possible to have a Flex-like feature that allowed defining variables accessible in both the lexer and parser contexts, such as:

%{
var chars = 0;
var words = 0;
var lines = 0;
%}

%lex
%options flex

%%
\s
[^ \t\n\r\f\v]+ { words++; chars+= yytext.length; }
. { chars++; }
\n { chars++; lines++ }
/lex

%%
E : { console.log(lines + "\t" + words + "\t" + chars) ; };

Ref.: Flex like features?

Although, in the latest version of Jison, this isn't valid. chars, words and lines cannot be reached from the parser context, generating an error.

Searching more about the new version, I found that it should be possible by defining output, on parser's context, inside of %{ ... %}, but it doesn't work, although it is used for multi-line statements. I'm generating code from a source to a target language and I'll prettify this code, applying the correct indentation, controlled by the scope and generating directly from parser, without building an AST.

How do global definitions currently work in Jison?

Carrelli answered 31/5, 2015 at 20:6 Comment(0)
Q
10

The current version of Jison has a variable named yy whose purpose is to allow the sharing of data between lexical actions, semantic actions, and other modules. Your code sample can work if you store all those variables in yy as follows:

%lex
%options flex

%{
if (!('chars' in yy)) {
  yy.chars = 0;
  yy.words = 0;
  yy.lines = 1;
}
%}

%%
[^ \t\n\r\f\v]+ { yy.words++; yy.chars += yytext.length; }
. { yy.chars++; }
\n { yy.chars++; yy.lines++ }
/lex

%%
E : { console.log( yy.lines + "\t" + yy.words + "\t" + yy.chars); };

The above code was tested using Jison 0.4.13 on Jison's try page.

Quetzal answered 13/8, 2015 at 3:47 Comment(1)
for multiple Expressions this global variable is initialized different for every other E. in that scenario if I want to store values by concating a string its not working. Here is my grammar if u can suggest what changes do i have to make so that my variable $x can store all the value across all E. jsfiddle.net/Lnukko75/1Readable
M
1

As a suggestion for Govind Mantri, instead of using 'chars' in the 'if' you should use a variable than if it is used, for example 'cities'. The same thing happened to me with the concatenation problems, but with that I solved it.

if (!('chars' in yy)) { yy.cities = ["Austin","New_York","Chicago","Las_Vegas"];

=>

if (!('cities' in yy)) { yy.cities = ["Austin","New_York","Chicago","Las_Vegas"];

Marcellmarcella answered 13/6, 2021 at 9:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.