10

在以前的 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) ; };

Ref.: 类似 Flex 的功能?

虽然,在最新版本的 Jison 中,这是无效的。charswords并且lines无法从解析器上下文中访问,从而产生错误。

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

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

4

2 回答 2

10

当前版本的 Jison 有一个名为的变量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的 try page上使用 Jison 0.4.13 进行了测试。

于 2015-08-13T03:47:54.820 回答
1

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

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

=>

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

于 2021-06-13T09:22:50.417 回答