正在Antlr中设置已解析值的类型



我有一个规则,看起来像这样:

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以排除手动铸造自定义令牌的要求。只支持使用一种令牌标签类型。因此,要使用多种令牌类型,需要手动强制转换。

最新更新