From f09e6ad09e41a9d591a7395998ae78c4a1461415 Mon Sep 17 00:00:00 2001 From: Marvin Schlegel Date: Thu, 27 Jun 2024 08:33:41 +0200 Subject: [PATCH] adjust parser for constructordeclaration --- Test/TestParser.hs | 38 +++++++++++++++++++------------------- project.cabal | 8 +------- src/Parser/JavaParser.y | 25 ++++++++++++++----------- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/Test/TestParser.hs b/Test/TestParser.hs index 2767c15..95a9512 100644 --- a/Test/TestParser.hs +++ b/Test/TestParser.hs @@ -7,56 +7,56 @@ import Ast testSingleEmptyClass = TestCase $ - assertEqual "expect single empty class hello" [Class "Hello" [] []] $ + assertEqual "expect single empty class hello" [Class "Hello" [] [] []] $ parse [CLASS, IDENTIFIER "Hello", LBRACKET, RBRACKET] testTwoEmptyClasses = TestCase $ - assertEqual "expect two empty classes" [Class "Class1" [] [], Class "Class2" [] []] $ + assertEqual "expect two empty classes" [Class "Class1" [] [] [], Class "Class2" [] [] []] $ parse [CLASS,IDENTIFIER "Class1",LBRACKET,RBRACKET,CLASS,IDENTIFIER "Class2",LBRACKET,RBRACKET] testBooleanField = TestCase $ - assertEqual "expect class with boolean field" [Class "WithBool" [] [VariableDeclaration "boolean" "value" Nothing]] $ + assertEqual "expect class with boolean field" [Class "WithBool" [] [] [VariableDeclaration "boolean" "value" Nothing]] $ parse [CLASS,IDENTIFIER "WithBool",LBRACKET,BOOLEAN,IDENTIFIER "value",SEMICOLON,RBRACKET] testIntField = TestCase $ - assertEqual "expect class with int field" [Class "WithInt" [] [VariableDeclaration "int" "value" Nothing]] $ + assertEqual "expect class with int field" [Class "WithInt" [] [] [VariableDeclaration "int" "value" Nothing]] $ parse [CLASS,IDENTIFIER "WithInt",LBRACKET,INT,IDENTIFIER "value",SEMICOLON,RBRACKET] testCustomTypeField = TestCase $ - assertEqual "expect class with foo field" [Class "WithFoo" [] [VariableDeclaration "Foo" "value" Nothing]] $ + assertEqual "expect class with foo field" [Class "WithFoo" [] [] [VariableDeclaration "Foo" "value" Nothing]] $ parse [CLASS,IDENTIFIER "WithFoo",LBRACKET,IDENTIFIER "Foo",IDENTIFIER "value",SEMICOLON,RBRACKET] testMultipleDeclarationSameLine = TestCase $ - assertEqual "expect class with two int fields" [Class "TwoInts" [] [VariableDeclaration "int" "num1" Nothing, VariableDeclaration "int" "num2" Nothing]] $ + assertEqual "expect class with two int fields" [Class "TwoInts" [] [] [VariableDeclaration "int" "num1" Nothing, VariableDeclaration "int" "num2" Nothing]] $ parse [CLASS,IDENTIFIER "TwoInts",LBRACKET,INT,IDENTIFIER "num1",COMMA,IDENTIFIER "num2",SEMICOLON,RBRACKET] testMultipleDeclarations = TestCase $ - assertEqual "expect class with int and char field" [Class "Multiple" [] [VariableDeclaration "int" "value" Nothing, VariableDeclaration "char" "letter" Nothing]] $ + assertEqual "expect class with int and char field" [Class "Multiple" [] [] [VariableDeclaration "int" "value" Nothing, VariableDeclaration "char" "letter" Nothing]] $ parse [CLASS,IDENTIFIER "Multiple",LBRACKET,INT,IDENTIFIER "value",SEMICOLON,CHAR,IDENTIFIER "letter",SEMICOLON,RBRACKET] testWithModifier = TestCase $ - assertEqual "expect class with int field" [Class "WithInt" [] [VariableDeclaration "int" "value" Nothing]] $ + assertEqual "expect class with int field" [Class "WithInt" [] [] [VariableDeclaration "int" "value" Nothing]] $ parse [ABSTRACT,CLASS,IDENTIFIER "WithInt",LBRACKET,PUBLIC,INT,IDENTIFIER "value",SEMICOLON,RBRACKET] testEmptyMethod = TestCase $ - assertEqual "expect class with method" [Class "WithMethod" [MethodDeclaration "int" "foo" [] (Block [])] []] $ + assertEqual "expect class with method" [Class "WithMethod" [] [MethodDeclaration "int" "foo" [] (Block [])] []] $ parse [CLASS,IDENTIFIER "WithMethod",LBRACKET,INT,IDENTIFIER "foo",LBRACE,RBRACE,SEMICOLON,RBRACKET] testEmptyPrivateMethod = TestCase $ - assertEqual "expect class with method" [Class "WithMethod" [MethodDeclaration "int" "foo" [] (Block [])] []] $ + assertEqual "expect class with method" [Class "WithMethod" [] [MethodDeclaration "int" "foo" [] (Block [])] []] $ parse [CLASS,IDENTIFIER "WithMethod",LBRACKET,PRIVATE,INT,IDENTIFIER "foo",LBRACE,RBRACE,LBRACKET,RBRACKET,RBRACKET] testEmptyVoidMethod = TestCase $ - assertEqual "expect class with method" [Class "WithMethod" [MethodDeclaration "void" "foo" [] (Block [])] []] $ + assertEqual "expect class with method" [Class "WithMethod" [] [MethodDeclaration "void" "foo" [] (Block [])] []] $ parse [CLASS,IDENTIFIER "WithMethod",LBRACKET,VOID,IDENTIFIER "foo",LBRACE,RBRACE,LBRACKET,RBRACKET,RBRACKET] testEmptyMethodWithParam = TestCase $ - assertEqual "expect class with method with param" [Class "WithParam" [MethodDeclaration "void" "foo" [ParameterDeclaration "int" "param"] (Block [])] []] $ + assertEqual "expect class with method with param" [Class "WithParam" [] [MethodDeclaration "void" "foo" [ParameterDeclaration "int" "param"] (Block [])] []] $ parse [CLASS,IDENTIFIER "WithParam",LBRACKET,VOID,IDENTIFIER "foo",LBRACE,INT,IDENTIFIER "param",RBRACE,SEMICOLON,RBRACKET] testEmptyMethodWithParams = TestCase $ - assertEqual "expect class with multiple params" [Class "WithParams" [MethodDeclaration "void" "foo" [ParameterDeclaration "int" "p1",ParameterDeclaration "Custom" "p2"] (Block [])] []] $ + assertEqual "expect class with multiple params" [Class "WithParams" [] [MethodDeclaration "void" "foo" [ParameterDeclaration "int" "p1",ParameterDeclaration "Custom" "p2"] (Block [])] []] $ parse [CLASS,IDENTIFIER "WithParams",LBRACKET,VOID,IDENTIFIER "foo",LBRACE,INT,IDENTIFIER "p1",COMMA,IDENTIFIER "Custom",IDENTIFIER "p2",RBRACE,SEMICOLON,RBRACKET] testClassWithMethodAndField = TestCase $ - assertEqual "expect class with method and field" [Class "WithMethodAndField" [MethodDeclaration "void" "foo" [] (Block []), MethodDeclaration "int" "bar" [] (Block [])] [VariableDeclaration "int" "value" Nothing]] $ + assertEqual "expect class with method and field" [Class "WithMethodAndField" [] [MethodDeclaration "void" "foo" [] (Block []), MethodDeclaration "int" "bar" [] (Block [])] [VariableDeclaration "int" "value" Nothing]] $ parse [CLASS,IDENTIFIER "WithMethodAndField",LBRACKET,VOID,IDENTIFIER "foo",LBRACE,RBRACE,LBRACKET,RBRACKET,INT,IDENTIFIER "value",SEMICOLON,INT,IDENTIFIER "bar",LBRACE,RBRACE,SEMICOLON,RBRACKET] testClassWithConstructor = TestCase $ - assertEqual "expect class with constructor" [Class "WithConstructor" [MethodDeclaration "void" "" [] (Block [])] []] $ + assertEqual "expect class with constructor" [Class "WithConstructor" [ConstructorDeclaration "WithConstructor" [] (Block [])] [] []] $ parse [CLASS,IDENTIFIER "WithConstructor",LBRACKET,IDENTIFIER "WithConstructor",LBRACE,RBRACE,LBRACKET,RBRACKET,RBRACKET] testConstructorWithParams = TestCase $ - assertEqual "expect constructor with params" [Class "WithParams" [MethodDeclaration "void" "" [ParameterDeclaration "int" "p1"] (Block [])] []] $ + assertEqual "expect constructor with params" [Class "WithParams" [ConstructorDeclaration "WithParams" [ParameterDeclaration "int" "p1"] (Block [])] [] []] $ parse [CLASS,IDENTIFIER "WithParams",LBRACKET,IDENTIFIER "WithParams",LBRACE,INT,IDENTIFIER "p1",RBRACE,LBRACKET,RBRACKET,RBRACKET] testConstructorWithStatements = TestCase $ - assertEqual "expect constructor with statement" [Class "WithConstructor" [MethodDeclaration "void" "" [] (Block [Return Nothing])] []] $ + assertEqual "expect constructor with statement" [Class "WithConstructor" [ConstructorDeclaration "WithConstructor" [] (Block [Return Nothing])] [] []] $ parse [CLASS,IDENTIFIER "WithConstructor",LBRACKET,IDENTIFIER "WithConstructor",LBRACE,RBRACE,LBRACKET,RETURN,SEMICOLON,RBRACKET,RBRACKET] @@ -78,13 +78,13 @@ testExpressionIntLiteral = TestCase $ assertEqual "expect IntLiteral" (IntegerLiteral 3) $ parseExpression [INTEGERLITERAL 3] testFieldWithInitialization = TestCase $ - assertEqual "expect Class with initialized field" [Class "WithInitField" [] [VariableDeclaration "int" "number" $ Just $ IntegerLiteral 3]] $ + assertEqual "expect Class with initialized field" [Class "WithInitField" [] [] [VariableDeclaration "int" "number" $ Just $ IntegerLiteral 3]] $ parse [CLASS,IDENTIFIER "WithInitField",LBRACKET,INT,IDENTIFIER "number",ASSIGN,INTEGERLITERAL 3,SEMICOLON,RBRACKET] testLocalBoolWithInitialization = TestCase $ assertEqual "expect block with with initialized local var" [Block [LocalVariableDeclaration $ VariableDeclaration "boolean" "b" $ Just $ BooleanLiteral False]] $ parseStatement [LBRACKET,BOOLEAN,IDENTIFIER "b",ASSIGN,BOOLLITERAL False,SEMICOLON,RBRACKET] testFieldNullWithInitialization = TestCase $ - assertEqual "expect Class with initialized field" [Class "WithInitField" [] [VariableDeclaration "Object" "bar" $ Just NullLiteral]] $ + assertEqual "expect Class with initialized field" [Class "WithInitField" [] [] [VariableDeclaration "Object" "bar" $ Just NullLiteral]] $ parse [CLASS,IDENTIFIER "WithInitField",LBRACKET,IDENTIFIER "Object",IDENTIFIER "bar",ASSIGN,NULLLITERAL,SEMICOLON,RBRACKET] testReturnVoid = TestCase $ assertEqual "expect block with return nothing" [Block [Return Nothing]] $ diff --git a/project.cabal b/project.cabal index 60ff6fb..baec851 100644 --- a/project.cabal +++ b/project.cabal @@ -42,10 +42,4 @@ test-suite tests Parser.JavaParser, Ast, TestLexer, - TestParser, - ByteCode.Util, - ByteCode.ByteUtil, - ByteCode.ClassFile, - ByteCode.Assembler, - ByteCode.Builder, - ByteCode.Constants + TestParser diff --git a/src/Parser/JavaParser.y b/src/Parser/JavaParser.y index 3e011d1..fe8bf0c 100644 --- a/src/Parser/JavaParser.y +++ b/src/Parser/JavaParser.y @@ -92,10 +92,10 @@ qualifiedname : name DOT IDENTIFIER { BinaryOperation NameResolution $1 (Ref simplename : IDENTIFIER { $1 } -classdeclaration : CLASS IDENTIFIER classbody { case $3 of (methods, fields) -> Class $2 methods fields } - | modifiers CLASS IDENTIFIER classbody { case $4 of (methods, fields) -> Class $3 methods fields } +classdeclaration : CLASS IDENTIFIER classbody { case $3 of (constructors, methods, fields) -> Class $2 constructors methods fields } + | modifiers CLASS IDENTIFIER classbody { case $4 of (constructors, methods, fields) -> Class $3 constructors methods fields } -classbody : LBRACKET RBRACKET { ([], []) } +classbody : LBRACKET RBRACKET { ([], [], []) } | LBRACKET classbodydeclarations RBRACKET { $2 } modifiers : modifier { } @@ -103,13 +103,15 @@ modifiers : modifier { } classbodydeclarations : classbodydeclaration { case $1 of - MethodDecl method -> ([method], []) - FieldDecls fields -> ([], fields) + ConstructorDecl constructor -> ([constructor], [], []) + MethodDecl method -> ([], [method], []) + FieldDecls fields -> ([], [], fields) } | classbodydeclarations classbodydeclaration { case ($1, $2) of - ((methods, fields), MethodDecl method) -> ((methods ++ [method]), fields) - ((methods, fields), FieldDecls newFields) -> (methods, (fields ++ newFields)) + ((constructors, methods, fields), ConstructorDecl constructor) -> ((constructors ++ [constructor]), methods, fields) + ((constructors, methods, fields), MethodDecl method) -> (constructors, (methods ++ [method]), fields) + ((constructors, methods, fields), FieldDecls newFields) -> (constructors, methods, (fields ++ newFields)) } modifier : PUBLIC { } @@ -128,8 +130,8 @@ classorinterfacetype : simplename { $1 } classmemberdeclaration : fielddeclaration { $1 } | methoddeclaration { $1 } -constructordeclaration : constructordeclarator constructorbody { MethodDecl $ MethodDeclaration "void" "" $1 $2 } - | modifiers constructordeclarator constructorbody { MethodDecl $ MethodDeclaration "void" "" $2 $3 } +constructordeclaration : constructordeclarator constructorbody { case $1 of (identifier, parameters) -> ConstructorDecl $ ConstructorDeclaration identifier parameters $2 } + | modifiers constructordeclarator constructorbody { case $2 of (identifier, parameters) -> ConstructorDecl $ ConstructorDeclaration identifier parameters $3 } fielddeclaration : type variabledeclarators SEMICOLON { FieldDecls $ map (convertDeclarator $1) $2 } | modifiers type variabledeclarators SEMICOLON { FieldDecls $ map (convertDeclarator $2) $3 } @@ -139,8 +141,8 @@ methoddeclaration : methodheader methodbody { case $1 of (returnType, (name, par block : LBRACKET RBRACKET { Block [] } | LBRACKET blockstatements RBRACKET { Block $2 } -constructordeclarator : simplename LBRACE RBRACE { [] } - | simplename LBRACE formalparameterlist RBRACE { $3 } +constructordeclarator : simplename LBRACE RBRACE { ($1, []) } + | simplename LBRACE formalparameterlist RBRACE { ($1, $3) } constructorbody : LBRACKET RBRACKET { Block [] } -- | LBRACKET explicitconstructorinvocation RBRACKET { } @@ -385,6 +387,7 @@ multiplicativeexpression : unaryexpression { $1 } { data MethodOrFieldDeclaration = MethodDecl MethodDeclaration + | ConstructorDecl ConstructorDeclaration | FieldDecls [VariableDeclaration] data Declarator = Declarator Identifier (Maybe Expression)