Jison全局变量

时间:2015-05-31 20:06:37

标签: compiler-construction flex-lexer jison

在以前的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中运作?

2 个答案:

答案 0 :(得分:8)

当前版本的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进行了测试。

答案 1 :(得分:1)

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

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

=>

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