Depending on the specific compiler, this is done in the contextual analysis/ typechecking - in the walkthrough of the parse tree. It is done by "decorating" the tree with types. This would put "string" as a type on the "hello world!" node, and "float" on the declaration node. The compiler would then be able to spot the mistake and give an error message.
Yes, it is done with the visitors provided with ANTLR. You can extend the BaseVisitor class to create your own visitor methods, in which you do the decoration and type checking. An example underneath from one of my own projects:
@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;
}
Obviously this requires you to have created your own nodes with the "type" and "typeCorrect" attributes. Concretely, this method is quite simple. When you visit a specific expression, you set the type depending on which type you have there. For example, an expression would be the "hello world"
part of the assignment in your example. When I visit the specific node (let's say it's called StringExpr
) I set the "type" attribute to String, and I do the same for the assignment node, which I set to "Float". I can then see, that the assignment and expression does not correspond, and can throw an error.