optionalFromTokenFromClause!
: (FROM!)? f:path (a:asAlias)? {
AST #range = #([RANGE, "RANGE"], #f, #a);
#optionalFromTokenFromClause = #([FROM, "FROM"], #range);
}
;
这个看起来比较麻烦,仔细分析也没什么。
1、f:path表示的就是表名,(a:asAlias)就是别名,(a:asAlias)?就是别名可有可无。path是另一个规则的定义:
path
: identifier ( DOT^ { weakKeywords(); } identifier )*
;
f:path定义了一个变量,变量的类型就是path。定义一个变量的意思就是方便后边action中引用。
2、
{ AST #range = #([RANGE, "RANGE"], #f, #a);
#optionalFromTokenFromClause = #([FROM, "FROM"], #range);
}
这个部分是action的定义,定义的action会将其转化成java代码插入到生成的java代码中。action主要是为了更灵活的控制代码生成而设立的。
AST #range = #([RANGE, "RANGE"], #f, #a);
代表声明一个AST类型的变量#range,新定义一个“RANGE”作为根,f、a为子树的树,并将其赋值给#range。
#optionalFromTokenFromClause = #([FROM, "FROM"], #range);
也是,建立一个“FROM”做为根, #range为子树的树,并将其做为返回值返回(因为#optionalFromTokenFromClause和当前rule名字一致,所
以做为返回值)
When rule is the name of the enclosing rule, ANTLR will translate this into the variable containing the result AST for the
rule. This allows you to set the return AST for a rule or examine it from within an action. This can be used when AST
generation is on or suppressed for the rule or alternate. For example:
r! : a:A { #r = #a; }
Setting the return tree is very useful in combination with normal tree construction because you can have ANTLR do all the
work of building a tree and then add an imaginary root node such as:
decl : ( TYPE ID )+
{ #decl = #([DECL,"decl"], #decl); }
;
ANTLR allows you to assign to #rule anywhere within an alternative of the rule. ANTLR ensures that references of and
assignments to #rule within an action force the parser‘s internal AST construction variables into a stable state. After you
assign to #rule, the state of the parser‘s automatic AST construction variables will be set as if ANTLR had generated the
tree rooted at #rule. For example, any children nodes added after the action will be added to the children of #rule.
alias
: a:identifier { #a.setType(ALIAS); }
别名也是一个标识符的实例,而标识符又有setType方法,这个方法可以用来表示标识符到底是什么类型的。