Jison 全局变量

Jison global variables

在以前的 Jison 版本中,可以具有类似 Flex 的功能,允许定义在词法分析器和解析器上下文中都可访问的变量,例如:

%{
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) ; };

参考: Flex like features?

不过,在最新版本的 Jison 中,这是无效的。无法从解析器上下文访问 charswordslines,从而生成错误。

搜索更多关于新版本的信息,我发现应该可以通过在 %{ ... %} 内部的解析器上下文中定义输出来实现,但它不起作用,尽管它用于多行声明。我正在从源代码生成目标语言的代码,我将美化这段代码,应用正确的缩进,由范围控制并直接从解析器生成,而不构建 AST。

全局定义目前在 Jison 中如何工作?

当前版本的 Jison 有一个 variable named yy 其目的是允许在词法动作、语义动作和其他模块之间共享数据。如果您将所有这些变量存储在 yy 中,您的代码示例就可以工作,如下所示:

%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); };

以上代码已在 Jison's try page.

上使用 Jison 0.4.13 进行测试

作为对 Govind Mantri 的建议,而不是在 'if' 中使用 'chars',你应该使用一个变量而不是使用它,例如 'cities'。连接问题也发生在我身上,但我解决了它。

if (!('chars' in yy)) { yy.cities = ["奥斯汀","New_York","芝加哥","Las_Vegas"];

=>

if (!('cities' in yy)) { yy.cities = ["奥斯汀","New_York","芝加哥","Las_Vegas"];