Merge pull request 'parser' (#3) from parser into main

Reviewed-on: #3
Reviewed-by: i22007 <i22007@hb.dhbw-stuttgart.de>
This commit is contained in:
Johannes Ehlert 2024-05-09 12:06:31 +00:00
commit 651a8b6ebf
43 changed files with 684 additions and 310 deletions

4
.idea/misc.xml generated
View File

@ -6,10 +6,10 @@
<PerGrammarGenerationSettings>
<option name="fileName" value="$PROJECT_DIR$/src/main/java/parser/SimpleJava.g4" />
<option name="autoGen" value="true" />
<option name="outputDir" value="C:\Users\ARB00075\Documents\DH\Compilerbau\NichtHaskell2.0\src\main\java\parser\out" />
<option name="outputDir" value="C:\Users\Maxi\Documents\DHBW\Compilerbau\NichtHaskell2.0\src\main\java\parser" />
<option name="libDir" value="" />
<option name="encoding" value="" />
<option name="pkg" value="" />
<option name="pkg" value="generated" />
<option name="language" value="" />
<option name="generateVisitor" value="true" />
</PerGrammarGenerationSettings>

View File

@ -2,6 +2,16 @@ public class Example {
public int test;
public Example(int conInput) {
}
public static int test(char b){
test = 3;
}
}
public class Test {

View File

@ -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;

View File

@ -0,0 +1,4 @@
package ast;
public class BlockNode {
}

View File

@ -1,10 +1,15 @@
package ast;
import ast.member.ConstructorNode;
import ast.member.MemberNode;
import ast.type.AccessTypeNode;
import ast.type.EnumAccessTypeNode;
import java.util.ArrayList;
import java.util.List;
public class ClassNode extends ASTNode{
public Identifier identifier;
public IdentifierNode identifier;
public AccessTypeNode accessType;
public String name;
public List<MemberNode> members = new ArrayList<>();

View File

@ -1,4 +0,0 @@
package ast;
public class ExpressionNode {
}

View File

@ -1,10 +1,10 @@
package ast;
public class Identifier {
public class IdentifierNode {
private String name;
public Identifier(String name){
public IdentifierNode(String name){
this.name = name;
}
@ -13,8 +13,8 @@ public class Identifier {
}
public boolean equals(Object obj) {
if(obj instanceof Identifier){
Identifier identifier = (Identifier) obj;
if(obj instanceof IdentifierNode){
IdentifierNode identifier = (IdentifierNode) obj;
if(name.equals(identifier.getName())){
return true;
} else {

View File

@ -1,4 +0,0 @@
package ast;
public class MemberNode extends ASTNode{
}

View File

@ -0,0 +1,13 @@
package ast.expression;
public class BinaryExpressionNode extends ExpressionNode {
public ExpressionNode left;
public ExpressionNode right;
public String operator; // Stores the operator as a string (e.g., "+", "-", "&&")
public BinaryExpressionNode(ExpressionNode left, ExpressionNode right, String operator) {
this.left = left;
this.right = right;
this.operator = operator;
}
}

View File

@ -0,0 +1,7 @@
package ast.expression;
import ast.ASTNode;
public class ExpressionNode extends ASTNode {
}

View File

@ -0,0 +1,9 @@
package ast.expression;
public class IdentifierExpressionNode extends ExpressionNode {
public String name;
public IdentifierExpressionNode(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,11 @@
package ast.expression;
public class UnaryExpressionNode extends ExpressionNode {
public ExpressionNode expression;
public String operator; // Stores the operator (e.g., "-", "!")
public UnaryExpressionNode(ExpressionNode expression, String operator) {
this.expression = expression;
this.operator = operator;
}
}

View File

@ -1,4 +1,6 @@
package ast;
package ast.member;
import ast.type.AccessTypeNode;
public class ConstructorNode extends MethodNode {
public ConstructorNode(AccessTypeNode visibility, String name) {

View File

@ -1,14 +1,18 @@
package ast;
package ast.member;
import ast.IdentifierNode;
import ast.type.AccessTypeNode;
import ast.type.TypeNode;
public class FieldNode extends MemberNode {
public AccessTypeNode accessTypeNode;
public TypeNode type;
public Identifier identifier;
public IdentifierNode identifier;
public FieldNode(AccessTypeNode accessTypeNode, TypeNode type, String name){
this.accessTypeNode = accessTypeNode;
this.type = type;
this.identifier = new Identifier(name);
this.identifier = new IdentifierNode(name);
}
}

View File

@ -0,0 +1,6 @@
package ast.member;
import ast.ASTNode;
public class MemberNode extends ASTNode {
}

View File

@ -1,10 +1,16 @@
package ast;
package ast.member;
import ast.IdentifierNode;
import ast.parameter.ParameterListNode;
import ast.statement.StatementNode;
import ast.type.AccessTypeNode;
import ast.type.TypeNode;
import java.util.ArrayList;
import java.util.List;
public class MethodNode extends MemberNode {
public Identifier identifier;
public IdentifierNode identifier;
public AccessTypeNode visibility;
public TypeNode type;
public String name;
@ -16,7 +22,7 @@ public class MethodNode extends MemberNode{
public MethodNode(AccessTypeNode visibility, TypeNode type, String name, ParameterListNode parameters,
List<StatementNode> statements){
this.visibility = visibility;
this.identifier = new Identifier(name);
this.identifier = new IdentifierNode(name);
this.type = type;
this.name = name;
this.parameters = parameters;
@ -25,6 +31,6 @@ public class MethodNode extends MemberNode{
public MethodNode(AccessTypeNode visibility, String name){
this.visibility = visibility;
this.identifier = new Identifier(name);
this.identifier = new IdentifierNode(name);
}
}

View File

@ -1,4 +1,6 @@
package ast;
package ast.parameter;
import ast.ASTNode;
import java.util.ArrayList;
import java.util.List;

View File

@ -1,4 +1,7 @@
package ast;
package ast.parameter;
import ast.ASTNode;
import ast.type.TypeNode;
public class ParameterNode extends ASTNode {
public TypeNode type;

View File

@ -0,0 +1,13 @@
package ast.statement;
import ast.expression.ExpressionNode;
public class AssignmentStatementNode extends StatementNode {
public String identifier;
public ExpressionNode expression;
public AssignmentStatementNode(String identifier, ExpressionNode expression) {
this.identifier = identifier;
this.expression = expression;
}
}

View File

@ -0,0 +1,15 @@
package ast.statement;
import ast.expression.ExpressionNode;
public class IfStatementNode extends StatementNode {
public ExpressionNode condition;
public StatementNode thenStatement;
public StatementNode elseStatement;
public IfStatementNode(ExpressionNode condition, StatementNode thenStatement, StatementNode elseStatement) {
this.condition = condition;
this.thenStatement = thenStatement;
this.elseStatement = elseStatement;
}
}

View File

@ -0,0 +1,11 @@
package ast.statement;
import ast.expression.ExpressionNode;
public class ReturnStatementNode extends StatementNode {
public ExpressionNode expression;
public ReturnStatementNode(ExpressionNode expression) {
this.expression = expression;
}
}

View File

@ -1,4 +1,4 @@
package ast;
package ast.statement;
import ast.ASTNode;

View File

@ -1,10 +1,12 @@
package ast;
package ast.statement;
import ast.type.TypeNode;
import ast.expression.ExpressionNode;
public class VariableDeclarationStatementNode extends StatementNode {
public TypeNode type;
public String identifier;
public ExpressionNode expression; // Nullable for cases without initialization
public ExpressionNode expression;
public VariableDeclarationStatementNode(TypeNode type, String identifier, ExpressionNode expression) {
this.type = type;
this.identifier = identifier;

View File

@ -0,0 +1,13 @@
package ast.statement;
import ast.expression.ExpressionNode;
public class WhileStatementNode extends StatementNode {
public ExpressionNode condition;
public StatementNode body;
public WhileStatementNode(ExpressionNode condition, StatementNode body) {
this.condition = condition;
this.body = body;
}
}

View File

@ -1,4 +1,6 @@
package ast;
package ast.type;
import ast.ASTNode;
public class AccessTypeNode extends ASTNode {
public EnumAccessTypeNode enumAccessTypeNode;

View File

@ -1,4 +1,4 @@
package ast;
package ast.type;
public enum EnumAccessTypeNode {
PUBLIC, PRIVATE

View File

@ -1,4 +1,4 @@
package ast;
package ast.type;
public enum EnumTypeNode {
INT, BOOLEAN, CHAR

View File

@ -1,4 +1,6 @@
package ast;
package ast.type;
import ast.ASTNode;
public class TypeNode extends ASTNode {
public EnumTypeNode enumTypeNode;

View File

@ -1,9 +1,9 @@
package bytecode;
import ast.ClassNode;
import ast.FieldNode;
import ast.MemberNode;
import ast.MethodNode;
import ast.member.FieldNode;
import ast.member.MemberNode;
import ast.member.MethodNode;
import java.io.File;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

View File

@ -1,9 +1,8 @@
package bytecode;
import ast.FieldNode;
import ast.member.FieldNode;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
public class FieldCodeGen {

View File

@ -1,7 +1,7 @@
package bytecode;
import ast.AccessTypeNode;
import ast.EnumAccessTypeNode;
import ast.type.AccessTypeNode;
import ast.type.EnumAccessTypeNode;
import org.objectweb.asm.Opcodes;
public class Mapper {

View File

@ -1,9 +1,8 @@
package bytecode;
import ast.MethodNode;
import ast.member.MethodNode;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class MethodCodeGen {
public void generateMethodCode(ClassWriter classWriter, MethodNode methodNode) {

View File

@ -1,6 +1,21 @@
package parser;
import ast.*;
import ast.expression.BinaryExpressionNode;
import ast.expression.ExpressionNode;
import ast.expression.IdentifierExpressionNode;
import ast.expression.UnaryExpressionNode;
import ast.member.FieldNode;
import ast.member.MemberNode;
import ast.member.MethodNode;
import ast.parameter.ParameterListNode;
import ast.parameter.ParameterNode;
import ast.statement.*;
import ast.type.AccessTypeNode;
import ast.type.EnumAccessTypeNode;
import ast.type.EnumTypeNode;
import ast.type.TypeNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import parser.generated.SimpleJavaBaseVisitor;
import parser.generated.SimpleJavaParser;
@ -20,7 +35,7 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
@Override
public ASTNode visitClassDeclaration(SimpleJavaParser.ClassDeclarationContext ctx) {
ClassNode classNode = new ClassNode((AccessTypeNode) visit(ctx.accessType()),ctx.IDENTIFIER().getText());
classNode.identifier = new Identifier(ctx.IDENTIFIER().getText());
classNode.identifier = new IdentifierNode(ctx.IDENTIFIER().getText());
for (SimpleJavaParser.MemberDeclarationContext member : ctx.memberDeclaration()) {
classNode.addMember((MemberNode) visit(member));
}
@ -107,4 +122,78 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
return null;
}
@Override
public ASTNode visitVariableDeclarationStatement(SimpleJavaParser.VariableDeclarationStatementContext ctx) {
TypeNode type = (TypeNode) visit(ctx.type());
String identifier = ctx.IDENTIFIER().getText();
ExpressionNode expression = null;
if (ctx.expression() != null) {
expression = (ExpressionNode) visit(ctx.expression());
}
return new VariableDeclarationStatementNode(type, identifier, expression);
}
@Override
public ASTNode visitAssignmentStatement(SimpleJavaParser.AssignmentStatementContext ctx) {
String identifier = ctx.IDENTIFIER().getText();
ExpressionNode expression = (ExpressionNode) visit(ctx.expression());
return new AssignmentStatementNode(identifier, expression);
}
@Override
public ASTNode visitIfStatement(SimpleJavaParser.IfStatementContext ctx) {
ExpressionNode condition = (ExpressionNode) visit(ctx.expression());
StatementNode thenStatement = (StatementNode) visit(ctx.statement(0)); // The 'then' branch
StatementNode elseStatement = null;
if (ctx.statement().size() > 1) {
elseStatement = (StatementNode) visit(ctx.statement(1)); // The 'else' branch, if present
}
return new IfStatementNode(condition, thenStatement, elseStatement);
}
@Override
public ASTNode visitWhileStatement(SimpleJavaParser.WhileStatementContext ctx) {
ExpressionNode condition = (ExpressionNode) visit(ctx.expression()); // Visit the condition part of the while statement
StatementNode body = (StatementNode) visit(ctx.statement()); // Visit the body part of the while statement
return new WhileStatementNode(condition, body);
}
@Override
public ASTNode visitReturnStatement(SimpleJavaParser.ReturnStatementContext ctx) {
ExpressionNode expression = null;
if (ctx.expression() != null) {
expression = (ExpressionNode) visit(ctx.expression()); // Visit the expression part of the return statement, if it exists
}
return new ReturnStatementNode(expression);
}
@Override
public ASTNode visitExpression(SimpleJavaParser.ExpressionContext ctx) {
// Handle binary operations
if (ctx.getChildCount() == 3 && ctx.getChild(1) instanceof TerminalNode) {
ExpressionNode left = (ExpressionNode) visit(ctx.expression(0));
ExpressionNode right = (ExpressionNode) visit(ctx.expression(1));
String operator = ctx.getChild(1).getText();
return new BinaryExpressionNode(left, right, operator);
}
// Handle unary operations
else if (ctx.getChildCount() == 2) {
String operator = ctx.getChild(0).getText();
ExpressionNode expression = (ExpressionNode) visit(ctx.expression(0));
return new UnaryExpressionNode(expression, operator);
}
// Handle parentheses
else if (ctx.getChildCount() == 3 && ctx.getChild(0).getText().equals("(")) {
return visit(ctx.expression(0)); // Simply return the inner expression
}
// Handle literals and identifiers
else if (ctx.literal() != null) {
return visit(ctx.literal());
}
else if (ctx.IDENTIFIER() != null) {
return new IdentifierExpressionNode(ctx.IDENTIFIER().getText());
}
return null; // Return null or throw an exception if no valid expression found
}
}

View File

@ -4,12 +4,14 @@ program : classDeclaration+;
classDeclaration : accessType 'class' IDENTIFIER '{' memberDeclaration* '}';
memberDeclaration : fieldDeclaration | methodDeclaration;
memberDeclaration : fieldDeclaration | methodDeclaration | constructorDeclaration;
fieldDeclaration : accessType type IDENTIFIER ';';
methodDeclaration : accessType 'static' type IDENTIFIER '(' parameterList? ')' '{' statement* '}' ;
constructorDeclaration : accessType IDENTIFIER '(' parameterList? ')' '{' statement* '}' ;
parameterList : parameter (',' parameter)* ;
parameter : type IDENTIFIER ;

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
// Generated from C:/Users/ARB00072/Desktop/DHBW/4. Semester/Compilerbau/Endprojekt/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
package parser.generated;
import org.antlr.v4.runtime.ParserRuleContext;
@ -72,6 +72,18 @@ public class SimpleJavaBaseListener implements SimpleJavaListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitMethodDeclaration(SimpleJavaParser.MethodDeclarationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -1,4 +1,4 @@
// Generated from C:/Users/ARB00072/Desktop/DHBW/4. Semester/Compilerbau/Endprojekt/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
package parser.generated;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
@ -47,6 +47,13 @@ public class SimpleJavaBaseVisitor<T> extends AbstractParseTreeVisitor<T> implem
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitMethodDeclaration(SimpleJavaParser.MethodDeclarationContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -1,4 +1,4 @@
// Generated from C:/Users/ARB00072/Desktop/DHBW/4. Semester/Compilerbau/Endprojekt/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
package parser.generated;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;

View File

@ -1,4 +1,4 @@
// Generated from C:/Users/ARB00072/Desktop/DHBW/4. Semester/Compilerbau/Endprojekt/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
package parser.generated;
import org.antlr.v4.runtime.tree.ParseTreeListener;
@ -57,6 +57,16 @@ public interface SimpleJavaListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitMethodDeclaration(SimpleJavaParser.MethodDeclarationContext ctx);
/**
* Enter a parse tree produced by {@link SimpleJavaParser#constructorDeclaration}.
* @param ctx the parse tree
*/
void enterConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx);
/**
* Exit a parse tree produced by {@link SimpleJavaParser#constructorDeclaration}.
* @param ctx the parse tree
*/
void exitConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx);
/**
* Enter a parse tree produced by {@link SimpleJavaParser#parameterList}.
* @param ctx the parse tree

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Generated from C:/Users/ARB00072/Desktop/DHBW/4. Semester/Compilerbau/Endprojekt/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
// Generated from C:/Users/Maxi/Documents/DHBW/Compilerbau/NichtHaskell2.0/src/main/java/parser/SimpleJava.g4 by ANTLR 4.13.1
package parser.generated;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
@ -40,6 +40,12 @@ public interface SimpleJavaVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitMethodDeclaration(SimpleJavaParser.MethodDeclarationContext ctx);
/**
* Visit a parse tree produced by {@link SimpleJavaParser#constructorDeclaration}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConstructorDeclaration(SimpleJavaParser.ConstructorDeclarationContext ctx);
/**
* Visit a parse tree produced by {@link SimpleJavaParser#parameterList}.
* @param ctx the parse tree

View File

@ -2,13 +2,16 @@ package semantic;
import ast.*;
import ast.member.ConstructorNode;
import ast.member.FieldNode;
import ast.member.MemberNode;
import java.util.ArrayList;
import java.util.List;
public class SemanticAnalyzer {
List<Identifier> usedIdentifier = new ArrayList<>();
List<IdentifierNode> usedIdentifier = new ArrayList<>();
public void analyze(ASTNode node) {
if (node == null) return;
@ -47,7 +50,7 @@ public class SemanticAnalyzer {
}
public boolean identifierAlreadyUsed(Identifier identifier){
public boolean identifierAlreadyUsed(IdentifierNode identifier){
if(usedIdentifier.contains(identifier)){
return true;
} else {