diff --git a/src/main/java/Example.java b/src/main/java/Example.txt similarity index 70% rename from src/main/java/Example.java rename to src/main/java/Example.txt index 6657954..8c28495 100644 --- a/src/main/java/Example.java +++ b/src/main/java/Example.txt @@ -1,6 +1,7 @@ class Example { int test; + char test; } diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 258411a..165c82d 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -9,9 +9,6 @@ import parser.ASTBuilder; import parser.generated.SimpleJavaLexer; import parser.generated.SimpleJavaParser; import semantic.SemanticAnalyzer; -import ast.ClassNode; -import ast.ProgramNode; -import bytecode.ByteCodeGenerator; import java.io.IOException; import java.nio.file.Paths; @@ -20,7 +17,7 @@ public class Main { public static void main(String[] args) throws Exception { CharStream codeCharStream = null; try { - codeCharStream = CharStreams.fromPath(Paths.get("./Example.java")); + codeCharStream = CharStreams.fromPath(Paths.get("src/main/java/Example.txt")); parsefile(codeCharStream); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); @@ -42,7 +39,7 @@ public class Main { // Optionally print or process the AST System.out.println("Parsed " + ast.classes.size() + " classes with identifiers/names:"); for (ClassNode classNode : ast.classes) { - System.out.println(classNode.name); + System.out.println(classNode.identifier.getName()); } SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); diff --git a/src/main/java/ast/ClassNode.java b/src/main/java/ast/ClassNode.java index 7943b5a..46a64eb 100644 --- a/src/main/java/ast/ClassNode.java +++ b/src/main/java/ast/ClassNode.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; public class ClassNode extends ASTNode{ - public String name; + public Identifier identifier; public List members = new ArrayList<>(); public boolean hasConstructor = false; @@ -17,7 +17,7 @@ public class ClassNode extends ASTNode{ public void ensureConstructor(){ if(!hasConstructor) { - ConstructorNode constructor = new ConstructorNode(new TypeNode("public"), name); + ConstructorNode constructor = new ConstructorNode(new TypeNode("public"), identifier.getName()); members.add(0,constructor); } } diff --git a/src/main/java/ast/FieldNode.java b/src/main/java/ast/FieldNode.java index 948701f..4d30573 100644 --- a/src/main/java/ast/FieldNode.java +++ b/src/main/java/ast/FieldNode.java @@ -2,11 +2,11 @@ package ast; public class FieldNode extends MemberNode { public TypeNode type; - public String name; + public Identifier identifier; public FieldNode(TypeNode type, String name){ this.type = type; - this.name = name; + this.identifier = new Identifier(name); } } diff --git a/src/main/java/ast/Identifier.java b/src/main/java/ast/Identifier.java new file mode 100644 index 0000000..2f6fe73 --- /dev/null +++ b/src/main/java/ast/Identifier.java @@ -0,0 +1,27 @@ +package ast; + +public class Identifier { + + private String name; + + public Identifier(String name){ + this.name = name; + } + + public String getName(){ + return name; + } + + public boolean equals(Object obj) { + if(obj instanceof Identifier){ + Identifier identifier = (Identifier) obj; + if(name.equals(identifier.getName())){ + return true; + } else { + return false; + } + } + return super.equals(obj); + } + +} diff --git a/src/main/java/ast/MethodNode.java b/src/main/java/ast/MethodNode.java index b8e15f2..4dd77f4 100644 --- a/src/main/java/ast/MethodNode.java +++ b/src/main/java/ast/MethodNode.java @@ -5,7 +5,7 @@ import java.util.List; public class MethodNode extends MemberNode{ public TypeNode visibility; - public String name; + public Identifier identifier; public ParameterListNode parameters; @@ -14,13 +14,13 @@ public class MethodNode extends MemberNode{ public MethodNode(TypeNode visibility, String name, ParameterListNode parameters, List statements){ this.visibility = visibility; - this.name = name; + this.identifier = new Identifier(name); this.parameters = parameters; this.statements = statements; } public MethodNode(TypeNode visibility, String name){ this.visibility = visibility; - this.name = name; + this.identifier = new Identifier(name); } } diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index 619068a..7ce5506 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -10,7 +10,7 @@ import java.io.IOException; public class ClassCodeGen { public void generateClassCode(ClassNode classNode) { ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, classNode.name, null, + classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, classNode.identifier.getName(), null, "java/lang/Object", null); FieldCodeGen fieldCodeGen = new FieldCodeGen(); @@ -20,7 +20,7 @@ public class ClassCodeGen { methodCodeGen.generateMethodCode(classWriter); classWriter.visitEnd(); - printIntoClassFile(classWriter.toByteArray(), classNode.name); + printIntoClassFile(classWriter.toByteArray(), classNode.identifier.getName()); classWriter.visitEnd(); } diff --git a/src/main/java/parser/ASTBuilder.java b/src/main/java/parser/ASTBuilder.java index 6519cc1..42e3fcd 100644 --- a/src/main/java/parser/ASTBuilder.java +++ b/src/main/java/parser/ASTBuilder.java @@ -20,7 +20,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor { @Override public ASTNode visitClassDeclaration(SimpleJavaParser.ClassDeclarationContext ctx) { ClassNode classNode = new ClassNode(); - classNode.name = ctx.IDENTIFIER().getText(); + classNode.identifier = new Identifier(ctx.IDENTIFIER().getText()); for (SimpleJavaParser.MemberDeclarationContext member : ctx.memberDeclaration()) { classNode.addMember((MemberNode) visit(member)); } diff --git a/src/main/java/semantic/SemanticAnalyzer.java b/src/main/java/semantic/SemanticAnalyzer.java index e486d16..5e405e5 100644 --- a/src/main/java/semantic/SemanticAnalyzer.java +++ b/src/main/java/semantic/SemanticAnalyzer.java @@ -3,16 +3,20 @@ package semantic; import ast.*; +import java.util.ArrayList; import java.util.List; public class SemanticAnalyzer { + + List usedIdentifier = new ArrayList<>(); + public void analyze(ASTNode node) { if (node == null) return; if (node instanceof ClassNode) { ClassNode classNode = (ClassNode) node; - if(classNode.name == null){ + if(classNode.identifier == null){ System.out.println("Klasse besitzt keinen Identifier"); } @@ -24,6 +28,14 @@ public class SemanticAnalyzer { }else if (node instanceof ConstructorNode) { + }else if (node instanceof FieldNode) { + + FieldNode fieldNode = (FieldNode) node; + if(identifierAlreadyUsed(fieldNode.identifier)){ + throw new RuntimeException("Error: Identifier already used"); + } + usedIdentifier.add(fieldNode.identifier); + }else if (node instanceof ProgramNode) { ProgramNode programNode = (ProgramNode) node; List classes = programNode.classes; @@ -33,4 +45,13 @@ public class SemanticAnalyzer { } } + + public boolean identifierAlreadyUsed(Identifier identifier){ + if(usedIdentifier.contains(identifier)){ + return true; + } else { + return false; + } + } + } \ No newline at end of file