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