diff --git a/Test/TestParser.hs b/Test/TestParser.hs index 775de17..ce3f2cc 100644 --- a/Test/TestParser.hs +++ b/Test/TestParser.hs @@ -12,10 +12,17 @@ testSingleEmptyClass = TestCase $ testTwoEmptyClasses = TestCase $ 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]] $ + parse [CLASS,IDENTIFIER "WithBool",LBRACKET,BOOLEAN,IDENTIFIER "value",SEMICOLON,RBRACKET] +testIntField = TestCase $ + assertEqual "expect class with int field" [Class "WithInt" [] [VariableDeclaration "int" "value" Nothing]] $ + parse [CLASS,IDENTIFIER "WithInt",LBRACKET,INT,IDENTIFIER "value",SEMICOLON,RBRACKET] tests = TestList [ testSingleEmptyClass, - testTwoEmptyClasses + testTwoEmptyClasses, + testBooleanField, + testIntField ] \ No newline at end of file diff --git a/src/Parser/JavaParser.y b/src/Parser/JavaParser.y index f673532..bfe74b2 100644 --- a/src/Parser/JavaParser.y +++ b/src/Parser/JavaParser.y @@ -89,17 +89,25 @@ qualifiedname : name DOT IDENTIFIER { } simplename : IDENTIFIER { } -classdeclaration : CLASS IDENTIFIER classbody { case $3 of (methods, attributes) -> Class $2 methods attributes } - | modifiers CLASS IDENTIFIER classbody { case $4 of (methods, attributes) -> Class $3 methods attributes } +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 } classbody : LBRACKET RBRACKET { ([], []) } - | LBRACKET classbodydeclarations RBRACKET { ([], []) } + | LBRACKET classbodydeclarations RBRACKET { $2 } modifiers : modifier { } | modifiers modifier { } -classbodydeclarations : classbodydeclaration { } - | classbodydeclarations classbodydeclaration{ } +classbodydeclarations : classbodydeclaration { + case $1 of + MethodDecl method -> ([method], []) + FieldDecls fields -> ([], fields) + } + -- | classbodydeclarations classbodydeclaration { + -- case ($1, $2) of + -- ((methods, fields), MethodDecl method) -> ((methods ++ [method]), fields) + -- ((methods, fields), FieldDecl field) -> (methods, (fields ++ [field])) + -- } modifier : PUBLIC { } | PROTECTED { } @@ -109,19 +117,19 @@ modifier : PUBLIC { } classtype : classorinterfacetype{ } -classbodydeclaration : classmemberdeclaration { } - | constructordeclaration { } +classbodydeclaration : classmemberdeclaration { $1 } + -- | constructordeclaration { FieldDecl $ VariableDeclaration "int" "a" Nothing } -- TODO classorinterfacetype : name{ } -classmemberdeclaration : fielddeclaration { } - | methoddeclaration { } +classmemberdeclaration : fielddeclaration { $1 } + -- | methoddeclaration { } constructordeclaration : constructordeclarator constructorbody { } | modifiers constructordeclarator constructorbody { } -fielddeclaration : type variabledeclarators SEMICOLON { } - | modifiers type variabledeclarators SEMICOLON { } +fielddeclaration : type variabledeclarators SEMICOLON { FieldDecls $ map (convertDeclarator $1) $2 } + -- | modifiers type variabledeclarators SEMICOLON {} methoddeclaration : methodheader methodbody { } @@ -141,11 +149,11 @@ methodheader : type methoddeclarator { } | VOID methoddeclarator { } | modifiers VOID methoddeclarator { } -type : primitivetype { } - | referencetype { } +type : primitivetype { $1 } + -- | referencetype { } -variabledeclarators : variabledeclarator { } - | variabledeclarators COMMA variabledeclarator { } +variabledeclarators : variabledeclarator { [$1] } + -- | variabledeclarators COMMA variabledeclarator { $1 ++ [$3] } methodbody : block { } | SEMICOLON { } @@ -165,14 +173,14 @@ classtypelist : classtype { } methoddeclarator : IDENTIFIER LBRACE RBRACE { } | IDENTIFIER LBRACE formalparameterlist RBRACE { } -primitivetype : BOOLEAN { } - | numerictype { } +primitivetype : BOOLEAN { "boolean" } + | numerictype { $1 } referencetype : classorinterfacetype { } -variabledeclarator : variabledeclaratorid { } - | variabledeclaratorid ASSIGN variableinitializer { } +variabledeclarator : variabledeclaratorid { Declarator $1 Nothing } + -- | variabledeclaratorid ASSIGN variableinitializer { Declarator $1 Nothing } -- TODO blockstatement : localvariabledeclarationstatement { } | statement { } @@ -182,9 +190,9 @@ formalparameter : type variabledeclaratorid { } argumentlist : expression { } | argumentlist COMMA expression { } -numerictype : integraltype { } +numerictype : integraltype { $1 } -variabledeclaratorid : IDENTIFIER { } +variabledeclaratorid : IDENTIFIER { $1 } variableinitializer : expression { } @@ -198,8 +206,8 @@ statement : statementwithouttrailingsubstatement{ } expression : assignmentexpression { } -integraltype : INT { } - | CHAR { } +integraltype : INT { "int" } + | CHAR { "char" } localvariabledeclaration : type variabledeclarators { } @@ -352,7 +360,18 @@ multiplicativeexpression : unaryexpression { } { +data MethodOrFieldDeclaration = MethodDecl MethodDeclaration + | FieldDecls [VariableDeclaration] + +data Declarator = Declarator Identifier (Maybe Expression) + +-- convertDeclaratorList :: [DataType] -> MethodOrFieldDeclaration +-- convertDeclaratorList = FieldDecls $ map + +convertDeclarator :: DataType -> Declarator -> VariableDeclaration +convertDeclarator dataType (Declarator id assigment) = VariableDeclaration dataType id assigment + parseError :: [Token] -> a -parseError _ = error "Parse error" +parseError msg = error ("Parse error: " ++ show msg) }