您希望在哪种情况下声明变量,全局范围或@members声明?在我看来,他们可以为同样的目的服务吗?
UPDATE 这是一个解释我的意思的语法。
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';
答案 0 :(得分:9)
请注意,除了全局(ANTLR)范围之外,您还可以拥有 local 规则范围,如下所示:
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
规则中设置它,但您可能正在更改此实例/ scope变量,之后解析器可以回溯,并且这个回溯将不导致全局变量被设置为它的原始形式/状态!本地范围的变量也将不“未设置”,但这可能不会带来风险:它们是单个规则的本地变量。
总结一下:是的,你是对的,全局范围和成员/实例变量非常相似。但是我会更快地选择成员变量,因为它具有更友好的语法。