我在看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的书或网上找到一个例子。
根据特定的编译器,这是在上下文分析/类型检查中完成的,在解析树的演练中完成。这是通过用类型"装饰"树来完成的。这将把"string"作为类型放在"helloworld!"节点上,把"float"放在声明节点上。编译器将能够发现错误并给出错误消息。
是的,这是与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;
}
显然,这需要您使用"type"one_answers"typeCorrect"属性创建自己的节点。具体来说,这种方法相当简单。当您访问特定的表达式时,您可以根据那里的类型设置类型。例如,在您的示例中,表达式将是赋值的"hello world"
部分。当我访问特定节点(假设它被称为StringExpr
)时,我将"type"属性设置为String,并对赋值节点执行同样的操作,我将其设置为"Float"。然后我可以看到,赋值和表达式不对应,并且可能引发错误。