ANTLR4 验证用户定义的类型匹配

ANTLR4 Validating user-defined types match

我在看 Antlr v4 语法。特别是 Java 示例。

https://github.com/antlr/grammars-v4/blob/master/java/Java.g4

我注意到使用提供的语法,下面的输入是有效的。

public class HelloWorld { 
    public static void main(String[] args) { 
       Float f = "hello world!";
    }
}

显然我们都知道这不是 Java 中的有效陈述。你如何在 Antlr4 中使它无效并抛出错误?我怀疑您是在 BaseVisitor 生成的函数中执行此操作,但我正在努力在 Antlr4 书籍或网上找到示例。

根据特定的编译器,这是在上下文分析/类型检查中完成的——在分析树的演练中。它是由 "decorating" 带有类型的树完成的。这会将 "string" 作为类型放在 "hello world!" 节点上,而 "float" 放在声明节点上。然后编译器将能够发现错误并给出错误消息。

是的,这是用 ANTLR 提供的访问者完成的。您可以扩展 BaseVisitor class 来创建您自己的访问者方法,您可以在其中进行修饰和类型检查。下面是我自己的项目之一的示例:

@Override
public Node visitEqCond(EqCondNode node){
    CondNode left = (CondNode) visit(node.left);
    CondNode right = (CondNode) visit(node.right);

    if(left.type.equals("num") && right.type.equals("num") && left.typeCorrect && right.typeCorrect){
        node.type = "bool";
    }
    else{
        node.typeCorrect = false;
        if(!left.type.equals("num")){
            err.TypeNotApplicableInOperationError(left.type, node.operator, node.lineNumber);
        }
        if(!right.type.equals("num")){
            err.TypeNotApplicableInOperationError(right.type, node.operator, node.lineNumber);
        }
    }
    return node;
}

显然,这需要您使用 "type" 和 "typeCorrect" 属性创建自己的节点。具体来说,这个方法很简单。当你访问一个特定的表达式时,你可以根据你在那里的类型来设置类型。例如,表达式将是示例中赋值的 "hello world" 部分。当我访问特定节点(假设它称为 StringExpr)时,我将 "type" 属性设置为 String,并且我对赋值节点执行相同的操作,我将其设置为 "Float"。然后我可以看到,赋值和表达式不对应,并且会抛出错误。