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

时间:2016-03-28 23:32:19

标签: java antlr antlr4 dsl

我在看Antlr v4 Grammars。特别是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书籍或网上找到一个例子。

2 个答案:

答案 0 :(得分:1)

根据具体的编译器,这在上下文分析/类型检查中完成 - 在解析树的演练中。这是由'#34;装饰"有类型的树。这会把"字符串"作为"你好世界的一种类型!"节点,"浮动"在声明节点上。然后,编译器将能够发现错误并给出错误消息。

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

@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;
}

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

答案 1 :(得分:0)

您可以通过利用语义谓词来实现。 看一下这篇文章:What is a 'semantic predicate' in ANTLR?