Added Test for Semantic Analyzier

This commit is contained in:
Bruder John 2024-05-14 17:47:26 +02:00
parent 7906a38cdd
commit 8b9b70b9ee
7 changed files with 117 additions and 11 deletions

View File

@ -40,7 +40,7 @@
</list> </list>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

View File

@ -32,7 +32,7 @@ public class Main {
} }
static void parsefile(CharStream codeCharStream) { static void parseFile(CharStream codeCharStream) {
/* ------------------------- Scanner -> tokens ------------------------- */ /* ------------------------- Scanner -> tokens ------------------------- */
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream); SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer); CommonTokenStream tokenStream = new CommonTokenStream(lexer);
@ -73,8 +73,8 @@ public class Main {
/* /*
* ------------------------- Semantic Analyzer -> Tast ------------------------- * ------------------------- Semantic Analyzer -> Tast -------------------------
*/ */
SemanticAnalyzer.generateTast(abstractSyntaxTree); SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer();
ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); ProgramNode typedAst = (ProgramNode) semanticAnalyzer.generateTast(abstractSyntaxTree);
// Printing the Tast // Printing the Tast
System.out.println("Tast generated"); System.out.println("Tast generated");

View File

@ -1,5 +1,6 @@
package ast; package ast;
import ast.type.TypeNode;
import semantic.SemanticVisitor; import semantic.SemanticVisitor;
import typechecker.TypeCheckResult; import typechecker.TypeCheckResult;
import visitor.Visitable; import visitor.Visitable;
@ -7,14 +8,14 @@ import visitor.Visitable;
public class VarNode implements ASTNode, Visitable { public class VarNode implements ASTNode, Visitable {
private String identifier; private String identifier;
private String type; private TypeNode type;
public VarNode(String type, String identifier){ public VarNode(TypeNode type, String identifier){
this.type = type; this.type = type;
this.identifier = identifier; this.identifier = identifier;
} }
public String getType(){ public TypeNode getType(){
return type; return type;
} }

View File

@ -144,7 +144,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
@Override @Override
public ASTNode visitVar(SimpleJavaParser.VarContext ctx) { public ASTNode visitVar(SimpleJavaParser.VarContext ctx) {
return new VarNode("int", ctx.getText()); return new VarNode(new BaseTypeNode(EnumTypeNode.INT), ctx.getText());
} }
@Override @Override

View File

@ -22,12 +22,12 @@ import typechecker.TypeCheckResult;
public class SemanticAnalyzer implements SemanticVisitor { public class SemanticAnalyzer implements SemanticVisitor {
private ArrayList<String> currentFields = new ArrayList<>(); private static ArrayList<String> currentFields = new ArrayList<>();
public static ArrayList<Exception> errors = new ArrayList<>(); public static ArrayList<Exception> errors = new ArrayList<>();
private Scope currentScope; private static Scope currentScope;
private ClassNode currentClass; private static ClassNode currentClass;
public static ASTNode generateTast(ASTNode node) { public static ASTNode generateTast(ASTNode node) {
SemanticAnalyzer semanticCheck = new SemanticAnalyzer(); SemanticAnalyzer semanticCheck = new SemanticAnalyzer();
@ -43,6 +43,13 @@ public class SemanticAnalyzer implements SemanticVisitor {
return null; return null;
} }
public static void clearAnalyzier(){
currentFields.clear();
errors.clear();
currentScope = null;
currentClass = null;
}
@Override @Override
public TypeCheckResult analyze(ProgramNode node) { public TypeCheckResult analyze(ProgramNode node) {

View File

@ -0,0 +1,98 @@
package semantic;
import ast.*;
import ast.expression.ExpressionNode;
import ast.member.FieldNode;
import ast.member.MemberNode;
import ast.member.MethodNode;
import ast.parameter.ParameterListNode;
import ast.parameter.ParameterNode;
import ast.statement.AssignmentStatementNode;
import ast.statement.StatementNode;
import ast.type.AccessTypeNode;
import ast.type.BaseTypeNode;
import ast.type.EnumAccessTypeNode;
import ast.type.EnumTypeNode;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import semantic.exeptions.AlreadyDeclearedException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class SemanticTester {
@BeforeEach
public void init() {
SemanticAnalyzer.clearAnalyzier();
}
@Test
public void alreadyDeclaredLocalFieldVar(){
ProgramNode programNode = new ProgramNode();
List<ClassNode> classList = new ArrayList<ClassNode>();
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
classNode.members.add(memberNode1);
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar");
classNode.members.add(memberNode2);
classList.add(classNode);
programNode.classes = classList;
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
assertEquals(1, SemanticAnalyzer.errors.size());
assertEquals(true, SemanticAnalyzer.errors.get(0) instanceof AlreadyDeclearedException);
assertEquals(null, typedAst);
}
@Test
public void shouldWorkWithNoError(){
ProgramNode programNode = new ProgramNode();
List<ClassNode> classList = new ArrayList<ClassNode>();
AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC);
ClassNode classNode = new ClassNode(accessTypeNode, "testClass");
MemberNode memberNode1 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar1");
classNode.members.add(memberNode1);
MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2");
classNode.members.add(memberNode2);
List<ParameterNode> parameterNodeList = new ArrayList<ParameterNode>();
ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1");
parameterNodeList.add(parameterNode1);
ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList);
List<StatementNode> statementNodeList = new ArrayList<StatementNode>();
VarNode varNode = new VarNode(new BaseTypeNode(EnumTypeNode.INT), "localVar1");
ExpressionNode expressionNode = new LiteralNode(1);
StatementNode statementNode1 = new AssignmentStatementNode(varNode, expressionNode);
statementNodeList.add(statementNode1);
MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList );
classNode.members.add(memberNode3);
classList.add(classNode);
programNode.classes = classList;
ASTNode typedAst = SemanticAnalyzer.generateTast(programNode);
assertEquals(0, SemanticAnalyzer.errors.size());
assertEquals(programNode, typedAst);
}
}