8

在哪种情况下,您更愿意声明一个变量,全局范围还是 @members 声明?在我看来,他们可以为同样的目的服务?

这里的更新是解释我的意思的语法。

grammar GlobalVsScope;

scope global{
  int i;
}
@lexer::header{package org.inanme.antlr;}
@parser::header{package org.inanme.antlr;}

@parser::members {
  int j;
}

start
scope global;
@init{
  System.out.println($global::i);
  System.out.println(j);
}:R EOF;

R:'which one';
4

1 回答 1

9

请注意,除了全局(ANTLR)范围之外,您还可以拥有本地规则范围,如下所示:

grammar T;

options { backtrack=true; }

parse
scope { String x; }
parse
 : 'foo'? ID {$parse::x = "xyz";} rule*
 | 'foo' ID
 ;

rule
 : ID {System.out.println("x=" + $parse::x);}
 ;  

我唯一考虑使用本地规则范围的情况是有很多谓词,或者启用了全局回溯(导致所有规则前面都有谓词)。在这种情况下,您可以创建一个成员变量String x(或在全局范围内定义它)并在parse规则中设置它,但您可能会更改此实例/范围变量,之后解析器可以回溯,并且此回溯不会导致全局变量设置为其原始形式/状态!本地范围变量也不会“未设置”,但这可能风险较小:它们是单个规则的本地变量。

总结一下:是的,你是对的,全局范围和成员/实例变量非常相似。但由于语法更友好,我会更早选择成员变量。

于 2012-05-16T10:21:46.430 回答