Added Some Semantice Checks
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
Bruder John 2024-06-27 08:11:17 +02:00
parent 8163d0b61e
commit 35b3e9ee46
7 changed files with 116 additions and 53 deletions

View File

@ -150,6 +150,9 @@ public class SemanticAnalyzer implements SemanticVisitor {
if (resultType == null) {
resultType = new BaseType(TypeEnum.VOID);
}
if(methodNode.getType() == null){
methodNode.setType(new BaseType(TypeEnum.VOID));
}
if (!resultType.equals(methodNode.getType())) {
errors.add(new TypeMismatchException("Method-Declaration " + methodNode.getIdentifier() + " with type "
+ methodNode.getType() + " has at least one Mismatching return Type:"));
@ -179,13 +182,13 @@ public class SemanticAnalyzer implements SemanticVisitor {
@Override
public TypeCheckResult analyze(ReturnNode toCheck) {
if(toCheck.expression != null){
if (toCheck.expression != null) {
var result = toCheck.expression.accept(this);
return new TypeCheckResult(true, result.getType());
} else {
return new TypeCheckResult(false, null);
} else if(toCheck.voidReturn){
return new TypeCheckResult(false, new BaseType(TypeEnum.VOID));
}
return new TypeCheckResult(true, null);
}
@ -206,8 +209,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
ITypeNode blockReturnType = null;
for (IStatementNode statementNode : blockNode.statements) {
var result = statementNode.accept(this);
if(result.getType() != null){
if(blockReturnType == null){
if (result.getType() != null) {
if (blockReturnType == null) {
blockReturnType = result.getType();
} else {
errors.add(new MultipleReturnTypes("There are multiple Return types"));
@ -219,7 +222,14 @@ public class SemanticAnalyzer implements SemanticVisitor {
@Override
public TypeCheckResult analyze(AssignableNode toCheck) {
return new TypeCheckResult(true, currentFields.get(toCheck.identifier));
if ( currentFields.get(toCheck.identifier) != null){
return new TypeCheckResult(true, currentFields.get(toCheck.identifier));
} else if (currentScope.getLocalVar(toCheck.identifier) != null) {
return new TypeCheckResult(true, currentScope.getLocalVar(toCheck.identifier));
}
return new TypeCheckResult(true, null);
}
@ -228,11 +238,6 @@ public class SemanticAnalyzer implements SemanticVisitor {
return null;
}
/*@Override
public TypeCheckResult analyze(ForNode toCheck) {
return null;
}*/
@Override
public TypeCheckResult analyze(AssignNode toCheck) {
AssignableNode assignable = toCheck.assignable;
@ -258,7 +263,12 @@ public class SemanticAnalyzer implements SemanticVisitor {
currentNullType = lResult.getType();
var rResult = rExpression.accept(this);
if (!Objects.equals(currentScope.getLocalVar(toCheck.assignable.identifier), rExpression.getType())) {
var variable = currentScope.getLocalVar(toCheck.assignable.identifier);
if(variable == null){
variable = currentFields.get(toCheck.assignable.identifier);
}
if (!Objects.equals(variable, rExpression.getType())) {
errors.add(new TypeMismatchException(
"Mismatch types in Assign-Statement: cannot convert from \"" + lResult.getType() + "\" to \""
+ rResult.getType() + "\""));
@ -273,8 +283,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
}
@Override
public TypeCheckResult analyze(DecrementNode toCheck) {
return null;
public TypeCheckResult analyze(DecrementNode decrementNode) {
return decrementNode.assignableExpression.accept(this);
}
@Override
@ -284,6 +294,27 @@ public class SemanticAnalyzer implements SemanticVisitor {
@Override
public TypeCheckResult analyze(MethodCallNode toCheck) {
var targetType = currentScope.getLocalVar(toCheck.target.identifier);
if(targetType == null){
targetType = currentFields.get(toCheck.target.identifier);
}
if(targetType instanceof ReferenceType reference){
var classContext = context.getClass(reference.getIdentifier());
if(classContext == null){
errors.add(new NotDefinedException(toCheck.target.identifier + "is not Defined"));
}else {
var methods = classContext.getMethods();
for (var method : methods) {
if(toCheck.identifier.equals(method.getIdentifier()) && method.getParameters().size() == toCheck.parameters.size()){
return new TypeCheckResult(true, method.getType());
}
}
}
} else {
}
return null;
}
@ -316,12 +347,17 @@ public class SemanticAnalyzer implements SemanticVisitor {
@Override
public TypeCheckResult analyze(NewDeclarationNode toCheck) {
if(context.containsClass(toCheck.identifier)) {
return new TypeCheckResult(true, new ReferenceType(toCheck.identifier));
}
return null;
}
@Override
public TypeCheckResult analyze(IncrementNode toCheck) {
return null;
return toCheck.assignableExpression.accept(this);
}
@Override
@ -357,13 +393,17 @@ public class SemanticAnalyzer implements SemanticVisitor {
var valid = true;
if (currentScope.contains(unary.identifier)) {
return new TypeCheckResult(valid, currentScope.getLocalVar(unary.identifier));
} else if(currentFields.get(unary.identifier) != null) {
return new TypeCheckResult(valid, currentFields.get(unary.identifier));
return new TypeCheckResult(valid, currentScope.getLocalVar(unary.identifier));
} else if (currentFields.get(unary.identifier) != null) {
return new TypeCheckResult(valid, currentFields.get(unary.identifier));
} else if (unary.statement != null) {
var result = unary.statement.accept(this);
unary.setType(result.getType());
return result;
} else {
errors.add(new NotDeclearedException("Var is not Decleared"));
}
return new TypeCheckResult(valid, null);
}
}
}

View File

@ -2,11 +2,15 @@ package semantic.context;
import ast.ClassNode;
import ast.members.FieldNode;
import ast.members.MethodNode;
import java.util.ArrayList;
import java.util.HashMap;
public class ClassContext {
private HashMap<String, FieldContext> fields;
private ArrayList<MethodNode> methods = new ArrayList<>();
public ClassContext(ClassNode classNode) {
@ -15,6 +19,8 @@ public class ClassContext {
classNode.members.forEach(member -> {
if(member instanceof FieldNode fieldNode) {
fields.put(fieldNode.identifier, new FieldContext(fieldNode));
}else if(member instanceof MethodNode methodNode) {
methods.add(methodNode);
}
});
@ -24,4 +30,8 @@ public class ClassContext {
return fields.get(name);
}
public ArrayList<MethodNode> getMethods() {
return methods;
}
}

View File

@ -21,4 +21,8 @@ public class Context {
return classes.get(identifier);
}
public boolean containsClass(String identifier) {
return classes.containsKey(identifier);
}
}

View File

@ -0,0 +1,9 @@
package semantic.exeptions;
public class NotDefinedException extends RuntimeException {
public NotDefinedException(String message) {
super(message);
}
}

View File

@ -50,7 +50,7 @@ public class EndToTAST {
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
assertEquals(SemanticAnalyzer.errors.size(), 0);
assertEquals(0, SemanticAnalyzer.errors.size());
assertNotNull(tast);
}
@ -255,28 +255,4 @@ public class EndToTAST {
}
@Test
public void wrongTypeInIfClause(){
CharStream codeCharStream = null;
try {
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/WrongIfClause.java"));
} catch (IOException e) {
throw new RuntimeException(e);
}
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
ParseTree parseTree = parser.program();
ASTBuilder astBuilder = new ASTBuilder();
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
assertFalse(SemanticAnalyzer.errors.isEmpty());
}
}

View File

@ -2,10 +2,41 @@ public class Example {
public int a;
public static int testMethod(int b, boolean bo){
public Car c;
public void test(){
c = new Car();
int speed = c.getSpeed();
}
public static int testReturnMethod(int b, boolean bo){
a = b;
return a;
}
public void testOjektMethod(int testInt){
Test testClass = new Test();
int b = testClass.getFirstInt(testInt);
}
}
public class Test {
public int firstInt;
public int getFirstInt(int b){
return firstInt--;
}
}
public class Car{
private int speed;
public int getSpeed(){
return speed;
}
}

View File

@ -1,7 +0,0 @@
public class Example {
public static void testMethod(int x){
}
}