From 2bae802cb23e886956594ffbbf9904d492c1b680 Mon Sep 17 00:00:00 2001 From: Bruder John Date: Thu, 9 May 2024 22:39:26 +0200 Subject: [PATCH] changed to visitor pattern --- src/main/java/CompilerInput.txt | 12 +-- src/main/java/Main.java | 15 +--- src/main/java/ast/ASTNode.java | 5 +- src/main/java/ast/ClassNode.java | 10 ++- src/main/java/ast/IdentifierNode.java | 10 ++- src/main/java/ast/ProgramNode.java | 10 ++- src/main/java/ast/member/FieldNode.java | 13 ++- src/main/java/ast/member/MethodNode.java | 22 +++-- src/main/java/bytecode/FieldCodeGen.java | 2 +- src/main/java/classFileOutput/Example.class | Bin 101 -> 111 bytes src/main/java/semantic/SemanticAnalyzer.java | 83 +++++++++++------- src/main/java/semantic/SemanticVisitor.java | 65 ++++++++++++++ src/main/java/typechecker/Type.java | 5 ++ .../java/typechecker/TypeCheckResult.java | 21 +++++ src/main/java/typechecker/Visitable.java | 16 ++++ 15 files changed, 218 insertions(+), 71 deletions(-) create mode 100644 src/main/java/semantic/SemanticVisitor.java create mode 100644 src/main/java/typechecker/Type.java create mode 100644 src/main/java/typechecker/TypeCheckResult.java create mode 100644 src/main/java/typechecker/Visitable.java diff --git a/src/main/java/CompilerInput.txt b/src/main/java/CompilerInput.txt index c85e668..49da971 100644 --- a/src/main/java/CompilerInput.txt +++ b/src/main/java/CompilerInput.txt @@ -1,16 +1,12 @@ public class Example { - public int Example; + public int testVar; - public Example(int conInput) { + public static int testMethod(char b){ - } + int a; + a = 3; - public static int test(char b){ - - char Example; - boolean Example; - int c; } diff --git a/src/main/java/Main.java b/src/main/java/Main.java index bcb48c5..e1673c1 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -15,11 +15,8 @@ import java.nio.file.Paths; public class Main { public static void main(String[] args) throws Exception { - - CharStream codeCharStream = null; - try { - codeCharStream = CharStreams.fromPath(Paths.get("src/main/java/CompilerInput.txt")); + CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/java/CompilerInput.txt")); parsefile(codeCharStream); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); @@ -28,7 +25,6 @@ public class Main { static void parsefile(CharStream codeCharStream){ - // CharStream codeCharStream = CharStreams.fromString("class javaFileInput.Example { } class Example2 { }"); SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream); CommonTokenStream tokens = new CommonTokenStream(lexer); SimpleJavaParser parser = new SimpleJavaParser(tokens); @@ -38,14 +34,7 @@ public class Main { ASTBuilder builder = new ASTBuilder(); ProgramNode ast = (ProgramNode) builder.visit(tree); // build the AST - // 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.identifier.getName()); - } - - SemanticAnalyzer semanticAnalyzer = new SemanticAnalyzer(); - semanticAnalyzer.analyze(ast); + SemanticAnalyzer.generateTast(ast); ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); byteCodeGenerator.generateByteCode(ast); diff --git a/src/main/java/ast/ASTNode.java b/src/main/java/ast/ASTNode.java index 7836a79..9c5880e 100644 --- a/src/main/java/ast/ASTNode.java +++ b/src/main/java/ast/ASTNode.java @@ -1,8 +1,7 @@ package ast; -import java.util.ArrayList; -import java.util.List; +public class ASTNode { -public abstract class ASTNode { } +} diff --git a/src/main/java/ast/ClassNode.java b/src/main/java/ast/ClassNode.java index 2f27d08..3e8d740 100644 --- a/src/main/java/ast/ClassNode.java +++ b/src/main/java/ast/ClassNode.java @@ -7,8 +7,11 @@ import ast.type.EnumAccessTypeNode; import java.util.ArrayList; import java.util.List; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; +import typechecker.Visitable; -public class ClassNode extends ASTNode{ +public class ClassNode extends ASTNode implements Visitable { public IdentifierNode identifier; public AccessTypeNode accessType; public String name; @@ -33,4 +36,9 @@ public class ClassNode extends ASTNode{ members.add(0,constructor); } } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.typeCheck(this); + } } diff --git a/src/main/java/ast/IdentifierNode.java b/src/main/java/ast/IdentifierNode.java index 0c220d7..992dc6b 100644 --- a/src/main/java/ast/IdentifierNode.java +++ b/src/main/java/ast/IdentifierNode.java @@ -1,6 +1,10 @@ package ast; -public class IdentifierNode extends ASTNode{ +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; +import typechecker.Visitable; + +public class IdentifierNode extends ASTNode implements Visitable { private String name; @@ -24,4 +28,8 @@ public class IdentifierNode extends ASTNode{ return super.equals(obj); } + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.typeCheck(this); + } } diff --git a/src/main/java/ast/ProgramNode.java b/src/main/java/ast/ProgramNode.java index 1fcc193..3d0af61 100644 --- a/src/main/java/ast/ProgramNode.java +++ b/src/main/java/ast/ProgramNode.java @@ -2,11 +2,19 @@ package ast; import java.util.ArrayList; import java.util.List; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; +import typechecker.Visitable; -public class ProgramNode extends ASTNode { +public class ProgramNode extends ASTNode implements Visitable{ public List classes = new ArrayList<>(); public void addClass(ClassNode classNode) { classes.add(classNode); } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.typeCheck(this); + } } \ No newline at end of file diff --git a/src/main/java/ast/member/FieldNode.java b/src/main/java/ast/member/FieldNode.java index 53a5335..569cea0 100644 --- a/src/main/java/ast/member/FieldNode.java +++ b/src/main/java/ast/member/FieldNode.java @@ -3,16 +3,23 @@ package ast.member; import ast.IdentifierNode; import ast.type.AccessTypeNode; import ast.type.TypeNode; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; +import typechecker.Visitable; -public class FieldNode extends MemberNode { +public class FieldNode extends MemberNode implements Visitable { public AccessTypeNode accessTypeNode; public TypeNode type; - public IdentifierNode identifier; + public String identifier; public FieldNode(AccessTypeNode accessTypeNode, TypeNode type, String name){ this.accessTypeNode = accessTypeNode; this.type = type; - this.identifier = new IdentifierNode(name); + this.identifier = name; } + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.typeCheck(this); + } } diff --git a/src/main/java/ast/member/MethodNode.java b/src/main/java/ast/member/MethodNode.java index 4c937cc..2d42cc2 100644 --- a/src/main/java/ast/member/MethodNode.java +++ b/src/main/java/ast/member/MethodNode.java @@ -8,29 +8,35 @@ import ast.type.TypeNode; import java.util.ArrayList; import java.util.List; +import semantic.SemanticVisitor; +import typechecker.TypeCheckResult; +import typechecker.Visitable; -public class MethodNode extends MemberNode { - public IdentifierNode identifier; +public class MethodNode extends MemberNode implements Visitable { public AccessTypeNode visibility; public TypeNode type; - public String name; + public String identifier; public ParameterListNode parameters; public List statements = new ArrayList<>(); - public MethodNode(AccessTypeNode visibility, TypeNode type, String name, ParameterListNode parameters, + public MethodNode(AccessTypeNode visibility, TypeNode type, String identifier, ParameterListNode parameters, List statements){ this.visibility = visibility; - this.identifier = new IdentifierNode(name); this.type = type; - this.name = name; + this.identifier = identifier; this.parameters = parameters; this.statements = statements; } - public MethodNode(AccessTypeNode visibility, String name){ + public MethodNode(AccessTypeNode visibility, String identifier){ this.visibility = visibility; - this.identifier = new IdentifierNode(name); + this.identifier = identifier; + } + + @Override + public TypeCheckResult accept(SemanticVisitor visitor) { + return visitor.typeCheck(this); } } diff --git a/src/main/java/bytecode/FieldCodeGen.java b/src/main/java/bytecode/FieldCodeGen.java index 76e2921..abbda43 100644 --- a/src/main/java/bytecode/FieldCodeGen.java +++ b/src/main/java/bytecode/FieldCodeGen.java @@ -8,6 +8,6 @@ public class FieldCodeGen { public void generateFieldCode(ClassWriter classWriter, FieldNode fieldNode) { Mapper mapper = new Mapper(); - FieldVisitor fieldVisitor = classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier.getName(), "", null, null); + FieldVisitor fieldVisitor = classWriter.visitField(mapper.mapAccesTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, "", null, null); } } diff --git a/src/main/java/classFileOutput/Example.class b/src/main/java/classFileOutput/Example.class index af810a65d3b0b58d08efeae8610930ab04023686..c0d9270e1638a12598a097c3a813e0adcc1b821b 100644 GIT binary patch delta 47 ycmYez=Q{Oo*FFXY1``I(iCiYq>?NtiC1Ht0j6fkq1||j;FwMxo&cHFzUkm^#%LzpQ delta 56 xcmc~# currentFields = new ArrayList<>(); - if (node instanceof ClassNode) { - ClassNode classNode = (ClassNode) node; + public static ASTNode generateTast(ASTNode node) throws RuntimeException { + SemanticAnalyzer semanticCheck = new SemanticAnalyzer(); + ProgramNode programNode = (ProgramNode) node; + var result = programNode.accept(semanticCheck); + if (result.isValid()) { + return node; + } else { + throw new RuntimeException("errorString ERROR"); + } + } - List memberNodes = classNode.members; - for (MemberNode member : memberNodes) { - analyze(member); - } + @Override + public TypeCheckResult typeCheck(ProgramNode node) { - } else if (node instanceof AssignmentStatementNode) { - AssignmentStatementNode assignmentStatementNode = (AssignmentStatementNode) node; + var valid = true; - IdentifierNode identifierNode = assignmentStatementNode.identifier; + List classes = node.classes; + for (ClassNode classNode : classes) { + classNode.accept(this); + } + return new TypeCheckResult(valid, null); + } - if(analyze(assignmentStatementNode.expression).equals("int")){ - System.out.println("INTEGER"); - } - - } else if (node instanceof LiteralNode) { - return "int"; - } else if (node instanceof MethodNode) { - MethodNode methodNode = (MethodNode) node; - List statementNodes = methodNode.statements; - for (StatementNode statement : statementNodes) { - analyze(statement); - } - - } else if (node instanceof ProgramNode) { - ProgramNode programNode = (ProgramNode) node; - List classes = programNode.classes; - for (ClassNode classNode : classes) { - analyze(classNode); + @Override + public TypeCheckResult typeCheck(ClassNode classNode) { + List members = classNode.members; + for (MemberNode memberNode : members) { + if (memberNode instanceof FieldNode fieldNode) { + fieldNode.accept(this); + } else if (memberNode instanceof MethodNode methodNode) { + methodNode.accept(this); } } return null; } + @Override + public TypeCheckResult typeCheck(IdentifierNode identifierNode) { + return null; + } + + @Override + public TypeCheckResult typeCheck(MethodNode methodNode) { + List statements = methodNode.statements; + return null; + } + + @Override + public TypeCheckResult typeCheck(FieldNode toCheck) { + if(currentFields.contains(toCheck.identifier)){ + throw new RuntimeException(toCheck.identifier + " Is Already Declared"); + }else { + currentFields.add(toCheck.identifier); + } + return null; + } + } \ No newline at end of file diff --git a/src/main/java/semantic/SemanticVisitor.java b/src/main/java/semantic/SemanticVisitor.java new file mode 100644 index 0000000..445db69 --- /dev/null +++ b/src/main/java/semantic/SemanticVisitor.java @@ -0,0 +1,65 @@ +package semantic; + + +import ast.ASTNode; +import ast.ClassNode; +import ast.IdentifierNode; +import ast.ProgramNode; +import ast.member.FieldNode; +import ast.member.MethodNode; +import typechecker.TypeCheckResult; + +public interface SemanticVisitor { +// TypeCheckResult typeCheck(ASTNode toCheck); + + TypeCheckResult typeCheck(ProgramNode toCheck); + + TypeCheckResult typeCheck(ClassNode toCheck); + + TypeCheckResult typeCheck(IdentifierNode toCheck); + + TypeCheckResult typeCheck(MethodNode toCheck); + + TypeCheckResult typeCheck(FieldNode toCheck); +// +// TypeCheckResult typeCheck(Assign toCheck); +// +// TypeCheckResult typeCheck(MethodParameter toCheck); +// +// TypeCheckResult typeCheck(ForStmt forStmt); +// +// TypeCheckResult typeCheck(WhileStmt whileStmt); +// +// TypeCheckResult typeCheck(ReturnStmt returnStmt); +// +// TypeCheckResult typeCheck(LocalVarDecl localVarDecl); +// +// TypeCheckResult typeCheck(IfStmt ifStmt); +// +// TypeCheckResult typeCheck(Block block); +// +// TypeCheckResult typeCheck(NewDecl newDecl); +// +// TypeCheckResult typeCheck(MethodCall methodCall); +// +// TypeCheckResult typeCheck(Unary unary); +// +// TypeCheckResult typeCheck(This aThis); +// +// TypeCheckResult typeCheck(Null aNull); +// +// TypeCheckResult typeCheck(LocalOrFieldVar localOrFieldVar); +// +// TypeCheckResult typeCheck(IntegerExpr integerExpr); +// +// TypeCheckResult typeCheck(InstVar instVar); +// +// TypeCheckResult typeCheck(CharExpr charExpr); +// +// TypeCheckResult typeCheck(BoolExpr boolExpr); +// +// TypeCheckResult typeCheck(Binary binary); +// +// TypeCheckResult typeCheck(StringExpr instVar); + +} \ No newline at end of file diff --git a/src/main/java/typechecker/Type.java b/src/main/java/typechecker/Type.java new file mode 100644 index 0000000..89b1c16 --- /dev/null +++ b/src/main/java/typechecker/Type.java @@ -0,0 +1,5 @@ +package typechecker; + +public interface Type { + boolean equals(Object obj); +} \ No newline at end of file diff --git a/src/main/java/typechecker/TypeCheckResult.java b/src/main/java/typechecker/TypeCheckResult.java new file mode 100644 index 0000000..9068c0d --- /dev/null +++ b/src/main/java/typechecker/TypeCheckResult.java @@ -0,0 +1,21 @@ +package typechecker; + + +public class TypeCheckResult { + + private boolean valid; + private Type type; + + public TypeCheckResult(boolean valid, Type type) { + this.valid = valid; + this.type = type; + } + + public boolean isValid() { + return valid; + } + + public Type getType() { + return type; + } +} \ No newline at end of file diff --git a/src/main/java/typechecker/Visitable.java b/src/main/java/typechecker/Visitable.java new file mode 100644 index 0000000..99694b7 --- /dev/null +++ b/src/main/java/typechecker/Visitable.java @@ -0,0 +1,16 @@ +package typechecker; + +import semantic.SemanticVisitor; + +public interface Visitable { +// default void accept(ProgramCodeVisitor visitor) { +// } +// +// default void accept(ClassCodeVisitor visitor) { +// } +// +// default void accept(MethodCodeVisitor visitor) { +// } + + TypeCheckResult accept(SemanticVisitor visitor); +}