我有一个规则,看起来像这样:
INTEGER : [0-9]+;
myFields : uno=INTEGER COMMA dos=INTEGER
现在要访问uno,我需要编码:
Integer i = Integer.parseInt(myFields.uno.getText())
如果我能让鹿角帮我做那个转换,那会干净得多;那么我只需要编码:
Integer i = myFields.uno
我有什么选择?
您可以将代码编写为操作,但它仍然是显式转换(最终)。解析器(像每个解析器一样)解析文本,然后通过"解析事件"(通过监听器、访问者或ANTLR4中的操作实现)来创建有意义的结构/对象。
当然,您可以扩展一些生成的或内置的类,然后直接获取类型,但如前所述,在某个时刻,您总是需要将文本转换为所需的某种类型。
处理令牌自定义操作的标准方法是将它们嵌入到自定义令牌类中:
public class MyToken extends CommonToken {
....
public Integer getInt() {
return Integer.parseInt(getText()); // TODO: error handling
}
}
同时创建
public class MyTokenFactory extends TokenFactory { .... }
以获取自定义令牌。使用Lexer#setTokenFactory()
将工厂添加到lexer。
在自定义TokenFactory
中,覆盖方法
Symbol create(int type, String text); // (typically override both factory methods)
以构建并返回新的CCD_ 3。
假设签名包括目标令牌类型type
,则可以返回自定义类型特定的令牌子类,每个子类都有自己的自定义方法。
不过有几个问题。首先,在实践中,通常不需要它:赋值var是静态类型的,因此在OP示例中,
options { TokenLabelType = "MyToken"; }
Integer i = myFields.uno.getInt(); // no cast required
如果需要Integer&应使用getInt()
。如果布尔。。。。
其次,ANTLR选项允许设置TokenLabelType
以排除手动铸造自定义令牌的要求。只支持使用一种令牌标签类型。因此,要使用多种令牌类型,需要手动强制转换。