Added semantic check for duplicate local variable declaration

master
Apoorva Ranade 3 years ago
parent b758a071dc
commit 92e6688289

@ -8,11 +8,15 @@ import java.util.List;
/** Semantic information for a function or method. */
public class FuncType extends Type {
/** Function's name. */
//public final String name;
/** Types of parameters. */
public final List<ValueType> parameters;
public List<ValueType> parameters;
/** Function's return type. */
public final ValueType returnType;
/** Create a FuncType returning RETURNTYPE0, initially parameterless. */
public FuncType(ValueType returnType0) {
this(new ArrayList<>(), returnType0);

@ -2,15 +2,14 @@ package chocopy.pa2;
import chocopy.common.analysis.AbstractNodeAnalyzer;
import chocopy.common.analysis.SymbolTable;
import chocopy.common.analysis.types.Type;
import chocopy.common.analysis.types.ValueType;
import chocopy.common.analysis.types.*;
import chocopy.common.astnodes.*;
/** Analyzes declarations to create a top-level symbol table. */
public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
/** Current symbol table. Changes with new declarative region. */
private final SymbolTable<Type> sym = new SymbolTable<>();
private SymbolTable<Type> sym = new SymbolTable<>();
/** Global symbol table. */
private final SymbolTable<Type> globals = sym;
/** Receiver for semantic error messages. */
@ -30,9 +29,8 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
for (Declaration decl : program.declarations) {
Identifier id = decl.getIdentifier();
String name = id.name;
Type type = decl.dispatch(this);
if (type == null) {
continue;
}
@ -52,4 +50,63 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type> {
public Type analyze(VarDef varDef) {
return ValueType.annotationToValueType(varDef.var.type);
}
@Override
public Type analyze(FuncDef node) {
FuncType current_func=new FuncType((ValueType) node.returnType.dispatch(this));
SymbolTable current_scope=new SymbolTable<>(sym);
sym=current_scope;
for (TypedVar param : node.params)
{
if (sym.declares(param.identifier.name))
{
errors.semError(
node.name, "Duplicate declaration of identifier in same " + "scope: %s", param.identifier.name);
continue;
}
/*
else if (sym.get(param.identifier.name)!= null)
{
System.out.println("Error:"+sym.get(param.identifier.name));
errors.semError(
node.name, "Parameter shadows class name: %s", param.identifier.name);
continue;
}*/
Type p = param.dispatch(this);
current_func.parameters.add((ValueType)p);
sym.put(param.identifier.name, p);
}
for (Declaration decl : node.declarations) {
Identifier id = decl.getIdentifier();
String name = id.name;
Type type = decl.dispatch(this);
if (type == null) {
continue;
}
if (sym.declares(name)) {
errors.semError(
id, "Duplicate declaration of identifier in same " + "scope: %s", name);
} else {
sym.put(name, type);
}
}
sym = sym.getParent();
return current_func;
}
@Override
public Type analyze(GlobalDecl node)
{
if (globals.declares(node.variable.name)==false)
{
errors.semError(
node.variable, "Not a global variable: %s", node.variable.name);
return null;
}
return globals.get(node.variable.name);
}
}

Loading…
Cancel
Save