antlr global rule scope declaration vs @members de

2020-07-09 03:12发布

问题:

Which one would you prefer to declare a variable in which case, global scope or @members declaration? It seems to me that they can serve for same purpose?

UPDATE here is a grammar to explain what i mean.

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';

回答1:

Note that besides global (ANTLR) scopes, you can also have local rule-scopes, like this:

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

The only time I'd consider using local rule-scopes is when there are a lot of predicates, or global backtracking is enabled (resulting in all rules to have predicates in front of them). In that case, you could create a member variable String x (or define it in a global scope) and set it in the parse rule, but you might be changing this instance/scope variable after which the parser could backtrack, and this backtracking will not cause the global variable to be set to it's original form/state! The local scoped variable will also not be "unset", but that will likely be less of a risk: them being local to a single rule.

To summarize: yes, you're right, global scopes and member/instance variables are much alike. But I'd sooner opt for members-variables because of the friendlier syntax.



标签: antlr antlr3