我在看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书籍或网上找到一个例子。
答案 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?